mirror of https://github.com/coder/coder.git
chore: allow terraform & echo built-in provisioners
Built-in provisioners server their respective types, not both.
This commit is contained in:
parent
845407fe7a
commit
e26141fcfd
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 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",
|
||||
|
|
Loading…
Reference in New Issue