capsite/toybox: mount lookups in SQL, not a scan in JS

Each request parsed every mount's labels and searched them in JS. Labels
now sit one per row in mount_label, indexed on (key, value): a lookup
joins the request's labels (json_each) on the index and keeps the vat
whose every label matched. The overlap check at registration is SQL too.

mount.labels keeps the whole set as JSON; mounts stored before
mount_label get their rows filled in when the schema runs. The SQL lives
in mounts-sql.js, tested on node:sqlite, old-shape state included.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
dckcandClaude Opus 5.5 committed 2026-10-13 21:44:29 -05:00
1 parent 9356f63c64
commit 7fcd251261
4 files changed
+124 -38

No files matched your search

-20
View File
@@ -51,23 +51,3 @@ export const checkUrl = (labels, url) => {
}
};
/**
* Do `a` and `b` give some key different values? Flower refuses to register
* a target that doesn't conflict with every other: lookups stay unambiguous.
*
* @param {Record<string, string>} a
* @param {Record<string, string>} b
*/
export const conflict = (a, b) => Object.entries(a).some(([k, v]) => k in b && b[k] !== v);
/**
* Does `request` carry every label of `mount`, with the same values?
*
* Stricter than Flower's match (no conflict): an ingress client holds no
* constrained handle, so a label it omits must not match, or a secret
* label would protect nothing.
*
* @param {Record<string, string>} mount
* @param {Record<string, string>} request
*/
export const carries = (mount, request) => Object.entries(mount).every(([k, v]) => request[k] === v);