mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
refactor(schemas): move restic schemas to a subfolder
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
import type { BackendStatus, BackendType, volumeConfigSchema } from "@ironmount/schemas";
|
||||
import type {
|
||||
BackendStatus,
|
||||
BackendType,
|
||||
CompressionMode,
|
||||
RepositoryBackend,
|
||||
RepositoryStatus,
|
||||
repositoryConfigSchema,
|
||||
volumeConfigSchema,
|
||||
} from "@ironmount/schemas";
|
||||
RepositoryStatus,
|
||||
} from "@ironmount/schemas/restic";
|
||||
import { sql } from "drizzle-orm";
|
||||
import { int, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import type { RepositoryConfig } from "@ironmount/schemas";
|
||||
import type { RepositoryConfig } from "@ironmount/schemas/restic";
|
||||
import { type } from "arktype";
|
||||
import { $ } from "bun";
|
||||
import { RESTIC_PASS_FILE } from "../core/constants";
|
||||
@@ -38,6 +38,8 @@ const ensurePassfile = async () => {
|
||||
|
||||
const buildRepoUrl = (config: RepositoryConfig): string => {
|
||||
switch (config.backend) {
|
||||
case "local":
|
||||
return config.path;
|
||||
case "s3":
|
||||
return `s3:${config.endpoint}/${config.bucket}`;
|
||||
default: {
|
||||
@@ -47,7 +49,9 @@ const buildRepoUrl = (config: RepositoryConfig): string => {
|
||||
};
|
||||
|
||||
const buildEnv = async (config: RepositoryConfig) => {
|
||||
const env: Record<string, string> = {};
|
||||
const env: Record<string, string> = {
|
||||
RESTIC_PASSWORD_FILE: RESTIC_PASS_FILE,
|
||||
};
|
||||
|
||||
switch (config.backend) {
|
||||
case "s3":
|
||||
@@ -65,7 +69,7 @@ const init = async (config: RepositoryConfig) => {
|
||||
const repoUrl = buildRepoUrl(config);
|
||||
const env = await buildEnv(config);
|
||||
|
||||
const res = await $`restic init --repo ${repoUrl} --password-file ${RESTIC_PASS_FILE} --json`.env(env).nothrow();
|
||||
const res = await $`restic init --repo ${repoUrl} --json`.env(env).nothrow();
|
||||
|
||||
if (res.exitCode !== 0) {
|
||||
logger.error(`Restic init failed: ${res.stderr}`);
|
||||
@@ -80,9 +84,7 @@ const backup = async (config: RepositoryConfig, source: string) => {
|
||||
const repoUrl = buildRepoUrl(config);
|
||||
const env = await buildEnv(config);
|
||||
|
||||
const res = await $`restic --repo ${repoUrl} backup ${source} --password-file /data/secrets/restic.pass --json`
|
||||
.env(env)
|
||||
.nothrow();
|
||||
const res = await $`restic --repo ${repoUrl} backup ${source} --json`.env(env).nothrow();
|
||||
|
||||
if (res.exitCode !== 0) {
|
||||
logger.error(`Restic backup failed: ${res.stderr}`);
|
||||
@@ -99,8 +101,23 @@ const backup = async (config: RepositoryConfig, source: string) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
const restore = async (config: RepositoryConfig, snapshotId: string, target: string) => {
|
||||
const repoUrl = buildRepoUrl(config);
|
||||
const env = await buildEnv(config);
|
||||
|
||||
const res = await $`restic --repo ${repoUrl} restore ${snapshotId} --target ${target} --json`.env(env).nothrow();
|
||||
|
||||
if (res.exitCode !== 0) {
|
||||
logger.error(`Restic restore failed: ${res.stderr}`);
|
||||
throw new Error(`Restic restore failed: ${res.stderr}`);
|
||||
}
|
||||
|
||||
logger.info(`Restic restore completed for snapshot ${snapshotId} to target ${target}`);
|
||||
};
|
||||
|
||||
export const restic = {
|
||||
ensurePassfile,
|
||||
init,
|
||||
backup,
|
||||
restore,
|
||||
};
|
||||
|
||||
@@ -4,6 +4,16 @@
|
||||
"private": true,
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./src/index.ts",
|
||||
"require": "./src/index.ts"
|
||||
},
|
||||
"./restic": {
|
||||
"import": "./src/restic.ts",
|
||||
"require": "./src/restic.ts"
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
"peerDependencies": {
|
||||
"arktype": ">=2"
|
||||
|
||||
@@ -53,41 +53,3 @@ export const BACKEND_STATUS = {
|
||||
} as const;
|
||||
|
||||
export type BackendStatus = keyof typeof BACKEND_STATUS;
|
||||
|
||||
export const REPOSITORY_BACKENDS = {
|
||||
local: "local",
|
||||
sftp: "sftp",
|
||||
s3: "s3",
|
||||
} as const;
|
||||
|
||||
export type RepositoryBackend = keyof typeof REPOSITORY_BACKENDS;
|
||||
|
||||
export const s3RepositoryConfigSchema = type({
|
||||
backend: "'s3'",
|
||||
endpoint: "string",
|
||||
bucket: "string",
|
||||
accessKeyId: "string",
|
||||
secretAccessKey: "string",
|
||||
});
|
||||
|
||||
export const repositoryConfigSchema = s3RepositoryConfigSchema;
|
||||
|
||||
export type RepositoryConfig = typeof repositoryConfigSchema.infer;
|
||||
|
||||
export const COMPRESSION_MODES = {
|
||||
off: "off",
|
||||
auto: "auto",
|
||||
fastest: "fastest",
|
||||
better: "better",
|
||||
max: "max",
|
||||
} as const;
|
||||
|
||||
export type CompressionMode = keyof typeof COMPRESSION_MODES;
|
||||
|
||||
export const REPOSITORY_STATUS = {
|
||||
healthy: "healthy",
|
||||
error: "error",
|
||||
unknown: "unknown",
|
||||
} as const;
|
||||
|
||||
export type RepositoryStatus = keyof typeof REPOSITORY_STATUS;
|
||||
|
||||
44
packages/schemas/src/restic.ts
Normal file
44
packages/schemas/src/restic.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { type } from "arktype";
|
||||
|
||||
export const REPOSITORY_BACKENDS = {
|
||||
local: "local",
|
||||
sftp: "sftp",
|
||||
s3: "s3",
|
||||
} as const;
|
||||
|
||||
export type RepositoryBackend = keyof typeof REPOSITORY_BACKENDS;
|
||||
|
||||
export const s3RepositoryConfigSchema = type({
|
||||
backend: "'s3'",
|
||||
endpoint: "string",
|
||||
bucket: "string",
|
||||
accessKeyId: "string",
|
||||
secretAccessKey: "string",
|
||||
});
|
||||
|
||||
export const localRepositoryConfigSchema = type({
|
||||
backend: "'local'",
|
||||
path: "string",
|
||||
});
|
||||
|
||||
export const repositoryConfigSchema = s3RepositoryConfigSchema.or(localRepositoryConfigSchema);
|
||||
|
||||
export type RepositoryConfig = typeof repositoryConfigSchema.infer;
|
||||
|
||||
export const COMPRESSION_MODES = {
|
||||
off: "off",
|
||||
auto: "auto",
|
||||
fastest: "fastest",
|
||||
better: "better",
|
||||
max: "max",
|
||||
} as const;
|
||||
|
||||
export type CompressionMode = keyof typeof COMPRESSION_MODES;
|
||||
|
||||
export const REPOSITORY_STATUS = {
|
||||
healthy: "healthy",
|
||||
error: "error",
|
||||
unknown: "unknown",
|
||||
} as const;
|
||||
|
||||
export type RepositoryStatus = keyof typeof REPOSITORY_STATUS;
|
||||
Reference in New Issue
Block a user