Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a28533f
fix: auto-save uncommitted implementation work (kad-qun.2, gt-pvx saf…
brandonpayton Jun 12, 2026
953828e
WIP: checkpoint (auto)
brandonpayton Jun 12, 2026
df9f45b
Revert "WIP: checkpoint (auto)"
brandonpayton Jun 12, 2026
6a53fbb
fix: harden MariaDB restart recovery (kad-qun.11)
brandonpayton Jun 13, 2026
2cdc918
test: refresh MariaDB Node expected passes (kad-qun.12)
brandonpayton Jun 13, 2026
b62ed9a
test: classify MariaDB lowercase_fs_on timeout (kad-qun.13)
brandonpayton Jun 13, 2026
71e1117
test: isolate MariaDB SP OOM fallout (kad-qun.15)
brandonpayton Jun 13, 2026
926225a
fix: handle MariaDB browser OOM kernel traps (kad-qun.16)
brandonpayton Jun 13, 2026
d249366
fix: reject non-wasm exec bytes (kad-qun.17)
brandonpayton Jun 13, 2026
4c39e72
fix: bootstrap MariaDB test grants (kad-qun.14)
brandonpayton Jun 13, 2026
eb1eda1
docs: record MariaDB Node full-suite status (kad-qun.4)
brandonpayton Jun 13, 2026
e37e6b3
fix: avoid host binary fallback in run-example exec
brandonpayton Jun 13, 2026
811ba5e
fix: expand MariaDB browser test VFS capacity (kad-qun.18)
brandonpayton Jun 13, 2026
9ff8a63
Merge commit '4c39e727fbaf544b2356b7e8548b707bdd5d5a36' into HEAD
brandonpayton Jun 13, 2026
5fa3e51
Merge commit 'd24936611b473ae39ec28baf708e52bf3809d9b9' into HEAD
brandonpayton Jun 13, 2026
cb3112a
docs: synthesize MariaDB both-host status (kad-qun.7)
brandonpayton Jun 13, 2026
3a6f3fd
docs: record MariaDB final hard counts (kad-qun.19)
brandonpayton Jun 13, 2026
6dbcf92
chore: merge main into MariaDB PR branch (kad-qun.8)
brandonpayton Jun 14, 2026
d101aeb
docs: inventory MariaDB full-suite failures (kad-qun.22)
brandonpayton Jun 14, 2026
b168d48
test: classify MariaDB browser expected failures (kad-qun.23)
brandonpayton Jun 14, 2026
0dc2e08
fix: fill MariaDB browser test fixtures (kad-qun.24)
brandonpayton Jun 14, 2026
50f5f51
fix: preserve browser VFS temp file state (kad-qun.25)
brandonpayton Jun 14, 2026
7b69170
Merge remote-tracking branch 'origin/polecat/max/kad-qun.25@mqd4sy0u'…
brandonpayton Jun 14, 2026
4e06ce1
fix: preserve browser MariaDB VFS state (kad-qun.27)
brandonpayton Jun 14, 2026
81b5bb8
Merge remote-tracking branch 'origin/polecat/immortan/kad-qun.27@mqds…
brandonpayton Jun 14, 2026
18d75d4
docs: route MariaDB residual full-suite failures (kad-qun.26)
brandonpayton Jun 14, 2026
899c036
Merge remote-tracking branch 'refs/remotes/origin/polecat/glory/kad-q…
brandonpayton Jun 14, 2026
6a25ace
test: classify MariaDB browser MERGE failures (kad-qun.28)
brandonpayton Jun 14, 2026
338eadc
test: classify MariaDB browser fulltext corruption (kad-qun.29)
brandonpayton Jun 14, 2026
27e33b8
Merge remote-tracking branch 'origin/polecat/goose/kad-qun.29@mqe4nmh…
brandonpayton Jun 14, 2026
da98985
Merge remote-tracking branch 'origin/polecat/dag/kad-qun.28@mqe4md5x'…
brandonpayton Jun 14, 2026
2802852
test: isolate MariaDB browser harness aborts
brandonpayton Jun 15, 2026
af8c77d
Merge branch 'polecat/angharad/kad-qun.10@harness-isolation' of githu…
brandonpayton Jun 15, 2026
bb35dfd
test: classify MariaDB sp stress resource limit
brandonpayton Jun 15, 2026
d8ee38d
Merge remote-tracking branch 'origin/polecat/coma/kad-qun.21' into re…
brandonpayton Jun 15, 2026
a5edbc0
test: classify MariaDB Node timeout failures
brandonpayton Jun 15, 2026
831a65f
Merge remote-tracking branch 'origin/polecat/dementus/kad-qun.20' int…
brandonpayton Jun 15, 2026
3fe0096
Let MariaDB browser smoke boot without rootfs
brandonpayton Jun 19, 2026
292a797
Fix kernel mmap bookkeeping under browser pressure
brandonpayton Jun 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions apps/browser-demos/lib/pty-terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,13 @@ export class PtyTerminal {
pty: true,
ptyCols: this.terminal.cols,
ptyRows: this.terminal.rows,
});

// The spawn creates the process with the next pid. We need to find it.
// BrowserKernel uses sequential pids starting from 1.
// The pid is assigned inside spawn() before the worker starts.
// We can get it from the exit promise's resolver tracking.
// Since spawn returns immediately after creating the process, the pid
// is the one that was just assigned. Access it via the kernel's internals.
const pid = (this.kernel as any).nextPid - 1;
this.pid = pid;
onStarted: (pid) => {
this.pid = pid;

// Connect PTY output → xterm.js
this.kernel.onPtyOutput(pid, (data: Uint8Array) => {
this.terminal.write(data);
this.kernel.onPtyOutput(pid, (data: Uint8Array) => {
this.terminal.write(data);
});
},
});

// Connect xterm.js input → PTY master
Expand Down
25 changes: 15 additions & 10 deletions apps/browser-demos/pages/benchmark/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,18 +724,23 @@ async function runMariaDbWithEngine(engine: string, arch: MariaDbArch = "wasm32"
try {

const bootstrapStdin = new TextEncoder().encode(bootstrapSql);
bootstrapKernel.spawn(mariadbBytes, [
"mariadbd", "--no-defaults", "--bootstrap",
"--user=mysql",
"--datadir=/data", "--tmpdir=/data/tmp",
...engineArgs,
"--skip-grant-tables",
"--key-buffer-size=1048576", "--table-open-cache=10",
"--sort-buffer-size=262144", "--skip-networking", "--log-warnings=0",
], { stdin: bootstrapStdin });
const bootstrapStarted = new Promise<number>((resolve) => {
void bootstrapKernel.spawn(mariadbBytes, [
"mariadbd", "--no-defaults", "--bootstrap",
"--user=mysql",
"--datadir=/data", "--tmpdir=/data/tmp",
...engineArgs,
"--skip-grant-tables",
"--key-buffer-size=1048576", "--table-open-cache=10",
"--sort-buffer-size=262144", "--skip-networking", "--log-warnings=0",
], {
stdin: bootstrapStdin,
onStarted: resolve,
});
});

// Wait for bootstrap stdin to be consumed
const bootstrapPid = (bootstrapKernel as any).nextPid - 1;
const bootstrapPid = await bootstrapStarted;
for (let i = 0; i < 1200; i++) {
try {
const consumed = await bootstrapKernel.isStdinConsumed(bootstrapPid);
Expand Down
74 changes: 66 additions & 8 deletions apps/browser-demos/pages/mariadb-test/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import { BrowserKernel } from "@host/browser-kernel-host";
import kernelWasmUrl from "@kernel-wasm?url";
import mysqlTestWasmUrl from "@binaries/programs/wasm32/mariadb/mysqltest.wasm?url";
import VFS_IMAGE_URL from "@binaries/programs/wasm32/mariadb-test.vfs.zst?url";

const MYSQL_PORT = 3306;

Expand All @@ -32,6 +31,8 @@ declare global {
interface Window {
__mariadbTestReady: boolean;
__runMariadbTest: (testName: string, timeoutMs?: number) => Promise<TestResult>;
__probeMariadb: (timeoutMs?: number) => Promise<boolean>;
__readMariadbFile: (path: string, timeoutMs?: number) => Promise<string>;
}
}

Expand All @@ -51,6 +52,28 @@ let kernel: BrowserKernel | null = null;
let mysqlTestBytes: ArrayBuffer | null = null;
let testStderr = "";

async function ensureMysqlTestDirs(): Promise<void> {
if (!kernel) return;
try {
const { exit } = await kernel.spawnFromVfs(
"/bin/mkdir",
["mkdir", "-p", "/data/tmp", "/tmp", "/log", "/run"],
{ env: ["PATH=/bin:/usr/bin"], cwd: "/" },
);
await exit;
const chmod = await kernel.spawnFromVfs(
"/bin/chmod",
["chmod", "777", "/data/tmp", "/tmp"],
{ env: ["PATH=/bin:/usr/bin"], cwd: "/" },
);
await chmod.exit;
} catch {
// The actual mysqltest invocation will report a concrete path error if
// the VFS helper is unavailable. Keep this best-effort so harness startup
// failures still surface through the normal test result path.
}
}

async function runMysqlTestCommand(
testName: string,
testFile: string,
Expand All @@ -62,23 +85,33 @@ async function runMysqlTestCommand(

const start = performance.now();
testStderr = "";
await ensureMysqlTestDirs();

const argv = [
"mysqltest", "--no-defaults",
"--host=127.0.0.1", "--port=3306",
"--user=root", "--database=test",
`--test-file=${testFile}`,
"--basedir=/mysql-test",
"--tmpdir=/tmp",
"--tmpdir=/data/tmp",
"--silent",
"--protocol=tcp",
];

const env = [
"HOME=/tmp", "PATH=/usr/bin", "TMPDIR=/tmp",
"HOME=/tmp", "PATH=/usr/bin", "TMPDIR=/data/tmp",
"MYSQL_TEST_DIR=/mysql-test",
// The upstream MTR tests require MYSQLD_DATADIR to be inside
// MYSQLTEST_VARDIR, and many hard-code $MYSQLTEST_VARDIR/tmp. The server
// itself still uses /tmp for internal temp tables; before each mysqltest
// spawn we recreate /data/tmp because tests may create/drop a database
// named `tmp`, which maps to the same datadir path.
"MYSQLTEST_VARDIR=/data",
"MYSQL_TMP_DIR=/tmp",
"MYSQL_TMP_DIR=/data/tmp",
"MYSQLD_DATADIR=/data/master-data",
"MYSQL_BINDIR=/usr/bin",
"MYSQL_SHAREDIR=/usr/share/mysql",
"MYSQL_LIBDIR=/usr/lib",
];

try {
Expand Down Expand Up @@ -108,11 +141,11 @@ async function init() {

const [kernelBytes, vfsImageBuf, mysqlTestBytesResult] = await Promise.all([
fetch(kernelWasmUrl).then((r) => r.arrayBuffer()),
fetch(VFS_IMAGE_URL).then((r) => {
fetch("/mariadb-test.vfs.zst").then((r) => {
if (!r.ok) {
throw new Error(
`Failed to load VFS image from ${VFS_IMAGE_URL} (${r.status}). ` +
`Run: bash packages/registry/mariadb-test/build-mariadb-test.sh`,
`mariadb-test.vfs.zst not found (${r.status}). ` +
`Run: bash images/vfs/scripts/build-mariadb-test-vfs-image.sh`,
);
}
return r.arrayBuffer();
Expand Down Expand Up @@ -154,7 +187,7 @@ async function init() {
const { exit } = await kernel.boot({
kernelWasm: kernelBytes,
vfsImage,
argv: ["/sbin/dinit", "--container", "-p", "/tmp/dinitctl"],
argv: ["/sbin/dinit", "--container", "-p", "/tmp/dinitctl", "mariadb"],
env: ["HOME=/root", "TERM=xterm-256color", "USER=root", "LOGNAME=root", "PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin"],
cwd: "/root",
uid: 0,
Expand Down Expand Up @@ -186,6 +219,31 @@ async function init() {
appendLog("Setup SQL complete.\n", "info");
}

window.__probeMariadb = async (timeoutMs = 5000): Promise<boolean> => {
const result = await runMysqlTestCommand("__probe", "/mysql-test/main/__probe.test", timeoutMs);
return result.exitCode === 0;
};

const runDiagnosticCommand = async (command: string, timeoutMs: number): Promise<string> => {
if (!kernel) return "";
testStderr = "";
const { exit } = await kernel.spawnFromVfs(
"/bin/sh",
["sh", "-c", `{ ${command}; } >&2`],
{ env: ["PATH=/bin:/usr/bin"], cwd: "/" },
);
const code = await Promise.race([
exit,
new Promise<number>((resolve) => setTimeout(() => resolve(-1), timeoutMs)),
]);
return `${command} exit=${code}\n${testStderr}`;
};

window.__readMariadbFile = async (path: string, timeoutMs = 5000): Promise<string> => {
const quotedPath = `'${path.replace(/'/g, "'\\''")}'`;
return runDiagnosticCommand(`cat ${quotedPath}`, timeoutMs);
};

window.__runMariadbTest = async (testName: string, timeoutMs = 60000): Promise<TestResult> => {
const resetResult = await runMysqlTestCommand("__reset", "/mysql-test/main/__reset.test", 15000);
if (resetResult.exitCode !== 0 && resetResult.stderr !== "TIMEOUT") {
Expand Down
18 changes: 13 additions & 5 deletions apps/browser-demos/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ function injectCorsProxyUrlPlaceholder(content: string, corsProxyUrl: string): s
* 2. `<repoRoot>/binaries/kernel.wasm` — populated by `./run.sh fetch`.
*
* `@rootfs-vfs` resolves to `<repoRoot>/host/wasm/rootfs.vfs` (built by
* mkrootfs during `bash build.sh`).
* mkrootfs during `bash build.sh`) when that artifact exists. If it does not,
* the alias resolves to a missing-runtime URL so kernel-owned VFS pages that
* never fetch rootfs.vfs can still serve/build; legacy init/default-rootfs
* callers fail when they actually fetch it.
*
* Resolution is deferred until import time so pages that don't consume
* these aliases can run without a kernel build present. Pages that do
Expand All @@ -60,6 +63,7 @@ function injectCorsProxyUrlPlaceholder(content: string, corsProxyUrl: string): s
function resolveKernelArtifactsAlias(): Plugin {
const KERNEL = "@kernel-wasm";
const ROOTFS = "@rootfs-vfs";
const MISSING_ROOTFS_VFS_URL_ID = "\0kandelo-missing-rootfs-vfs-url";
return {
name: "resolve-kernel-artifacts-alias",
enforce: "pre",
Expand Down Expand Up @@ -89,10 +93,13 @@ function resolveKernelArtifactsAlias(): Plugin {
for (const file of candidates) {
if (fs.existsSync(file)) return file + query;
}
this.error(
"rootfs.vfs not found. Run `bash build.sh` from the repo root, or fetch/build the rootfs package.\n" +
candidates.map((file) => ` Looked at: ${file}`).join("\n")
);
return MISSING_ROOTFS_VFS_URL_ID;
}
return null;
},
load(id) {
if (id === MISSING_ROOTFS_VFS_URL_ID) {
return 'export default "/__kandelo_missing_rootfs.vfs";';
}
return null;
},
Expand Down Expand Up @@ -403,6 +410,7 @@ const defaultDemoInputs = {

const demoInputs = {
...defaultDemoInputs,
"mariadb-test": path.resolve(__dirname, "pages/mariadb-test/index.html"),
"sqlite-test": path.resolve(__dirname, "pages/sqlite-test/index.html"),
// The perl, python, ruby, erlang, texlive, and redis package entries
// are not bundled into this static build while their slow builds
Expand Down
Loading