Harden image admission, resource recovery and session renewal
Add exact-image compatibility policy, experimental admission, paginated build history and shared reauthentication checks. Preserve uncertain Docker creation records, bound frontend resource waits and renew runtime sessions proactively. Lazy-load and split Monaco, add regression and opt-in live Docker fault tests, and record full race and real-browser acceptance results.
This commit is contained in:
@@ -20,13 +20,13 @@ func TestImageLegacyMigrationNeverCertifies(t *testing.T) {
|
||||
io.WriteString(w, "[]")
|
||||
return
|
||||
}
|
||||
writeImageInspect(w, "legacy-image", "1.2.3")
|
||||
writeImageInspect(w, strings.TrimSuffix(strings.TrimPrefix(r.URL.Path, "/v1.47/images/"), "/json"), "0.2.0-rc.1")
|
||||
})
|
||||
_, err := a.s.DB.Exec(`CREATE TABLE image_builds(id TEXT PRIMARY KEY,version TEXT NOT NULL,status TEXT NOT NULL,logs TEXT NOT NULL DEFAULT '',error TEXT NOT NULL DEFAULT '',image_id TEXT NOT NULL DEFAULT '',created_at TEXT NOT NULL);
|
||||
CREATE UNIQUE INDEX image_builds_version ON image_builds(version) WHERE status IN ('queued','running','validating','success');
|
||||
INSERT INTO image_builds(id,version,status,image_id,created_at) VALUES('legacy','1.2.3','success','legacy-image','now'),('queued','1.2.4','queued','','now');
|
||||
INSERT INTO image_builds(id,version,status,image_id,created_at) VALUES('legacy','0.2.0-rc.1','success','legacy-image','now'),('queued','0.2.0-rc.2','queued','','now');
|
||||
CREATE TABLE images(image_id TEXT PRIMARY KEY,version TEXT NOT NULL,tag TEXT NOT NULL DEFAULT '',status TEXT NOT NULL,built_at TEXT NOT NULL);
|
||||
INSERT INTO images VALUES('legacy-image','1.2.3','','available','now');`)
|
||||
INSERT INTO images VALUES('legacy-image','0.2.0-rc.1','','available','now');`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -50,9 +50,9 @@ func TestImageLegacyMigrationNeverCertifies(t *testing.T) {
|
||||
if err = a.s.DB.QueryRow("SELECT status FROM image_builds WHERE id='queued'").Scan(&status); err != nil || status != "failed" {
|
||||
t.Fatal(status, err)
|
||||
}
|
||||
seedVerifiedImage(t, a, "new-image", "1.2.3")
|
||||
seedVerifiedImage(t, a, "new-image", "0.2.0-rc.1")
|
||||
verified, err = a.verifiedImages(context.Background())
|
||||
if err != nil || len(verified) != 1 || verified["new-image"] != "1.2.3" {
|
||||
if err != nil || len(verified) != 1 || verified["new-image"] != "0.2.0-rc.1" {
|
||||
t.Fatal(verified, err)
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ func TestImageInspectIdentity(t *testing.T) {
|
||||
return
|
||||
}
|
||||
parts := strings.Split(imagePlatform, "/")
|
||||
labels := map[string]string{"dsh-mgr.role": "runtime", "dsh-mgr.version": "1.2.3", "dsh-mgr.recipe": imageRecipeRev}
|
||||
labels := map[string]string{"dsh-mgr.role": "runtime", "dsh-mgr.version": "0.2.0-rc.1", "dsh-mgr.recipe": imageRecipeRev}
|
||||
im := map[string]any{"Id": "image", "Os": parts[0], "Architecture": parts[1], "Config": map[string]any{"Labels": labels}}
|
||||
switch mode {
|
||||
case "recipe":
|
||||
@@ -96,7 +96,7 @@ func TestImageInspectIdentity(t *testing.T) {
|
||||
}
|
||||
writeJSON(w, im)
|
||||
})
|
||||
ok, err := a.imageMatches(context.Background(), "image", "1.2.3")
|
||||
ok, err := a.imageMatches(context.Background(), "image", "0.2.0-rc.1")
|
||||
if ok != (mode == "valid") || (err != nil) != (mode == "unavailable") {
|
||||
t.Fatal(ok, err)
|
||||
}
|
||||
@@ -129,8 +129,8 @@ func TestImageIndexLocalInventory(t *testing.T) {
|
||||
return
|
||||
}
|
||||
parts := strings.Split(imagePlatform, "/")
|
||||
im := inspectedImage{ID: "image", Os: parts[0], Architecture: parts[1], Created: "2026-01-01T00:00:00Z", RepoTags: []string{"dsh-web:1.2.3"}}
|
||||
im.Config.Labels = map[string]string{"dsh-mgr.role": "runtime", "dsh-mgr.version": "1.2.3", "dsh-mgr.recipe": imageRecipeRev}
|
||||
im := inspectedImage{ID: "image", Os: parts[0], Architecture: parts[1], Created: "2026-01-01T00:00:00Z", RepoTags: []string{"dsh-web:0.2.0-rc.1"}}
|
||||
im.Config.Labels = map[string]string{"dsh-mgr.role": "runtime", "dsh-mgr.version": "0.2.0-rc.1", "dsh-mgr.recipe": imageRecipeRev}
|
||||
if mode == "old-recipe" {
|
||||
im.Config.Labels["dsh-mgr.recipe"] = "1"
|
||||
}
|
||||
@@ -140,7 +140,7 @@ func TestImageIndexLocalInventory(t *testing.T) {
|
||||
writeJSON(w, im)
|
||||
})
|
||||
if mode != "external" {
|
||||
seedVerifiedImage(t, a, "image", "1.2.3")
|
||||
seedVerifiedImage(t, a, "image", "0.2.0-rc.1")
|
||||
}
|
||||
if mode == "old-recipe" {
|
||||
if _, err := a.s.DB.Exec("UPDATE image_builds SET recipe_rev='1'"); err != nil {
|
||||
@@ -155,8 +155,12 @@ func TestImageIndexLocalInventory(t *testing.T) {
|
||||
}
|
||||
return
|
||||
}
|
||||
wantStatus := "unverified"
|
||||
if mode == "old-recipe" {
|
||||
wantStatus = "existing_only"
|
||||
}
|
||||
var images []imageRecord
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &images); err != nil || w.Code != 200 || len(images) != 1 || images[0].Status != "unverified" || images[0].Version != "1.2.3" || images[0].Created != "2026-01-01T00:00:00Z" || images[0].Tag != "dsh-web:1.2.3" {
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &images); err != nil || w.Code != 200 || len(images) != 1 || images[0].Status != wantStatus || images[0].Version != "0.2.0-rc.1" || images[0].Created != "2026-01-01T00:00:00Z" || images[0].Tag != "dsh-web:0.2.0-rc.1" {
|
||||
t.Fatal(w.Body.String(), err)
|
||||
}
|
||||
if mode == "other-platform" && images[0].Platform != strings.Split(imagePlatform, "/")[0]+"/arm/v7" {
|
||||
@@ -193,10 +197,10 @@ func TestImageIndexUsageMissingAndDockerFailure(t *testing.T) {
|
||||
case 2:
|
||||
w.WriteHeader(404)
|
||||
default:
|
||||
writeImageInspect(w, "image", "1.2.3")
|
||||
writeImageInspect(w, "image", "0.2.0-rc.1")
|
||||
}
|
||||
})
|
||||
seedVerifiedImage(t, a, "image", "1.2.3")
|
||||
seedVerifiedImage(t, a, "image", "0.2.0-rc.1")
|
||||
if _, err := a.s.DB.Exec(`INSERT INTO instances(id,uid,name,image_id,status,created) VALUES('one','u','one','image','running',0),('two','other-user','two','image','stopped',0),('three','u','three','other','running',0)`); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -237,21 +241,21 @@ func TestImageIndexUsageMissingAndDockerFailure(t *testing.T) {
|
||||
func TestBuildRateLimitDoesNotPenalizeSharedTask(t *testing.T) {
|
||||
a, sid := imageTestAPI(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/v1.47/images/verified/json" {
|
||||
writeImageInspect(w, "verified", "1.2.3")
|
||||
writeImageInspect(w, "verified", "0.2.0-rc.1")
|
||||
return
|
||||
}
|
||||
io.WriteString(w, `[{"Id":"verified","Labels":{"dsh-mgr.role":"runtime","dsh-mgr.version":"1.2.3","dsh-mgr.recipe":"`+imageRecipeRev+`"}}]`)
|
||||
io.WriteString(w, `[{"Id":"verified","Labels":{"dsh-mgr.role":"runtime","dsh-mgr.version":"0.2.0-rc.1","dsh-mgr.recipe":"`+imageRecipeRev+`"}}]`)
|
||||
})
|
||||
seedVerifiedImage(t, a, "verified", "1.2.3")
|
||||
seedVerifiedImage(t, a, "verified", "0.2.0-rc.1")
|
||||
for _, id := range []string{"a", "b", "c"} {
|
||||
if _, err := a.s.DB.Exec("INSERT INTO image_build_requests VALUES('u',?,?)", id, time.Now().UTC().Format(time.RFC3339Nano)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if w := imageRequest(a.builds, sid, "POST", `{"version":"1.2.3"}`); w.Code != 202 {
|
||||
if w := imageRequest(a.builds, sid, "POST", `{"version":"0.2.0-rc.1"}`); w.Code != 202 {
|
||||
t.Fatal(w.Code, w.Body.String())
|
||||
}
|
||||
if w := imageRequest(a.builds, sid, "POST", `{"version":"1.2.4"}`); w.Code != 429 || w.Header().Get("Retry-After") == "" {
|
||||
if w := imageRequest(a.builds, sid, "POST", `{"version":"0.2.0-rc.2"}`); w.Code != 429 || w.Header().Get("Retry-After") == "" {
|
||||
t.Fatal(w.Code, w.Body.String())
|
||||
}
|
||||
var n int
|
||||
@@ -314,7 +318,7 @@ func TestUnknownDockerDiskBlocksBuild(t *testing.T) {
|
||||
io.WriteString(w, "[]")
|
||||
})
|
||||
t.Setenv("DSH_DOCKER_ROOT_VISIBLE", "")
|
||||
w := imageRequest(a.builds, sid, "POST", `{"version":"1.2.3"}`)
|
||||
w := imageRequest(a.builds, sid, "POST", `{"version":"0.2.0-rc.1"}`)
|
||||
if w.Code != 202 {
|
||||
t.Fatal(w.Body.String())
|
||||
}
|
||||
@@ -343,19 +347,19 @@ func TestExactNPMMetadata(t *testing.T) {
|
||||
status int
|
||||
ok bool
|
||||
}{
|
||||
{`{"version":"1.2.3"}`, 200, true},
|
||||
{`{"version":"1.2.4"}`, 200, false},
|
||||
{`{"version":"0.2.0-rc.1"}`, 200, true},
|
||||
{`{"version":"0.2.0-rc.2"}`, 200, false},
|
||||
{`{"version":"latest"}`, 200, false},
|
||||
{`{}`, 404, false},
|
||||
{`invalid`, 200, false},
|
||||
} {
|
||||
client := &http.Client{Transport: imageRoundTrip(func(r *http.Request) (*http.Response, error) {
|
||||
if r.URL.Host != "registry.npmjs.org" || !strings.HasSuffix(r.URL.Path, "/1.2.3") {
|
||||
if r.URL.Host != "registry.npmjs.org" || !strings.HasSuffix(r.URL.Path, "/0.2.0-rc.1") {
|
||||
t.Error(r.URL)
|
||||
}
|
||||
return &http.Response{StatusCode: test.status, Body: io.NopCloser(strings.NewReader(test.body)), Header: make(http.Header)}, nil
|
||||
})}
|
||||
_, err := fetchNPMVersion(context.Background(), client, "1.2.3")
|
||||
_, err := fetchNPMVersion(context.Background(), client, "0.2.0-rc.1")
|
||||
if (err == nil) != test.ok {
|
||||
t.Fatalf("%s: %v", test.body, err)
|
||||
}
|
||||
@@ -363,19 +367,56 @@ func TestExactNPMMetadata(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBuildListReconcilesMissingAndLatestTimestamp(t *testing.T) {
|
||||
a, sid := imageTestAPI(t, func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "[]") })
|
||||
seedVerifiedImage(t, a, "deleted", "1.2.3")
|
||||
a, sid := imageTestAPI(t, func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })
|
||||
seedVerifiedImage(t, a, "deleted", "0.2.0-rc.1")
|
||||
w := imageRequest(a.builds, sid, "GET", "")
|
||||
var records []buildRecord
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &records); err != nil || len(records) != 1 || records[0].Status != "missing" {
|
||||
t.Fatal(w.Body.String())
|
||||
}
|
||||
w = imageRequest(a.latest, sid, "GET", "")
|
||||
var latest map[string]string
|
||||
var latest struct {
|
||||
Version string `json:"version"`
|
||||
CheckedAt string `json:"checked_at"`
|
||||
}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &latest); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := time.Parse(time.RFC3339, latest["checked_at"]); err != nil || latest["version"] != "1.2.3" {
|
||||
if _, err := time.Parse(time.RFC3339, latest.CheckedAt); err != nil || latest.Version != "0.2.0-rc.1" {
|
||||
t.Fatal(latest, err)
|
||||
}
|
||||
}
|
||||
|
||||
// The one-second intent poller must reuse per-image evaluations instead of
|
||||
// re-inspecting Docker every tick, and a generation bump (deletion or
|
||||
// admission change) must invalidate the cache.
|
||||
func TestIntentPollerCachesImageEvaluations(t *testing.T) {
|
||||
inspects := 0
|
||||
a, _ := imageTestAPI(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path == "/v1.47/images/image/json" {
|
||||
inspects++
|
||||
writeImageInspect(w, "image", "0.2.0-rc.1")
|
||||
return
|
||||
}
|
||||
w.WriteHeader(404)
|
||||
})
|
||||
seedVerifiedImage(t, a, "image", "0.2.0-rc.1")
|
||||
for n := 0; n < 3; n++ {
|
||||
verified, err := a.verifiedImagesPoll(context.Background())
|
||||
if err != nil || len(verified) != 1 || verified["image"] != "0.2.0-rc.1" {
|
||||
t.Fatal(verified, err)
|
||||
}
|
||||
}
|
||||
if inspects != 1 {
|
||||
t.Fatalf("poller re-inspected Docker %d times for the same image", inspects)
|
||||
}
|
||||
buildQueue.Lock()
|
||||
a.imageDeleteGeneration++
|
||||
buildQueue.Unlock()
|
||||
if _, err := a.verifiedImagesPoll(context.Background()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if inspects != 2 {
|
||||
t.Fatalf("generation bump did not invalidate the cache: %d inspects", inspects)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user