mirror of https://github.com/coder/coder.git
Merge 847090a03a
into 93d8812284
This commit is contained in:
commit
bf88bde7cd
|
@ -944,7 +944,19 @@ 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. 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.DaemonsEcho.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
|
||||
// the 64 character limit.
|
||||
|
@ -952,7 +964,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 +1352,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 +1373,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 +1401,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 +1440,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,
|
||||
|
|
|
@ -1367,7 +1367,8 @@ func TestServer(t *testing.T) {
|
|||
"--in-memory",
|
||||
"--http-address", ":0",
|
||||
"--access-url", "http://example.com",
|
||||
"--provisioner-daemons-echo",
|
||||
"--provisioner-daemons=0",
|
||||
"--provisioner-daemons-echo=3",
|
||||
"--log-human", fiName,
|
||||
)
|
||||
clitest.Start(t, root)
|
||||
|
@ -1385,7 +1386,8 @@ func TestServer(t *testing.T) {
|
|||
"--in-memory",
|
||||
"--http-address", ":0",
|
||||
"--access-url", "http://example.com",
|
||||
"--provisioner-daemons-echo",
|
||||
"--provisioner-daemons=0",
|
||||
"--provisioner-daemons-echo=3",
|
||||
"--log-human", fi,
|
||||
)
|
||||
clitest.Start(t, root)
|
||||
|
@ -1403,7 +1405,8 @@ func TestServer(t *testing.T) {
|
|||
"--in-memory",
|
||||
"--http-address", ":0",
|
||||
"--access-url", "http://example.com",
|
||||
"--provisioner-daemons-echo",
|
||||
"--provisioner-daemons=0",
|
||||
"--provisioner-daemons-echo=3",
|
||||
"--log-json", fi,
|
||||
)
|
||||
clitest.Start(t, root)
|
||||
|
@ -1424,7 +1427,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-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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -10487,10 +10487,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"
|
||||
|
|
|
@ -9423,10 +9423,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"
|
||||
|
|
|
@ -1351,7 +1351,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() {
|
||||
|
@ -1368,18 +1368,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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 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"`
|
||||
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
@ -3693,21 +3693,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
|
||||
|
||||
|
|
|
@ -711,7 +711,7 @@ Enables capturing of logs as events in traces. This is useful for debugging, but
|
|||
| YAML | <code>provisioning.daemons</code> |
|
||||
| Default | <code>3</code> |
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -58,8 +58,9 @@ export default defineConfig({
|
|||
"--in-memory",
|
||||
"--telemetry=false",
|
||||
"--dangerous-disable-rate-limits",
|
||||
"--provisioner-daemons 10",
|
||||
"--provisioner-daemons-echo",
|
||||
// TODO: Enable some terraform provisioners
|
||||
"--provisioner-daemons 0",
|
||||
"--provisioner-daemons-echo 10",
|
||||
"--web-terminal-renderer=dom",
|
||||
"--pprof-enable",
|
||||
]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 (
|
||||
<Tooltip title="Type" key={daemon.id + provType}>
|
||||
<Pill icon={<ViewInArIcon />}>
|
||||
<code>{provType}</code>
|
||||
</Pill>
|
||||
</Tooltip>
|
||||
);
|
||||
})
|
||||
}
|
||||
<Tooltip title="API Version">
|
||||
<Pill icon={<SwapHoriz />}>
|
||||
<code>{daemon.api_version}</code>
|
||||
|
|
Loading…
Reference in New Issue