From a6a9a03ac91ccbc2fb90b62586ba3c7c073b9ac7 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 15:54:14 -0500 Subject: [PATCH 01/17] chore: allow terraform & echo built-in provisioners Built-in provisioners server their respective types, not both. --- cli/server.go | 28 +++++++++++++++++++++++----- cli/server_test.go | 8 ++++---- coderd/coderd.go | 19 +++++++++++-------- coderd/coderdtest/coderdtest.go | 2 +- codersdk/deployment.go | 14 ++++++++------ 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/cli/server.go b/cli/server.go index 5b804f927869f..898bfd4d03ac7 100644 --- a/cli/server.go +++ b/cli/server.go @@ -944,7 +944,13 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. var provisionerdWaitGroup sync.WaitGroup defer provisionerdWaitGroup.Wait() provisionerdMetrics := provisionerd.NewMetrics(options.PrometheusRegistry) - for i := int64(0); i < vals.Provisioner.Daemons.Value(); i++ { + // Create a list of daemon types. The length is the total number of built in provisioners, and + // the slice value is the type for each. + daemons := append( + fill(make([]codersdk.ProvisionerType, vals.Provisioner.DaemonsTerraform.Value()), codersdk.ProvisionerTypeTerraform), + fill(make([]codersdk.ProvisionerType, vals.Provisioner.DaemonsEcho.Value()), codersdk.ProvisionerTypeEcho)..., + ) + for i, provisionerType := range daemons { suffix := fmt.Sprintf("%d", i) // The suffix is added to the hostname, so we may need to trim to fit into // the 64 character limit. @@ -952,7 +958,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. name := fmt.Sprintf("%s-%s", hostname, suffix) daemonCacheDir := filepath.Join(cacheDir, fmt.Sprintf("provisioner-%d", i)) daemon, err := newProvisionerDaemon( - ctx, coderAPI, provisionerdMetrics, logger, vals, daemonCacheDir, errCh, &provisionerdWaitGroup, name, + ctx, coderAPI, provisionerdMetrics, logger, vals, daemonCacheDir, errCh, &provisionerdWaitGroup, name, provisionerType, ) if err != nil { return xerrors.Errorf("create provisioner daemon: %w", err) @@ -1340,6 +1346,7 @@ func newProvisionerDaemon( errCh chan error, wg *sync.WaitGroup, name string, + provisionerType codersdk.ProvisionerType, ) (srv *provisionerd.Server, err error) { ctx, cancel := context.WithCancel(ctx) defer func() { @@ -1360,7 +1367,8 @@ func newProvisionerDaemon( } connector := provisionerd.LocalProvisioners{} - if cfg.Provisioner.DaemonsEcho { + switch provisionerType { + case codersdk.ProvisionerTypeEcho: echoClient, echoServer := drpc.MemTransportPipe() wg.Add(1) go func() { @@ -1387,7 +1395,7 @@ func newProvisionerDaemon( } }() connector[string(database.ProvisionerTypeEcho)] = sdkproto.NewDRPCProvisionerClient(echoClient) - } else { + case codersdk.ProvisionerTypeTerraform: tfDir := filepath.Join(cacheDir, "tf") err = os.MkdirAll(tfDir, 0o700) if err != nil { @@ -1426,12 +1434,14 @@ func newProvisionerDaemon( }() connector[string(database.ProvisionerTypeTerraform)] = sdkproto.NewDRPCProvisionerClient(terraformClient) + default: + return nil, fmt.Errorf("unknown provisioner type %q", provisionerType) } return provisionerd.New(func(dialCtx context.Context) (proto.DRPCProvisionerDaemonClient, error) { // This debounces calls to listen every second. Read the comment // in provisionerdserver.go to learn more! - return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, name) + return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, name, []codersdk.ProvisionerType{provisionerType}) }, &provisionerd.Options{ Logger: logger.Named(fmt.Sprintf("provisionerd-%s", name)), UpdateInterval: time.Second, @@ -2574,3 +2584,11 @@ func getPostgresDB(ctx context.Context, logger slog.Logger, postgresURL string, return sqlDB, dbURL, nil } + +// fill will fill the src with the value 'v' +func fill[T any](src []T, v T) []T { + for i := range src { + src[i] = v + } + return src +} diff --git a/cli/server_test.go b/cli/server_test.go index 065131fd9785f..46be4eed39d95 100644 --- a/cli/server_test.go +++ b/cli/server_test.go @@ -1367,7 +1367,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo", + "--provisioner-daemons-echo=3", "--log-human", fiName, ) clitest.Start(t, root) @@ -1385,7 +1385,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo", + "--provisioner-daemons-echo=3", "--log-human", fi, ) clitest.Start(t, root) @@ -1403,7 +1403,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo", + "--provisioner-daemons-echo=3", "--log-json", fi, ) clitest.Start(t, root) @@ -1424,7 +1424,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo", + "--provisioner-daemons-echo=3", "--log-stackdriver", fi, ) // Attach pty so we get debug output from the command if this test diff --git a/coderd/coderd.go b/coderd/coderd.go index 0bd6a5a4ae746..9dcda1a71536e 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -1348,7 +1348,7 @@ func compressHandler(h http.Handler) http.Handler { // CreateInMemoryProvisionerDaemon is an in-memory connection to a provisionerd. // Useful when starting coderd and provisionerd in the same process. -func (api *API) CreateInMemoryProvisionerDaemon(dialCtx context.Context, name string) (client proto.DRPCProvisionerDaemonClient, err error) { +func (api *API) CreateInMemoryProvisionerDaemon(dialCtx context.Context, name string, provisionerTypes []codersdk.ProvisionerType) (client proto.DRPCProvisionerDaemonClient, err error) { tracer := api.TracerProvider.Tracer(tracing.TracerName) clientSession, serverSession := drpc.MemTransportPipe() defer func() { @@ -1365,18 +1365,21 @@ func (api *API) CreateInMemoryProvisionerDaemon(dialCtx context.Context, name st return nil, xerrors.Errorf("unable to fetch default org for in memory provisioner: %w", err) } + dbTypes := make([]database.ProvisionerType, 0, len(provisionerTypes)) + for _, tp := range provisionerTypes { + dbTypes = append(dbTypes, database.ProvisionerType(tp)) + } + //nolint:gocritic // in-memory provisioners are owned by system daemon, err := api.Database.UpsertProvisionerDaemon(dbauthz.AsSystemRestricted(dialCtx), database.UpsertProvisionerDaemonParams{ Name: name, OrganizationID: defaultOrg.ID, CreatedAt: dbtime.Now(), - Provisioners: []database.ProvisionerType{ - database.ProvisionerTypeEcho, database.ProvisionerTypeTerraform, - }, - Tags: provisionersdk.MutateTags(uuid.Nil, nil), - LastSeenAt: sql.NullTime{Time: dbtime.Now(), Valid: true}, - Version: buildinfo.Version(), - APIVersion: proto.CurrentVersion.String(), + Provisioners: dbTypes, + Tags: provisionersdk.MutateTags(uuid.Nil, nil), + LastSeenAt: sql.NullTime{Time: dbtime.Now(), Valid: true}, + Version: buildinfo.Version(), + APIVersion: proto.CurrentVersion.String(), }) if err != nil { return nil, xerrors.Errorf("failed to create in-memory provisioner daemon: %w", err) diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index b3288c84b8988..14a2fb9231561 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -578,7 +578,7 @@ func NewProvisionerDaemon(t testing.TB, coderAPI *coderd.API) io.Closer { }() daemon := provisionerd.New(func(dialCtx context.Context) (provisionerdproto.DRPCProvisionerDaemonClient, error) { - return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, "test") + return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, "test", []codersdk.ProvisionerType{codersdk.ProvisionerTypeEcho}) }, &provisionerd.Options{ Logger: coderAPI.Logger.Named("provisionerd").Leveled(slog.LevelDebug), UpdateInterval: 250 * time.Millisecond, diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 8b11e2c827e16..301e0d5ba49b3 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -406,8 +406,10 @@ type ExternalAuthConfig struct { } type ProvisionerConfig struct { - Daemons serpent.Int64 `json:"daemons" typescript:",notnull"` - DaemonsEcho serpent.Bool `json:"daemons_echo" typescript:",notnull"` + // DaemonsTerraform for legacy reasons is just called "daemons". It is the default + // choice. + DaemonsTerraform serpent.Int64 `json:"daemons" typescript:",notnull"` + DaemonsEcho serpent.Int64 `json:"daemons_echo" typescript:",notnull"` DaemonPollInterval serpent.Duration `json:"daemon_poll_interval" typescript:",notnull"` DaemonPollJitter serpent.Duration `json:"daemon_poll_jitter" typescript:",notnull"` ForceCancelInterval serpent.Duration `json:"force_cancel_interval" typescript:",notnull"` @@ -1404,21 +1406,21 @@ when required by your organization's security policy.`, // Provisioner settings { Name: "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.", + Description: "Number of terraform provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.", Flag: "provisioner-daemons", Env: "CODER_PROVISIONER_DAEMONS", Default: "3", - Value: &c.Provisioner.Daemons, + Value: &c.Provisioner.DaemonsTerraform, Group: &deploymentGroupProvisioning, YAML: "daemons", }, { Name: "Echo Provisioner", - Description: "Whether to use echo provisioner daemons instead of Terraform. This is for E2E tests.", + Description: "Number of built-in echo provisioners to create on start. Can be done alongside actual terraform provisioners. This is for E2E tests.", Flag: "provisioner-daemons-echo", Env: "CODER_PROVISIONER_DAEMONS_ECHO", Hidden: true, - Default: "false", + Default: "0", Value: &c.Provisioner.DaemonsEcho, Group: &deploymentGroupProvisioning, YAML: "daemonsEcho", From 80960ccc079b8d710056c6baee3614e4d25626bd Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 16:12:42 -0500 Subject: [PATCH 02/17] make gen --- coderd/apidoc/docs.go | 3 ++- coderd/apidoc/swagger.json | 3 ++- codersdk/deployment.go | 4 ++-- docs/api/general.md | 2 +- docs/api/schemas.md | 22 +++++++++++----------- docs/cli/server.md | 2 +- site/src/api/typesGenerated.ts | 2 +- 7 files changed, 20 insertions(+), 18 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index b3607a1c7a351..743482dfa0213 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -10485,10 +10485,11 @@ const docTemplate = `{ "type": "string" }, "daemons": { + "description": "DaemonsTerraform is the number of built-in terraform provisioners. The\njson is 'daemons' for legacy reasons.", "type": "integer" }, "daemons_echo": { - "type": "boolean" + "type": "integer" }, "force_cancel_interval": { "type": "integer" diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index e73b54f3c92d0..b9b3792218abf 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -9419,10 +9419,11 @@ "type": "string" }, "daemons": { + "description": "DaemonsTerraform is the number of built-in terraform provisioners. The\njson is 'daemons' for legacy reasons.", "type": "integer" }, "daemons_echo": { - "type": "boolean" + "type": "integer" }, "force_cancel_interval": { "type": "integer" diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 301e0d5ba49b3..ee464d472b33f 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -406,8 +406,8 @@ type ExternalAuthConfig struct { } type ProvisionerConfig struct { - // DaemonsTerraform for legacy reasons is just called "daemons". It is the default - // choice. + // DaemonsTerraform is the number of built-in terraform provisioners. The + // json is 'daemons' for legacy reasons. DaemonsTerraform serpent.Int64 `json:"daemons" typescript:",notnull"` DaemonsEcho serpent.Int64 `json:"daemons_echo" typescript:",notnull"` DaemonPollInterval serpent.Duration `json:"daemon_poll_interval" typescript:",notnull"` diff --git a/docs/api/general.md b/docs/api/general.md index 02399a6e3e794..7d8c0a7ee5801 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -326,7 +326,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": true, + "daemons_echo": 0, "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 040e6adcdd5b8..9d808fb08d882 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2054,7 +2054,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": true, + "daemons_echo": 0, "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, @@ -2427,7 +2427,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": true, + "daemons_echo": 0, "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, @@ -3692,21 +3692,21 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": true, + "daemons_echo": 0, "force_cancel_interval": 0 } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ----------------------- | ------- | -------- | ------------ | ----------- | -| `daemon_poll_interval` | integer | false | | | -| `daemon_poll_jitter` | integer | false | | | -| `daemon_psk` | string | false | | | -| `daemons` | integer | false | | | -| `daemons_echo` | boolean | false | | | -| `force_cancel_interval` | integer | false | | | +| Name | Type | Required | Restrictions | Description | +| ----------------------- | ------- | -------- | ------------ | --------------------------------------------------------------------------------------------------- | +| `daemon_poll_interval` | integer | false | | | +| `daemon_poll_jitter` | integer | false | | | +| `daemon_psk` | string | false | | | +| `daemons` | integer | false | | Daemons is the number of built-in terraform provisioners. The json is 'daemons' for legacy reasons. | +| `daemons_echo` | integer | false | | | +| `force_cancel_interval` | integer | false | | | ## codersdk.ProvisionerDaemon diff --git a/docs/cli/server.md b/docs/cli/server.md index a7c32c2d78420..0f010d73d4fb2 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -711,7 +711,7 @@ Enables capturing of logs as events in traces. This is useful for debugging, but | YAML | provisioning.daemons | | Default | 3 | -Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. +Number of terraform provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. ### --provisioner-daemon-poll-interval diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 5488d5c161ad4..623bad4767f42 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -838,7 +838,7 @@ export interface PrometheusConfig { // From codersdk/deployment.go export interface ProvisionerConfig { readonly daemons: number; - readonly daemons_echo: boolean; + readonly daemons_echo: number; readonly daemon_poll_interval: number; readonly daemon_poll_jitter: number; readonly force_cancel_interval: number; From d151b48d20b64c24ed6f1650b0c1302ed22e474d Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 16:26:41 -0500 Subject: [PATCH 03/17] add icon to health provisioner page for prov type --- .../src/pages/HealthPage/ProvisionerDaemonsPage.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx b/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx index 63ee9280987c5..a676786b00558 100644 --- a/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx +++ b/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx @@ -4,6 +4,7 @@ import CloseIcon from "@mui/icons-material/Close"; import Person from "@mui/icons-material/Person"; import Sell from "@mui/icons-material/Sell"; import SwapHoriz from "@mui/icons-material/SwapHoriz"; +import ViewInArIcon from "@mui/icons-material/ViewInAr"; import IconButton from "@mui/material/IconButton"; import Tooltip from "@mui/material/Tooltip"; import type { FC } from "react"; @@ -115,6 +116,18 @@ export const ProvisionerDaemonsPage: FC = () => { gap: 12, }} > + { + // Add pills for the supported provisioenr types. + daemon.provisioners.map((provType) => { + return ( + + }> + {provType} + + + ); + }) + } }> {daemon.api_version} From e7fea3f772f71a276748dbfdd98e7499d486579b Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 16:32:19 -0500 Subject: [PATCH 04/17] update golden files --- cli/testdata/coder_server_--help.golden | 4 ++-- cli/testdata/server-config.yaml.golden | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 6d8f866c11c0b..69ee62e07c472 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -460,8 +460,8 @@ updating, and deleting workspace resources. server. --provisioner-daemons int, $CODER_PROVISIONER_DAEMONS (default: 3) - Number of provisioner daemons to create on start. If builds are stuck - in queued state for a long time, consider increasing this. + Number of terraform provisioner daemons to create on start. If builds + are stuck in queued state for a long time, consider increasing this. TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index 4366dbc4d9677..2bce3bbb2900c 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -375,14 +375,14 @@ telemetry: # Tune the behavior of the provisioner, which is responsible for creating, # updating, and deleting workspace resources. provisioning: - # Number of provisioner daemons to create on start. If builds are stuck in queued - # state for a long time, consider increasing this. + # Number of terraform provisioner daemons to create on start. If builds are stuck + # in queued state for a long time, consider increasing this. # (default: 3, type: int) daemons: 3 - # Whether to use echo provisioner daemons instead of Terraform. This is for E2E - # tests. - # (default: false, type: bool) - daemonsEcho: false + # Number of built-in echo provisioners to create on start. Can be done alongside + # actual terraform provisioners. This is for E2E tests. + # (default: 0, type: int) + daemonsEcho: 0 # Deprecated and ignored. # (default: 1s, type: duration) daemonPollInterval: 1s From a56a4c65e6fddb21dd3b20b07767aa156de8caec Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 16:37:41 -0500 Subject: [PATCH 05/17] default to 10 echo provisioners and 0 terraform --- site/e2e/playwright.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/e2e/playwright.config.ts b/site/e2e/playwright.config.ts index 7bc8ead8e4fb9..7563e1a426025 100644 --- a/site/e2e/playwright.config.ts +++ b/site/e2e/playwright.config.ts @@ -58,8 +58,8 @@ export default defineConfig({ "--in-memory", "--telemetry=false", "--dangerous-disable-rate-limits", - "--provisioner-daemons 10", - "--provisioner-daemons-echo", + "--provisioner-daemons 0", + "--provisioner-daemons-echo 10", "--web-terminal-renderer=dom", "--pprof-enable", ] From 87ad0a0ed375b2c9d59f7e62291b0c2eac238187 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 16:37:57 -0500 Subject: [PATCH 06/17] fixup! default to 10 echo provisioners and 0 terraform --- site/e2e/playwright.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/site/e2e/playwright.config.ts b/site/e2e/playwright.config.ts index 7563e1a426025..5486580189fe1 100644 --- a/site/e2e/playwright.config.ts +++ b/site/e2e/playwright.config.ts @@ -58,6 +58,7 @@ export default defineConfig({ "--in-memory", "--telemetry=false", "--dangerous-disable-rate-limits", + // TODO: Enable some terraform provisioners "--provisioner-daemons 0", "--provisioner-daemons-echo 10", "--web-terminal-renderer=dom", From 23ef0f21f821fa7396624ffb40feb5c9f3eb7311 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 16:46:11 -0500 Subject: [PATCH 07/17] fixup tests --- cli/server_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cli/server_test.go b/cli/server_test.go index 46be4eed39d95..021a0fdfa63d9 100644 --- a/cli/server_test.go +++ b/cli/server_test.go @@ -1367,6 +1367,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", + "--provisioner-daemons=0", "--provisioner-daemons-echo=3", "--log-human", fiName, ) @@ -1385,6 +1386,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", + "--provisioner-daemons=0", "--provisioner-daemons-echo=3", "--log-human", fi, ) @@ -1403,6 +1405,7 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", + "--provisioner-daemons=0", "--provisioner-daemons-echo=3", "--log-json", fi, ) @@ -1425,6 +1428,7 @@ func TestServer(t *testing.T) { "--http-address", ":0", "--access-url", "http://example.com", "--provisioner-daemons-echo=3", + "--provisioner-daemons=0", "--log-stackdriver", fi, ) // Attach pty so we get debug output from the command if this test @@ -1459,7 +1463,8 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo", + "--provisioner-daemons-echo=3", + "--provisioner-daemons=0", "--log-human", fi1, "--log-json", fi2, "--log-stackdriver", fi3, From 540377b41d70026b6d7923546b444a549f4acf33 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 17:02:19 -0500 Subject: [PATCH 08/17] update golden files --- enterprise/cli/testdata/coder_server_--help.golden | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 4d4576d6d57cc..4a873ce9c8779 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -461,8 +461,8 @@ updating, and deleting workspace resources. server. --provisioner-daemons int, $CODER_PROVISIONER_DAEMONS (default: 3) - Number of provisioner daemons to create on start. If builds are stuck - in queued state for a long time, consider increasing this. + Number of terraform provisioner daemons to create on start. If builds + are stuck in queued state for a long time, consider increasing this. TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all From 2a2c4b8940d515bb0991f0800dd1fb3f7413b870 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 17:13:44 -0500 Subject: [PATCH 09/17] fixup comment --- cli/server.go | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/cli/server.go b/cli/server.go index 898bfd4d03ac7..a0e15f522cfa8 100644 --- a/cli/server.go +++ b/cli/server.go @@ -944,12 +944,18 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. var provisionerdWaitGroup sync.WaitGroup defer provisionerdWaitGroup.Wait() provisionerdMetrics := provisionerd.NewMetrics(options.PrometheusRegistry) - // Create a list of daemon types. The length is the total number of built in provisioners, and - // the slice value is the type for each. - daemons := append( - fill(make([]codersdk.ProvisionerType, vals.Provisioner.DaemonsTerraform.Value()), codersdk.ProvisionerTypeTerraform), - fill(make([]codersdk.ProvisionerType, vals.Provisioner.DaemonsEcho.Value()), codersdk.ProvisionerTypeEcho)..., - ) + + // Create a list of daemon types. The length is the total number of built-in provisioners, and + // the slice value is the type for each. This is just an easy way to pass the types + // to a single loop. Ensuring each provisioner has a unique suffix with their index. + daemons := make([]codersdk.ProvisionerType, 0) + for i := int64(0); i < vals.Provisioner.DaemonsTerraform.Value(); i++ { + daemons = append(daemons, codersdk.ProvisionerTypeTerraform) + } + for i := int64(0); i < vals.Provisioner.DaemonsTerraform.Value(); i++ { + daemons = append(daemons, codersdk.ProvisionerTypeEcho) + } + for i, provisionerType := range daemons { suffix := fmt.Sprintf("%d", i) // The suffix is added to the hostname, so we may need to trim to fit into @@ -2584,11 +2590,3 @@ func getPostgresDB(ctx context.Context, logger slog.Logger, postgresURL string, return sqlDB, dbURL, nil } - -// fill will fill the src with the value 'v' -func fill[T any](src []T, v T) []T { - for i := range src { - src[i] = v - } - return src -} From 52514d656d8050ab8388ac60ac5eb7448f4b6ebc Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Wed, 1 May 2024 17:14:58 -0500 Subject: [PATCH 10/17] fixup! fixup comment --- cli/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/server.go b/cli/server.go index a0e15f522cfa8..2febfa182aa01 100644 --- a/cli/server.go +++ b/cli/server.go @@ -952,7 +952,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. for i := int64(0); i < vals.Provisioner.DaemonsTerraform.Value(); i++ { daemons = append(daemons, codersdk.ProvisionerTypeTerraform) } - for i := int64(0); i < vals.Provisioner.DaemonsTerraform.Value(); i++ { + for i := int64(0); i < vals.Provisioner.DaemonsEcho.Value(); i++ { daemons = append(daemons, codersdk.ProvisionerTypeEcho) } From 0c3884de3ad91dc9409c798167ba0819680e2566 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 13:58:57 -0500 Subject: [PATCH 11/17] builtin provisioner supporting multiple types --- cli/server.go | 155 +++++++++++++++++++------------------- cli/server_test.go | 20 ++--- codersdk/deployment.go | 52 ++++++++----- codersdk/organizations.go | 11 +++ 4 files changed, 132 insertions(+), 106 deletions(-) diff --git a/cli/server.go b/cli/server.go index 2febfa182aa01..e96c8cacdc744 100644 --- a/cli/server.go +++ b/cli/server.go @@ -945,18 +945,13 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. defer provisionerdWaitGroup.Wait() provisionerdMetrics := provisionerd.NewMetrics(options.PrometheusRegistry) - // Create a list of daemon types. The length is the total number of built-in provisioners, and - // the slice value is the type for each. This is just an easy way to pass the types - // to a single loop. Ensuring each provisioner has a unique suffix with their index. - daemons := make([]codersdk.ProvisionerType, 0) - for i := int64(0); i < vals.Provisioner.DaemonsTerraform.Value(); i++ { - daemons = append(daemons, codersdk.ProvisionerTypeTerraform) + // Built in provisioner daemons will support the same types. + // By default, this is the slice {"terraform"} + provisionerTypes := make([]codersdk.ProvisionerType, 0) + for _, pt := range vals.Provisioner.DaemonTypes { + provisionerTypes = append(provisionerTypes, codersdk.ProvisionerType(pt)) } - for i := int64(0); i < vals.Provisioner.DaemonsEcho.Value(); i++ { - daemons = append(daemons, codersdk.ProvisionerTypeEcho) - } - - for i, provisionerType := range daemons { + for i := int64(0); i < vals.Provisioner.Daemons.Value(); i++ { suffix := fmt.Sprintf("%d", i) // The suffix is added to the hostname, so we may need to trim to fit into // the 64 character limit. @@ -964,7 +959,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. name := fmt.Sprintf("%s-%s", hostname, suffix) daemonCacheDir := filepath.Join(cacheDir, fmt.Sprintf("provisioner-%d", i)) daemon, err := newProvisionerDaemon( - ctx, coderAPI, provisionerdMetrics, logger, vals, daemonCacheDir, errCh, &provisionerdWaitGroup, name, provisionerType, + ctx, coderAPI, provisionerdMetrics, logger, vals, daemonCacheDir, errCh, &provisionerdWaitGroup, name, provisionerTypes, ) if err != nil { return xerrors.Errorf("create provisioner daemon: %w", err) @@ -1352,7 +1347,7 @@ func newProvisionerDaemon( errCh chan error, wg *sync.WaitGroup, name string, - provisionerType codersdk.ProvisionerType, + provisionerTypes []codersdk.ProvisionerType, ) (srv *provisionerd.Server, err error) { ctx, cancel := context.WithCancel(ctx) defer func() { @@ -1372,82 +1367,88 @@ func newProvisionerDaemon( return nil, xerrors.Errorf("mkdir work dir: %w", err) } + // Omit any duplicates + provisionerTypes = slice.Unique(provisionerTypes) + + // Populate the connector with the supported types. connector := provisionerd.LocalProvisioners{} - switch provisionerType { - case codersdk.ProvisionerTypeEcho: - echoClient, echoServer := drpc.MemTransportPipe() - wg.Add(1) - go func() { - defer wg.Done() - <-ctx.Done() - _ = echoClient.Close() - _ = echoServer.Close() - }() - wg.Add(1) - go func() { - defer wg.Done() - defer cancel() + for _, provisionerType := range provisionerTypes { + switch provisionerType { + case codersdk.ProvisionerTypeEcho: + echoClient, echoServer := drpc.MemTransportPipe() + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + _ = echoClient.Close() + _ = echoServer.Close() + }() + wg.Add(1) + go func() { + defer wg.Done() + defer cancel() - err := echo.Serve(ctx, &provisionersdk.ServeOptions{ - Listener: echoServer, - WorkDirectory: workDir, - Logger: logger.Named("echo"), - }) - if err != nil { - select { - case errCh <- err: - default: + err := echo.Serve(ctx, &provisionersdk.ServeOptions{ + Listener: echoServer, + WorkDirectory: workDir, + Logger: logger.Named("echo"), + }) + if err != nil { + select { + case errCh <- err: + default: + } } + }() + connector[string(database.ProvisionerTypeEcho)] = sdkproto.NewDRPCProvisionerClient(echoClient) + case codersdk.ProvisionerTypeTerraform: + tfDir := filepath.Join(cacheDir, "tf") + err = os.MkdirAll(tfDir, 0o700) + if err != nil { + return nil, xerrors.Errorf("mkdir terraform dir: %w", err) } - }() - connector[string(database.ProvisionerTypeEcho)] = sdkproto.NewDRPCProvisionerClient(echoClient) - case codersdk.ProvisionerTypeTerraform: - tfDir := filepath.Join(cacheDir, "tf") - err = os.MkdirAll(tfDir, 0o700) - if err != nil { - return nil, xerrors.Errorf("mkdir terraform dir: %w", err) - } - tracer := coderAPI.TracerProvider.Tracer(tracing.TracerName) - terraformClient, terraformServer := drpc.MemTransportPipe() - wg.Add(1) - go func() { - defer wg.Done() - <-ctx.Done() - _ = terraformClient.Close() - _ = terraformServer.Close() - }() - wg.Add(1) - go func() { - defer wg.Done() - defer cancel() - - err := terraform.Serve(ctx, &terraform.ServeOptions{ - ServeOptions: &provisionersdk.ServeOptions{ - Listener: terraformServer, - Logger: logger.Named("terraform"), - WorkDirectory: workDir, - }, - CachePath: tfDir, - Tracer: tracer, - }) - if err != nil && !xerrors.Is(err, context.Canceled) { - select { - case errCh <- err: - default: + tracer := coderAPI.TracerProvider.Tracer(tracing.TracerName) + terraformClient, terraformServer := drpc.MemTransportPipe() + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + _ = terraformClient.Close() + _ = terraformServer.Close() + }() + wg.Add(1) + go func() { + defer wg.Done() + defer cancel() + + err := terraform.Serve(ctx, &terraform.ServeOptions{ + ServeOptions: &provisionersdk.ServeOptions{ + Listener: terraformServer, + Logger: logger.Named("terraform"), + WorkDirectory: workDir, + }, + CachePath: tfDir, + Tracer: tracer, + }) + if err != nil && !xerrors.Is(err, context.Canceled) { + select { + case errCh <- err: + default: + } } - } - }() + }() - connector[string(database.ProvisionerTypeTerraform)] = sdkproto.NewDRPCProvisionerClient(terraformClient) - default: - return nil, fmt.Errorf("unknown provisioner type %q", provisionerType) + connector[string(database.ProvisionerTypeTerraform)] = sdkproto.NewDRPCProvisionerClient(terraformClient) + default: + return nil, fmt.Errorf("unknown provisioner type %q", provisionerType) + } } return provisionerd.New(func(dialCtx context.Context) (proto.DRPCProvisionerDaemonClient, error) { // This debounces calls to listen every second. Read the comment // in provisionerdserver.go to learn more! - return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, name, []codersdk.ProvisionerType{provisionerType}) + return coderAPI.CreateInMemoryProvisionerDaemon(dialCtx, name, provisionerTypes) }, &provisionerd.Options{ Logger: logger.Named(fmt.Sprintf("provisionerd-%s", name)), UpdateInterval: time.Second, diff --git a/cli/server_test.go b/cli/server_test.go index 021a0fdfa63d9..3ca57cf0ce162 100644 --- a/cli/server_test.go +++ b/cli/server_test.go @@ -1367,8 +1367,8 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons=0", - "--provisioner-daemons-echo=3", + "--provisioner-daemons=3", + "--provisioner-types=echo", "--log-human", fiName, ) clitest.Start(t, root) @@ -1386,8 +1386,8 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons=0", - "--provisioner-daemons-echo=3", + "--provisioner-daemons=3", + "--provisioner-types=echo", "--log-human", fi, ) clitest.Start(t, root) @@ -1405,8 +1405,8 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons=0", - "--provisioner-daemons-echo=3", + "--provisioner-daemons=3", + "--provisioner-types=echo", "--log-json", fi, ) clitest.Start(t, root) @@ -1427,8 +1427,8 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo=3", - "--provisioner-daemons=0", + "--provisioner-daemons=3", + "--provisioner-types=echo", "--log-stackdriver", fi, ) // Attach pty so we get debug output from the command if this test @@ -1463,8 +1463,8 @@ func TestServer(t *testing.T) { "--in-memory", "--http-address", ":0", "--access-url", "http://example.com", - "--provisioner-daemons-echo=3", - "--provisioner-daemons=0", + "--provisioner-daemons=3", + "--provisioner-types=echo", "--log-human", fi1, "--log-json", fi2, "--log-stackdriver", fi3, diff --git a/codersdk/deployment.go b/codersdk/deployment.go index ee464d472b33f..8e68a3b053808 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -406,14 +406,13 @@ type ExternalAuthConfig struct { } type ProvisionerConfig struct { - // DaemonsTerraform is the number of built-in terraform provisioners. The - // json is 'daemons' for legacy reasons. - DaemonsTerraform serpent.Int64 `json:"daemons" typescript:",notnull"` - DaemonsEcho serpent.Int64 `json:"daemons_echo" typescript:",notnull"` - DaemonPollInterval serpent.Duration `json:"daemon_poll_interval" typescript:",notnull"` - DaemonPollJitter serpent.Duration `json:"daemon_poll_jitter" typescript:",notnull"` - ForceCancelInterval serpent.Duration `json:"force_cancel_interval" typescript:",notnull"` - DaemonPSK serpent.String `json:"daemon_psk" typescript:",notnull"` + // Daemons is the number of built-in terraform provisioners. + Daemons serpent.Int64 `json:"daemons" typescript:",notnull"` + DaemonTypes serpent.StringArray `json:"daemons_echo" typescript:",notnull"` + DaemonPollInterval serpent.Duration `json:"daemon_poll_interval" typescript:",notnull"` + DaemonPollJitter serpent.Duration `json:"daemon_poll_jitter" typescript:",notnull"` + ForceCancelInterval serpent.Duration `json:"force_cancel_interval" typescript:",notnull"` + DaemonPSK serpent.String `json:"daemon_psk" typescript:",notnull"` } type RateLimitConfig struct { @@ -1406,24 +1405,39 @@ when required by your organization's security policy.`, // Provisioner settings { Name: "Provisioner Daemons", - Description: "Number of terraform provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.", + Description: "Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this.", Flag: "provisioner-daemons", Env: "CODER_PROVISIONER_DAEMONS", Default: "3", - Value: &c.Provisioner.DaemonsTerraform, + Value: &c.Provisioner.Daemons, Group: &deploymentGroupProvisioning, YAML: "daemons", }, { - Name: "Echo Provisioner", - Description: "Number of built-in echo provisioners to create on start. Can be done alongside actual terraform provisioners. This is for E2E tests.", - Flag: "provisioner-daemons-echo", - Env: "CODER_PROVISIONER_DAEMONS_ECHO", - Hidden: true, - Default: "0", - Value: &c.Provisioner.DaemonsEcho, - Group: &deploymentGroupProvisioning, - YAML: "daemonsEcho", + Name: "Provisioner Daemon Types", + Description: fmt.Sprintf("The supported job types for the built-in provisioners. By default, this is only the terraform type. Supported types: %s.", + strings.Join([]string{ + string(ProvisionerTypeTerraform), string(ProvisionerTypeEcho), + }, ",")), + Flag: "provisioner-types", + Env: "CODER_PROVISIONER_TYPES", + Hidden: true, + Default: string(ProvisionerTypeTerraform), + Value: serpent.Validate(&c.Provisioner.DaemonTypes, func(values *serpent.StringArray) error { + if values == nil { + return nil + } + + for _, value := range *values { + if err := ProvisionerTypeValid(value); err != nil { + return err + } + } + + return nil + }), + Group: &deploymentGroupProvisioning, + YAML: "daemonsEcho", }, { Name: "Poll Interval", diff --git a/codersdk/organizations.go b/codersdk/organizations.go index cb353dff27cc6..f887d5ea4de5a 100644 --- a/codersdk/organizations.go +++ b/codersdk/organizations.go @@ -27,6 +27,17 @@ const ( ProvisionerTypeTerraform ProvisionerType = "terraform" ) +// ProvisionerTypeValid accepts string or ProvisionerType for easier usage. +// Will validate the enum is in the set. +func ProvisionerTypeValid[T ProvisionerType | string](pt T) error { + switch string(pt) { + case string(ProvisionerTypeEcho), string(ProvisionerTypeTerraform): + return nil + default: + return fmt.Errorf("provisioner type '%s' is not supported", pt) + } +} + // Organization is the JSON representation of a Coder organization. type Organization struct { ID uuid.UUID `table:"id" json:"id" validate:"required" format:"uuid"` From 0c081157944c63bab708171516419d481ca9c9b7 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 13:59:38 -0500 Subject: [PATCH 12/17] update e2e --- site/e2e/playwright.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/e2e/playwright.config.ts b/site/e2e/playwright.config.ts index 5486580189fe1..0e10c1ff34b0a 100644 --- a/site/e2e/playwright.config.ts +++ b/site/e2e/playwright.config.ts @@ -58,9 +58,9 @@ export default defineConfig({ "--in-memory", "--telemetry=false", "--dangerous-disable-rate-limits", + "--provisioner-daemons 10", // TODO: Enable some terraform provisioners - "--provisioner-daemons 0", - "--provisioner-daemons-echo 10", + "--provisioner-types=echo", "--web-terminal-renderer=dom", "--pprof-enable", ] From d1f82a871160d04cb4fcb7c20f3dd43fa0b2ca51 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 14:00:57 -0500 Subject: [PATCH 13/17] make gen --- coderd/apidoc/docs.go | 7 +++++-- coderd/apidoc/swagger.json | 7 +++++-- docs/api/general.md | 2 +- docs/api/schemas.md | 22 +++++++++++----------- docs/cli/server.md | 2 +- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 743482dfa0213..84324afe17a39 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -10485,11 +10485,14 @@ const docTemplate = `{ "type": "string" }, "daemons": { - "description": "DaemonsTerraform is the number of built-in terraform provisioners. The\njson is 'daemons' for legacy reasons.", + "description": "Daemons is the number of built-in terraform provisioners.", "type": "integer" }, "daemons_echo": { - "type": "integer" + "type": "array", + "items": { + "type": "string" + } }, "force_cancel_interval": { "type": "integer" diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index b9b3792218abf..8ddd994c0a202 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -9419,11 +9419,14 @@ "type": "string" }, "daemons": { - "description": "DaemonsTerraform is the number of built-in terraform provisioners. The\njson is 'daemons' for legacy reasons.", + "description": "Daemons is the number of built-in terraform provisioners.", "type": "integer" }, "daemons_echo": { - "type": "integer" + "type": "array", + "items": { + "type": "string" + } }, "force_cancel_interval": { "type": "integer" diff --git a/docs/api/general.md b/docs/api/general.md index 7d8c0a7ee5801..444def8f58031 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -326,7 +326,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": 0, + "daemons_echo": ["string"], "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 9d808fb08d882..fc297ea48ed54 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2054,7 +2054,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": 0, + "daemons_echo": ["string"], "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, @@ -2427,7 +2427,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": 0, + "daemons_echo": ["string"], "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, @@ -3692,21 +3692,21 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_jitter": 0, "daemon_psk": "string", "daemons": 0, - "daemons_echo": 0, + "daemons_echo": ["string"], "force_cancel_interval": 0 } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ----------------------- | ------- | -------- | ------------ | --------------------------------------------------------------------------------------------------- | -| `daemon_poll_interval` | integer | false | | | -| `daemon_poll_jitter` | integer | false | | | -| `daemon_psk` | string | false | | | -| `daemons` | integer | false | | Daemons is the number of built-in terraform provisioners. The json is 'daemons' for legacy reasons. | -| `daemons_echo` | integer | false | | | -| `force_cancel_interval` | integer | false | | | +| Name | Type | Required | Restrictions | Description | +| ----------------------- | --------------- | -------- | ------------ | --------------------------------------------------------- | +| `daemon_poll_interval` | integer | false | | | +| `daemon_poll_jitter` | integer | false | | | +| `daemon_psk` | string | false | | | +| `daemons` | integer | false | | Daemons is the number of built-in terraform provisioners. | +| `daemons_echo` | array of string | false | | | +| `force_cancel_interval` | integer | false | | | ## codersdk.ProvisionerDaemon diff --git a/docs/cli/server.md b/docs/cli/server.md index 0f010d73d4fb2..a7c32c2d78420 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -711,7 +711,7 @@ Enables capturing of logs as events in traces. This is useful for debugging, but | YAML | provisioning.daemons | | Default | 3 | -Number of terraform provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. +Number of provisioner daemons to create on start. If builds are stuck in queued state for a long time, consider increasing this. ### --provisioner-daemon-poll-interval From 3f652c3ea8f1b34ba41c928526e95b3a65221223 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 14:10:56 -0500 Subject: [PATCH 14/17] fixup options --- coderd/apidoc/docs.go | 10 +++++----- coderd/apidoc/swagger.json | 10 +++++----- codersdk/deployment.go | 4 ++-- docs/api/general.md | 2 +- docs/api/schemas.md | 8 ++++---- site/src/api/typesGenerated.ts | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 84324afe17a39..9e746d2df6abf 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -10484,16 +10484,16 @@ const docTemplate = `{ "daemon_psk": { "type": "string" }, - "daemons": { - "description": "Daemons is the number of built-in terraform provisioners.", - "type": "integer" - }, - "daemons_echo": { + "daemon_types": { "type": "array", "items": { "type": "string" } }, + "daemons": { + "description": "Daemons is the number of built-in terraform provisioners.", + "type": "integer" + }, "force_cancel_interval": { "type": "integer" } diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 8ddd994c0a202..d0e60d65aabfe 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -9418,16 +9418,16 @@ "daemon_psk": { "type": "string" }, - "daemons": { - "description": "Daemons is the number of built-in terraform provisioners.", - "type": "integer" - }, - "daemons_echo": { + "daemon_types": { "type": "array", "items": { "type": "string" } }, + "daemons": { + "description": "Daemons is the number of built-in terraform provisioners.", + "type": "integer" + }, "force_cancel_interval": { "type": "integer" } diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 8e68a3b053808..2aa675727b72b 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -408,7 +408,7 @@ type ExternalAuthConfig struct { type ProvisionerConfig struct { // Daemons is the number of built-in terraform provisioners. Daemons serpent.Int64 `json:"daemons" typescript:",notnull"` - DaemonTypes serpent.StringArray `json:"daemons_echo" typescript:",notnull"` + DaemonTypes serpent.StringArray `json:"daemon_types" typescript:",notnull"` DaemonPollInterval serpent.Duration `json:"daemon_poll_interval" typescript:",notnull"` DaemonPollJitter serpent.Duration `json:"daemon_poll_jitter" typescript:",notnull"` ForceCancelInterval serpent.Duration `json:"force_cancel_interval" typescript:",notnull"` @@ -1437,7 +1437,7 @@ when required by your organization's security policy.`, return nil }), Group: &deploymentGroupProvisioning, - YAML: "daemonsEcho", + YAML: "daemonTypes", }, { Name: "Poll Interval", diff --git a/docs/api/general.md b/docs/api/general.md index 444def8f58031..52313409cb02c 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -325,8 +325,8 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "daemon_poll_interval": 0, "daemon_poll_jitter": 0, "daemon_psk": "string", + "daemon_types": ["string"], "daemons": 0, - "daemons_echo": ["string"], "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, diff --git a/docs/api/schemas.md b/docs/api/schemas.md index fc297ea48ed54..26b38a7c1ec78 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2053,8 +2053,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_interval": 0, "daemon_poll_jitter": 0, "daemon_psk": "string", + "daemon_types": ["string"], "daemons": 0, - "daemons_echo": ["string"], "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, @@ -2426,8 +2426,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_interval": 0, "daemon_poll_jitter": 0, "daemon_psk": "string", + "daemon_types": ["string"], "daemons": 0, - "daemons_echo": ["string"], "force_cancel_interval": 0 }, "proxy_health_status_interval": 0, @@ -3691,8 +3691,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "daemon_poll_interval": 0, "daemon_poll_jitter": 0, "daemon_psk": "string", + "daemon_types": ["string"], "daemons": 0, - "daemons_echo": ["string"], "force_cancel_interval": 0 } ``` @@ -3704,8 +3704,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o | `daemon_poll_interval` | integer | false | | | | `daemon_poll_jitter` | integer | false | | | | `daemon_psk` | string | false | | | +| `daemon_types` | array of string | false | | | | `daemons` | integer | false | | Daemons is the number of built-in terraform provisioners. | -| `daemons_echo` | array of string | false | | | | `force_cancel_interval` | integer | false | | | ## codersdk.ProvisionerDaemon diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 623bad4767f42..d91a6b430de27 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -838,7 +838,7 @@ export interface PrometheusConfig { // From codersdk/deployment.go export interface ProvisionerConfig { readonly daemons: number; - readonly daemons_echo: number; + readonly daemon_types: string[]; readonly daemon_poll_interval: number; readonly daemon_poll_jitter: number; readonly force_cancel_interval: number; From 672979b2e71a6c42134e3210e0164508254cbf6b Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 14:33:03 -0500 Subject: [PATCH 15/17] update golden files --- cli/testdata/coder_server_--help.golden | 4 ++-- enterprise/cli/testdata/coder_server_--help.golden | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index 69ee62e07c472..6d8f866c11c0b 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -460,8 +460,8 @@ updating, and deleting workspace resources. server. --provisioner-daemons int, $CODER_PROVISIONER_DAEMONS (default: 3) - Number of terraform provisioner daemons to create on start. If builds - are stuck in queued state for a long time, consider increasing this. + Number of provisioner daemons to create on start. If builds are stuck + in queued state for a long time, consider increasing this. TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 4a873ce9c8779..4d4576d6d57cc 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -461,8 +461,8 @@ updating, and deleting workspace resources. server. --provisioner-daemons int, $CODER_PROVISIONER_DAEMONS (default: 3) - Number of terraform provisioner daemons to create on start. If builds - are stuck in queued state for a long time, consider increasing this. + Number of provisioner daemons to create on start. If builds are stuck + in queued state for a long time, consider increasing this. TELEMETRY OPTIONS: Telemetry is critical to our ability to improve Coder. We strip all From 57f081c2657e6e1472214fb6d787ffcadf4ef272 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 14:39:50 -0500 Subject: [PATCH 16/17] remove ui pills for provisioners on health page --- cli/testdata/server-config.yaml.golden | 13 +++++++------ .../src/pages/HealthPage/ProvisionerDaemonsPage.tsx | 12 ------------ 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index 2bce3bbb2900c..bf49239bc4e63 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -375,14 +375,15 @@ telemetry: # Tune the behavior of the provisioner, which is responsible for creating, # updating, and deleting workspace resources. provisioning: - # Number of terraform provisioner daemons to create on start. If builds are stuck - # in queued state for a long time, consider increasing this. + # Number of provisioner daemons to create on start. If builds are stuck in queued + # state for a long time, consider increasing this. # (default: 3, type: int) daemons: 3 - # Number of built-in echo provisioners to create on start. Can be done alongside - # actual terraform provisioners. This is for E2E tests. - # (default: 0, type: int) - daemonsEcho: 0 + # The supported job types for the built-in provisioners. By default, this is only + # the terraform type. Supported types: terraform,echo. + # (default: terraform, type: string-array) + daemonTypes: + - terraform # Deprecated and ignored. # (default: 1s, type: duration) daemonPollInterval: 1s diff --git a/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx b/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx index a676786b00558..ebd0c5ff630b5 100644 --- a/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx +++ b/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx @@ -116,18 +116,6 @@ export const ProvisionerDaemonsPage: FC = () => { gap: 12, }} > - { - // Add pills for the supported provisioenr types. - daemon.provisioners.map((provType) => { - return ( - - }> - {provType} - - - ); - }) - } }> {daemon.api_version} From 487f0a86d1501d6da4fd0237b5752055149ef21f Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 2 May 2024 14:42:24 -0500 Subject: [PATCH 17/17] remove unused import --- site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx b/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx index ebd0c5ff630b5..63ee9280987c5 100644 --- a/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx +++ b/site/src/pages/HealthPage/ProvisionerDaemonsPage.tsx @@ -4,7 +4,6 @@ import CloseIcon from "@mui/icons-material/Close"; import Person from "@mui/icons-material/Person"; import Sell from "@mui/icons-material/Sell"; import SwapHoriz from "@mui/icons-material/SwapHoriz"; -import ViewInArIcon from "@mui/icons-material/ViewInAr"; import IconButton from "@mui/material/IconButton"; import Tooltip from "@mui/material/Tooltip"; import type { FC } from "react";