mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
refactor: rebrand to zerobyte (#45)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { CalendarClock, Database, HardDrive, Mountain, Settings } from "lucide-react";
|
||||
import { CalendarClock, Database, HardDrive, Settings } from "lucide-react";
|
||||
import { Link, NavLink } from "react-router";
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -46,13 +46,17 @@ export function AppSidebar() {
|
||||
<Sidebar variant="inset" collapsible="icon" className="p-0">
|
||||
<SidebarHeader className="bg-card-header border-b border-border/50 hidden md:flex h-[65px] flex-row items-center p-4">
|
||||
<Link to="/volumes" className="flex items-center gap-3 font-semibold pl-2">
|
||||
<Mountain className="size-5 text-strong-accent" />
|
||||
<img
|
||||
src="/images/zerobyte.png"
|
||||
alt="Zerobyte Logo"
|
||||
className={cn("h-8 w-8 flex-shrink-0 object-contain -ml-2")}
|
||||
/>
|
||||
<span
|
||||
className={cn("text-base transition-all duration-200", {
|
||||
className={cn("text-base transition-all duration-200 -ml-1", {
|
||||
"opacity-0 w-0 overflow-hidden ": state === "collapsed",
|
||||
})}
|
||||
>
|
||||
Ironmount
|
||||
Zerobyte
|
||||
</span>
|
||||
</Link>
|
||||
</SidebarHeader>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Mountain } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
type AuthLayoutProps = {
|
||||
@@ -13,8 +12,8 @@ export function AuthLayout({ title, description, children }: AuthLayoutProps) {
|
||||
<div className="flex flex-1 items-center justify-center bg-background p-8">
|
||||
<div className="w-full max-w-md space-y-8">
|
||||
<div className="flex items-center gap-3">
|
||||
<Mountain className="size-5 text-strong-accent" />
|
||||
<span className="text-lg font-semibold">Ironmount</span>
|
||||
<img src="/images/zerobyte.png" alt="Zerobyte Logo" className="h-5 w-5 object-contain" />
|
||||
<span className="text-lg font-semibold">Zerobyte</span>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
|
||||
@@ -229,12 +229,12 @@ export const CreateRepositoryForm = ({
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="default">Use Ironmount's password</SelectItem>
|
||||
<SelectItem value="default">Use Zerobyte's password</SelectItem>
|
||||
<SelectItem value="custom">Enter password manually</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
Choose whether to use Ironmount's master password or enter a custom password for the existing
|
||||
Choose whether to use Zerobyte's master password or enter a custom password for the existing
|
||||
repository.
|
||||
</FormDescription>
|
||||
</FormItem>
|
||||
@@ -266,7 +266,7 @@ export const CreateRepositoryForm = ({
|
||||
<FormLabel>Repository Directory</FormLabel>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex-1 text-sm font-mono bg-muted px-3 py-2 rounded-md border">
|
||||
{form.watch("path") || "/var/lib/ironmount/repositories"}
|
||||
{form.watch("path") || "/var/lib/zerobyte/repositories"}
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
@@ -299,7 +299,7 @@ export const CreateRepositoryForm = ({
|
||||
restarts.
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
The default path <code className="bg-muted px-1 rounded">/var/lib/ironmount/repositories</code> is
|
||||
The default path <code className="bg-muted px-1 rounded">/var/lib/zerobyte/repositories</code> is
|
||||
already mounted from the host and is safe to use.
|
||||
</p>
|
||||
</AlertDialogDescription>
|
||||
@@ -329,7 +329,7 @@ export const CreateRepositoryForm = ({
|
||||
<div className="py-4">
|
||||
<DirectoryBrowser
|
||||
onSelectPath={(path) => form.setValue("path", path)}
|
||||
selectedPath={form.watch("path") || "/var/lib/ironmount/repositories"}
|
||||
selectedPath={form.watch("path") || "/var/lib/zerobyte/repositories"}
|
||||
/>
|
||||
</div>
|
||||
<AlertDialogFooter>
|
||||
@@ -632,7 +632,7 @@ export const CreateRepositoryForm = ({
|
||||
<FormItem>
|
||||
<FormLabel>Path</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="backups/ironmount" {...field} />
|
||||
<Input placeholder="backups/zerobyte" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>Path within the remote where backups will be stored.</FormDescription>
|
||||
<FormMessage />
|
||||
|
||||
@@ -59,7 +59,7 @@ export default function Layout({ loaderData }: Route.ComponentProps) {
|
||||
</Button>
|
||||
<Button variant="default" size="sm" className="relative overflow-hidden hidden lg:inline-flex">
|
||||
<a
|
||||
href="https://github.com/nicotsx/ironmount/issues/new"
|
||||
href="https://github.com/nicotsx/zerobyte/issues/new"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="flex items-center gap-2"
|
||||
|
||||
@@ -16,7 +16,7 @@ export const clientMiddleware = [authMiddleware];
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Download Recovery Key" },
|
||||
{ title: "Zerobyte - Download Recovery Key" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Download your backup recovery key to ensure you can restore your data.",
|
||||
|
||||
@@ -16,10 +16,10 @@ export const clientMiddleware = [authMiddleware];
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Login" },
|
||||
{ title: "Zerobyte - Login" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Sign in to your Ironmount account.",
|
||||
content: "Sign in to your Zerobyte account.",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ export const clientMiddleware = [authMiddleware];
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Onboarding" },
|
||||
{ title: "Zerobyte - Onboarding" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Welcome to Ironmount. Create your admin account to get started.",
|
||||
content: "Welcome to Zerobyte. Create your admin account to get started.",
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -82,7 +82,7 @@ export default function OnboardingPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthLayout title="Welcome to Ironmount" description="Create the admin user to get started">
|
||||
<AuthLayout title="Welcome to Zerobyte" description="Create the admin user to get started">
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<FormField
|
||||
|
||||
@@ -40,7 +40,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Backup Job Details" },
|
||||
{ title: "Zerobyte - Backup Job Details" },
|
||||
{
|
||||
name: "description",
|
||||
content: "View and manage backup job configuration, schedule, and snapshots.",
|
||||
|
||||
@@ -15,7 +15,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Backup Jobs" },
|
||||
{ title: "Zerobyte - Backup Jobs" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Automate volume backups with scheduled jobs and retention policies.",
|
||||
|
||||
@@ -24,7 +24,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Create Backup Job" },
|
||||
{ title: "Zerobyte - Create Backup Job" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Create a new automated backup job for your volumes.",
|
||||
|
||||
@@ -17,7 +17,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Create Repository" },
|
||||
{ title: "Zerobyte - Create Repository" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Create a new backup repository with encryption and compression.",
|
||||
|
||||
@@ -20,7 +20,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Repositories" },
|
||||
{ title: "Zerobyte - Repositories" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Manage your backup repositories with encryption and compression.",
|
||||
|
||||
@@ -36,7 +36,7 @@ export const handle = {
|
||||
|
||||
export function meta({ params }: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: `Ironmount - ${params.name}` },
|
||||
{ title: `Zerobyte - ${params.name}` },
|
||||
{
|
||||
name: "description",
|
||||
content: "View repository configuration, status, and snapshots.",
|
||||
|
||||
@@ -17,7 +17,7 @@ export const handle = {
|
||||
|
||||
export function meta({ params }: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: `Ironmount - Snapshot ${params.snapshotId}` },
|
||||
{ title: `Zerobyte - Snapshot ${params.snapshotId}` },
|
||||
{
|
||||
name: "description",
|
||||
content: "Browse and restore files from a backup snapshot.",
|
||||
|
||||
@@ -30,7 +30,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Settings" },
|
||||
{ title: "Zerobyte - Settings" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Manage your account settings and preferences.",
|
||||
|
||||
@@ -17,7 +17,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Create Volume" },
|
||||
{ title: "Zerobyte - Create Volume" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Create a new storage volume with automatic mounting and health checks.",
|
||||
|
||||
@@ -37,7 +37,7 @@ export const handle = {
|
||||
|
||||
export function meta({ params }: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: `Ironmount - ${params.name}` },
|
||||
{ title: `Zerobyte - ${params.name}` },
|
||||
{
|
||||
name: "description",
|
||||
content: "View and manage volume details, configuration, and files.",
|
||||
|
||||
@@ -20,7 +20,7 @@ export const handle = {
|
||||
|
||||
export function meta(_: Route.MetaArgs) {
|
||||
return [
|
||||
{ title: "Ironmount - Volumes" },
|
||||
{ title: "Zerobyte - Volumes" },
|
||||
{
|
||||
name: "description",
|
||||
content: "Create, manage, monitor, and automate your Docker volumes with ease.",
|
||||
|
||||
@@ -46,7 +46,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
||||
<link rel="icon" type="image/svg+xml" href="/images/favicon/favicon.svg" />
|
||||
<link rel="shortcut icon" href="/images/favicon/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/images/favicon/apple-touch-icon.png" />
|
||||
<meta name="apple-mobile-web-app-title" content="Ironmount" />
|
||||
<meta name="apple-mobile-web-app-title" content="Zerobyte" />
|
||||
<link rel="manifest" href="/images/favicon/site.webmanifest" />
|
||||
<Meta />
|
||||
<Links />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export const OPERATION_TIMEOUT = 5000;
|
||||
export const VOLUME_MOUNT_BASE = "/var/lib/ironmount/volumes";
|
||||
export const REPOSITORY_BASE = "/var/lib/ironmount/repositories";
|
||||
export const DATABASE_URL = "/var/lib/ironmount/data/ironmount.db";
|
||||
export const RESTIC_PASS_FILE = "/var/lib/ironmount/data/restic.pass";
|
||||
export const SOCKET_PATH = "/run/docker/plugins/ironmount.sock";
|
||||
export const VOLUME_MOUNT_BASE = "/var/lib/zerobyte/volumes";
|
||||
export const REPOSITORY_BASE = "/var/lib/zerobyte/repositories";
|
||||
export const DATABASE_URL = "/var/lib/zerobyte/data/ironmount.db";
|
||||
export const RESTIC_PASS_FILE = "/var/lib/zerobyte/data/restic.pass";
|
||||
export const SOCKET_PATH = "/run/docker/plugins/zerobyte.sock";
|
||||
|
||||
@@ -24,7 +24,7 @@ export const generalDescriptor = (app: Hono) =>
|
||||
openAPIRouteHandler(app, {
|
||||
documentation: {
|
||||
info: {
|
||||
title: "Ironmount API",
|
||||
title: "Zerobyte API",
|
||||
version: "1.0.0",
|
||||
description: "API for managing volumes",
|
||||
},
|
||||
@@ -33,8 +33,8 @@ export const generalDescriptor = (app: Hono) =>
|
||||
});
|
||||
|
||||
export const scalarDescriptor = Scalar({
|
||||
title: "Ironmount API Docs",
|
||||
pageTitle: "Ironmount API Docs",
|
||||
title: "Zerobyte API Docs",
|
||||
pageTitle: "Zerobyte API Docs",
|
||||
url: "/api/v1/openapi.json",
|
||||
});
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export class CleanupDanglingMountsJob extends Job {
|
||||
const allSystemMounts = await readMountInfo();
|
||||
|
||||
for (const mount of allSystemMounts) {
|
||||
if (mount.mountPoint.includes("ironmount") && mount.mountPoint.endsWith("_data")) {
|
||||
if (mount.mountPoint.includes("zerobyte") && mount.mountPoint.endsWith("_data")) {
|
||||
const matchingVolume = allVolumes.find((v) => getVolumePath(v) === mount.mountPoint);
|
||||
if (!matchingVolume) {
|
||||
logger.info(`Found dangling mount at ${mount.mountPoint}, attempting to unmount...`);
|
||||
@@ -32,9 +32,9 @@ export class CleanupDanglingMountsJob extends Job {
|
||||
}
|
||||
}
|
||||
|
||||
const allIronmountDirs = await fs.readdir(VOLUME_MOUNT_BASE).catch(() => []);
|
||||
const allZerobyteDirs = await fs.readdir(VOLUME_MOUNT_BASE).catch(() => []);
|
||||
|
||||
for (const dir of allIronmountDirs) {
|
||||
for (const dir of allZerobyteDirs) {
|
||||
const volumePath = `${VOLUME_MOUNT_BASE}/${dir}/_data`;
|
||||
const matchingVolume = allVolumes.find((v) => getVolumePath(v) === volumePath);
|
||||
if (!matchingVolume) {
|
||||
|
||||
@@ -30,7 +30,7 @@ export const driverController = new Hono()
|
||||
return c.json({ Err: "Volume name is required" }, 400);
|
||||
}
|
||||
|
||||
const volumeName = body.Name.replace(/^im-/, "");
|
||||
const volumeName = body.Name.replace(/^zb-/, "");
|
||||
|
||||
return c.json({
|
||||
Mountpoint: getVolumePath(volumeName),
|
||||
@@ -48,7 +48,7 @@ export const driverController = new Hono()
|
||||
return c.json({ Err: "Volume name is required" }, 400);
|
||||
}
|
||||
|
||||
const { volume } = await volumeService.getVolume(body.Name.replace(/^im-/, ""));
|
||||
const { volume } = await volumeService.getVolume(body.Name.replace(/^zb-/, ""));
|
||||
|
||||
return c.json({
|
||||
Mountpoint: getVolumePath(volume),
|
||||
@@ -61,11 +61,11 @@ export const driverController = new Hono()
|
||||
return c.json({ Err: "Volume name is required" }, 400);
|
||||
}
|
||||
|
||||
const { volume } = await volumeService.getVolume(body.Name.replace(/^im-/, ""));
|
||||
const { volume } = await volumeService.getVolume(body.Name.replace(/^zb-/, ""));
|
||||
|
||||
return c.json({
|
||||
Volume: {
|
||||
Name: `im-${volume.name}`,
|
||||
Name: `zb-${volume.name}`,
|
||||
Mountpoint: getVolumePath(volume),
|
||||
Status: {},
|
||||
},
|
||||
@@ -76,7 +76,7 @@ export const driverController = new Hono()
|
||||
const volumes = await volumeService.listVolumes();
|
||||
|
||||
const res = volumes.map((volume) => ({
|
||||
Name: `im-${volume.name}`,
|
||||
Name: `zb-${volume.name}`,
|
||||
Mountpoint: getVolumePath(volume),
|
||||
Status: {},
|
||||
}));
|
||||
|
||||
@@ -186,7 +186,7 @@ const updateVolume = async (name: string, volumeData: UpdateVolumeBody) => {
|
||||
};
|
||||
|
||||
const testConnection = async (backendConfig: BackendConfig) => {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "ironmount-test-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "zerobyte-test-"));
|
||||
|
||||
const mockVolume = {
|
||||
id: 0,
|
||||
|
||||
@@ -96,13 +96,13 @@ const buildRepoUrl = (config: RepositoryConfig): string => {
|
||||
|
||||
const buildEnv = async (config: RepositoryConfig) => {
|
||||
const env: Record<string, string> = {
|
||||
RESTIC_CACHE_DIR: "/var/lib/ironmount/restic/cache",
|
||||
RESTIC_CACHE_DIR: "/var/lib/zerobyte/restic/cache",
|
||||
PATH: process.env.PATH || "/usr/local/bin:/usr/bin:/bin",
|
||||
};
|
||||
|
||||
if (config.isExistingRepository && config.customPassword) {
|
||||
const decryptedPassword = await cryptoUtils.decrypt(config.customPassword);
|
||||
const passwordFilePath = path.join("/tmp", `ironmount-pass-${crypto.randomBytes(8).toString("hex")}.txt`);
|
||||
const passwordFilePath = path.join("/tmp", `zerobyte-pass-${crypto.randomBytes(8).toString("hex")}.txt`);
|
||||
|
||||
await fs.writeFile(passwordFilePath, decryptedPassword, { mode: 0o600 });
|
||||
env.RESTIC_PASSWORD_FILE = passwordFilePath;
|
||||
@@ -123,7 +123,7 @@ const buildEnv = async (config: RepositoryConfig) => {
|
||||
break;
|
||||
case "gcs": {
|
||||
const decryptedCredentials = await cryptoUtils.decrypt(config.credentialsJson);
|
||||
const credentialsPath = path.join("/tmp", `ironmount-gcs-${crypto.randomBytes(8).toString("hex")}.json`);
|
||||
const credentialsPath = path.join("/tmp", `zerobyte-gcs-${crypto.randomBytes(8).toString("hex")}.json`);
|
||||
await fs.writeFile(credentialsPath, decryptedCredentials, { mode: 0o600 });
|
||||
env.GOOGLE_PROJECT_ID = config.projectId;
|
||||
env.GOOGLE_APPLICATION_CREDENTIALS = credentialsPath;
|
||||
|
||||
Reference in New Issue
Block a user