fix(master): review fixes for drift restore and accept (#10)
This commit is contained in:
@@ -118,7 +118,7 @@ func TestAcceptRunning_WritesRunningRefAndPublishes(t *testing.T) {
|
||||
ch, cancel := broker.Subscribe()
|
||||
defer cancel()
|
||||
|
||||
resp, _ := postTo(t, srv, "/services/1/accept", url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2"}})
|
||||
resp, _ := postTo(t, srv, "/services/1/accept", url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftActual}})
|
||||
|
||||
assert.Equal(t, http.StatusSeeOther, resp.StatusCode)
|
||||
assert.Equal(t, "/services/1", resp.Header.Get("Location"))
|
||||
@@ -139,7 +139,7 @@ func TestAcceptRunning_ReturnToOverview(t *testing.T) {
|
||||
driftService(store)
|
||||
|
||||
resp, _ := postTo(t, srv, "/services/1/accept",
|
||||
url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2"}, "return": {"overview"}})
|
||||
url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftActual}, "return": {"overview"}})
|
||||
|
||||
assert.Equal(t, http.StatusSeeOther, resp.StatusCode)
|
||||
assert.Equal(t, "/", resp.Header.Get("Location"))
|
||||
@@ -151,6 +151,7 @@ func TestAcceptRunning_Refusals(t *testing.T) {
|
||||
path string
|
||||
form url.Values
|
||||
notDrifted bool
|
||||
removed bool
|
||||
acceptErr error
|
||||
wantCode int
|
||||
wantBody string
|
||||
@@ -158,12 +159,17 @@ func TestAcceptRunning_Refusals(t *testing.T) {
|
||||
{name: "missing actual", path: "/services/1/accept", form: url.Values{}, wantCode: http.StatusBadRequest},
|
||||
{name: "stale actual", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.3.0"}},
|
||||
wantCode: http.StatusConflict, wantBody: "The running version changed; check it again."},
|
||||
{name: "not drifted", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2"}},
|
||||
{name: "same ref, other digest", path: "/services/1/accept",
|
||||
form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftDesired}},
|
||||
wantCode: http.StatusConflict, wantBody: "The running version changed; check it again."},
|
||||
{name: "not drifted", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftActual}},
|
||||
notDrifted: true, wantCode: http.StatusConflict, wantBody: "Cannot accept: the service runs its desired version."},
|
||||
{name: "changed under our feet", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2"}},
|
||||
{name: "changed under our feet", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftActual}},
|
||||
acceptErr: model.ErrConflict, wantCode: http.StatusConflict, wantBody: "The running version changed; check it again."},
|
||||
{name: "unknown service", path: "/services/9/accept", form: url.Values{"actual": {"x"}}, wantCode: http.StatusNotFound},
|
||||
{name: "removed meanwhile", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2"}},
|
||||
{name: "removed", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftActual}},
|
||||
removed: true, wantCode: http.StatusNotFound},
|
||||
{name: "removed meanwhile", path: "/services/1/accept", form: url.Values{"actual": {"gitea.shcizo.se/shcizo/slusk:1.4.2@" + driftActual}},
|
||||
acceptErr: model.ErrNotFound, wantCode: http.StatusNotFound},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -172,6 +178,10 @@ func TestAcceptRunning_Refusals(t *testing.T) {
|
||||
if !tt.notDrifted {
|
||||
driftService(store)
|
||||
}
|
||||
if tt.removed {
|
||||
removedAt := time.Now()
|
||||
store.services[0].RemovedAt = &removedAt
|
||||
}
|
||||
store.acceptErr = tt.acceptErr
|
||||
|
||||
resp, body := postTo(t, srv, tt.path, tt.form)
|
||||
|
||||
@@ -349,13 +349,7 @@ func (s *Server) updateService(w http.ResponseWriter, r *http.Request) {
|
||||
case err == nil || errors.Is(err, model.ErrJobActive):
|
||||
http.Redirect(w, r, "/jobs/"+strconv.FormatInt(job.ID, 10), http.StatusSeeOther)
|
||||
case errors.As(err, &nu):
|
||||
data, derr := s.serviceDetail(r, id)
|
||||
if derr != nil {
|
||||
s.failLookup(w, derr)
|
||||
return
|
||||
}
|
||||
data.Error = "Cannot update: " + nu.Reason + "."
|
||||
s.render(w, http.StatusConflict, "service.html", "layout", data)
|
||||
s.renderServiceError(w, r, id, http.StatusConflict, "Cannot update: "+nu.Reason+".")
|
||||
default:
|
||||
s.failLookup(w, err)
|
||||
}
|
||||
@@ -381,8 +375,9 @@ func (s *Server) restoreDesired(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// acceptRunning makes the running version of a drifted service the desired
|
||||
// one. The form's actual field is the ref the user saw; it only guards against
|
||||
// the service having changed since, the value written comes from the row.
|
||||
// one. The form's actual field is the running ref the user saw (Service.RunningRef);
|
||||
// it only guards against the service having changed since, the value written
|
||||
// comes from the row.
|
||||
func (s *Server) acceptRunning(w http.ResponseWriter, r *http.Request) {
|
||||
id, ok := pathID(w, r)
|
||||
if !ok {
|
||||
@@ -394,6 +389,9 @@ func (s *Server) acceptRunning(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
svc, err := s.store.GetService(r.Context(), id)
|
||||
if err == nil && svc.RemovedAt != nil {
|
||||
err = model.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
s.failLookup(w, err)
|
||||
return
|
||||
@@ -402,11 +400,11 @@ func (s *Server) acceptRunning(w http.ResponseWriter, r *http.Request) {
|
||||
s.renderServiceError(w, r, id, http.StatusConflict, "Cannot accept: the service runs its desired version.")
|
||||
return
|
||||
}
|
||||
if actual != svc.ActualRef {
|
||||
if actual != svc.RunningRef() {
|
||||
s.renderServiceError(w, r, id, http.StatusConflict, "The running version changed; check it again.")
|
||||
return
|
||||
}
|
||||
desired := model.RunningRef(svc.ActualRef, svc.ActualDigest)
|
||||
desired := svc.RunningRef()
|
||||
err = s.store.AcceptRunning(r.Context(), id, svc.ActualRef, svc.ActualDigest, desired)
|
||||
switch {
|
||||
case errors.Is(err, model.ErrConflict):
|
||||
@@ -458,7 +456,7 @@ func (s *Server) mergeService(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
sess, _ := webauth.SessionFrom(r.Context())
|
||||
s.log.Info("service_merged", "from", from, "to", id, "subject", sess.Subject)
|
||||
s.log.Info("service_merged", "from_id", from, "to_id", id, "subject", sess.Subject)
|
||||
s.broker.Publish(events.Services)
|
||||
s.broker.Publish(events.Jobs)
|
||||
http.Redirect(w, r, "/services/"+strconv.FormatInt(from, 10), http.StatusSeeOther)
|
||||
@@ -498,13 +496,7 @@ func (s *Server) setMode(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
var nu *model.NotUpdatableError
|
||||
if err := s.jobs.AutoAllowed(svc); errors.As(err, &nu) {
|
||||
data, derr := s.serviceDetail(r, id)
|
||||
if derr != nil {
|
||||
s.failLookup(w, derr)
|
||||
return
|
||||
}
|
||||
data.Error = "Cannot enable auto: " + nu.Reason + "."
|
||||
s.render(w, http.StatusConflict, "service.html", "layout", data)
|
||||
s.renderServiceError(w, r, id, http.StatusConflict, "Cannot enable auto: "+nu.Reason+".")
|
||||
return
|
||||
} else if err != nil {
|
||||
s.fail(w, err)
|
||||
|
||||
Reference in New Issue
Block a user