diff --git a/cli/agent_test.go b/cli/agent_test.go index 70c32dd9662b3..71bc7b1d6949c 100644 --- a/cli/agent_test.go +++ b/cli/agent_test.go @@ -19,10 +19,10 @@ func TestWorkspaceAgent(t *testing.T) { instanceID := "instanceidentifier" certificates, metadataClient := coderdtest.NewAzureInstanceIdentity(t, instanceID) client := coderdtest.New(t, &coderdtest.Options{ - AzureCertificates: certificates, + AzureCertificates: certificates, + IncludeProvisionerD: true, }) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -73,10 +73,10 @@ func TestWorkspaceAgent(t *testing.T) { instanceID := "instanceidentifier" certificates, metadataClient := coderdtest.NewAWSInstanceIdentity(t, instanceID) client := coderdtest.New(t, &coderdtest.Options{ - AWSCertificates: certificates, + AWSCertificates: certificates, + IncludeProvisionerD: true, }) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -128,9 +128,9 @@ func TestWorkspaceAgent(t *testing.T) { validator, metadata := coderdtest.NewGoogleInstanceIdentity(t, instanceID, false) client := coderdtest.New(t, &coderdtest.Options{ GoogleTokenValidator: validator, + IncludeProvisionerD: true, }) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ diff --git a/cli/autostart_test.go b/cli/autostart_test.go index 8c9ff40ee25d0..31f3ab600614f 100644 --- a/cli/autostart_test.go +++ b/cli/autostart_test.go @@ -22,8 +22,7 @@ func TestAutostart(t *testing.T) { var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -54,8 +53,7 @@ func TestAutostart(t *testing.T) { var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -99,8 +97,7 @@ func TestAutostart(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -117,8 +114,7 @@ func TestAutostart(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -136,8 +132,7 @@ func TestAutostart(t *testing.T) { var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) diff --git a/cli/configssh_test.go b/cli/configssh_test.go index 61b83c0781844..85e06188974b8 100644 --- a/cli/configssh_test.go +++ b/cli/configssh_test.go @@ -27,9 +27,8 @@ import ( func TestConfigSSH(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) authToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, diff --git a/cli/create_test.go b/cli/create_test.go index b9746df993196..f81f2a027d4d2 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -17,9 +17,8 @@ func TestCreate(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -48,9 +47,8 @@ func TestCreate(t *testing.T) { t.Run("CreateFromList", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -79,9 +77,8 @@ func TestCreate(t *testing.T) { t.Run("FromNothing", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -111,9 +108,8 @@ func TestCreate(t *testing.T) { t.Run("WithParameter", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) defaultValue := "something" version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ diff --git a/cli/gitssh_test.go b/cli/gitssh_test.go index 2db9131c3c7be..084407c9e3a72 100644 --- a/cli/gitssh_test.go +++ b/cli/gitssh_test.go @@ -22,7 +22,7 @@ import ( func TestGitSSH(t *testing.T) { t.Parallel() t.Run("Dial", func(t *testing.T) { - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) // get user public key @@ -31,9 +31,8 @@ func TestGitSSH(t *testing.T) { publicKey, _, _, _, err := gossh.ParseAuthorizedKey([]byte(keypair.PublicKey)) require.NoError(t, err) - // setup provisioner + // setup template agentToken := uuid.NewString() - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, ProvisionDryRun: echo.ProvisionComplete, diff --git a/cli/list_test.go b/cli/list_test.go index 5dd24eddd0347..76408ea3f1f33 100644 --- a/cli/list_test.go +++ b/cli/list_test.go @@ -14,9 +14,8 @@ func TestList(t *testing.T) { t.Parallel() t.Run("Single", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) diff --git a/cli/portforward_test.go b/cli/portforward_test.go index 0c0d3ddc5fa08..f400587d4ba0e 100644 --- a/cli/portforward_test.go +++ b/cli/portforward_test.go @@ -149,7 +149,7 @@ func TestPortForward(t *testing.T) { t.Run("OnePort", func(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) _, workspace = runAgent(t, client, user.UserID) l1, p1 = setupTestListener(t, c.setupRemote(t)) @@ -193,7 +193,7 @@ func TestPortForward(t *testing.T) { t.Run("TwoPorts", func(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) _, workspace = runAgent(t, client, user.UserID) l1, p1 = setupTestListener(t, c.setupRemote(t)) @@ -244,7 +244,7 @@ func TestPortForward(t *testing.T) { t.Run("TCP2Unix", func(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) _, workspace = runAgent(t, client, user.UserID) @@ -297,7 +297,7 @@ func TestPortForward(t *testing.T) { t.Run("All", func(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) _, workspace = runAgent(t, client, user.UserID) // These aren't fixed size because we exclude Unix on Windows. @@ -371,9 +371,8 @@ func runAgent(t *testing.T, client *codersdk.Client, userID uuid.UUID) ([]coders require.Greater(t, len(user.OrganizationIDs), 0, "user has no organizations") orgID := user.OrganizationIDs[0] - // Setup echo provisioner + // Setup template agentToken := uuid.NewString() - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, orgID, &echo.Responses{ Parse: echo.ParseComplete, ProvisionDryRun: echo.ProvisionComplete, diff --git a/cli/server.go b/cli/server.go index 6c861c116e87e..1462f1956ce5e 100644 --- a/cli/server.go +++ b/cli/server.go @@ -19,6 +19,8 @@ import ( "path/filepath" "time" + "github.com/coder/coder/provisioner/echo" + "github.com/briandowns/spinner" "github.com/coreos/go-systemd/daemon" "github.com/google/go-github/v43/github" @@ -249,7 +251,7 @@ func server() *cobra.Command { } } - handler, closeCoderd := coderd.New(options) + coderDaemon := coderd.New(options) client := codersdk.New(localURL) if tlsEnable { // Secure transport isn't needed for locally communicating! @@ -275,7 +277,7 @@ func server() *cobra.Command { errCh := make(chan error, 1) provisionerDaemons := make([]*provisionerd.Server, 0) for i := 0; uint8(i) < provisionerDaemonCount; i++ { - daemonClose, err := newProvisionerDaemon(cmd.Context(), client, logger, cacheDir, errCh) + daemonClose, err := newProvisionerDaemon(cmd.Context(), coderDaemon, logger, cacheDir, errCh, dev) if err != nil { return xerrors.Errorf("create provisioner daemon: %w", err) } @@ -295,7 +297,7 @@ func server() *cobra.Command { // These errors are typically noise like "TLS: EOF". Vault does similar: // https://github.com/hashicorp/vault/blob/e2490059d0711635e529a4efcbaa1b26998d6e1c/command/server.go#L2714 ErrorLog: log.New(io.Discard, "", 0), - Handler: handler, + Handler: coderDaemon.Handler(), BaseContext: func(_ net.Listener) context.Context { return shutdownConnsCtx }, @@ -363,7 +365,7 @@ func server() *cobra.Command { signal.Notify(stopChan, os.Interrupt) select { case <-cmd.Context().Done(): - closeCoderd() + coderDaemon.CloseWait() return cmd.Context().Err() case err := <-tunnelErrChan: if err != nil { @@ -371,7 +373,7 @@ func server() *cobra.Command { } case err := <-errCh: shutdownConns() - closeCoderd() + coderDaemon.CloseWait() return err case <-stopChan: } @@ -435,7 +437,7 @@ func server() *cobra.Command { _, _ = fmt.Fprintf(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Waiting for WebSocket connections to close...\n") shutdownConns() - closeCoderd() + coderDaemon.CloseWait() return nil }, } @@ -529,7 +531,9 @@ func createFirstUser(cmd *cobra.Command, client *codersdk.Client, cfg config.Roo return nil } -func newProvisionerDaemon(ctx context.Context, client *codersdk.Client, logger slog.Logger, cacheDir string, errChan chan error) (*provisionerd.Server, error) { +// nolint:revive +func newProvisionerDaemon(ctx context.Context, coderDaemon coderd.CoderD, + logger slog.Logger, cacheDir string, errChan chan error, dev bool) (*provisionerd.Server, error) { err := os.MkdirAll(cacheDir, 0700) if err != nil { return nil, xerrors.Errorf("mkdir %q: %w", cacheDir, err) @@ -554,14 +558,26 @@ func newProvisionerDaemon(ctx context.Context, client *codersdk.Client, logger s return nil, err } - return provisionerd.New(client.ListenProvisionerDaemon, &provisionerd.Options{ + provisioners := provisionerd.Provisioners{ + string(database.ProvisionerTypeTerraform): proto.NewDRPCProvisionerClient(provisionersdk.Conn(terraformClient)), + } + // include echo provisioner when in dev mode + if dev { + echoClient, echoServer := provisionersdk.TransportPipe() + go func() { + err := echo.Serve(ctx, &provisionersdk.ServeOptions{Listener: echoServer}) + if err != nil { + errChan <- err + } + }() + provisioners[string(database.ProvisionerTypeEcho)] = proto.NewDRPCProvisionerClient(provisionersdk.Conn(echoClient)) + } + return provisionerd.New(coderDaemon.ListenProvisionerDaemon, &provisionerd.Options{ Logger: logger, PollInterval: 500 * time.Millisecond, UpdateInterval: 500 * time.Millisecond, - Provisioners: provisionerd.Provisioners{ - string(database.ProvisionerTypeTerraform): proto.NewDRPCProvisionerClient(provisionersdk.Conn(terraformClient)), - }, - WorkDirectory: tempDir, + Provisioners: provisioners, + WorkDirectory: tempDir, }), nil } diff --git a/cli/server_test.go b/cli/server_test.go index ef0d72a1cd493..d18515172e996 100644 --- a/cli/server_test.go +++ b/cli/server_test.go @@ -236,12 +236,11 @@ func TestServer(t *testing.T) { } ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() - root, cfg := clitest.New(t, "server", "--dev", "--tunnel=false", "--address", ":0", "--provisioner-daemons", "0") - done := make(chan struct{}) + root, cfg := clitest.New(t, "server", "--dev", "--tunnel=false", "--address", ":0", "--provisioner-daemons", "1") + serverErr := make(chan error) go func() { - defer close(done) err := root.ExecuteContext(ctx) - require.NoError(t, err) + serverErr <- err }() var token string require.Eventually(t, func() bool { @@ -258,7 +257,6 @@ func TestServer(t *testing.T) { client.SessionToken = token orgs, err := client.OrganizationsByUser(ctx, codersdk.Me) require.NoError(t, err) - coderdtest.NewProvisionerDaemon(t, client) // Create a workspace so the cleanup occurs! version := coderdtest.CreateTemplateVersion(t, client, orgs[0].ID, nil) @@ -278,7 +276,8 @@ func TestServer(t *testing.T) { require.NoError(t, err) err = currentProcess.Signal(os.Interrupt) require.NoError(t, err) - <-done + err = <-serverErr + require.NoError(t, err) }) t.Run("DatadogTracerNoLeak", func(t *testing.T) { t.Parallel() diff --git a/cli/ssh_test.go b/cli/ssh_test.go index 868f813b1c675..ac638e7cef45a 100644 --- a/cli/ssh_test.go +++ b/cli/ssh_test.go @@ -26,9 +26,8 @@ func TestSSH(t *testing.T) { t.Parallel() t.Run("ImmediateExit", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) agentToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -81,9 +80,8 @@ func TestSSH(t *testing.T) { }) t.Run("Stdio", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) agentToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, diff --git a/cli/state_test.go b/cli/state_test.go index f1decece85c1c..59f56f2bea504 100644 --- a/cli/state_test.go +++ b/cli/state_test.go @@ -20,9 +20,8 @@ func TestStatePull(t *testing.T) { t.Parallel() t.Run("File", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) wantState := []byte("some state") version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -49,9 +48,8 @@ func TestStatePull(t *testing.T) { }) t.Run("Stdout", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) wantState := []byte("some state") version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -81,9 +79,8 @@ func TestStatePush(t *testing.T) { t.Parallel() t.Run("File", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: echo.ProvisionComplete, @@ -109,9 +106,8 @@ func TestStatePush(t *testing.T) { t.Run("Stdin", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: echo.ProvisionComplete, diff --git a/cli/templatecreate_test.go b/cli/templatecreate_test.go index 403b7d1ea018e..37bc0cb3a0080 100644 --- a/cli/templatecreate_test.go +++ b/cli/templatecreate_test.go @@ -16,7 +16,7 @@ func TestTemplateCreate(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) coderdtest.CreateFirstUser(t, client) source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ Parse: echo.ParseComplete, @@ -24,7 +24,6 @@ func TestTemplateCreate(t *testing.T) { }) cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho)) clitest.SetupConfig(t, client, root) - _ = coderdtest.NewProvisionerDaemon(t, client) pty := ptytest.New(t) cmd.SetIn(pty.Input()) cmd.SetOut(pty.Output()) diff --git a/cli/templatedelete_test.go b/cli/templatedelete_test.go index 95328f44f91df..92fb0b2932fa0 100644 --- a/cli/templatedelete_test.go +++ b/cli/templatedelete_test.go @@ -18,9 +18,8 @@ func TestTemplateDelete(t *testing.T) { t.Run("Ok", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - _ = coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -36,9 +35,8 @@ func TestTemplateDelete(t *testing.T) { t.Run("Multiple", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - _ = coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) templates := []codersdk.Template{ @@ -64,9 +62,8 @@ func TestTemplateDelete(t *testing.T) { t.Run("Selector", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - _ = coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) diff --git a/cli/templateupdate_test.go b/cli/templateupdate_test.go index b29199fab960e..134e884370733 100644 --- a/cli/templateupdate_test.go +++ b/cli/templateupdate_test.go @@ -18,9 +18,8 @@ import ( func TestTemplateUpdate(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - _ = coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) diff --git a/cli/ttl_test.go b/cli/ttl_test.go index 46c48b877012d..d6ea9929eeb4f 100644 --- a/cli/ttl_test.go +++ b/cli/ttl_test.go @@ -22,8 +22,7 @@ func TestTTL(t *testing.T) { var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -53,8 +52,7 @@ func TestTTL(t *testing.T) { var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -97,8 +95,7 @@ func TestTTL(t *testing.T) { var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -141,8 +138,7 @@ func TestTTL(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -159,8 +155,7 @@ func TestTTL(t *testing.T) { t.Parallel() var ( - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) diff --git a/coderd/autobuild/executor/lifecycle_executor_test.go b/coderd/autobuild/executor/lifecycle_executor_test.go index a0aa20dc3bd0f..5b1bdfafe6e73 100644 --- a/coderd/autobuild/executor/lifecycle_executor_test.go +++ b/coderd/autobuild/executor/lifecycle_executor_test.go @@ -27,7 +27,8 @@ func TestExecutorAutostartOK(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -67,7 +68,8 @@ func TestExecutorAutostartTemplateUpdated(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -119,7 +121,8 @@ func TestExecutorAutostartAlreadyRunning(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -157,7 +160,8 @@ func TestExecutorAutostartNotEnabled(t *testing.T) { var ( tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -190,7 +194,8 @@ func TestExecutorAutostopOK(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -230,7 +235,8 @@ func TestExecutorAutostopAlreadyStopped(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -268,7 +274,8 @@ func TestExecutorAutostopNotEnabled(t *testing.T) { var ( tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -301,7 +308,8 @@ func TestExecutorWorkspaceDeleted(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -341,7 +349,8 @@ func TestExecutorWorkspaceAutostartTooEarly(t *testing.T) { err error tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -379,7 +388,8 @@ func TestExecutorWorkspaceTTLTooEarly(t *testing.T) { ctx = context.Background() tickCh = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) // Given: we have a user with a workspace workspace = mustProvisionWorkspace(t, client) @@ -420,7 +430,8 @@ func TestExecutorAutostartMultipleOK(t *testing.T) { tickCh = make(chan time.Time) tickCh2 = make(chan time.Time) client = coderdtest.New(t, &coderdtest.Options{ - AutobuildTicker: tickCh, + AutobuildTicker: tickCh, + IncludeProvisionerD: true, }) _ = coderdtest.New(t, &coderdtest.Options{ AutobuildTicker: tickCh2, @@ -470,7 +481,6 @@ func TestExecutorAutostartMultipleOK(t *testing.T) { func mustProvisionWorkspace(t *testing.T, client *codersdk.Client) codersdk.Workspace { t.Helper() - coderdtest.NewProvisionerDaemon(t, client) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) diff --git a/coderd/coderd.go b/coderd/coderd.go index a7e1ea202167d..cb1d345983a03 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -27,6 +27,7 @@ import ( "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/coderd/turnconn" "github.com/coder/coder/codersdk" + "github.com/coder/coder/provisionerd/proto" "github.com/coder/coder/site" ) @@ -53,11 +54,22 @@ type Options struct { Authorizer rbac.Authorizer } -// New constructs the Coder API into an HTTP handler. -// -// A wait function is returned to handle awaiting closure of hijacked HTTP -// requests. -func New(options *Options) (http.Handler, func()) { +type CoderD interface { + Handler() http.Handler + CloseWait() + + // An in-process provisionerd connection. + ListenProvisionerDaemon(ctx context.Context) (proto.DRPCProvisionerDaemonClient, error) +} + +type coderD struct { + api *api + router chi.Router + options *Options +} + +// newRouter constructs the Chi Router for the given API. +func newRouter(options *Options, a *api) chi.Router { if options.AgentConnectionUpdateFrequency == 0 { options.AgentConnectionUpdateFrequency = 3 * time.Second } @@ -73,9 +85,6 @@ func New(options *Options) (http.Handler, func()) { panic(xerrors.Errorf("rego authorize panic: %w", err)) } } - api := &api{ - Options: options, - } apiKeyMiddleware := httpmw.ExtractAPIKey(options.Database, &httpmw.OAuth2Configs{ Github: options.GithubOAuth2Config, }) @@ -105,7 +114,7 @@ func New(options *Options) (http.Handler, func()) { r.Use( // Specific routes can specify smaller limits. httpmw.RateLimitPerMinute(options.APIRateLimit), - debugLogRequest(api.Logger), + debugLogRequest(a.Logger), ) r.Get("/", func(w http.ResponseWriter, r *http.Request) { httpapi.Write(w, http.StatusOK, httpapi.Response{ @@ -127,8 +136,8 @@ func New(options *Options) (http.Handler, func()) { // file content is expensive so it should be small. httpmw.RateLimitPerMinute(12), ) - r.Get("/{hash}", api.fileByHash) - r.Post("/", api.postFile) + r.Get("/{hash}", a.fileByHash) + r.Post("/", a.postFile) }) r.Route("/organizations/{organization}", func(r chi.Router) { r.Use( @@ -136,39 +145,39 @@ func New(options *Options) (http.Handler, func()) { httpmw.ExtractOrganizationParam(options.Database), authRolesMiddleware, ) - r.Get("/", api.organization) - r.Get("/provisionerdaemons", api.provisionerDaemonsByOrganization) - r.Post("/templateversions", api.postTemplateVersionsByOrganization) + r.Get("/", a.organization) + r.Get("/provisionerdaemons", a.provisionerDaemonsByOrganization) + r.Post("/templateversions", a.postTemplateVersionsByOrganization) r.Route("/templates", func(r chi.Router) { - r.Post("/", api.postTemplateByOrganization) - r.Get("/", api.templatesByOrganization) - r.Get("/{templatename}", api.templateByOrganizationAndName) + r.Post("/", a.postTemplateByOrganization) + r.Get("/", a.templatesByOrganization) + r.Get("/{templatename}", a.templateByOrganizationAndName) }) r.Route("/workspaces", func(r chi.Router) { - r.Post("/", api.postWorkspacesByOrganization) - r.Get("/", api.workspacesByOrganization) + r.Post("/", a.postWorkspacesByOrganization) + r.Get("/", a.workspacesByOrganization) r.Route("/{user}", func(r chi.Router) { r.Use(httpmw.ExtractUserParam(options.Database)) - r.Get("/{workspacename}", api.workspaceByOwnerAndName) - r.Get("/", api.workspacesByOwner) + r.Get("/{workspacename}", a.workspaceByOwnerAndName) + r.Get("/", a.workspacesByOwner) }) }) r.Route("/members", func(r chi.Router) { - r.Get("/roles", api.assignableOrgRoles) + r.Get("/roles", a.assignableOrgRoles) r.Route("/{user}", func(r chi.Router) { r.Use( httpmw.ExtractUserParam(options.Database), ) - r.Put("/roles", api.putMemberRoles) + r.Put("/roles", a.putMemberRoles) }) }) }) r.Route("/parameters/{scope}/{id}", func(r chi.Router) { r.Use(apiKeyMiddleware) - r.Post("/", api.postParameter) - r.Get("/", api.parameters) + r.Post("/", a.postParameter) + r.Get("/", a.parameters) r.Route("/{name}", func(r chi.Router) { - r.Delete("/", api.deleteParameter) + r.Delete("/", a.deleteParameter) }) }) r.Route("/templates/{template}", func(r chi.Router) { @@ -177,12 +186,12 @@ func New(options *Options) (http.Handler, func()) { httpmw.ExtractTemplateParam(options.Database), ) - r.Get("/", api.template) - r.Delete("/", api.deleteTemplate) + r.Get("/", a.template) + r.Delete("/", a.deleteTemplate) r.Route("/versions", func(r chi.Router) { - r.Get("/", api.templateVersionsByTemplate) - r.Patch("/", api.patchActiveTemplateVersion) - r.Get("/{templateversionname}", api.templateVersionByName) + r.Get("/", a.templateVersionsByTemplate) + r.Patch("/", a.patchActiveTemplateVersion) + r.Get("/{templateversionname}", a.templateVersionByName) }) }) r.Route("/templateversions/{templateversion}", func(r chi.Router) { @@ -191,28 +200,28 @@ func New(options *Options) (http.Handler, func()) { httpmw.ExtractTemplateVersionParam(options.Database), ) - r.Get("/", api.templateVersion) - r.Patch("/cancel", api.patchCancelTemplateVersion) - r.Get("/schema", api.templateVersionSchema) - r.Get("/parameters", api.templateVersionParameters) - r.Get("/resources", api.templateVersionResources) - r.Get("/logs", api.templateVersionLogs) + r.Get("/", a.templateVersion) + r.Patch("/cancel", a.patchCancelTemplateVersion) + r.Get("/schema", a.templateVersionSchema) + r.Get("/parameters", a.templateVersionParameters) + r.Get("/resources", a.templateVersionResources) + r.Get("/logs", a.templateVersionLogs) }) r.Route("/provisionerdaemons", func(r chi.Router) { r.Route("/me", func(r chi.Router) { - r.Get("/listen", api.provisionerDaemonsListen) + r.Get("/listen", a.provisionerDaemonsListen) }) }) r.Route("/users", func(r chi.Router) { - r.Get("/first", api.firstUser) - r.Post("/first", api.postFirstUser) - r.Post("/login", api.postLogin) - r.Post("/logout", api.postLogout) - r.Get("/authmethods", api.userAuthMethods) + r.Get("/first", a.firstUser) + r.Post("/first", a.postFirstUser) + r.Post("/login", a.postLogin) + r.Post("/logout", a.postLogout) + r.Get("/authmethods", a.userAuthMethods) r.Route("/oauth2", func(r chi.Router) { r.Route("/github", func(r chi.Router) { r.Use(httpmw.ExtractOAuth2(options.GithubOAuth2Config)) - r.Get("/callback", api.userOAuth2Github) + r.Get("/callback", a.userOAuth2Github) }) }) r.Group(func(r chi.Router) { @@ -220,62 +229,62 @@ func New(options *Options) (http.Handler, func()) { apiKeyMiddleware, authRolesMiddleware, ) - r.Post("/", api.postUser) - r.Get("/", api.users) + r.Post("/", a.postUser) + r.Get("/", a.users) // These routes query information about site wide roles. r.Route("/roles", func(r chi.Router) { - r.Get("/", api.assignableSiteRoles) + r.Get("/", a.assignableSiteRoles) }) r.Route("/{user}", func(r chi.Router) { r.Use(httpmw.ExtractUserParam(options.Database)) - r.Get("/", api.userByName) - r.Put("/profile", api.putUserProfile) + r.Get("/", a.userByName) + r.Put("/profile", a.putUserProfile) r.Route("/status", func(r chi.Router) { - r.Put("/suspend", api.putUserStatus(database.UserStatusSuspended)) - r.Put("/active", api.putUserStatus(database.UserStatusActive)) + r.Put("/suspend", a.putUserStatus(database.UserStatusSuspended)) + r.Put("/active", a.putUserStatus(database.UserStatusActive)) }) r.Route("/password", func(r chi.Router) { - r.Put("/", api.putUserPassword) + r.Put("/", a.putUserPassword) }) // These roles apply to the site wide permissions. - r.Put("/roles", api.putUserRoles) - r.Get("/roles", api.userRoles) + r.Put("/roles", a.putUserRoles) + r.Get("/roles", a.userRoles) - r.Post("/authorization", api.checkPermissions) + r.Post("/authorization", a.checkPermissions) - r.Post("/keys", api.postAPIKey) + r.Post("/keys", a.postAPIKey) r.Route("/organizations", func(r chi.Router) { - r.Post("/", api.postOrganizationsByUser) - r.Get("/", api.organizationsByUser) - r.Get("/{organizationname}", api.organizationByUserAndName) + r.Post("/", a.postOrganizationsByUser) + r.Get("/", a.organizationsByUser) + r.Get("/{organizationname}", a.organizationByUserAndName) }) - r.Get("/gitsshkey", api.gitSSHKey) - r.Put("/gitsshkey", api.regenerateGitSSHKey) + r.Get("/gitsshkey", a.gitSSHKey) + r.Put("/gitsshkey", a.regenerateGitSSHKey) }) }) }) r.Route("/workspaceagents", func(r chi.Router) { - r.Post("/azure-instance-identity", api.postWorkspaceAuthAzureInstanceIdentity) - r.Post("/aws-instance-identity", api.postWorkspaceAuthAWSInstanceIdentity) - r.Post("/google-instance-identity", api.postWorkspaceAuthGoogleInstanceIdentity) + r.Post("/azure-instance-identity", a.postWorkspaceAuthAzureInstanceIdentity) + r.Post("/aws-instance-identity", a.postWorkspaceAuthAWSInstanceIdentity) + r.Post("/google-instance-identity", a.postWorkspaceAuthGoogleInstanceIdentity) r.Route("/me", func(r chi.Router) { r.Use(httpmw.ExtractWorkspaceAgent(options.Database)) - r.Get("/metadata", api.workspaceAgentMetadata) - r.Get("/listen", api.workspaceAgentListen) - r.Get("/gitsshkey", api.agentGitSSHKey) - r.Get("/turn", api.workspaceAgentTurn) - r.Get("/iceservers", api.workspaceAgentICEServers) + r.Get("/metadata", a.workspaceAgentMetadata) + r.Get("/listen", a.workspaceAgentListen) + r.Get("/gitsshkey", a.agentGitSSHKey) + r.Get("/turn", a.workspaceAgentTurn) + r.Get("/iceservers", a.workspaceAgentICEServers) }) r.Route("/{workspaceagent}", func(r chi.Router) { r.Use( apiKeyMiddleware, httpmw.ExtractWorkspaceAgentParam(options.Database), ) - r.Get("/", api.workspaceAgent) - r.Get("/dial", api.workspaceAgentDial) - r.Get("/turn", api.workspaceAgentTurn) - r.Get("/pty", api.workspaceAgentPTY) - r.Get("/iceservers", api.workspaceAgentICEServers) + r.Get("/", a.workspaceAgent) + r.Get("/dial", a.workspaceAgentDial) + r.Get("/turn", a.workspaceAgentTurn) + r.Get("/pty", a.workspaceAgentPTY) + r.Get("/iceservers", a.workspaceAgentICEServers) }) }) r.Route("/workspaceresources/{workspaceresource}", func(r chi.Router) { @@ -284,31 +293,31 @@ func New(options *Options) (http.Handler, func()) { httpmw.ExtractWorkspaceResourceParam(options.Database), httpmw.ExtractWorkspaceParam(options.Database), ) - r.Get("/", api.workspaceResource) + r.Get("/", a.workspaceResource) }) r.Route("/workspaces", func(r chi.Router) { r.Use( apiKeyMiddleware, authRolesMiddleware, ) - r.Get("/", api.workspaces) + r.Get("/", a.workspaces) r.Route("/{workspace}", func(r chi.Router) { r.Use( httpmw.ExtractWorkspaceParam(options.Database), ) - r.Get("/", api.workspace) + r.Get("/", a.workspace) r.Route("/builds", func(r chi.Router) { - r.Get("/", api.workspaceBuilds) - r.Post("/", api.postWorkspaceBuilds) - r.Get("/{workspacebuildname}", api.workspaceBuildByName) + r.Get("/", a.workspaceBuilds) + r.Post("/", a.postWorkspaceBuilds) + r.Get("/{workspacebuildname}", a.workspaceBuildByName) }) r.Route("/autostart", func(r chi.Router) { - r.Put("/", api.putWorkspaceAutostart) + r.Put("/", a.putWorkspaceAutostart) }) r.Route("/ttl", func(r chi.Router) { - r.Put("/", api.putWorkspaceTTL) + r.Put("/", a.putWorkspaceTTL) }) - r.Get("/watch", api.watchWorkspace) + r.Get("/watch", a.watchWorkspace) }) }) r.Route("/workspacebuilds/{workspacebuild}", func(r chi.Router) { @@ -318,24 +327,39 @@ func New(options *Options) (http.Handler, func()) { httpmw.ExtractWorkspaceBuildParam(options.Database), httpmw.ExtractWorkspaceParam(options.Database), ) - r.Get("/", api.workspaceBuild) - r.Patch("/cancel", api.patchCancelWorkspaceBuild) - r.Get("/logs", api.workspaceBuildLogs) - r.Get("/resources", api.workspaceBuildResources) - r.Get("/state", api.workspaceBuildState) + r.Get("/", a.workspaceBuild) + r.Patch("/cancel", a.patchCancelWorkspaceBuild) + r.Get("/logs", a.workspaceBuildLogs) + r.Get("/resources", a.workspaceBuildResources) + r.Get("/state", a.workspaceBuildState) }) }) var _ = xerrors.New("test") r.NotFound(site.DefaultHandler().ServeHTTP) - return r, func() { - api.websocketWaitMutex.Lock() - api.websocketWaitGroup.Wait() - api.websocketWaitMutex.Unlock() + return r +} + +func New(options *Options) CoderD { + a := &api{Options: options} + return &coderD{ + api: a, + router: newRouter(options, a), + options: options, } } +func (c *coderD) CloseWait() { + c.api.websocketWaitMutex.Lock() + c.api.websocketWaitGroup.Wait() + c.api.websocketWaitMutex.Unlock() +} + +func (c *coderD) Handler() http.Handler { + return c.router +} + // API contains all route handlers. Only HTTP handlers should // be added to this struct for code clarity. type api struct { diff --git a/coderd/coderd_test.go b/coderd/coderd_test.go index d462263dcd0ae..f3d13dc8b8b75 100644 --- a/coderd/coderd_test.go +++ b/coderd/coderd_test.go @@ -36,15 +36,15 @@ func TestAuthorizeAllEndpoints(t *testing.T) { t.Parallel() authorizer := &fakeAuthorizer{} - srv, client := coderdtest.NewWithServer(t, &coderdtest.Options{ - Authorizer: authorizer, + srv, client, _ := coderdtest.NewWithServer(t, &coderdtest.Options{ + Authorizer: authorizer, + IncludeProvisionerD: true, }) admin := coderdtest.CreateFirstUser(t, client) organization, err := client.Organization(context.Background(), admin.OrganizationID) require.NoError(t, err, "fetch org") // Setup some data in the database. - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID) diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index caffdf0fabf98..4392ab81d55ea 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -63,18 +63,21 @@ type Options struct { SSHKeygenAlgorithm gitsshkey.Algorithm APIRateLimit int AutobuildTicker <-chan time.Time + + // IncludeProvisionerD when true means to start an in-memory provisionerD + IncludeProvisionerD bool } // New constructs an in-memory coderd instance and returns // the connected client. func New(t *testing.T, options *Options) *codersdk.Client { - _, cli := NewWithServer(t, options) + _, cli, _ := NewWithServer(t, options) return cli } // NewWithServer returns an in-memory coderd instance and // the HTTP server it started with. -func NewWithServer(t *testing.T, options *Options) (*httptest.Server, *codersdk.Client) { +func NewWithServer(t *testing.T, options *Options) (*httptest.Server, *codersdk.Client, coderd.CoderD) { if options == nil { options = &Options{} } @@ -130,7 +133,6 @@ func NewWithServer(t *testing.T, options *Options) (*httptest.Server, *codersdk. srv.Start() serverURL, err := url.Parse(srv.URL) require.NoError(t, err) - var closeWait func() // match default with cli default if options.SSHKeygenAlgorithm == "" { @@ -141,7 +143,7 @@ func NewWithServer(t *testing.T, options *Options) (*httptest.Server, *codersdk. require.NoError(t, err) // We set the handler after server creation for the access URL. - srv.Config.Handler, closeWait = coderd.New(&coderd.Options{ + coderDaemon := coderd.New(&coderd.Options{ AgentConnectionUpdateFrequency: 150 * time.Millisecond, AccessURL: serverURL, Logger: slogtest.Make(t, nil).Leveled(slog.LevelDebug), @@ -157,20 +159,24 @@ func NewWithServer(t *testing.T, options *Options) (*httptest.Server, *codersdk. APIRateLimit: options.APIRateLimit, Authorizer: options.Authorizer, }) + srv.Config.Handler = coderDaemon.Handler() + if options.IncludeProvisionerD { + _ = NewProvisionerDaemon(t, coderDaemon) + } t.Cleanup(func() { cancelFunc() _ = turnServer.Close() srv.Close() - closeWait() + coderDaemon.CloseWait() }) - return srv, codersdk.New(serverURL) + return srv, codersdk.New(serverURL), coderDaemon } // NewProvisionerDaemon launches a provisionerd instance configured to work // well with coderd testing. It registers the "echo" provisioner for // quick testing. -func NewProvisionerDaemon(t *testing.T, client *codersdk.Client) io.Closer { +func NewProvisionerDaemon(t *testing.T, coderDaemon coderd.CoderD) io.Closer { echoClient, echoServer := provisionersdk.TransportPipe() ctx, cancelFunc := context.WithCancel(context.Background()) t.Cleanup(func() { @@ -185,7 +191,7 @@ func NewProvisionerDaemon(t *testing.T, client *codersdk.Client) io.Closer { require.NoError(t, err) }() - closer := provisionerd.New(client.ListenProvisionerDaemon, &provisionerd.Options{ + closer := provisionerd.New(coderDaemon.ListenProvisionerDaemon, &provisionerd.Options{ Logger: slogtest.Make(t, nil).Named("provisionerd").Leveled(slog.LevelDebug), PollInterval: 50 * time.Millisecond, UpdateInterval: 250 * time.Millisecond, diff --git a/coderd/coderdtest/coderdtest_test.go b/coderd/coderdtest/coderdtest_test.go index 86a358405f774..10ee90d9d3435 100644 --- a/coderd/coderdtest/coderdtest_test.go +++ b/coderd/coderdtest/coderdtest_test.go @@ -14,9 +14,9 @@ func TestMain(m *testing.M) { func TestNew(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - closer := coderdtest.NewProvisionerDaemon(t, client) + closer := coderdtest.NewProvisionerDaemon(t, coderDaemon) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) diff --git a/coderd/gitsshkey_test.go b/coderd/gitsshkey_test.go index fe0071c67c262..97a8d28672edb 100644 --- a/coderd/gitsshkey_test.go +++ b/coderd/gitsshkey_test.go @@ -79,9 +79,9 @@ func TestGitSSHKey(t *testing.T) { func TestAgentGitSSHKey(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - daemonCloser := coderdtest.NewProvisionerDaemon(t, client) + daemonCloser := coderdtest.NewProvisionerDaemon(t, coderDaemon) authToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index 5cdebc1c942f2..9c0c6592226c6 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -120,6 +120,60 @@ func (api *api) provisionerDaemonsListen(rw http.ResponseWriter, r *http.Request _ = conn.Close(websocket.StatusGoingAway, "") } +// ListenProvisionerDaemon is an in-memory connection to a provisionerd. Useful when starting coderd and provisionerd +// in the same process. +func (c *coderD) ListenProvisionerDaemon(ctx context.Context) (client proto.DRPCProvisionerDaemonClient, err error) { + clientSession, serverSession := provisionersdk.TransportPipe() + defer func() { + if err != nil { + _ = clientSession.Close() + _ = serverSession.Close() + } + }() + + daemon, err := c.api.Database.InsertProvisionerDaemon(ctx, database.InsertProvisionerDaemonParams{ + ID: uuid.New(), + CreatedAt: database.Now(), + Name: namesgenerator.GetRandomName(1), + Provisioners: []database.ProvisionerType{database.ProvisionerTypeEcho, database.ProvisionerTypeTerraform}, + }) + if err != nil { + return nil, err + } + + mux := drpcmux.New() + err = proto.DRPCRegisterProvisionerDaemon(mux, &provisionerdServer{ + AccessURL: c.options.AccessURL, + ID: daemon.ID, + Database: c.options.Database, + Pubsub: c.options.Pubsub, + Provisioners: daemon.Provisioners, + Logger: c.options.Logger.Named(fmt.Sprintf("provisionerd-%s", daemon.Name)), + }) + if err != nil { + return nil, err + } + server := drpcserver.NewWithOptions(mux, drpcserver.Options{ + Log: func(err error) { + if xerrors.Is(err, io.EOF) { + return + } + c.options.Logger.Debug(ctx, "drpc server error", slog.Error(err)) + }, + }) + go func() { + err = server.Serve(ctx, serverSession) + if err != nil && !xerrors.Is(err, io.EOF) { + c.options.Logger.Debug(ctx, "provisioner daemon disconnected", slog.Error(err)) + } + // close the sessions so we don't leak goroutines serving them. + _ = clientSession.Close() + _ = serverSession.Close() + }() + + return proto.NewDRPCProvisionerDaemonClient(provisionersdk.Conn(clientSession)), nil +} + // The input for a "workspace_provision" job. type workspaceProvisionJob struct { WorkspaceBuildID uuid.UUID `json:"workspace_build_id"` diff --git a/coderd/provisionerdaemons_test.go b/coderd/provisionerdaemons_test.go index 5e6bf0b37624c..65c7cd511d6e4 100644 --- a/coderd/provisionerdaemons_test.go +++ b/coderd/provisionerdaemons_test.go @@ -23,9 +23,8 @@ func TestProvisionerDaemons(t *testing.T) { // Takes too long to allocate memory on Windows! t.Skip() } - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) data := make([]byte, provisionersdk.MaxMessageSize) rand.Read(data) resp, err := client.Upload(context.Background(), codersdk.ContentTypeTar, data) diff --git a/coderd/provisionerjobs_test.go b/coderd/provisionerjobs_test.go index 1d04c78c54f3d..404cd53683aa3 100644 --- a/coderd/provisionerjobs_test.go +++ b/coderd/provisionerjobs_test.go @@ -17,9 +17,8 @@ func TestProvisionerJobLogs(t *testing.T) { t.Parallel() t.Run("StreamAfterComplete", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -55,9 +54,8 @@ func TestProvisionerJobLogs(t *testing.T) { t.Run("StreamWhileRunning", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -91,9 +89,8 @@ func TestProvisionerJobLogs(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ diff --git a/coderd/templates_test.go b/coderd/templates_test.go index 1b204ed738f34..24c401203958a 100644 --- a/coderd/templates_test.go +++ b/coderd/templates_test.go @@ -146,9 +146,8 @@ func TestDeleteTemplate(t *testing.T) { t.Run("Workspaces", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index de945adec2a36..92c5036090c15 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -91,9 +91,8 @@ func TestPatchCancelTemplateVersion(t *testing.T) { t.Parallel() t.Run("AlreadyCompleted", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) err := client.CancelTemplateVersion(context.Background(), version.ID) @@ -103,9 +102,8 @@ func TestPatchCancelTemplateVersion(t *testing.T) { }) t.Run("AlreadyCanceled", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -130,9 +128,8 @@ func TestPatchCancelTemplateVersion(t *testing.T) { }) t.Run("Success", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -173,9 +170,8 @@ func TestTemplateVersionSchema(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: []*proto.Parse_Response{{ Type: &proto.Parse_Response_Complete{ @@ -199,9 +195,8 @@ func TestTemplateVersionSchema(t *testing.T) { }) t.Run("ListContains", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: []*proto.Parse_Response{{ Type: &proto.Parse_Response_Complete{ @@ -243,9 +238,8 @@ func TestTemplateVersionParameters(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: []*proto.Parse_Response{{ Type: &proto.Parse_Response_Complete{ @@ -289,9 +283,8 @@ func TestTemplateVersionResources(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -325,9 +318,8 @@ func TestTemplateVersionResources(t *testing.T) { func TestTemplateVersionLogs(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) before := time.Now() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -461,10 +453,9 @@ func TestPaginatedTemplateVersions(t *testing.T) { t.Parallel() ctx := context.Background() - client := coderdtest.New(t, &coderdtest.Options{APIRateLimit: -1}) + client := coderdtest.New(t, &coderdtest.Options{APIRateLimit: -1, IncludeProvisionerD: true}) // Prepare database. user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) diff --git a/coderd/users_test.go b/coderd/users_test.go index 2ac25b47fa0d1..6d452f1b3f4c9 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -607,9 +607,8 @@ func TestWorkspacesByUser(t *testing.T) { }) t.Run("Access", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) newUser, err := client.CreateUser(context.Background(), codersdk.CreateUserRequest{ Email: "test@coder.com", Username: "someone", diff --git a/coderd/workspaceagents_test.go b/coderd/workspaceagents_test.go index 15bf01d065bad..9a8b9c4ee9b61 100644 --- a/coderd/workspaceagents_test.go +++ b/coderd/workspaceagents_test.go @@ -27,9 +27,9 @@ func TestWorkspaceAgent(t *testing.T) { t.Parallel() t.Run("Connect", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - daemonCloser := coderdtest.NewProvisionerDaemon(t, client) + daemonCloser := coderdtest.NewProvisionerDaemon(t, coderDaemon) authToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -68,9 +68,9 @@ func TestWorkspaceAgent(t *testing.T) { func TestWorkspaceAgentListen(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - daemonCloser := coderdtest.NewProvisionerDaemon(t, client) + daemonCloser := coderdtest.NewProvisionerDaemon(t, coderDaemon) authToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -118,9 +118,9 @@ func TestWorkspaceAgentListen(t *testing.T) { func TestWorkspaceAgentTURN(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - daemonCloser := coderdtest.NewProvisionerDaemon(t, client) + daemonCloser := coderdtest.NewProvisionerDaemon(t, coderDaemon) authToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -179,9 +179,9 @@ func TestWorkspaceAgentPTY(t *testing.T) { // it seems like it could be either. t.Skip("ConPTY appears to be inconsistent on Windows.") } - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - daemonCloser := coderdtest.NewProvisionerDaemon(t, client) + daemonCloser := coderdtest.NewProvisionerDaemon(t, coderDaemon) authToken := uuid.NewString() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, diff --git a/coderd/workspacebuilds_test.go b/coderd/workspacebuilds_test.go index e50c2281f7e13..8b5b9478601bf 100644 --- a/coderd/workspacebuilds_test.go +++ b/coderd/workspacebuilds_test.go @@ -17,9 +17,8 @@ import ( func TestWorkspaceBuild(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -32,9 +31,8 @@ func TestWorkspaceBuilds(t *testing.T) { t.Parallel() t.Run("Single", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -48,9 +46,8 @@ func TestWorkspaceBuilds(t *testing.T) { t.Run("PaginateLimitOffset", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -87,9 +84,8 @@ func TestWorkspaceBuilds(t *testing.T) { func TestPatchCancelWorkspaceBuild(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -123,9 +119,9 @@ func TestWorkspaceBuildResources(t *testing.T) { t.Parallel() t.Run("ListRunning", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - closeDaemon := coderdtest.NewProvisionerDaemon(t, client) + closeDaemon := coderdtest.NewProvisionerDaemon(t, coderDaemon) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) closeDaemon.Close() @@ -138,9 +134,8 @@ func TestWorkspaceBuildResources(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -177,9 +172,8 @@ func TestWorkspaceBuildResources(t *testing.T) { func TestWorkspaceBuildLogs(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) before := time.Now() version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, @@ -229,9 +223,8 @@ func TestWorkspaceBuildLogs(t *testing.T) { func TestWorkspaceBuildState(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) wantState := []byte("some kinda state") version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, diff --git a/coderd/workspaceresourceauth_test.go b/coderd/workspaceresourceauth_test.go index 496ead71fca52..04374c1821dc4 100644 --- a/coderd/workspaceresourceauth_test.go +++ b/coderd/workspaceresourceauth_test.go @@ -18,10 +18,10 @@ func TestPostWorkspaceAuthAzureInstanceIdentity(t *testing.T) { instanceID := "instanceidentifier" certificates, metadataClient := coderdtest.NewAzureInstanceIdentity(t, instanceID) client := coderdtest.New(t, &coderdtest.Options{ - AzureCertificates: certificates, + AzureCertificates: certificates, + IncludeProvisionerD: true, }) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -57,10 +57,10 @@ func TestPostWorkspaceAuthAWSInstanceIdentity(t *testing.T) { instanceID := "instanceidentifier" certificates, metadataClient := coderdtest.NewAWSInstanceIdentity(t, instanceID) client := coderdtest.New(t, &coderdtest.Options{ - AWSCertificates: certificates, + AWSCertificates: certificates, + IncludeProvisionerD: true, }) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ @@ -124,9 +124,9 @@ func TestPostWorkspaceAuthGoogleInstanceIdentity(t *testing.T) { validator, metadata := coderdtest.NewGoogleInstanceIdentity(t, instanceID, false) client := coderdtest.New(t, &coderdtest.Options{ GoogleTokenValidator: validator, + IncludeProvisionerD: true, }) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ diff --git a/coderd/workspaceresources_test.go b/coderd/workspaceresources_test.go index 8b4a846cfa258..83d10187562b5 100644 --- a/coderd/workspaceresources_test.go +++ b/coderd/workspaceresources_test.go @@ -15,9 +15,8 @@ func TestWorkspaceResource(t *testing.T) { t.Parallel() t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Parse: echo.ParseComplete, Provision: []*proto.Provision_Response{{ diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index a11e6c2fc3ff7..cd44a1895d450 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -24,9 +24,8 @@ func TestWorkspace(t *testing.T) { t.Run("OK", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -38,9 +37,8 @@ func TestWorkspace(t *testing.T) { t.Run("Deleted", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -73,9 +71,8 @@ func TestWorkspace(t *testing.T) { func TestAdminViewAllWorkspaces(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -142,8 +139,7 @@ func TestPostWorkspacesByOrganization(t *testing.T) { t.Run("AlreadyExists", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) - coderdtest.NewProvisionerDaemon(t, client) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -161,8 +157,7 @@ func TestPostWorkspacesByOrganization(t *testing.T) { t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) - coderdtest.NewProvisionerDaemon(t, client) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -182,8 +177,7 @@ func TestWorkspacesByOrganization(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) - coderdtest.NewProvisionerDaemon(t, client) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -207,8 +201,7 @@ func TestWorkspacesByOwner(t *testing.T) { t.Run("ListMine", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) - coderdtest.NewProvisionerDaemon(t, client) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) me, err := client.User(context.Background(), codersdk.Me) require.NoError(t, err) @@ -245,8 +238,7 @@ func TestWorkspaceByOwnerAndName(t *testing.T) { }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) - coderdtest.NewProvisionerDaemon(t, client) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -261,8 +253,7 @@ func TestPostWorkspaceBuild(t *testing.T) { t.Parallel() t.Run("NoTemplateVersion", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) - coderdtest.NewProvisionerDaemon(t, client) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -280,9 +271,8 @@ func TestPostWorkspaceBuild(t *testing.T) { t.Run("TemplateVersionFailedImport", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ Provision: []*proto.Provision_Response{{}}, }) @@ -299,9 +289,9 @@ func TestPostWorkspaceBuild(t *testing.T) { t.Run("AlreadyActive", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - closeDaemon := coderdtest.NewProvisionerDaemon(t, client) + closeDaemon := coderdtest.NewProvisionerDaemon(t, coderDaemon) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -320,9 +310,8 @@ func TestPostWorkspaceBuild(t *testing.T) { t.Run("IncrementBuildNumber", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -338,9 +327,9 @@ func TestPostWorkspaceBuild(t *testing.T) { t.Run("WithState", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + _, client, coderDaemon := coderdtest.NewWithServer(t, nil) user := coderdtest.CreateFirstUser(t, client) - closeDaemon := coderdtest.NewProvisionerDaemon(t, client) + closeDaemon := coderdtest.NewProvisionerDaemon(t, coderDaemon) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -361,9 +350,8 @@ func TestPostWorkspaceBuild(t *testing.T) { t.Run("Delete", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -386,9 +374,8 @@ func TestWorkspaceBuildByName(t *testing.T) { t.Parallel() t.Run("NotFound", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -401,9 +388,8 @@ func TestWorkspaceBuildByName(t *testing.T) { t.Run("Found", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -489,8 +475,7 @@ func TestWorkspaceUpdateAutostart(t *testing.T) { t.Parallel() var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -575,8 +560,7 @@ func TestWorkspaceUpdateAutostop(t *testing.T) { t.Parallel() var ( ctx = context.Background() - client = coderdtest.New(t, nil) - _ = coderdtest.NewProvisionerDaemon(t, client) + client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user = coderdtest.CreateFirstUser(t, client) version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) @@ -626,9 +610,8 @@ func TestWorkspaceUpdateAutostop(t *testing.T) { func TestWorkspaceWatcher(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) - coderdtest.NewProvisionerDaemon(t, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)