mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: add lifecycle.Executor to manage autostart and autostop (#1183)
This PR adds a package lifecycle and an Executor implementation that attempts to schedule a build of workspaces with autostart configured. - lifecycle.Executor takes a chan time.Time in its constructor (e.g. time.Tick(time.Minute)) - Whenever a value is received from this channel, it executes one iteration of looping through the workspaces and triggering lifecycle operations. - When the context passed to the executor is Done, it exits. - Only workspaces that meet the following criteria will have a lifecycle operation applied to them: - Workspace has a valid and non-empty autostart or autostop schedule (either) - Workspace's last build was successful - The following transitions will be applied depending on the current workspace state: - If the workspace is currently running, it will be stopped. - If the workspace is currently stopped, it will be started. - Otherwise, nothing will be done. - Workspace builds will be created with the same parameters and template version as the last successful build (for example, template version)
This commit is contained in:
@ -36,6 +36,7 @@ import (
|
||||
"cdr.dev/slog"
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
"github.com/coder/coder/coderd"
|
||||
"github.com/coder/coder/coderd/autobuild/executor"
|
||||
"github.com/coder/coder/coderd/awsidentity"
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/database/databasefake"
|
||||
@ -57,6 +58,7 @@ type Options struct {
|
||||
GoogleTokenValidator *idtoken.Validator
|
||||
SSHKeygenAlgorithm gitsshkey.Algorithm
|
||||
APIRateLimit int
|
||||
LifecycleTicker <-chan time.Time
|
||||
}
|
||||
|
||||
// New constructs an in-memory coderd instance and returns
|
||||
@ -72,6 +74,11 @@ func New(t *testing.T, options *Options) *codersdk.Client {
|
||||
options.GoogleTokenValidator, err = idtoken.NewValidator(ctx, option.WithoutAuthentication())
|
||||
require.NoError(t, err)
|
||||
}
|
||||
if options.LifecycleTicker == nil {
|
||||
ticker := make(chan time.Time)
|
||||
options.LifecycleTicker = ticker
|
||||
t.Cleanup(func() { close(ticker) })
|
||||
}
|
||||
|
||||
// This can be hotswapped for a live database instance.
|
||||
db := databasefake.New()
|
||||
@ -96,8 +103,16 @@ func New(t *testing.T, options *Options) *codersdk.Client {
|
||||
})
|
||||
}
|
||||
|
||||
srv := httptest.NewUnstartedServer(nil)
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
lifecycleExecutor := executor.New(
|
||||
ctx,
|
||||
db,
|
||||
slogtest.Make(t, nil).Named("autobuild.executor").Leveled(slog.LevelDebug),
|
||||
options.LifecycleTicker,
|
||||
)
|
||||
lifecycleExecutor.Run()
|
||||
|
||||
srv := httptest.NewUnstartedServer(nil)
|
||||
srv.Config.BaseContext = func(_ net.Listener) context.Context {
|
||||
return ctx
|
||||
}
|
||||
@ -246,6 +261,23 @@ func CreateTemplate(t *testing.T, client *codersdk.Client, organization uuid.UUI
|
||||
return template
|
||||
}
|
||||
|
||||
// UpdateTemplateVersion creates a new template version with the "echo" provisioner
|
||||
// and associates it with the given templateID.
|
||||
func UpdateTemplateVersion(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses, templateID uuid.UUID) codersdk.TemplateVersion {
|
||||
data, err := echo.Tar(res)
|
||||
require.NoError(t, err)
|
||||
file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, data)
|
||||
require.NoError(t, err)
|
||||
templateVersion, err := client.CreateTemplateVersion(context.Background(), organizationID, codersdk.CreateTemplateVersionRequest{
|
||||
TemplateID: templateID,
|
||||
StorageSource: file.Hash,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return templateVersion
|
||||
}
|
||||
|
||||
// AwaitTemplateImportJob awaits for an import job to reach completed status.
|
||||
func AwaitTemplateVersionJob(t *testing.T, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
|
||||
var templateVersion codersdk.TemplateVersion
|
||||
|
Reference in New Issue
Block a user