feat: add 'impending deletion' badges to workspaces page (#7530)

* update deleting logic

* added status badge on workspaces page

* licensing and feature flagging

* preset filter for failed workspaces

* remove comment

* PR feedback

* Revert "PR feedback"

This reverts commit 2dfbb50acd.

* PR feedback 2
This commit is contained in:
Kira Pilot
2023-05-15 07:59:17 -07:00
committed by GitHub
parent 854e974bb4
commit 224d25d4e1
12 changed files with 120 additions and 43 deletions
+7 -9
View File
@@ -14,6 +14,7 @@ import (
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/tabbed/pqtype"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"cdr.dev/slog"
@@ -1171,7 +1172,7 @@ func convertWorkspace(
var (
ttlMillis = convertWorkspaceTTLMillis(workspace.Ttl)
deletingAt = calculateDeletingAt(workspace, template)
deletingAt = calculateDeletingAt(workspace, template, workspaceBuild)
)
return codersdk.Workspace{
ID: workspace.ID,
@@ -1206,14 +1207,11 @@ func convertWorkspaceTTLMillis(i sql.NullInt64) *int64 {
// Calculate the time of the upcoming workspace deletion, if applicable; otherwise, return nil.
// Workspaces may have impending deletions if InactivityTTL feature is turned on and the workspace is inactive.
func calculateDeletingAt(workspace database.Workspace, template database.Template) *time.Time {
var (
year, month, day = time.Now().Date()
beginningOfToday = time.Date(year, month, day, 0, 0, 0, 0, time.Now().Location())
)
// If InactivityTTL is turned off (set to 0), if the workspace has already been deleted,
// or if the workspace was used sometime within the last day, there is no impending deletion
if template.InactivityTTL == 0 || workspace.Deleted || workspace.LastUsedAt.After(beginningOfToday) {
func calculateDeletingAt(workspace database.Workspace, template database.Template, build codersdk.WorkspaceBuild) *time.Time {
inactiveStatuses := []codersdk.WorkspaceStatus{codersdk.WorkspaceStatusStopped, codersdk.WorkspaceStatusCanceled, codersdk.WorkspaceStatusFailed, codersdk.WorkspaceStatusDeleted}
isInactive := slices.Contains(inactiveStatuses, build.Status)
// If InactivityTTL is turned off (set to 0) or if the workspace is active, there is no impending deletion
if template.InactivityTTL == 0 || !isInactive {
return nil
}
+15 -15
View File
@@ -8,6 +8,7 @@ import (
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/util/ptr"
"github.com/coder/coder/codersdk"
)
func Test_calculateDeletingAt(t *testing.T) {
@@ -17,10 +18,11 @@ func Test_calculateDeletingAt(t *testing.T) {
name string
workspace database.Workspace
template database.Template
build codersdk.WorkspaceBuild
expected *time.Time
}{
{
name: "DeletingAt",
name: "InactiveWorkspace",
workspace: database.Workspace{
Deleted: false,
LastUsedAt: time.Now().Add(time.Duration(-10) * time.Hour * 24), // 10 days ago
@@ -28,6 +30,9 @@ func Test_calculateDeletingAt(t *testing.T) {
template: database.Template{
InactivityTTL: int64(9 * 24 * time.Hour), // 9 days
},
build: codersdk.WorkspaceBuild{
Status: codersdk.WorkspaceStatusStopped,
},
expected: ptr.Ref(time.Now().Add(time.Duration(-1) * time.Hour * 24)), // yesterday
},
{
@@ -39,27 +44,22 @@ func Test_calculateDeletingAt(t *testing.T) {
template: database.Template{
InactivityTTL: 0,
},
expected: nil,
},
{
name: "DeletedWorkspace",
workspace: database.Workspace{
Deleted: true,
LastUsedAt: time.Now().Add(time.Duration(-10) * time.Hour * 24),
},
template: database.Template{
InactivityTTL: int64(9 * 24 * time.Hour),
build: codersdk.WorkspaceBuild{
Status: codersdk.WorkspaceStatusStopped,
},
expected: nil,
},
{
name: "ActiveWorkspace",
workspace: database.Workspace{
Deleted: true,
LastUsedAt: time.Now().Add(time.Duration(-5) * time.Hour), // 5 hours ago
Deleted: false,
LastUsedAt: time.Now(),
},
template: database.Template{
InactivityTTL: int64(1 * 24 * time.Hour), // 1 day
InactivityTTL: int64(1 * 24 * time.Hour),
},
build: codersdk.WorkspaceBuild{
Status: codersdk.WorkspaceStatusRunning,
},
expected: nil,
},
@@ -70,7 +70,7 @@ func Test_calculateDeletingAt(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
found := calculateDeletingAt(tc.workspace, tc.template)
found := calculateDeletingAt(tc.workspace, tc.template, tc.build)
if tc.expected == nil {
require.Nil(t, found, "impending deletion should be nil")
} else {