hopefully all ts works (it's getting pushed to prod fuck you)
This commit is contained in:
@@ -1630,21 +1630,24 @@ async function uploadFileViaHttpPull(file, path, transfer) {
|
||||
|
||||
console.debug("[filebrowser] upload stage url", { uploadUrl });
|
||||
|
||||
const uploadRequestOptions = {
|
||||
headers: { "Content-Type": "application/octet-stream" },
|
||||
credentials: "include",
|
||||
body: file,
|
||||
signal: transfer.abortController?.signal,
|
||||
};
|
||||
|
||||
let uploadRes;
|
||||
try {
|
||||
uploadRes = await fetch(uploadUrl, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/octet-stream" },
|
||||
credentials: "include",
|
||||
body: file,
|
||||
method: "POST",
|
||||
...uploadRequestOptions,
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn("[filebrowser] upload stage PUT failed, retrying as POST", err);
|
||||
console.warn("[filebrowser] upload stage POST failed, retrying as PUT", err);
|
||||
uploadRes = await fetch(uploadUrl, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/octet-stream" },
|
||||
credentials: "include",
|
||||
body: file,
|
||||
method: "PUT",
|
||||
...uploadRequestOptions,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1721,6 +1724,7 @@ async function uploadFile(file) {
|
||||
ackedOffsets: new Set(),
|
||||
transferId,
|
||||
completed: false,
|
||||
abortController: new AbortController(),
|
||||
};
|
||||
|
||||
fileUploads.set(path, transfer);
|
||||
|
||||
@@ -4,6 +4,7 @@ import fs from "fs";
|
||||
import { saveBuild } from "../db";
|
||||
import { logger } from "../logger";
|
||||
import { getConfig } from "../config";
|
||||
import { ensureDataDir } from "../paths";
|
||||
import * as buildManager from "../build/buildManager";
|
||||
import type { BuildStream } from "../build/types";
|
||||
import { ALLOWED_PLATFORMS } from "./validation-constants";
|
||||
@@ -33,6 +34,16 @@ function resolveClientModuleDir(rootDir: string): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveClientBuildCacheRoot(): string {
|
||||
const explicit = process.env.OVERLORD_CLIENT_BUILD_CACHE_DIR?.trim();
|
||||
if (explicit) {
|
||||
return path.resolve(explicit);
|
||||
}
|
||||
|
||||
// Keep UI build caches under persistent app data by default.
|
||||
return path.resolve(ensureDataDir(), "client-build-cache");
|
||||
}
|
||||
|
||||
type BuildProcessConfig = {
|
||||
platforms: string[];
|
||||
serverUrl?: string;
|
||||
@@ -133,10 +144,16 @@ export async function startBuildProcess(
|
||||
);
|
||||
}
|
||||
const outDir = path.join(rootDir, "dist-clients");
|
||||
const cacheRoot = resolveClientBuildCacheRoot();
|
||||
const goBuildCacheDir = path.join(cacheRoot, "go-build");
|
||||
const goModCacheDir = path.join(cacheRoot, "go-mod");
|
||||
|
||||
await Bun.$`mkdir -p ${outDir}`.quiet();
|
||||
fs.mkdirSync(goBuildCacheDir, { recursive: true });
|
||||
fs.mkdirSync(goModCacheDir, { recursive: true });
|
||||
sendToStream({ type: "output", text: `Build directory: ${outDir}\n`, level: "info" });
|
||||
sendToStream({ type: "output", text: `Client source: ${clientDir}\n`, level: "info" });
|
||||
sendToStream({ type: "output", text: `Client build cache: ${cacheRoot}\n`, level: "info" });
|
||||
|
||||
const platformsToBuild = (config.platforms || []).filter((p) => ALLOWED_PLATFORMS.has(p));
|
||||
if (platformsToBuild.length !== (config.platforms || []).length) {
|
||||
@@ -168,6 +185,8 @@ export async function startBuildProcess(
|
||||
GOARCH: actualArch,
|
||||
CGO_ENABLED: config.disableCgo === true ? "0" : "1",
|
||||
GOWORK: "off",
|
||||
GOCACHE: goBuildCacheDir,
|
||||
GOMODCACHE: goModCacheDir,
|
||||
...(goarm ? { GOARM: goarm } : {}),
|
||||
};
|
||||
|
||||
|
||||
@@ -118,6 +118,24 @@ const UUID_TOKEN_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{
|
||||
const uploadIntents = new Map<string, UploadIntent>();
|
||||
const uploadPulls = new Map<string, UploadPull>();
|
||||
|
||||
function parsePositiveIntEnv(name: string, fallback: number): number {
|
||||
const raw = process.env[name];
|
||||
if (!raw) return fallback;
|
||||
const parsed = Number(raw);
|
||||
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
||||
return Math.floor(parsed);
|
||||
}
|
||||
|
||||
// WAN uploads can be significantly slower than LAN transfers.
|
||||
const FILE_UPLOAD_INTENT_TTL_MS = parsePositiveIntEnv(
|
||||
"OVERLORD_FILE_UPLOAD_INTENT_TTL_MS",
|
||||
30 * 60_000,
|
||||
);
|
||||
const FILE_UPLOAD_PULL_TTL_MS = parsePositiveIntEnv(
|
||||
"OVERLORD_FILE_UPLOAD_PULL_TTL_MS",
|
||||
30 * 60_000,
|
||||
);
|
||||
|
||||
function isSafeRemotePath(value: string): boolean {
|
||||
if (!value || value.length > 4096) return false;
|
||||
return !/[\x00-\x1F\x7F]/.test(value);
|
||||
@@ -323,10 +341,10 @@ export async function handleFileDownloadRoutes(
|
||||
}
|
||||
|
||||
const uploadId = uuidv4();
|
||||
const expiresAt = Date.now() + 2 * 60_000;
|
||||
const expiresAt = Date.now() + FILE_UPLOAD_INTENT_TTL_MS;
|
||||
const timeout = setTimeout(() => {
|
||||
uploadIntents.delete(uploadId);
|
||||
}, 2 * 60_000);
|
||||
}, FILE_UPLOAD_INTENT_TTL_MS);
|
||||
|
||||
uploadIntents.set(uploadId, {
|
||||
id: uploadId,
|
||||
@@ -423,14 +441,14 @@ export async function handleFileDownloadRoutes(
|
||||
clearTimeout(intent.timeout);
|
||||
|
||||
const pullId = uuidv4();
|
||||
const pullExpiresAt = Date.now() + 10 * 60_000;
|
||||
const pullExpiresAt = Date.now() + FILE_UPLOAD_PULL_TTL_MS;
|
||||
const pullTimeout = setTimeout(() => {
|
||||
const pull = uploadPulls.get(pullId);
|
||||
uploadPulls.delete(pullId);
|
||||
if (pull) {
|
||||
void fs.unlink(pull.tmpPath).catch(() => {});
|
||||
}
|
||||
}, 10 * 60_000);
|
||||
}, FILE_UPLOAD_PULL_TTL_MS);
|
||||
|
||||
uploadPulls.set(pullId, {
|
||||
id: pullId,
|
||||
|
||||
Reference in New Issue
Block a user