mirror of
https://github.com/nicotsx/ironmount.git
synced 2025-12-10 12:10:51 +01:00
Compare commits
10 Commits
altendorfm
...
v0.8.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d78b4adfd9 | ||
|
|
4d3ec524e2 | ||
|
|
681cf5dff1 | ||
|
|
31da747c2d | ||
|
|
b86081b2e8 | ||
|
|
3622fd57ef | ||
|
|
5b1d7eff17 | ||
|
|
2b3d8dffc5 | ||
|
|
1ddd4d701b | ||
|
|
9a1797b8b2 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -9,3 +9,6 @@
|
|||||||
.env
|
.env
|
||||||
.turbo
|
.turbo
|
||||||
CLAUDE.md
|
CLAUDE.md
|
||||||
|
|
||||||
|
mutagen.yml.lock
|
||||||
|
notes.md
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -36,7 +36,7 @@ In order to run Ironmount, you need to have Docker and Docker Compose installed
|
|||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
ironmount:
|
ironmount:
|
||||||
image: ghcr.io/nicotsx/ironmount:v0.7
|
image: ghcr.io/nicotsx/ironmount:v0.8
|
||||||
container_name: ironmount
|
container_name: ironmount
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
@@ -68,7 +68,7 @@ If you want to track a local directory on the same server where Ironmount is run
|
|||||||
```diff
|
```diff
|
||||||
services:
|
services:
|
||||||
ironmount:
|
ironmount:
|
||||||
image: ghcr.io/nicotsx/ironmount:v0.7
|
image: ghcr.io/nicotsx/ironmount:v0.8
|
||||||
container_name: ironmount
|
container_name: ironmount
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
@@ -133,7 +133,7 @@ Ironmount can use [rclone](https://rclone.org/) to support 40+ cloud storage pro
|
|||||||
```diff
|
```diff
|
||||||
services:
|
services:
|
||||||
ironmount:
|
ironmount:
|
||||||
image: ghcr.io/nicotsx/ironmount:v0.7
|
image: ghcr.io/nicotsx/ironmount:v0.8
|
||||||
container_name: ironmount
|
container_name: ironmount
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
@@ -189,7 +189,7 @@ In order to enable this feature, you need to change your bind mount `/var/lib/ir
|
|||||||
```diff
|
```diff
|
||||||
services:
|
services:
|
||||||
ironmount:
|
ironmount:
|
||||||
image: ghcr.io/nicotsx/ironmount:v0.7
|
image: ghcr.io/nicotsx/ironmount:v0.8
|
||||||
container_name: ironmount
|
container_name: ironmount
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
@@ -217,7 +217,7 @@ In order to enable this feature, you need to run Ironmount with several items sh
|
|||||||
```diff
|
```diff
|
||||||
services:
|
services:
|
||||||
ironmount:
|
ironmount:
|
||||||
image: ghcr.io/nicotsx/ironmount:v0.7
|
image: ghcr.io/nicotsx/ironmount:v0.8
|
||||||
container_name: ironmount
|
container_name: ironmount
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
cap_add:
|
cap_add:
|
||||||
|
|||||||
@@ -536,6 +536,7 @@ export const CreateVolumeForm = ({ onSubmit, mode = "create", initialValues, for
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{watchedBackend !== "directory" && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
@@ -572,6 +573,7 @@ export const CreateVolumeForm = ({ onSubmit, mode = "create", initialValues, for
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
{mode === "update" && (
|
{mode === "update" && (
|
||||||
<Button type="submit" className="w-full" loading={loading}>
|
<Button type="submit" className="w-full" loading={loading}>
|
||||||
Save Changes
|
Save Changes
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
|
|||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Backup paths</CardTitle>
|
<CardTitle>Backup paths</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Select which folders to include in the backup. If no paths are selected, the entire volume will be
|
Select which folders or files to include in the backup. If no paths are selected, the entire volume will be
|
||||||
backed up.
|
backed up.
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
@@ -264,7 +264,7 @@ export const CreateScheduleForm = ({ initialValues, formId, onSubmit, volume }:
|
|||||||
selectedPaths={selectedPaths}
|
selectedPaths={selectedPaths}
|
||||||
onSelectionChange={handleSelectionChange}
|
onSelectionChange={handleSelectionChange}
|
||||||
withCheckboxes={true}
|
withCheckboxes={true}
|
||||||
foldersOnly={true}
|
foldersOnly={false}
|
||||||
className="flex-1 border rounded-md bg-card p-2 min-h-[300px] max-h-[400px] overflow-auto"
|
className="flex-1 border rounded-md bg-card p-2 min-h-[300px] max-h-[400px] overflow-auto"
|
||||||
/>
|
/>
|
||||||
{selectedPaths.size > 0 && (
|
{selectedPaths.size > 0 && (
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ export class CleanupDanglingMountsJob extends Job {
|
|||||||
const matchingVolume = allVolumes.find((v) => getVolumePath(v) === mount.mountPoint);
|
const matchingVolume = allVolumes.find((v) => getVolumePath(v) === mount.mountPoint);
|
||||||
if (!matchingVolume) {
|
if (!matchingVolume) {
|
||||||
logger.info(`Found dangling mount at ${mount.mountPoint}, attempting to unmount...`);
|
logger.info(`Found dangling mount at ${mount.mountPoint}, attempting to unmount...`);
|
||||||
await executeUnmount(mount.mountPoint);
|
await executeUnmount(mount.mountPoint).catch((err) => {
|
||||||
|
logger.warn(`Failed to unmount dangling mount ${mount.mountPoint}: ${toMessage(err)}`);
|
||||||
|
});
|
||||||
|
|
||||||
await fs.rmdir(path.dirname(mount.mountPoint)).catch((err) => {
|
await fs.rmdir(path.dirname(mount.mountPoint)).catch((err) => {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ export const executeMount = async (args: string[]): Promise<void> => {
|
|||||||
if (stderr?.trim()) {
|
if (stderr?.trim()) {
|
||||||
logger.warn(stderr.trim());
|
logger.warn(stderr.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.exitCode !== 0) {
|
||||||
|
throw new Error(`Mount command failed with exit code ${result.exitCode}: ${stderr?.trim()}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const executeUnmount = async (path: string): Promise<void> => {
|
export const executeUnmount = async (path: string): Promise<void> => {
|
||||||
@@ -24,6 +28,10 @@ export const executeUnmount = async (path: string): Promise<void> => {
|
|||||||
if (stderr?.trim()) {
|
if (stderr?.trim()) {
|
||||||
logger.warn(stderr.trim());
|
logger.warn(stderr.trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.exitCode !== 0) {
|
||||||
|
throw new Error(`Mount command failed with exit code ${result.exitCode}: ${stderr?.trim()}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createTestFile = async (path: string): Promise<void> => {
|
export const createTestFile = async (path: string): Promise<void> => {
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ services:
|
|||||||
|
|
||||||
- ./app:/app/app
|
- ./app:/app/app
|
||||||
- ~/.config/rclone:/root/.config/rclone
|
- ~/.config/rclone:/root/.config/rclone
|
||||||
|
- /var/lib/ironmount:/var/lib/ironmount:rshared
|
||||||
|
- /run/docker/plugins:/run/docker/plugins
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
|
||||||
ironmount-prod:
|
ironmount-prod:
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
proj_Nwis7nYU1DiPGTtNlwRKBVtdgo5cOWPsnwbtxj2Urg0
|
|
||||||
Reference in New Issue
Block a user