feat: deployment flags (#4426)

This commit is contained in:
Garrett Delfosse
2022-10-10 15:04:15 -04:00
committed by GitHub
parent b50bb99fe7
commit b1faaef482
11 changed files with 949 additions and 284 deletions

455
cli/deployment/flags.go Normal file
View File

@ -0,0 +1,455 @@
package deployment
import (
"flag"
"os"
"path/filepath"
"reflect"
"time"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/spf13/pflag"
"github.com/coder/coder/cli/cliflag"
"github.com/coder/coder/codersdk"
)
const (
secretValue = "********"
)
func Flags() codersdk.DeploymentFlags {
return codersdk.DeploymentFlags{
AccessURL: codersdk.StringFlag{
Name: "Access URL",
Flag: "access-url",
EnvVar: "CODER_ACCESS_URL",
Description: "External URL to access your deployment. This must be accessible by all provisioned workspaces.",
},
WildcardAccessURL: codersdk.StringFlag{
Name: "Wildcard Address URL",
Flag: "wildcard-access-url",
EnvVar: "CODER_WILDCARD_ACCESS_URL",
Description: `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".`,
},
Address: codersdk.StringFlag{
Name: "Bind Address",
Flag: "address",
EnvVar: "CODER_ADDRESS",
Shorthand: "a",
Description: "Bind address of the server.",
Default: "127.0.0.1:3000",
},
AutobuildPollInterval: codersdk.DurationFlag{
Name: "Autobuild Poll Interval",
Flag: "autobuild-poll-interval",
EnvVar: "CODER_AUTOBUILD_POLL_INTERVAL",
Description: "Interval to poll for scheduled workspace builds.",
Default: time.Minute,
},
DerpServerEnable: codersdk.BoolFlag{
Name: "DERP Server Enabled",
Flag: "derp-server-enable",
EnvVar: "CODER_DERP_SERVER_ENABLE",
Description: "Whether to enable or disable the embedded DERP relay server.",
Default: true,
},
DerpServerRegionID: codersdk.IntFlag{
Name: "DERP Server Region ID",
Flag: "derp-server-region-id",
EnvVar: "CODER_DERP_SERVER_REGION_ID",
Description: "Region ID to use for the embedded DERP server.",
Default: 999,
},
DerpServerRegionCode: codersdk.StringFlag{
Name: "DERP Server Region Code",
Flag: "derp-server-region-code",
EnvVar: "CODER_DERP_SERVER_REGION_CODE",
Description: "Region code to use for the embedded DERP server.",
Default: "coder",
},
DerpServerRegionName: codersdk.StringFlag{
Name: "DERP Server Region Name",
Flag: "derp-server-region-name",
EnvVar: "CODER_DERP_SERVER_REGION_NAME",
Description: "Region name that for the embedded DERP server.",
Default: "Coder Embedded Relay",
},
DerpServerSTUNAddresses: codersdk.StringArrayFlag{
Name: "DERP Server STUN Addresses",
Flag: "derp-server-stun-addresses",
EnvVar: "CODER_DERP_SERVER_STUN_ADDRESSES",
Description: "Addresses for STUN servers to establish P2P connections. Set empty to disable P2P connections.",
Default: []string{"stun.l.google.com:19302"},
},
DerpConfigURL: codersdk.StringFlag{
Name: "DERP Config URL",
Flag: "derp-config-url",
EnvVar: "CODER_DERP_CONFIG_URL",
Description: "URL to fetch a DERP mapping on startup. See: https://tailscale.com/kb/1118/custom-derp-servers/",
},
DerpConfigPath: codersdk.StringFlag{
Name: "DERP Config Path",
Flag: "derp-config-path",
EnvVar: "CODER_DERP_CONFIG_PATH",
Description: "Path to read a DERP mapping from. See: https://tailscale.com/kb/1118/custom-derp-servers/",
},
PromEnabled: codersdk.BoolFlag{
Name: "Prometheus Enabled",
Flag: "prometheus-enable",
EnvVar: "CODER_PROMETHEUS_ENABLE",
Description: "Serve prometheus metrics on the address defined by `prometheus-address`.",
},
PromAddress: codersdk.StringFlag{
Name: "Prometheus Address",
Flag: "prometheus-address",
EnvVar: "CODER_PROMETHEUS_ADDRESS",
Description: "The bind address to serve prometheus metrics.",
Default: "127.0.0.1:2112",
},
PprofEnabled: codersdk.BoolFlag{
Name: "pprof Enabled",
Flag: "pprof-enable",
EnvVar: "CODER_PPROF_ENABLE",
Description: "Serve pprof metrics on the address defined by `pprof-address`.",
},
PprofAddress: codersdk.StringFlag{
Name: "pprof Address",
Flag: "pprof-address",
EnvVar: "CODER_PPROF_ADDRESS",
Description: "The bind address to serve pprof.",
Default: "127.0.0.1:6060",
},
CacheDir: codersdk.StringFlag{
Name: "Cache Directory",
Flag: "cache-dir",
EnvVar: "CODER_CACHE_DIRECTORY",
Description: "The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is set, it will be used for compatibility with systemd.",
Default: defaultCacheDir(),
},
InMemoryDatabase: codersdk.BoolFlag{
Name: "In-Memory Database",
Flag: "in-memory",
EnvVar: "CODER_INMEMORY",
Description: "Controls whether data will be stored in an in-memory database.",
},
ProvisionerDaemonCount: codersdk.IntFlag{
Name: "Provisioner Daemons",
Flag: "provisioner-daemons",
EnvVar: "CODER_PROVISIONER_DAEMONS",
Description: "Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.",
Default: 3,
},
PostgresURL: codersdk.StringFlag{
Name: "Postgres URL",
Flag: "postgres-url",
EnvVar: "CODER_PG_CONNECTION_URL",
Description: "URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven (https://repo1.maven.org/maven2) and store all data in the config root. Access the built-in database with \"coder server postgres-builtin-url\"",
Secret: true,
},
OAuth2GithubClientID: codersdk.StringFlag{
Name: "Oauth2 Github Client ID",
Flag: "oauth2-github-client-id",
EnvVar: "CODER_OAUTH2_GITHUB_CLIENT_ID",
Description: "Client ID for Login with GitHub.",
},
OAuth2GithubClientSecret: codersdk.StringFlag{
Name: "Oauth2 Github Client Secret",
Flag: "oauth2-github-client-secret",
EnvVar: "CODER_OAUTH2_GITHUB_CLIENT_SECRET",
Description: "Client secret for Login with GitHub.",
Secret: true,
},
OAuth2GithubAllowedOrganizations: codersdk.StringArrayFlag{
Name: "Oauth2 Github Allowed Organizations",
Flag: "oauth2-github-allowed-orgs",
EnvVar: "CODER_OAUTH2_GITHUB_ALLOWED_ORGS",
Description: "Organizations the user must be a member of to Login with GitHub.",
},
OAuth2GithubAllowedTeams: codersdk.StringArrayFlag{
Name: "Oauth2 Github Allowed Teams",
Flag: "oauth2-github-allowed-teams",
EnvVar: "CODER_OAUTH2_GITHUB_ALLOWED_TEAMS",
Description: "Teams inside organizations the user must be a member of to Login with GitHub. Structured as: <organization-name>/<team-slug>.",
},
OAuth2GithubAllowSignups: codersdk.BoolFlag{
Name: "Oauth2 Github Allow Signups",
Flag: "oauth2-github-allow-signups",
EnvVar: "CODER_AUTOBUILD_POLL_INTERVAL",
Description: "Whether new users can sign up with GitHub.",
},
OAuth2GithubEnterpriseBaseURL: codersdk.StringFlag{
Name: "Oauth2 Github Enterprise Base URL",
Flag: "oauth2-github-enterprise-base-url",
EnvVar: "CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL",
Description: "Base URL of a GitHub Enterprise deployment to use for Login with GitHub.",
},
OIDCAllowSignups: codersdk.BoolFlag{
Name: "OIDC Allow Signups",
Flag: "oidc-allow-signups",
EnvVar: "CODER_OIDC_ALLOW_SIGNUPS",
Description: "Whether new users can sign up with OIDC.",
Default: true,
},
OIDCClientID: codersdk.StringFlag{
Name: "OIDC Client ID",
Flag: "oidc-client-id",
EnvVar: "CODER_OIDC_CLIENT_ID",
Description: "Client ID to use for Login with OIDC.",
},
OIDCClientSecret: codersdk.StringFlag{
Name: "OIDC Client Secret",
Flag: "oidc-client-secret",
EnvVar: "CODER_OIDC_CLIENT_SECRET",
Description: "Client secret to use for Login with OIDC.",
Secret: true,
},
OIDCEmailDomain: codersdk.StringFlag{
Name: "OIDC Email Domain",
Flag: "oidc-email-domain",
EnvVar: "CODER_OIDC_EMAIL_DOMAIN",
Description: "Email domain that clients logging in with OIDC must match.",
},
OIDCIssuerURL: codersdk.StringFlag{
Name: "OIDC Issuer URL",
Flag: "oidc-issuer-url",
EnvVar: "CODER_OIDC_ISSUER_URL",
Description: "Issuer URL to use for Login with OIDC.",
},
OIDCScopes: codersdk.StringArrayFlag{
Name: "OIDC Scopes",
Flag: "oidc-scopes",
EnvVar: "CODER_OIDC_SCOPES",
Description: "Scopes to grant when authenticating with OIDC.",
Default: []string{oidc.ScopeOpenID, "profile", "email"},
},
TelemetryEnable: codersdk.BoolFlag{
Name: "Telemetry Enabled",
Flag: "telemetry",
EnvVar: "CODER_TELEMETRY",
Description: "Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product.",
Default: flag.Lookup("test.v") == nil,
},
TelemetryTraceEnable: codersdk.BoolFlag{
Name: "Trace Telemetry Enabled",
Flag: "telemetry-trace",
EnvVar: "CODER_TELEMETRY_TRACE",
Shorthand: "",
Description: "Whether Opentelemetry traces are sent to Coder. Coder collects anonymized application tracing to help improve our product. Disabling telemetry also disables this option.",
Default: flag.Lookup("test.v") == nil,
},
TelemetryURL: codersdk.StringFlag{
Name: "Telemetry URL",
Flag: "telemetry-url",
EnvVar: "CODER_TELEMETRY_URL",
Description: "URL to send telemetry.",
Default: "https://telemetry.coder.com",
},
TLSEnable: codersdk.BoolFlag{
Name: "TLS Enabled",
Flag: "tls-enable",
EnvVar: "CODER_TLS_ENABLE",
Description: "Whether TLS will be enabled.",
},
TLSCertFiles: codersdk.StringArrayFlag{
Name: "TLS Cert Files",
Flag: "tls-cert-file",
EnvVar: "CODER_TLS_CERT_FILE",
Description: "Path to each certificate for TLS. It requires a PEM-encoded file. " +
"To configure the listener to use a CA certificate, concatenate the primary certificate " +
"and the CA certificate together. The primary certificate should appear first in the combined file.",
Default: []string{},
},
TLSClientCAFile: codersdk.StringFlag{
Name: "TLS Client CA File",
Flag: "tls-client-ca-file",
EnvVar: "CODER_TLS_CLIENT_CA_FILE",
Description: "PEM-encoded Certificate Authority file used for checking the authenticity of client",
},
TLSClientAuth: codersdk.StringFlag{
Name: "TLS Client Auth",
Flag: "tls-client-auth",
EnvVar: "CODER_TLS_KEY_FILE",
Description: `Policy the server will follow for TLS Client Authentication. ` +
`Accepted values are "none", "request", "require-any", "verify-if-given", or "require-and-verify"`,
Default: "request",
},
TLSKeyFiles: codersdk.StringArrayFlag{
Name: "TLS Key Files",
Flag: "tls-key-file",
EnvVar: "CODER_TLS_KEY_FILE",
Description: "Paths to the private keys for each of the certificates. It requires a PEM-encoded file",
Default: []string{},
},
TLSMinVersion: codersdk.StringFlag{
Name: "TLS Min Version",
Flag: "tls-min-version",
EnvVar: "CODER_TLS_MIN_VERSION",
Description: `Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13"`,
Default: "tls12",
},
TraceEnable: codersdk.BoolFlag{
Name: "Trace Enabled",
Flag: "trace",
EnvVar: "CODER_TRACE",
Description: "Whether application tracing data is collected.",
},
SecureAuthCookie: codersdk.BoolFlag{
Name: "Secure Auth Cookie",
Flag: "secure-auth-cookie",
EnvVar: "CODER_SECURE_AUTH_COOKIE",
Description: "Controls if the 'Secure' property is set on browser session cookies",
},
SSHKeygenAlgorithm: codersdk.StringFlag{
Name: "SSH Keygen Algorithm",
Flag: "ssh-keygen-algorithm",
EnvVar: "CODER_SSH_KEYGEN_ALGORITHM",
Description: "The algorithm to use for generating ssh keys. " +
`Accepted values are "ed25519", "ecdsa", or "rsa4096"`,
Default: "ed25519",
},
AutoImportTemplates: codersdk.StringArrayFlag{
Name: "Auto Import Templates",
Flag: "auto-import-template",
EnvVar: "CODER_TEMPLATE_AUTOIMPORT",
Description: "Templates to auto-import. Available auto-importable templates are: kubernetes",
Default: []string{},
},
MetricsCacheRefreshInterval: codersdk.DurationFlag{
Name: "Metrics Cache Refresh Interval",
Flag: "metrics-cache-refresh-interval",
EnvVar: "CODER_METRICS_CACHE_REFRESH_INTERVAL",
Description: "How frequently metrics are refreshed",
Default: time.Hour,
},
AgentStatRefreshInterval: codersdk.DurationFlag{
Name: "Agent Stats Refresh Interval",
Flag: "agent-stats-refresh-interval",
EnvVar: "CODER_AGENT_STATS_REFRESH_INTERVAL",
Description: "How frequently agent stats are recorded",
Default: 10 * time.Minute,
},
Verbose: codersdk.BoolFlag{
Name: "Verbose Logging",
Flag: "verbose",
EnvVar: "CODER_VERBOSE",
Shorthand: "v",
Description: "Enables verbose logging.",
},
AuditLogging: codersdk.BoolFlag{
Name: "Audit Logging",
Flag: "audit-logging",
EnvVar: "CODER_AUDIT_LOGGING",
Description: "Specifies whether audit logging is enabled.",
Default: true,
Enterprise: true,
},
BrowserOnly: codersdk.BoolFlag{
Name: "Browser Only",
Flag: "browser-only",
EnvVar: "CODER_BROWSER_ONLY",
Description: "Whether Coder only allows connections to workspaces via the browser.",
Enterprise: true,
},
SCIMAuthHeader: codersdk.StringFlag{
Name: "SCIM Authentication Header",
Flag: "scim-auth-header",
EnvVar: "CODER_SCIM_API_KEY",
Description: "Enables SCIM and sets the authentication header for the built-in SCIM server. New users are automatically created with OIDC authentication.",
Secret: true,
Enterprise: true,
},
UserWorkspaceQuota: codersdk.IntFlag{
Name: "User Workspace Quota",
Flag: "user-workspace-quota",
EnvVar: "CODER_USER_WORKSPACE_QUOTA",
Description: "Enables and sets a limit on how many workspaces each user can create.",
Default: 0,
Enterprise: true,
},
}
}
func RemoveSensitiveValues(df codersdk.DeploymentFlags) codersdk.DeploymentFlags {
v := reflect.ValueOf(&df).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
fv := v.Field(i)
if v, ok := fv.Interface().(codersdk.StringFlag); ok {
if v.Secret && v.Value != "" {
v.Value = secretValue
fv.Set(reflect.ValueOf(v))
}
}
}
return df
}
func StringFlag(flagset *pflag.FlagSet, fl *codersdk.StringFlag) {
cliflag.StringVarP(flagset,
&fl.Value,
fl.Flag,
fl.Shorthand,
fl.EnvVar,
fl.Default,
fl.Description,
)
}
func BoolFlag(flagset *pflag.FlagSet, fl *codersdk.BoolFlag) {
cliflag.BoolVarP(flagset,
&fl.Value,
fl.Flag,
fl.Shorthand,
fl.EnvVar,
fl.Default,
fl.Description,
)
}
func IntFlag(flagset *pflag.FlagSet, fl *codersdk.IntFlag) {
cliflag.IntVarP(flagset,
&fl.Value,
fl.Flag,
fl.Shorthand,
fl.EnvVar,
fl.Default,
fl.Description,
)
}
func DurationFlag(flagset *pflag.FlagSet, fl *codersdk.DurationFlag) {
cliflag.DurationVarP(flagset,
&fl.Value,
fl.Flag,
fl.Shorthand,
fl.EnvVar,
fl.Default,
fl.Description,
)
}
func StringArrayFlag(flagset *pflag.FlagSet, fl *codersdk.StringArrayFlag) {
cliflag.StringArrayVarP(flagset,
&fl.Value,
fl.Flag,
fl.Shorthand,
fl.EnvVar,
fl.Default,
fl.Description,
)
}
func defaultCacheDir() string {
defaultCacheDir, err := os.UserCacheDir()
if err != nil {
defaultCacheDir = os.TempDir()
}
if dir := os.Getenv("CACHE_DIRECTORY"); dir != "" {
// For compatibility with systemd.
defaultCacheDir = dir
}
return filepath.Join(defaultCacheDir, "coder")
}

View File

@ -22,6 +22,7 @@ import (
"github.com/coder/coder/cli/cliflag"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/cli/config"
"github.com/coder/coder/cli/deployment"
"github.com/coder/coder/coderd"
"github.com/coder/coder/codersdk"
)
@ -98,7 +99,9 @@ func Core() []*cobra.Command {
}
func AGPL() []*cobra.Command {
all := append(Core(), Server(func(_ context.Context, o *coderd.Options) (*coderd.API, error) {
df := deployment.Flags()
all := append(Core(), Server(df, func(_ context.Context, o *coderd.Options) (*coderd.API, error) {
o.DeploymentFlags = &df
return coderd.New(o), nil
}))
return all

View File

@ -43,9 +43,9 @@ import (
"cdr.dev/slog"
"cdr.dev/slog/sloggers/sloghuman"
"github.com/coder/coder/buildinfo"
"github.com/coder/coder/cli/cliflag"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/cli/config"
"github.com/coder/coder/cli/deployment"
"github.com/coder/coder/coderd"
"github.com/coder/coder/coderd/autobuild/executor"
"github.com/coder/coder/coderd/database"
@ -67,67 +67,14 @@ import (
)
// nolint:gocyclo
func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) *cobra.Command {
var (
accessURL string
address string
wildcardAccessURL string
autobuildPollInterval time.Duration
derpServerEnabled bool
derpServerRegionID int
derpServerRegionCode string
derpServerRegionName string
derpServerSTUNAddrs []string
derpConfigURL string
derpConfigPath string
promEnabled bool
promAddress string
pprofEnabled bool
pprofAddress string
cacheDir string
inMemoryDatabase bool
// provisionerDaemonCount is a uint8 to ensure a number > 0.
provisionerDaemonCount uint8
postgresURL string
oauth2GithubClientID string
oauth2GithubClientSecret string
oauth2GithubAllowedOrganizations []string
oauth2GithubAllowedTeams []string
oauth2GithubAllowSignups bool
oauth2GithubEnterpriseBaseURL string
oidcAllowSignups bool
oidcClientID string
oidcClientSecret string
oidcEmailDomain string
oidcIssuerURL string
oidcScopes []string
tailscaleEnable bool
telemetryEnable bool
telemetryTraceEnable bool
telemetryURL string
tlsCertFiles []string
tlsClientCAFile string
tlsClientAuth string
tlsEnable bool
tlsKeyFiles []string
tlsMinVersion string
traceEnable bool
secureAuthCookie bool
sshKeygenAlgorithmRaw string
autoImportTemplates []string
spooky bool
verbose bool
metricsCacheRefreshInterval time.Duration
agentStatRefreshInterval time.Duration
)
func Server(dflags codersdk.DeploymentFlags, newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) *cobra.Command {
root := &cobra.Command{
Use: "server",
Short: "Start a Coder server",
RunE: func(cmd *cobra.Command, args []string) error {
printLogo(cmd, spooky)
printLogo(cmd)
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
if verbose {
if dflags.Verbose.Value {
logger = logger.Leveled(slog.LevelDebug)
}
@ -162,16 +109,16 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
// Coder tracing should be disabled if telemetry is disabled unless
// --telemetry-trace was explicitly provided.
shouldCoderTrace := telemetryEnable && !isTest()
shouldCoderTrace := dflags.TelemetryEnable.Value && !isTest()
// Only override if telemetryTraceEnable was specifically set.
// By default we want it to be controlled by telemetryEnable.
if cmd.Flags().Changed("telemetry-trace") {
shouldCoderTrace = telemetryTraceEnable
shouldCoderTrace = dflags.TelemetryTraceEnable.Value
}
if traceEnable || shouldCoderTrace {
if dflags.TraceEnable.Value || shouldCoderTrace {
sdkTracerProvider, closeTracing, err := tracing.TracerProvider(ctx, "coderd", tracing.TracerOpts{
Default: traceEnable,
Default: dflags.TraceEnable.Value,
Coder: shouldCoderTrace,
})
if err != nil {
@ -196,10 +143,10 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
config := createConfig(cmd)
builtinPostgres := false
// Only use built-in if PostgreSQL URL isn't specified!
if !inMemoryDatabase && postgresURL == "" {
if !dflags.InMemoryDatabase.Value && dflags.PostgresURL.Value == "" {
var closeFunc func() error
cmd.Printf("Using built-in PostgreSQL (%s)\n", config.PostgresPath())
postgresURL, closeFunc, err = startBuiltinPostgres(ctx, config, logger)
dflags.PostgresURL.Value, closeFunc, err = startBuiltinPostgres(ctx, config, logger)
if err != nil {
return err
}
@ -212,14 +159,20 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
}()
}
listener, err := net.Listen("tcp", address)
listener, err := net.Listen("tcp", dflags.Address.Value)
if err != nil {
return xerrors.Errorf("listen %q: %w", address, err)
return xerrors.Errorf("listen %q: %w", dflags.Address.Value, err)
}
defer listener.Close()
if tlsEnable {
listener, err = configureServerTLS(listener, tlsMinVersion, tlsClientAuth, tlsCertFiles, tlsKeyFiles, tlsClientCAFile)
if dflags.TLSEnable.Value {
listener, err = configureServerTLS(
listener, dflags.TLSMinVersion.Value,
dflags.TLSClientAuth.Value,
dflags.TLSCertFiles.Value,
dflags.TLSKeyFiles.Value,
dflags.TLSClientCAFile.Value,
)
if err != nil {
return xerrors.Errorf("configure tls: %w", err)
}
@ -239,7 +192,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
Scheme: "http",
Host: tcpAddr.String(),
}
if tlsEnable {
if dflags.TLSEnable.Value {
localURL.Scheme = "https"
}
@ -252,16 +205,16 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
// If the access URL is empty, we attempt to run a reverse-proxy tunnel
// to make the initial setup really simple.
if accessURL == "" {
if dflags.AccessURL.Value == "" {
cmd.Printf("Opening tunnel so workspaces can connect to your deployment. For production scenarios, specify an external access URL\n")
tunnel, tunnelErr, err = devtunnel.New(ctxTunnel, logger.Named("devtunnel"))
if err != nil {
return xerrors.Errorf("create tunnel: %w", err)
}
accessURL = tunnel.URL
dflags.AccessURL.Value = tunnel.URL
}
accessURLParsed, err := parseURL(ctx, accessURL)
accessURLParsed, err := parseURL(ctx, dflags.AccessURL.Value)
if err != nil {
return xerrors.Errorf("parse URL: %w", err)
}
@ -296,17 +249,17 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
return err
}
sshKeygenAlgorithm, err := gitsshkey.ParseAlgorithm(sshKeygenAlgorithmRaw)
sshKeygenAlgorithm, err := gitsshkey.ParseAlgorithm(dflags.SSHKeygenAlgorithm.Value)
if err != nil {
return xerrors.Errorf("parse ssh keygen algorithm %s: %w", sshKeygenAlgorithmRaw, err)
return xerrors.Errorf("parse ssh keygen algorithm %s: %w", dflags.SSHKeygenAlgorithm.Value, err)
}
// Validate provided auto-import templates.
var (
validatedAutoImportTemplates = make([]coderd.AutoImportTemplate, len(autoImportTemplates))
seenValidatedAutoImportTemplates = make(map[coderd.AutoImportTemplate]struct{}, len(autoImportTemplates))
validatedAutoImportTemplates = make([]coderd.AutoImportTemplate, len(dflags.AutoImportTemplates.Value))
seenValidatedAutoImportTemplates = make(map[coderd.AutoImportTemplate]struct{}, len(dflags.AutoImportTemplates.Value))
)
for i, autoImportTemplate := range autoImportTemplates {
for i, autoImportTemplate := range dflags.AutoImportTemplates.Value {
var v coderd.AutoImportTemplate
switch autoImportTemplate {
case "kubernetes":
@ -324,27 +277,27 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
defaultRegion := &tailcfg.DERPRegion{
EmbeddedRelay: true,
RegionID: derpServerRegionID,
RegionCode: derpServerRegionCode,
RegionName: derpServerRegionName,
RegionID: dflags.DerpServerRegionID.Value,
RegionCode: dflags.DerpServerRegionCode.Value,
RegionName: dflags.DerpServerRegionName.Value,
Nodes: []*tailcfg.DERPNode{{
Name: fmt.Sprintf("%db", derpServerRegionID),
RegionID: derpServerRegionID,
Name: fmt.Sprintf("%db", dflags.DerpServerRegionID.Value),
RegionID: dflags.DerpServerRegionID.Value,
HostName: accessURLParsed.Hostname(),
DERPPort: accessURLPort,
STUNPort: -1,
ForceHTTP: accessURLParsed.Scheme == "http",
}},
}
if !derpServerEnabled {
if !dflags.DerpServerEnable.Value {
defaultRegion = nil
}
derpMap, err := tailnet.NewDERPMap(ctx, defaultRegion, derpServerSTUNAddrs, derpConfigURL, derpConfigPath)
derpMap, err := tailnet.NewDERPMap(ctx, defaultRegion, dflags.DerpServerSTUNAddresses.Value, dflags.DerpConfigURL.Value, dflags.DerpConfigPath.Value)
if err != nil {
return xerrors.Errorf("create derp map: %w", err)
}
appHostname := strings.TrimPrefix(wildcardAccessURL, "http://")
appHostname := strings.TrimPrefix(dflags.WildcardAccessURL.Value, "http://")
appHostname = strings.TrimPrefix(appHostname, "https://")
appHostname = strings.TrimPrefix(appHostname, "*.")
@ -355,34 +308,42 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
Database: databasefake.New(),
DERPMap: derpMap,
Pubsub: database.NewPubsubInMemory(),
CacheDir: cacheDir,
CacheDir: dflags.CacheDir.Value,
GoogleTokenValidator: googleTokenValidator,
SecureAuthCookie: secureAuthCookie,
SecureAuthCookie: dflags.SecureAuthCookie.Value,
SSHKeygenAlgorithm: sshKeygenAlgorithm,
TracerProvider: tracerProvider,
Telemetry: telemetry.NewNoop(),
AutoImportTemplates: validatedAutoImportTemplates,
MetricsCacheRefreshInterval: metricsCacheRefreshInterval,
AgentStatsRefreshInterval: agentStatRefreshInterval,
MetricsCacheRefreshInterval: dflags.MetricsCacheRefreshInterval.Value,
AgentStatsRefreshInterval: dflags.AgentStatRefreshInterval.Value,
Experimental: ExperimentalEnabled(cmd),
DeploymentFlags: &dflags,
}
if oauth2GithubClientSecret != "" {
options.GithubOAuth2Config, err = configureGithubOAuth2(accessURLParsed, oauth2GithubClientID, oauth2GithubClientSecret, oauth2GithubAllowSignups, oauth2GithubAllowedOrganizations, oauth2GithubAllowedTeams, oauth2GithubEnterpriseBaseURL)
if dflags.OAuth2GithubClientSecret.Value != "" {
options.GithubOAuth2Config, err = configureGithubOAuth2(accessURLParsed,
dflags.OAuth2GithubClientID.Value,
dflags.OAuth2GithubClientSecret.Value,
dflags.OAuth2GithubAllowSignups.Value,
dflags.OAuth2GithubAllowedOrganizations.Value,
dflags.OAuth2GithubAllowedTeams.Value,
dflags.OAuth2GithubEnterpriseBaseURL.Value,
)
if err != nil {
return xerrors.Errorf("configure github oauth2: %w", err)
}
}
if oidcClientSecret != "" {
if oidcClientID == "" {
if dflags.OIDCClientSecret.Value != "" {
if dflags.OIDCClientID.Value == "" {
return xerrors.Errorf("OIDC client ID be set!")
}
if oidcIssuerURL == "" {
if dflags.OIDCIssuerURL.Value == "" {
return xerrors.Errorf("OIDC issuer URL must be set!")
}
oidcProvider, err := oidc.NewProvider(ctx, oidcIssuerURL)
oidcProvider, err := oidc.NewProvider(ctx, dflags.OIDCIssuerURL.Value)
if err != nil {
return xerrors.Errorf("configure oidc provider: %w", err)
}
@ -392,25 +353,25 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
}
options.OIDCConfig = &coderd.OIDCConfig{
OAuth2Config: &oauth2.Config{
ClientID: oidcClientID,
ClientSecret: oidcClientSecret,
ClientID: dflags.OIDCClientID.Value,
ClientSecret: dflags.OIDCClientSecret.Value,
RedirectURL: redirectURL.String(),
Endpoint: oidcProvider.Endpoint(),
Scopes: oidcScopes,
Scopes: dflags.OIDCScopes.Value,
},
Verifier: oidcProvider.Verifier(&oidc.Config{
ClientID: oidcClientID,
ClientID: dflags.OIDCClientID.Value,
}),
EmailDomain: oidcEmailDomain,
AllowSignups: oidcAllowSignups,
EmailDomain: dflags.OIDCEmailDomain.Value,
AllowSignups: dflags.OIDCAllowSignups.Value,
}
}
if inMemoryDatabase {
if dflags.InMemoryDatabase.Value {
options.Database = databasefake.New()
options.Pubsub = database.NewPubsubInMemory()
} else {
sqlDB, err := sql.Open(sqlDriver, postgresURL)
sqlDB, err := sql.Open(sqlDriver, dflags.PostgresURL.Value)
if err != nil {
return xerrors.Errorf("dial postgres: %w", err)
}
@ -425,7 +386,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
return xerrors.Errorf("migrate up: %w", err)
}
options.Database = database.New(sqlDB)
options.Pubsub, err = database.NewPubsub(ctx, sqlDB, postgresURL)
options.Pubsub, err = database.NewPubsub(ctx, sqlDB, dflags.PostgresURL.Value)
if err != nil {
return xerrors.Errorf("create pubsub: %w", err)
}
@ -448,26 +409,26 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
}
// Parse the raw telemetry URL!
telemetryURL, err := parseURL(ctx, telemetryURL)
telemetryURL, err := parseURL(ctx, dflags.TelemetryURL.Value)
if err != nil {
return xerrors.Errorf("parse telemetry url: %w", err)
}
// Disable telemetry if the in-memory database is used unless explicitly defined!
if inMemoryDatabase && !cmd.Flags().Changed("telemetry") {
telemetryEnable = false
if dflags.InMemoryDatabase.Value && !cmd.Flags().Changed(dflags.TelemetryEnable.Flag) {
dflags.TelemetryEnable.Value = false
}
if telemetryEnable {
if dflags.TelemetryEnable.Value {
options.Telemetry, err = telemetry.New(telemetry.Options{
BuiltinPostgres: builtinPostgres,
DeploymentID: deploymentID,
Database: options.Database,
Logger: logger.Named("telemetry"),
URL: telemetryURL,
GitHubOAuth: oauth2GithubClientID != "",
OIDCAuth: oidcClientID != "",
OIDCIssuerURL: oidcIssuerURL,
Prometheus: promEnabled,
STUN: len(derpServerSTUNAddrs) != 0,
GitHubOAuth: dflags.OAuth2GithubClientID.Value != "",
OIDCAuth: dflags.OIDCClientID.Value != "",
OIDCIssuerURL: dflags.OIDCIssuerURL.Value,
Prometheus: dflags.PromEnabled.Value,
STUN: len(dflags.DerpServerSTUNAddresses.Value) != 0,
Tunnel: tunnel != nil,
})
if err != nil {
@ -478,11 +439,11 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
// This prevents the pprof import from being accidentally deleted.
_ = pprof.Handler
if pprofEnabled {
if dflags.PprofEnabled.Value {
//nolint:revive
defer serveHandler(ctx, logger, nil, pprofAddress, "pprof")()
defer serveHandler(ctx, logger, nil, dflags.PprofAddress.Value, "pprof")()
}
if promEnabled {
if dflags.PromEnabled.Value {
options.PrometheusRegistry = prometheus.NewRegistry()
closeUsersFunc, err := prometheusmetrics.ActiveUsers(ctx, options.PrometheusRegistry, options.Database, 0)
if err != nil {
@ -499,7 +460,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
//nolint:revive
defer serveHandler(ctx, logger, promhttp.InstrumentMetricHandler(
options.PrometheusRegistry, promhttp.HandlerFor(options.PrometheusRegistry, promhttp.HandlerOpts{}),
), promAddress, "prometheus")()
), dflags.PromAddress.Value, "prometheus")()
}
coderAPI, err := newAPI(ctx, options)
@ -509,7 +470,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
defer coderAPI.Close()
client := codersdk.New(localURL)
if tlsEnable {
if dflags.TLSEnable.Value {
// Secure transport isn't needed for locally communicating!
client.HTTPClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
@ -533,8 +494,8 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
_ = daemon.Close()
}
}()
for i := 0; uint8(i) < provisionerDaemonCount; i++ {
daemon, err := newProvisionerDaemon(ctx, coderAPI, logger, cacheDir, errCh, false)
for i := 0; i < dflags.ProvisionerDaemonCount.Value; i++ {
daemon, err := newProvisionerDaemon(ctx, coderAPI, logger, dflags.CacheDir.Value, errCh, false)
if err != nil {
return xerrors.Errorf("create provisioner daemon: %w", err)
}
@ -600,7 +561,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
return xerrors.Errorf("notify systemd: %w", err)
}
autobuildPoller := time.NewTicker(autobuildPollInterval)
autobuildPoller := time.NewTicker(dflags.AutobuildPollInterval.Value)
defer autobuildPoller.Stop()
autobuildExecutor := executor.New(ctx, options.Database, logger, autobuildPoller.C)
autobuildExecutor.Run()
@ -665,7 +626,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
go func() {
defer wg.Done()
if verbose {
if dflags.Verbose.Value {
cmd.Printf("Shutting down provisioner daemon %d...\n", id)
}
err := shutdownWithTimeout(provisionerDaemon.Shutdown, 5*time.Second)
@ -678,7 +639,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
cmd.PrintErrf("Close provisioner daemon %d: %s\n", id, err)
return
}
if verbose {
if dflags.Verbose.Value {
cmd.Printf("Gracefully shut down provisioner daemon %d\n", id)
}
}()
@ -730,7 +691,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
RunE: func(cmd *cobra.Command, args []string) error {
cfg := createConfig(cmd)
logger := slog.Make(sloghuman.Sink(cmd.ErrOrStderr()))
if verbose {
if dflags.Verbose.Value {
logger = logger.Leveled(slog.LevelDebug)
}
@ -751,128 +712,58 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
},
})
cliflag.DurationVarP(root.Flags(), &autobuildPollInterval, "autobuild-poll-interval", "", "CODER_AUTOBUILD_POLL_INTERVAL", time.Minute,
"Interval to poll for scheduled workspace builds.")
_ = root.Flags().MarkHidden("autobuild-poll-interval")
cliflag.StringVarP(root.Flags(), &accessURL, "access-url", "", "CODER_ACCESS_URL", "",
"External URL to access your deployment. This must be accessible by all provisioned workspaces.")
cliflag.StringVarP(root.Flags(), &address, "address", "a", "CODER_ADDRESS", "127.0.0.1:3000",
"Bind address of the server.")
cliflag.StringVarP(root.Flags(), &wildcardAccessURL, "wildcard-access-url", "", "CODER_WILDCARD_ACCESS_URL", "", `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".`)
cliflag.StringVarP(root.Flags(), &derpConfigURL, "derp-config-url", "", "CODER_DERP_CONFIG_URL", "",
"URL to fetch a DERP mapping on startup. See: https://tailscale.com/kb/1118/custom-derp-servers/")
cliflag.StringVarP(root.Flags(), &derpConfigPath, "derp-config-path", "", "CODER_DERP_CONFIG_PATH", "",
"Path to read a DERP mapping from. See: https://tailscale.com/kb/1118/custom-derp-servers/")
cliflag.BoolVarP(root.Flags(), &derpServerEnabled, "derp-server-enable", "", "CODER_DERP_SERVER_ENABLE", true,
"Whether to enable or disable the embedded DERP relay server.")
cliflag.IntVarP(root.Flags(), &derpServerRegionID, "derp-server-region-id", "", "CODER_DERP_SERVER_REGION_ID", 999,
"Region ID to use for the embedded DERP server.")
cliflag.StringVarP(root.Flags(), &derpServerRegionCode, "derp-server-region-code", "", "CODER_DERP_SERVER_REGION_CODE", "coder",
"Region code that for the embedded DERP server.")
cliflag.StringVarP(root.Flags(), &derpServerRegionName, "derp-server-region-name", "", "CODER_DERP_SERVER_REGION_NAME", "Coder Embedded Relay",
"Region name that for the embedded DERP server.")
cliflag.StringArrayVarP(root.Flags(), &derpServerSTUNAddrs, "derp-server-stun-addresses", "", "CODER_DERP_SERVER_STUN_ADDRESSES", []string{
"stun.l.google.com:19302",
}, "Addresses for STUN servers to establish P2P connections. Set empty to disable P2P connections.")
cliflag.BoolVarP(root.Flags(), &promEnabled, "prometheus-enable", "", "CODER_PROMETHEUS_ENABLE", false,
"Serve prometheus metrics on the address defined by `prometheus-address`.")
cliflag.StringVarP(root.Flags(), &promAddress, "prometheus-address", "", "CODER_PROMETHEUS_ADDRESS", "127.0.0.1:2112",
"The bind address to serve prometheus metrics.")
cliflag.BoolVarP(root.Flags(), &pprofEnabled, "pprof-enable", "", "CODER_PPROF_ENABLE", false,
"Serve pprof metrics on the address defined by `pprof-address`.")
cliflag.StringVarP(root.Flags(), &pprofAddress, "pprof-address", "", "CODER_PPROF_ADDRESS", "127.0.0.1:6060",
"The bind address to serve pprof.")
defaultCacheDir, err := os.UserCacheDir()
if err != nil {
defaultCacheDir = os.TempDir()
}
if dir := os.Getenv("CACHE_DIRECTORY"); dir != "" {
// For compatibility with systemd.
defaultCacheDir = dir
}
defaultCacheDir = filepath.Join(defaultCacheDir, "coder")
cliflag.StringVarP(root.Flags(), &cacheDir, "cache-dir", "", "CODER_CACHE_DIRECTORY", defaultCacheDir,
"The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is set, it will be used for compatibility with systemd.")
cliflag.BoolVarP(root.Flags(), &inMemoryDatabase, "in-memory", "", "CODER_INMEMORY", false,
"Controls whether data will be stored in an in-memory database.")
_ = root.Flags().MarkHidden("in-memory")
cliflag.StringVarP(root.Flags(), &postgresURL, "postgres-url", "", "CODER_PG_CONNECTION_URL", "",
"URL of a PostgreSQL database. If empty, PostgreSQL binaries will be downloaded from Maven (https://repo1.maven.org/maven2) and store all data in the config root. Access the built-in database with \"coder server postgres-builtin-url\"")
cliflag.Uint8VarP(root.Flags(), &provisionerDaemonCount, "provisioner-daemons", "", "CODER_PROVISIONER_DAEMONS", 3,
"Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.")
cliflag.StringVarP(root.Flags(), &oauth2GithubClientID, "oauth2-github-client-id", "", "CODER_OAUTH2_GITHUB_CLIENT_ID", "",
"Client ID for Login with GitHub.")
cliflag.StringVarP(root.Flags(), &oauth2GithubClientSecret, "oauth2-github-client-secret", "", "CODER_OAUTH2_GITHUB_CLIENT_SECRET", "",
"Client secret for Login with GitHub.")
cliflag.StringArrayVarP(root.Flags(), &oauth2GithubAllowedOrganizations, "oauth2-github-allowed-orgs", "", "CODER_OAUTH2_GITHUB_ALLOWED_ORGS", nil,
"Organizations the user must be a member of to Login with GitHub.")
cliflag.StringArrayVarP(root.Flags(), &oauth2GithubAllowedTeams, "oauth2-github-allowed-teams", "", "CODER_OAUTH2_GITHUB_ALLOWED_TEAMS", nil,
"Teams inside organizations the user must be a member of to Login with GitHub. Structured as: <organization-name>/<team-slug>.")
cliflag.BoolVarP(root.Flags(), &oauth2GithubAllowSignups, "oauth2-github-allow-signups", "", "CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS", false,
"Whether new users can sign up with GitHub.")
cliflag.StringVarP(root.Flags(), &oauth2GithubEnterpriseBaseURL, "oauth2-github-enterprise-base-url", "", "CODER_OAUTH2_GITHUB_ENTERPRISE_BASE_URL", "",
"Base URL of a GitHub Enterprise deployment to use for Login with GitHub.")
cliflag.BoolVarP(root.Flags(), &oidcAllowSignups, "oidc-allow-signups", "", "CODER_OIDC_ALLOW_SIGNUPS", true,
"Whether new users can sign up with OIDC.")
cliflag.StringVarP(root.Flags(), &oidcClientID, "oidc-client-id", "", "CODER_OIDC_CLIENT_ID", "",
"Client ID to use for Login with OIDC.")
cliflag.StringVarP(root.Flags(), &oidcClientSecret, "oidc-client-secret", "", "CODER_OIDC_CLIENT_SECRET", "",
"Client secret to use for Login with OIDC.")
cliflag.StringVarP(root.Flags(), &oidcEmailDomain, "oidc-email-domain", "", "CODER_OIDC_EMAIL_DOMAIN", "",
"Email domain that clients logging in with OIDC must match.")
cliflag.StringVarP(root.Flags(), &oidcIssuerURL, "oidc-issuer-url", "", "CODER_OIDC_ISSUER_URL", "",
"Issuer URL to use for Login with OIDC.")
cliflag.StringArrayVarP(root.Flags(), &oidcScopes, "oidc-scopes", "", "CODER_OIDC_SCOPES", []string{oidc.ScopeOpenID, "profile", "email"},
"Scopes to grant when authenticating with OIDC.")
cliflag.BoolVarP(root.Flags(), &tailscaleEnable, "tailscale", "", "CODER_TAILSCALE", true,
"Specifies whether Tailscale networking is used for web applications and terminals.")
_ = root.Flags().MarkHidden("tailscale")
enableTelemetryByDefault := !isTest()
cliflag.BoolVarP(root.Flags(), &telemetryEnable, "telemetry", "", "CODER_TELEMETRY", enableTelemetryByDefault,
"Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product.")
cliflag.BoolVarP(root.Flags(), &telemetryTraceEnable, "telemetry-trace", "", "CODER_TELEMETRY_TRACE", enableTelemetryByDefault,
"Whether Opentelemetry traces are sent to Coder. Coder collects anonymized application tracing to help improve our product. Disabling telemetry also disables this option.")
cliflag.StringVarP(root.Flags(), &telemetryURL, "telemetry-url", "", "CODER_TELEMETRY_URL", "https://telemetry.coder.com",
"URL to send telemetry.")
_ = root.Flags().MarkHidden("telemetry-url")
cliflag.BoolVarP(root.Flags(), &tlsEnable, "tls-enable", "", "CODER_TLS_ENABLE", false,
"Whether TLS will be enabled.")
cliflag.StringArrayVarP(root.Flags(), &tlsCertFiles, "tls-cert-file", "", "CODER_TLS_CERT_FILE", []string{},
"Path to each certificate for TLS. It requires a PEM-encoded file. "+
"To configure the listener to use a CA certificate, concatenate the primary certificate "+
"and the CA certificate together. The primary certificate should appear first in the combined file.")
cliflag.StringVarP(root.Flags(), &tlsClientCAFile, "tls-client-ca-file", "", "CODER_TLS_CLIENT_CA_FILE", "",
"PEM-encoded Certificate Authority file used for checking the authenticity of client")
cliflag.StringVarP(root.Flags(), &tlsClientAuth, "tls-client-auth", "", "CODER_TLS_CLIENT_AUTH", "request",
`Policy the server will follow for TLS Client Authentication. `+
`Accepted values are "none", "request", "require-any", "verify-if-given", or "require-and-verify"`)
cliflag.StringArrayVarP(root.Flags(), &tlsKeyFiles, "tls-key-file", "", "CODER_TLS_KEY_FILE", []string{},
"Paths to the private keys for each of the certificates. It requires a PEM-encoded file")
cliflag.StringVarP(root.Flags(), &tlsMinVersion, "tls-min-version", "", "CODER_TLS_MIN_VERSION", "tls12",
`Minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13"`)
cliflag.BoolVarP(root.Flags(), &traceEnable, "trace", "", "CODER_TRACE", false,
"Whether application tracing data is collected.")
cliflag.BoolVarP(root.Flags(), &secureAuthCookie, "secure-auth-cookie", "", "CODER_SECURE_AUTH_COOKIE", false,
"Controls if the 'Secure' property is set on browser session cookies")
cliflag.StringVarP(root.Flags(), &sshKeygenAlgorithmRaw, "ssh-keygen-algorithm", "", "CODER_SSH_KEYGEN_ALGORITHM", "ed25519",
"The algorithm to use for generating ssh keys. "+
`Accepted values are "ed25519", "ecdsa", or "rsa4096"`)
cliflag.StringArrayVarP(root.Flags(), &autoImportTemplates, "auto-import-template", "", "CODER_TEMPLATE_AUTOIMPORT", []string{},
"Templates to auto-import. Available auto-importable templates are: kubernetes")
_ = root.Flags().MarkHidden("auto-import-template")
cliflag.BoolVarP(root.Flags(), &spooky, "spooky", "", "", false, "Specifies spookiness level...")
_ = root.Flags().MarkHidden("spooky")
cliflag.BoolVarP(root.Flags(), &verbose, "verbose", "v", "CODER_VERBOSE", false,
"Enables verbose logging.")
// These metrics flags are for manually testing the metric system.
// The defaults should be acceptable for any Coder deployment of any
// reasonable size.
cliflag.DurationVarP(root.Flags(), &metricsCacheRefreshInterval, "metrics-cache-refresh-interval", "", "CODER_METRICS_CACHE_REFRESH_INTERVAL", time.Hour, "How frequently metrics are refreshed")
_ = root.Flags().MarkHidden("metrics-cache-refresh-interval")
cliflag.DurationVarP(root.Flags(), &agentStatRefreshInterval, "agent-stats-refresh-interval", "", "CODER_AGENT_STATS_REFRESH_INTERVAL", time.Minute*10, "How frequently agent stats are recorded")
_ = root.Flags().MarkHidden("agent-stats-refresh-interval")
deployment.StringFlag(root.Flags(), &dflags.AccessURL)
deployment.StringFlag(root.Flags(), &dflags.WildcardAccessURL)
deployment.StringFlag(root.Flags(), &dflags.Address)
deployment.DurationFlag(root.Flags(), &dflags.AutobuildPollInterval)
_ = root.Flags().MarkHidden(dflags.AutobuildPollInterval.Flag)
deployment.BoolFlag(root.Flags(), &dflags.DerpServerEnable)
deployment.IntFlag(root.Flags(), &dflags.DerpServerRegionID)
deployment.StringFlag(root.Flags(), &dflags.DerpServerRegionCode)
deployment.StringFlag(root.Flags(), &dflags.DerpServerRegionName)
deployment.StringArrayFlag(root.Flags(), &dflags.DerpServerSTUNAddresses)
deployment.StringFlag(root.Flags(), &dflags.DerpConfigURL)
deployment.StringFlag(root.Flags(), &dflags.DerpConfigPath)
deployment.BoolFlag(root.Flags(), &dflags.PromEnabled)
deployment.StringFlag(root.Flags(), &dflags.PromAddress)
deployment.BoolFlag(root.Flags(), &dflags.PprofEnabled)
deployment.StringFlag(root.Flags(), &dflags.CacheDir)
deployment.BoolFlag(root.Flags(), &dflags.InMemoryDatabase)
_ = root.Flags().MarkHidden(dflags.InMemoryDatabase.Flag)
deployment.IntFlag(root.Flags(), &dflags.ProvisionerDaemonCount)
deployment.StringFlag(root.Flags(), &dflags.PostgresURL)
deployment.StringFlag(root.Flags(), &dflags.OAuth2GithubClientID)
deployment.StringFlag(root.Flags(), &dflags.OAuth2GithubClientSecret)
deployment.StringArrayFlag(root.Flags(), &dflags.OAuth2GithubAllowedOrganizations)
deployment.StringArrayFlag(root.Flags(), &dflags.OAuth2GithubAllowedTeams)
deployment.BoolFlag(root.Flags(), &dflags.OAuth2GithubAllowSignups)
deployment.StringFlag(root.Flags(), &dflags.OAuth2GithubEnterpriseBaseURL)
deployment.BoolFlag(root.Flags(), &dflags.OIDCAllowSignups)
deployment.StringFlag(root.Flags(), &dflags.OIDCClientID)
deployment.StringFlag(root.Flags(), &dflags.OIDCClientSecret)
deployment.StringFlag(root.Flags(), &dflags.OIDCEmailDomain)
deployment.StringFlag(root.Flags(), &dflags.OIDCIssuerURL)
deployment.StringArrayFlag(root.Flags(), &dflags.OIDCScopes)
deployment.BoolFlag(root.Flags(), &dflags.TelemetryEnable)
deployment.BoolFlag(root.Flags(), &dflags.TelemetryTraceEnable)
deployment.StringFlag(root.Flags(), &dflags.TelemetryURL)
_ = root.Flags().MarkHidden(dflags.TelemetryURL.Flag)
deployment.BoolFlag(root.Flags(), &dflags.TLSEnable)
deployment.StringArrayFlag(root.Flags(), &dflags.TLSCertFiles)
deployment.StringFlag(root.Flags(), &dflags.TLSClientCAFile)
deployment.StringFlag(root.Flags(), &dflags.TLSClientAuth)
deployment.StringArrayFlag(root.Flags(), &dflags.TLSKeyFiles)
deployment.StringFlag(root.Flags(), &dflags.TLSMinVersion)
deployment.BoolFlag(root.Flags(), &dflags.TraceEnable)
deployment.BoolFlag(root.Flags(), &dflags.SecureAuthCookie)
deployment.StringFlag(root.Flags(), &dflags.SSHKeygenAlgorithm)
deployment.StringArrayFlag(root.Flags(), &dflags.AutoImportTemplates)
_ = root.Flags().MarkHidden(dflags.AutoImportTemplates.Flag)
deployment.DurationFlag(root.Flags(), &dflags.MetricsCacheRefreshInterval)
_ = root.Flags().MarkHidden(dflags.MetricsCacheRefreshInterval.Flag)
deployment.DurationFlag(root.Flags(), &dflags.AgentStatRefreshInterval)
_ = root.Flags().MarkHidden(dflags.AgentStatRefreshInterval.Flag)
deployment.BoolFlag(root.Flags(), &dflags.Verbose)
return root
}
@ -1016,21 +907,7 @@ func newProvisionerDaemon(
}
// nolint: revive
func printLogo(cmd *cobra.Command, spooky bool) {
if spooky {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), `▄████▄ ▒█████ ▓█████▄ ▓█████ ██▀███
▒██▀ ▀█ ▒██▒ ██▒▒██▀ ██▌▓█ ▀ ▓██ ▒ ██▒
▒▓█ ▄ ▒██░ ██▒░██ █▌▒███ ▓██ ░▄█ ▒
▒▓▓▄ ▄██▒▒██ ██░░▓█▄ ▌▒▓█ ▄ ▒██▀▀█▄
▒ ▓███▀ ░░ ████▓▒░░▒████▓ ░▒████▒░██▓ ▒██▒
░ ░▒ ▒ ░░ ▒░▒░▒░ ▒▒▓ ▒ ░░ ▒░ ░░ ▒▓ ░▒▓░
░ ▒ ░ ▒ ▒░ ░ ▒ ▒ ░ ░ ░ ░▒ ░ ▒░
░ ░ ░ ░ ▒ ░ ░ ░ ░ ░░ ░
░ ░ ░ ░ ░ ░ ░ ░
░ ░
`)
return
}
func printLogo(cmd *cobra.Command) {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s - Remote development on your infrastucture\n", cliui.Styles.Bold.Render("Coder "+buildinfo.Version()))
}