From 20bc9fe17aa2a9263fb605da0fd0e99dcdd24b01 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Fri, 2 May 2025 00:42:50 +0200 Subject: [PATCH] feat(webui): add state force unlock Closes #13 --- pkg/database/locks.go | 12 ++++++++++++ pkg/webui/html/statesId.html | 3 ++- pkg/webui/statesId.go | 27 +++++++++++++++++---------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/pkg/database/locks.go b/pkg/database/locks.go index 1d7496c..059c022 100644 --- a/pkg/database/locks.go +++ b/pkg/database/locks.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" + "git.adyxax.org/adyxax/tfstated/pkg/model" "go.n16f.net/uuid" ) @@ -83,4 +84,15 @@ func (db *DB) Unlock(path string, lock any) (bool, error) { } return n == 1, nil } + +func (db *DB) ForceUnlock(state *model.State) error { + _, err := db.Exec( + `UPDATE states + SET lock = NULL + WHERE id = ?;`, + state.Id) + if err != nil { + return fmt.Errorf("failed to update state: %w", err) + } + return nil } diff --git a/pkg/webui/html/statesId.html b/pkg/webui/html/statesId.html index 412ec5f..96e6b3d 100644 --- a/pkg/webui/html/statesId.html +++ b/pkg/webui/html/statesId.html @@ -70,7 +70,8 @@
Danger Zone - + +
diff --git a/pkg/webui/statesId.go b/pkg/webui/statesId.go index 38a5cee..f37162f 100644 --- a/pkg/webui/statesId.go +++ b/pkg/webui/statesId.go @@ -66,7 +66,6 @@ func handleStatesIdPOST(db *database.DB) http.Handler { if !verifyCSRFToken(w, r) { return } - action := r.FormValue("action") var stateId uuid.UUID if err := stateId.Parse(r.PathValue("id")); err != nil { errorResponse(w, r, http.StatusBadRequest, err) @@ -87,6 +86,7 @@ func handleStatesIdPOST(db *database.DB) http.Handler { errorResponse(w, r, http.StatusInternalServerError, err) return } + action := r.FormValue("action") switch action { case "delete": errorResponse(w, r, http.StatusNotImplemented, err) @@ -121,17 +121,24 @@ func handleStatesIdPOST(db *database.DB) http.Handler { }) return } - render(w, statesIdTemplate, http.StatusOK, StatesIdPage{ - Page: makePage(r, &Page{ - Section: "states", - Title: state.Path, - }), - State: state, - Usernames: usernames, - Versions: versions, - }) + case "unlock": + if err := db.ForceUnlock(state); err != nil { + errorResponse(w, r, http.StatusInternalServerError, err) + return + } + state.Lock = nil default: errorResponse(w, r, http.StatusBadRequest, err) + return } + render(w, statesIdTemplate, http.StatusOK, StatesIdPage{ + Page: makePage(r, &Page{ + Section: "states", + Title: state.Path, + }), + State: state, + Usernames: usernames, + Versions: versions, + }) }) }