mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-10-19 14:07:19 +02:00
115 lines
3.7 KiB
JavaScript
115 lines
3.7 KiB
JavaScript
// rclone's S3 server, the storage under both sync test harnesses
|
|
// (scripts/sync-test-harness.mjs and e2e/run.mjs).
|
|
//
|
|
// MinIO used to play this part, but MinIO withdrew its community binaries and
|
|
// every dl.min.io path now answers 410. rclone still publishes a single binary
|
|
// per platform, and `rclone serve s3` speaks enough of the API for these tests:
|
|
// path-style addressing, a static key pair, and bucket creation (a bucket is a
|
|
// directory under the served root). It has no health endpoint, so wait for its
|
|
// port to accept connections.
|
|
|
|
import { spawnSync } from "node:child_process";
|
|
import { chmodSync, existsSync, mkdirSync, renameSync } from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
|
|
// Pinned so a fresh rclone release cannot change what CI runs underneath us.
|
|
export const RCLONE_VERSION = "v1.75.1";
|
|
|
|
function rcloneAsset() {
|
|
const platform = os.platform();
|
|
const arch = os.arch() === "arm64" ? "arm64" : "amd64";
|
|
if (platform === "darwin") return `rclone-${RCLONE_VERSION}-osx-${arch}`;
|
|
if (platform === "linux") return `rclone-${RCLONE_VERSION}-linux-${arch}`;
|
|
if (platform === "win32") return `rclone-${RCLONE_VERSION}-windows-amd64`;
|
|
throw new Error(`Unsupported platform: ${platform}-${os.arch()}`);
|
|
}
|
|
|
|
// Mirrors src-tauri/download-xray.mjs: PowerShell owns zip extraction on
|
|
// Windows, `unzip` everywhere else. Both are present on every runner these
|
|
// harnesses target.
|
|
function extractZip(archive, destinationDir) {
|
|
const result =
|
|
os.platform() === "win32"
|
|
? spawnSync(
|
|
"powershell",
|
|
[
|
|
"-NoProfile",
|
|
"-NonInteractive",
|
|
"-Command",
|
|
"Expand-Archive -LiteralPath $env:DONUT_RCLONE_ARCHIVE -DestinationPath $env:DONUT_RCLONE_DESTINATION -Force",
|
|
],
|
|
{
|
|
stdio: "inherit",
|
|
env: {
|
|
...process.env,
|
|
DONUT_RCLONE_ARCHIVE: archive,
|
|
DONUT_RCLONE_DESTINATION: destinationDir,
|
|
},
|
|
},
|
|
)
|
|
: spawnSync(
|
|
"unzip",
|
|
["-qq", "-j", "-o", archive, "*/rclone", "-d", destinationDir],
|
|
{ stdio: "inherit" },
|
|
);
|
|
if (result.status !== 0) {
|
|
throw new Error("Failed to extract the rclone archive");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The rclone binary cached in `cacheDir`, fetched with `download(url, dest)`
|
|
* the first time.
|
|
*/
|
|
export async function ensureRclone(cacheDir, download, log) {
|
|
const isWindows = os.platform() === "win32";
|
|
const binName = isWindows ? "rclone.exe" : "rclone";
|
|
const bin = path.join(cacheDir, binName);
|
|
if (existsSync(bin)) {
|
|
return bin;
|
|
}
|
|
|
|
log("Downloading rclone binary...");
|
|
mkdirSync(cacheDir, { recursive: true });
|
|
const asset = rcloneAsset();
|
|
const archive = path.join(cacheDir, `${asset}.zip`);
|
|
await download(
|
|
`https://github.com/rclone/rclone/releases/download/${RCLONE_VERSION}/${asset}.zip`,
|
|
archive,
|
|
);
|
|
extractZip(archive, cacheDir);
|
|
|
|
if (isWindows) {
|
|
// Expand-Archive keeps the archive's own directory, so lift the binary out.
|
|
const nested = path.join(cacheDir, asset, binName);
|
|
if (existsSync(nested)) {
|
|
renameSync(nested, bin);
|
|
}
|
|
}
|
|
if (!existsSync(bin)) {
|
|
throw new Error(`rclone archive did not contain ${binName}`);
|
|
}
|
|
if (!isWindows) {
|
|
chmodSync(bin, 0o755);
|
|
}
|
|
log("rclone binary downloaded");
|
|
return bin;
|
|
}
|
|
|
|
/** Arguments for `rclone serve s3` over `dataDir` at `address` (host:port). */
|
|
export function serveS3Args({ dataDir, address, accessKey, secretKey }) {
|
|
return [
|
|
"serve",
|
|
"s3",
|
|
dataDir,
|
|
"--addr",
|
|
address,
|
|
"--auth-key",
|
|
`${accessKey},${secretKey}`,
|
|
"--force-path-style",
|
|
"--vfs-cache-mode",
|
|
"writes",
|
|
];
|
|
}
|