mirror of
https://github.com/coder/coder.git
synced 2025-07-12 00:14:10 +00:00
feat: update workspace deadline when workspace ttl updated (#2165)
This commit adds the following changes to workspace scheduling behaviour: * CLI: updating a workspace TTL updates the deadline of the workspace. * If the TTL is being un-set, the workspace deadline is set to zero. * If the TTL is being set, the workspace deadline is updated to be the last updated time of the workspace build plus the requested TTL. Additionally, the user is prompted to confirm interactively (can be bypassed with -y). * UI: updating the workspace schedule behaves similarly to the CLI, showing a message to the user if the updated TTL/time to shutdown would effect changes to the lifetime of the running workspace.
This commit is contained in:
@ -3,16 +3,19 @@ package cli_test
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/cli/clitest"
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/coderd/util/ptr"
|
||||
"github.com/coder/coder/codersdk"
|
||||
"github.com/coder/coder/pty/ptytest"
|
||||
)
|
||||
|
||||
func TestTTL(t *testing.T) {
|
||||
@ -22,33 +25,29 @@ func TestTTL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
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)
|
||||
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
|
||||
template = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
ttl = 7*time.Hour + 30*time.Minute + 30*time.Second
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
|
||||
cwr.TTLMillis = ptr.Ref(ttl.Milliseconds())
|
||||
})
|
||||
cmdArgs = []string{"ttl", "show", workspace.Name}
|
||||
ttl = 8*time.Hour + 30*time.Minute + 30*time.Second
|
||||
stdoutBuf = &bytes.Buffer{}
|
||||
)
|
||||
|
||||
err := client.UpdateWorkspaceTTL(ctx, workspace.ID, codersdk.UpdateWorkspaceTTLRequest{
|
||||
TTLMillis: ptr.Ref(ttl.Milliseconds()),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
cmd, root := clitest.New(t, cmdArgs...)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
cmd.SetOut(stdoutBuf)
|
||||
|
||||
err = cmd.Execute()
|
||||
err := cmd.Execute()
|
||||
require.NoError(t, err, "unexpected error")
|
||||
require.Equal(t, ttl.Truncate(time.Minute).String(), strings.TrimSpace(stdoutBuf.String()))
|
||||
})
|
||||
|
||||
t.Run("SetUnsetOK", func(t *testing.T) {
|
||||
t.Run("UnsetOK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
@ -58,9 +57,11 @@ func TestTTL(t *testing.T) {
|
||||
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
|
||||
ttl = 8*time.Hour + 30*time.Minute + 30*time.Second
|
||||
cmdArgs = []string{"ttl", "set", workspace.Name, ttl.String()}
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
|
||||
cwr.TTLMillis = ptr.Ref(ttl.Milliseconds())
|
||||
})
|
||||
cmdArgs = []string{"ttl", "unset", workspace.Name}
|
||||
stdoutBuf = &bytes.Buffer{}
|
||||
)
|
||||
|
||||
@ -71,24 +72,52 @@ func TestTTL(t *testing.T) {
|
||||
err := cmd.Execute()
|
||||
require.NoError(t, err, "unexpected error")
|
||||
|
||||
// Ensure ttl unset
|
||||
updated, err := client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err, "fetch updated workspace")
|
||||
require.Nil(t, updated.TTLMillis, "expected ttl to not be set")
|
||||
})
|
||||
|
||||
t.Run("SetOK", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
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)
|
||||
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
ttl = 8*time.Hour + 30*time.Minute + 30*time.Second
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
|
||||
cwr.TTLMillis = ptr.Ref(ttl.Milliseconds())
|
||||
})
|
||||
_ = coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
cmdArgs = []string{"ttl", "set", workspace.Name, ttl.String()}
|
||||
done = make(chan struct{})
|
||||
)
|
||||
|
||||
cmd, root := clitest.New(t, cmdArgs...)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
go func() {
|
||||
defer close(done)
|
||||
err := cmd.Execute()
|
||||
assert.NoError(t, err, "unexpected error")
|
||||
}()
|
||||
|
||||
pty.ExpectMatch(fmt.Sprintf("warning: ttl rounded down to %s", ttl.Truncate(time.Minute)))
|
||||
pty.ExpectMatch(fmt.Sprintf("Workspace %q will be stopped in 8h29m0s. Are you sure?", workspace.Name))
|
||||
pty.WriteLine("yes")
|
||||
// Ensure ttl updated
|
||||
updated, err := client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err, "fetch updated workspace")
|
||||
require.Equal(t, ttl.Truncate(time.Minute), time.Duration(*updated.TTLMillis)*time.Millisecond)
|
||||
require.Contains(t, stdoutBuf.String(), "warning: ttl rounded down")
|
||||
|
||||
// unset schedule
|
||||
cmd, root = clitest.New(t, "ttl", "unset", workspace.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
cmd.SetOut(stdoutBuf)
|
||||
|
||||
err = cmd.Execute()
|
||||
require.NoError(t, err, "unexpected error")
|
||||
|
||||
// Ensure ttl updated
|
||||
updated, err = client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err, "fetch updated workspace")
|
||||
require.Nil(t, updated.TTLMillis, "expected ttl to not be set")
|
||||
<-done
|
||||
})
|
||||
|
||||
t.Run("ZeroInvalid", func(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user