mirror of
https://github.com/unraid/api.git
synced 2026-01-01 22:20:05 -06:00
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced full RClone remote management with creation, deletion, listing, and detailed remote info via a multi-step, schema-driven UI. - Added guided configuration forms supporting advanced and provider-specific options for RClone remotes. - Enabled flash backup initiation through API mutations. - Added new Vue components for RClone configuration, overview, remote item cards, and flash backup page. - Integrated new combobox, stepped layout, control wrapper, label renderer, and improved form renderers with enhanced validation and error display. - Added JSON Forms visibility composable and Unraid settings layout for consistent UI rendering. - **Bug Fixes** - Standardized JSON scalar usage in Docker-related types, replacing `JSONObject` with `JSON`. - **Chores** - Added utility scripts and helpers to manage rclone binary installation and versioning. - Updated build scripts and Storybook configuration for CSS handling and improved developer workflow. - Refactored ESLint config for modularity and enhanced code quality enforcement. - Improved component registration with runtime type checks and error handling. - **Documentation** - Added extensive test coverage for RClone API service, JSON Forms schema merging, and provider config slice generation. - **Style** - Improved UI consistency with new layouts, tooltips on select options, password visibility toggles, and error handling components. - Removed deprecated components and consolidated renderer registrations for JSON Forms. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import { join } from "path";
|
|
import { existsSync, mkdirSync, createWriteStream, readFileSync } from "fs";
|
|
import { writeFile, readFile, unlink } from "fs/promises";
|
|
import { get } from "https";
|
|
import { $ } from "zx";
|
|
import { startingDir } from "./consts";
|
|
|
|
const RCLONE_VERSION_PATHS = [
|
|
join(startingDir, "..", ".rclone-version"),
|
|
join(startingDir, ".rclone-version"),
|
|
];
|
|
|
|
const findRcloneVersion = () => {
|
|
for (const path of RCLONE_VERSION_PATHS) {
|
|
if (existsSync(path)) {
|
|
return readFileSync(path, "utf8").trim();
|
|
}
|
|
}
|
|
throw new Error(".rclone-version file not found");
|
|
};
|
|
|
|
const RCLONE_VERSION = findRcloneVersion();
|
|
const RCLONE_FILENAME = `rclone-v${RCLONE_VERSION}-linux-amd64.zip`;
|
|
const RCLONE_URL = `https://downloads.rclone.org/v${RCLONE_VERSION}/${RCLONE_FILENAME}`;
|
|
const RCLONE_DEST = join(startingDir, "source", "dynamix.unraid.net", "usr", "local", "rclone");
|
|
const RCLONE_VERSION_FILE = join(RCLONE_DEST, ".rclone-version");
|
|
const RCLONE_BIN = join(RCLONE_DEST, "rclone");
|
|
|
|
async function fetchFile(url: string, dest: string) {
|
|
return new Promise((resolve, reject) => {
|
|
const file = createWriteStream(dest);
|
|
get(url, (response) => {
|
|
if (response.statusCode !== 200) {
|
|
reject(new Error(`Failed to get '${url}' (${response.statusCode})`));
|
|
return;
|
|
}
|
|
response.pipe(file);
|
|
file.on("finish", () => file.close(resolve));
|
|
file.on("error", reject);
|
|
}).on("error", reject);
|
|
});
|
|
}
|
|
|
|
export async function ensureRclone() {
|
|
let currentVersion: string | null = null;
|
|
if (existsSync(RCLONE_VERSION_FILE)) {
|
|
currentVersion = (await readFile(RCLONE_VERSION_FILE, "utf8")).trim();
|
|
}
|
|
if (currentVersion !== RCLONE_VERSION) {
|
|
mkdirSync(RCLONE_DEST, { recursive: true });
|
|
if (!existsSync(RCLONE_FILENAME)) {
|
|
await fetchFile(RCLONE_URL, RCLONE_FILENAME);
|
|
}
|
|
await $`unzip -oj ${RCLONE_FILENAME} rclone-v${RCLONE_VERSION}-linux-amd64/rclone -d ${RCLONE_DEST}`;
|
|
await $`chmod +x ${RCLONE_BIN}`;
|
|
await writeFile(RCLONE_VERSION_FILE, RCLONE_VERSION, "utf8");
|
|
// Clean up old rclone archives
|
|
const glob = await import("glob");
|
|
const files = glob.sync("rclone-v*-linux-amd64.zip", { cwd: startingDir });
|
|
for (const file of files) {
|
|
if (file !== RCLONE_FILENAME) await unlink(join(startingDir, file));
|
|
}
|
|
}
|
|
}
|