chore: verbose logging for mount commands
This commit is contained in:
parent
a25d303d54
commit
10b85fdd42
3 changed files with 50 additions and 20 deletions
|
|
@ -10,8 +10,9 @@ ENV VITE_RESTIC_VERSION=${RESTIC_VERSION} \
|
|||
VITE_RCLONE_VERSION=${RCLONE_VERSION} \
|
||||
VITE_SHOUTRRR_VERSION=${SHOUTRRR_VERSION}
|
||||
|
||||
RUN apk upgrade --no-cache && \
|
||||
apk add --no-cache davfs2=1.6.1-r2 openssh-client fuse3 sshfs tini nfs-utils cifs-utils
|
||||
RUN apk update --no-cache && \
|
||||
apk upgrade --no-cache && \
|
||||
apk add --no-cache davfs2=1.6.1-r2 openssh-client fuse3 sshfs tini nfs-utils cifs-utils util-linux
|
||||
|
||||
ENTRYPOINT ["/sbin/tini", "-s", "--"]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import * as fs from "node:fs/promises";
|
||||
import * as os from "node:os";
|
||||
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
||||
import { OPERATION_TIMEOUT } from "../../../core/constants";
|
||||
import { toMessage } from "../../../utils/errors";
|
||||
import { logger } from "../../../utils/logger";
|
||||
|
|
@ -7,19 +8,24 @@ import { getMountForPath } from "../../../utils/mountinfo";
|
|||
import { withTimeout } from "../../../utils/timeout";
|
||||
import type { VolumeBackend } from "../backend";
|
||||
import { executeMount, executeUnmount } from "../utils/backend-utils";
|
||||
import { BACKEND_STATUS, type BackendConfig } from "~/schemas/volumes";
|
||||
|
||||
const mount = async (config: BackendConfig, path: string) => {
|
||||
logger.debug(`Mounting volume ${path}...`);
|
||||
|
||||
if (config.backend !== "nfs") {
|
||||
logger.error("Provided config is not for NFS backend");
|
||||
return { status: BACKEND_STATUS.error, error: "Provided config is not for NFS backend" };
|
||||
return {
|
||||
status: BACKEND_STATUS.error,
|
||||
error: "Provided config is not for NFS backend",
|
||||
};
|
||||
}
|
||||
|
||||
if (os.platform() !== "linux") {
|
||||
logger.error("NFS mounting is only supported on Linux hosts.");
|
||||
return { status: BACKEND_STATUS.error, error: "NFS mounting is only supported on Linux hosts." };
|
||||
return {
|
||||
status: BACKEND_STATUS.error,
|
||||
error: "NFS mounting is only supported on Linux hosts.",
|
||||
};
|
||||
}
|
||||
|
||||
const { status } = await checkHealth(path);
|
||||
|
|
@ -28,7 +34,9 @@ const mount = async (config: BackendConfig, path: string) => {
|
|||
}
|
||||
|
||||
if (status === "error") {
|
||||
logger.debug(`Trying to unmount any existing mounts at ${path} before mounting...`);
|
||||
logger.debug(
|
||||
`Trying to unmount any existing mounts at ${path} before mounting...`,
|
||||
);
|
||||
await unmount(path);
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +45,9 @@ const mount = async (config: BackendConfig, path: string) => {
|
|||
|
||||
const source = `${config.server}:${config.exportPath}`;
|
||||
const options = [`vers=${config.version}`, `port=${config.port}`];
|
||||
if (config.version === "3") {
|
||||
options.push("nolock");
|
||||
}
|
||||
if (config.readOnly) {
|
||||
options.push("ro");
|
||||
}
|
||||
|
|
@ -62,7 +73,10 @@ const mount = async (config: BackendConfig, path: string) => {
|
|||
const unmount = async (path: string) => {
|
||||
if (os.platform() !== "linux") {
|
||||
logger.error("NFS unmounting is only supported on Linux hosts.");
|
||||
return { status: BACKEND_STATUS.error, error: "NFS unmounting is only supported on Linux hosts." };
|
||||
return {
|
||||
status: BACKEND_STATUS.error,
|
||||
error: "NFS unmounting is only supported on Linux hosts.",
|
||||
};
|
||||
}
|
||||
|
||||
const run = async () => {
|
||||
|
|
@ -83,7 +97,10 @@ const unmount = async (path: string) => {
|
|||
try {
|
||||
return await withTimeout(run(), OPERATION_TIMEOUT, "NFS unmount");
|
||||
} catch (err) {
|
||||
logger.error("Error unmounting NFS volume", { path, error: toMessage(err) });
|
||||
logger.error("Error unmounting NFS volume", {
|
||||
path,
|
||||
error: toMessage(err),
|
||||
});
|
||||
return { status: BACKEND_STATUS.error, error: toMessage(err) };
|
||||
}
|
||||
};
|
||||
|
|
@ -103,7 +120,9 @@ const checkHealth = async (path: string) => {
|
|||
}
|
||||
|
||||
if (!mount.fstype.startsWith("nfs")) {
|
||||
throw new Error(`Path ${path} is not mounted as NFS (found ${mount.fstype}).`);
|
||||
throw new Error(
|
||||
`Path ${path} is not mounted as NFS (found ${mount.fstype}).`,
|
||||
);
|
||||
}
|
||||
|
||||
logger.debug(`NFS volume at ${path} is healthy and mounted.`);
|
||||
|
|
@ -121,7 +140,10 @@ const checkHealth = async (path: string) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const makeNfsBackend = (config: BackendConfig, path: string): VolumeBackend => ({
|
||||
export const makeNfsBackend = (
|
||||
config: BackendConfig,
|
||||
path: string,
|
||||
): VolumeBackend => ({
|
||||
mount: () => mount(config, path),
|
||||
unmount: () => unmount(path),
|
||||
checkHealth: () => checkHealth(path),
|
||||
|
|
|
|||
|
|
@ -1,23 +1,30 @@
|
|||
import * as fs from "node:fs/promises";
|
||||
import * as npath from "node:path";
|
||||
import { $ } from "bun";
|
||||
import { toMessage } from "../../../utils/errors";
|
||||
import { logger } from "../../../utils/logger";
|
||||
import { $ } from "bun";
|
||||
|
||||
export const executeMount = async (args: string[]): Promise<void> => {
|
||||
let stderr: string | undefined;
|
||||
const shouldBeVerbose = process.env.LOG_LEVEL === "debug" || process.env.NODE_ENV !== "production";
|
||||
const hasVerboseFlag = args.some((arg) => arg === "-v" || arg.startsWith("-vv"));
|
||||
const effectiveArgs = shouldBeVerbose && !hasVerboseFlag ? ["-vvv", ...args] : args;
|
||||
|
||||
logger.debug(`Executing mount ${args.join(" ")}`);
|
||||
const result = await $`mount ${args}`.nothrow();
|
||||
stderr = result.stderr.toString();
|
||||
logger.debug(`Executing mount ${effectiveArgs.join(" ")}`);
|
||||
const result = await $`mount ${effectiveArgs}`.nothrow();
|
||||
|
||||
if (stderr?.trim()) {
|
||||
logger.warn(stderr.trim());
|
||||
const stdout = result.stdout.toString().trim();
|
||||
const stderr = result.stderr.toString().trim();
|
||||
|
||||
if (result.exitCode === 0) {
|
||||
logger.debug(stdout);
|
||||
logger.debug(stderr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
throw new Error(`Mount command failed with exit code ${result.exitCode}: ${stderr?.trim()}`);
|
||||
}
|
||||
logger.warn(stdout);
|
||||
logger.warn(stderr);
|
||||
|
||||
throw new Error(`Mount command failed with exit code ${result.exitCode}: ${stderr || stdout || "unknown error"}`);
|
||||
};
|
||||
|
||||
export const executeUnmount = async (path: string): Promise<void> => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue