Compare commits

..

10 Commits

Author SHA1 Message Date
Nicolas Meienberger
d78b4adfd9 chore: update readme 2025-11-15 10:37:35 +01:00
Nicolas Meienberger
4d3ec524e2 chore: add all caps for dev container 2025-11-15 10:23:15 +01:00
Nicolas Meienberger
681cf5dff1 fix: hide test-connection button for directories 2025-11-15 10:15:25 +01:00
Nicolas Meienberger
31da747c2d fix: mount and unmount command not properly throwing errors 2025-11-15 10:08:16 +01:00
Nicolas Meienberger
b86081b2e8 Merge branch 'altendorfme-backup-file-path' 2025-11-15 09:51:05 +01:00
Nicolas Meienberger
3622fd57ef refactor(repository): keep the error if repo is already init 2025-11-15 09:45:04 +01:00
Nicolas Meienberger
5b1d7eff17 chore: update .gitignore 2025-11-15 09:45:04 +01:00
Nicolas Meienberger
2b3d8dffc5 Merge branch 'altendorfme-main' 2025-11-15 09:42:50 +01:00
Nicolas Meienberger
1ddd4d701b chore: update .gitignore 2025-11-15 09:39:49 +01:00
Renan Bernordi
9a1797b8b2 backup file and folders 2025-11-14 23:21:13 -03:00
9 changed files with 61 additions and 48 deletions

3
.gitignore vendored
View File

@@ -9,3 +9,6 @@
.env .env
.turbo .turbo
CLAUDE.md CLAUDE.md
mutagen.yml.lock
notes.md

View File

@@ -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:

View File

@@ -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

View File

@@ -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 && (

View File

@@ -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(

View File

@@ -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> => {

View File

@@ -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:

View File

@@ -1 +0,0 @@
proj_Nwis7nYU1DiPGTtNlwRKBVtdgo5cOWPsnwbtxj2Urg0

View File

@@ -1,4 +0,0 @@
docker run --rm -it -v nicolas:/data alpine sh -lc 'echo hello > /data/hi && cat /data/hi'
mount -t davfs http://192.168.2.42 /mnt/webdav