Hello,
First of all: thank you for publishing this. I went looking for something that
archives to LTFS and leaves self-describing tapes behind — tapes that still mean
something without the appliance that wrote them — and this is the only project I
found that takes that seriously. That property is the reason I am here.
I have been running it in a homelab since spring on real hardware, and I ended up
maintaining a fork to get there. This issue is not a request for anything; it is
an offer, in case any of it is useful to you.
Environment
- Ubuntu 24.04 LTS, Python 3.12
- IBM ULTRIUM-HH7 (LTO-7 half-height SAS, drive only, no changer)
- Sources over CIFS/SMB from a NAS
- Roughly 40 TB of replaceable media plus a smaller set of private data
What the fork changes
The bulk of it is installation and runtime work needed to get a clean start on
Ubuntu 24.04 — systemd unit, sudoers rules for the mount helpers, the installer
itself, gunicorn settings. Beyond that a number of behavioural fixes, of which
these are the ones I would look at first if I were you:
- Files that fail to write are recorded as backed up and are never retried.
A partial run reports completed and writes the full scan result into the
snapshot, so the next incremental skips the failed files as unchanged — for
good, as long as they do not change on the source. Reproducible in a few lines
without tape hardware. I will open this as a separate issue with the details.
search_archived_files truncates at LIMIT 1000 with no pagination and no
indication in the UI. For a small archive this is invisible; at archive scale
the restore browser silently shows a fraction of what is on tape.
FOSSILSAFE_CATALOG.json is written to a fixed name at the volume root, so
on a tape holding more than one job only the last one describes itself. That
weakens the disaster-recovery path, and the self-describing tape is what makes
the project distinctive.
- The catalog export does not include the snapshot manifests. The database
rows only carry a manifest_path; the per-file state an incremental compares
against lives in JSON files under the data dir, which nothing backs up. Restore
the database alone and the chain silently restarts as a full backup.
restore_from_external_catalog reads and verifies the JSON catalog but does
not restore the database or config that write_catalog_to_tape puts on tape.
One smaller observation, take it or leave it: the restore browser is search-first,
which works well when you know the file name. Browsing a directory tree and
restoring a whole folder in one action is currently awkward, and that is the more
common case for me. I mention it only as a user report — the version-per-path
question it raises is yours to decide, not mine.
How this was produced
I should be upfront: the fixes were developed with substantial help from an AI
assistant, working from the code and from failures observed on real hardware.
Every change is backed by a regression test that fails without it, and everything
runs on my own archive before I would suggest it to anyone. If AI-assisted
contributions are not something you want in the project, tell me and I will keep
the fork to myself — no hard feelings either way.
If you want any of it
The fork is currently a patch series against 1e228fe. I have deliberately not
opened pull requests, because a single cumulative diff is not reviewable and I do
not want to dump work on a solo maintainer uninvited. If you are interested, I
will split it into one branch per fix, each with its test and a DCO sign-off, and
open them one at a time at whatever pace suits you.
If the project is resting for now, that is entirely fine — I will keep the fork
running for my own archive either way, and the notes above stay here in case they
save someone else the debugging.
Hello,
First of all: thank you for publishing this. I went looking for something that
archives to LTFS and leaves self-describing tapes behind — tapes that still mean
something without the appliance that wrote them — and this is the only project I
found that takes that seriously. That property is the reason I am here.
I have been running it in a homelab since spring on real hardware, and I ended up
maintaining a fork to get there. This issue is not a request for anything; it is
an offer, in case any of it is useful to you.
Environment
What the fork changes
The bulk of it is installation and runtime work needed to get a clean start on
Ubuntu 24.04 — systemd unit, sudoers rules for the mount helpers, the installer
itself, gunicorn settings. Beyond that a number of behavioural fixes, of which
these are the ones I would look at first if I were you:
A partial run reports
completedand writes the full scan result into thesnapshot, so the next incremental skips the failed files as unchanged — for
good, as long as they do not change on the source. Reproducible in a few lines
without tape hardware. I will open this as a separate issue with the details.
search_archived_filestruncates atLIMIT 1000with no pagination and noindication in the UI. For a small archive this is invisible; at archive scale
the restore browser silently shows a fraction of what is on tape.
FOSSILSAFE_CATALOG.jsonis written to a fixed name at the volume root, soon a tape holding more than one job only the last one describes itself. That
weakens the disaster-recovery path, and the self-describing tape is what makes
the project distinctive.
rows only carry a
manifest_path; the per-file state an incremental comparesagainst lives in JSON files under the data dir, which nothing backs up. Restore
the database alone and the chain silently restarts as a full backup.
restore_from_external_catalogreads and verifies the JSON catalog but doesnot restore the database or config that
write_catalog_to_tapeputs on tape.One smaller observation, take it or leave it: the restore browser is search-first,
which works well when you know the file name. Browsing a directory tree and
restoring a whole folder in one action is currently awkward, and that is the more
common case for me. I mention it only as a user report — the version-per-path
question it raises is yours to decide, not mine.
How this was produced
I should be upfront: the fixes were developed with substantial help from an AI
assistant, working from the code and from failures observed on real hardware.
Every change is backed by a regression test that fails without it, and everything
runs on my own archive before I would suggest it to anyone. If AI-assisted
contributions are not something you want in the project, tell me and I will keep
the fork to myself — no hard feelings either way.
If you want any of it
The fork is currently a patch series against
1e228fe. I have deliberately notopened pull requests, because a single cumulative diff is not reviewable and I do
not want to dump work on a solo maintainer uninvited. If you are interested, I
will split it into one branch per fix, each with its test and a DCO sign-off, and
open them one at a time at whatever pace suits you.
If the project is resting for now, that is entirely fine — I will keep the fork
running for my own archive either way, and the notes above stay here in case they
save someone else the debugging.