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:
Cian Johnston
2022-06-09 22:10:24 +01:00
committed by GitHub
parent 411d7da661
commit 119db78bff
9 changed files with 360 additions and 56 deletions

View File

@ -1,12 +1,14 @@
package cli
import (
"errors"
"fmt"
"time"
"github.com/spf13/cobra"
"golang.org/x/xerrors"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk"
)
@ -89,6 +91,30 @@ func ttlset() *cobra.Command {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "warning: ttl rounded down to %s\n", truncated)
}
if changed, newDeadline := changedNewDeadline(workspace, truncated); changed {
// For the purposes of the user, "less than a minute" is essentially the same as "immediately".
timeRemaining := time.Until(newDeadline).Truncate(time.Minute)
humanRemaining := "in " + timeRemaining.String()
if timeRemaining <= 0 {
humanRemaining = "immediately"
}
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
Text: fmt.Sprintf(
"Workspace %q will be stopped %s. Are you sure?",
workspace.Name,
humanRemaining,
),
Default: "yes",
IsConfirm: true,
})
if err != nil {
if errors.Is(err, cliui.Canceled) {
return nil
}
return err
}
}
millis := truncated.Milliseconds()
if err = client.UpdateWorkspaceTTL(cmd.Context(), workspace.ID, codersdk.UpdateWorkspaceTTLRequest{
TTLMillis: &millis,
@ -131,3 +157,18 @@ func ttlunset() *cobra.Command {
},
}
}
func changedNewDeadline(ws codersdk.Workspace, newTTL time.Duration) (changed bool, newDeadline time.Time) {
if ws.LatestBuild.Transition != codersdk.WorkspaceTransitionStart {
// not running
return false, newDeadline
}
if ws.LatestBuild.Job.CompletedAt == nil {
// still building
return false, newDeadline
}
newDeadline = ws.LatestBuild.Job.CompletedAt.Add(newTTL)
return true, newDeadline
}