Rewrite README and Manual front pages in project voice
The repo front page read like generic documentation rather than a record of why any of this exists. Adds the origin story, the current honest state, real failure history, and fixes drift in platform_*() naming, the fallback tier variable pattern, and the Plugin/unraid script locations.
This commit is contained in:
@@ -23,6 +23,51 @@ correct adapter. The scripts themselves never branch on the OS.
|
||||
|
||||
---
|
||||
|
||||
## ━━━ HOW THIS GOT HERE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
**One server. One script. Three lines.**
|
||||
|
||||
That's genuinely where this started. Something needed doing on a schedule, so I wrote three
|
||||
lines and moved on.
|
||||
|
||||
Then it was two servers, 50 miles apart, and about **60 scripts** with nothing holding them
|
||||
together. Every one standalone. Every one with its own hardcoded paths, its own container
|
||||
names, its own idea of how to log something or send a notification.
|
||||
|
||||
**And it worked.** That's the part worth saying. The stack stayed up, the media kept playing,
|
||||
the backups kept running. It was not broken.
|
||||
|
||||
It was just *miserable to change.*
|
||||
|
||||
Every adjustment meant finding every script that touched the thing, on both machines, and
|
||||
editing each one the same way — then hoping I'd found them all. Miss one and it didn't error.
|
||||
It just quietly kept doing the old thing until I noticed weeks later. Two servers meant two
|
||||
copies of every mistake, and the two copies drifted apart a little more every time I touched
|
||||
them.
|
||||
|
||||
So it got rebuilt, in roughly this order:
|
||||
|
||||
```
|
||||
git stop editing live scripts on two machines and calling it version control
|
||||
common.sh one place for log, notify, locking, host detection, retries
|
||||
master.conf thresholds and toggles — shared, one copy
|
||||
host*.conf credentials, paths, container names — per server
|
||||
load_config.sh sources all of it, in the right order, at the top of every script
|
||||
```
|
||||
|
||||
Then the long part: refactoring 60 standalone scripts into that shape, one at a time, until
|
||||
every value lived in a conf file and every shared behaviour lived in `common.sh`. Change the
|
||||
retry count once, every script gets it. Rename a container in one place, everything follows.
|
||||
|
||||
That is the whole idea, and it's why the structure looks the way it does. The three-file
|
||||
config model and the shared library aren't design patterns picked out of a book — they're
|
||||
the specific answer to "I have 60 scripts on two machines and I'm scared to touch any of
|
||||
them."
|
||||
|
||||
That became Varaverk.
|
||||
|
||||
---
|
||||
|
||||
## ━━━ WHERE THIS ACTUALLY IS RIGHT NOW ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
This is a live system, not a finished product. HOST1 has been running the whole stack
|
||||
@@ -57,7 +102,7 @@ HOST1 — unRAID-Gmer4Lfe
|
||||
|
||||
HOST2 — unRAID-Jayred365
|
||||
Hardware: Intel i5 10th gen, 64GB RAM
|
||||
Location: Remote — different building, different power utility
|
||||
Location: Remote — 50 miles away, different power utility and ISP
|
||||
Domain: Gmer4Lfe.us
|
||||
Arrs: Anime_Shows, Anime_Movies — union with HOST1 via arr_sync
|
||||
His own Emby — for his household
|
||||
@@ -173,6 +218,10 @@ as sync targets and mount points — a mismatch is a broken path.
|
||||
|
||||
## ━━━ THE MEDIA LIBRARY MODEL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Two households, one library, and a hard line between "our media" and "your stuff." Everything
|
||||
in this section comes down to that split — media is pooled and shared freely, personal data
|
||||
never is, and no script gets to blur the two.
|
||||
|
||||
### ── Common Libraries — Shared Pool ─────────────────────────────────────────
|
||||
|
||||
Common media like Movies, Music, and TV Shows are a **shared pool**. Every container
|
||||
@@ -257,8 +306,13 @@ across separate shares per-user or per-application.
|
||||
|
||||
## ━━━ WHAT SYNCS AND WHAT DOESN'T ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Not everything needs to sync. Not everything should sync. Understanding what goes
|
||||
where determines whether you need encryption and whether sync failure matters.
|
||||
Not everything needs to sync. Not everything *should*. Two households means some of this
|
||||
data is mine, some of it is his, and some of it belongs to both of us — and treating all
|
||||
three the same way is how you end up either leaking someone's photos or losing the thing you
|
||||
actually needed a copy of.
|
||||
|
||||
Where a piece of data lands in this table decides two things: whether it needs encryption,
|
||||
and whether a failed sync is something to fix tonight or something to shrug at.
|
||||
|
||||
---
|
||||
|
||||
@@ -504,6 +558,15 @@ Monitoring:
|
||||
|
||||
## ━━━ FOLDER STRUCTURE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Folders are grouped by **what a script does to the system**, not by which service it happens
|
||||
to talk to. There's no `Sonarr/` folder — cleaning up after Sonarr is media work, watching
|
||||
whether its container is alive is watchdog work, and those two things belong next to their
|
||||
own kind.
|
||||
|
||||
Every folder has its own README explaining the group, and every script has a header
|
||||
explaining itself. If you're looking for one specific thing, the README reference near the
|
||||
bottom of this page is the faster route.
|
||||
|
||||
```
|
||||
varaverk/
|
||||
│
|
||||
@@ -563,6 +626,16 @@ varaverk/
|
||||
|
||||
## ━━━ CONFIGURATION — Configurations/ FOLDER, THREE FILES ━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
This is the part that fixed the 60-script problem. Three files, one rule:
|
||||
|
||||
**Thresholds and toggles go in `master.conf`. Credentials, paths and container names go in
|
||||
`host*.conf`.** If you find yourself about to hardcode a value in a script, it belongs in one
|
||||
of these instead — that's the whole discipline, and everything else follows from it.
|
||||
|
||||
Sparse checkout means each server only ever receives its own `host*.conf`. HOST1 never has
|
||||
HOST2's credentials sitting on disk, and vice versa. The partner's conf arrives at runtime
|
||||
through the RAM cache, which is why `conf_sync.sh` exists.
|
||||
|
||||
```bash
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# All three conf files live in Configurations/. load_config.sh sources them.
|
||||
@@ -642,7 +715,8 @@ Every 4 hours:
|
||||
|
||||
2:30am Sunday:
|
||||
weekly_sync_maintenance.sh stop → update images → clean sync → start → weekly restarts
|
||||
+ playback_aware_lidarr/radarr/sonarr_discovery.sh (behavior-driven arr discovery)
|
||||
+ playback_aware_{lidarr,radarr,sonarr}_discovery.sh
|
||||
(behaviour-driven discovery from real playback history)
|
||||
|
||||
8am daily:
|
||||
weekly_health_digest.sh DIGEST_PROFILE controls when it actually notifies
|
||||
@@ -714,8 +788,9 @@ restart lands on the new image. Change the order and things break quietly rather
|
||||
|
||||
## ━━━ THE SELF-HEALING STACK ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
Problems are handled at the most appropriate level. Scripts escalate only when the
|
||||
level below them has failed:
|
||||
Nothing here jumps straight to the big hammer. Each layer only gets involved because the one
|
||||
below it already tried and failed — and the layer holding the biggest hammer, the one that
|
||||
can reboot the box, is the most reluctant of all:
|
||||
|
||||
```
|
||||
Problem: Emby container using 22GB RAM (limit: 18GB)
|
||||
@@ -833,7 +908,12 @@ CPU-based) instead of PaddleOCR. Same plugin, no VRAM.
|
||||
|
||||
## ━━━ SETUP — WHERE TO START ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
|
||||
If you're setting this up from scratch on two servers:
|
||||
If you're setting this up from scratch on two servers, the order below is not a suggestion.
|
||||
Steps 2 and 3 are cheap now and expensive later — renaming a container or a share after the
|
||||
confs, the fallback tiers and the sync profiles all reference it means touching every one of
|
||||
them, and missing one doesn't error.
|
||||
|
||||
Do the naming first. Everything after it assumes the names are already right.
|
||||
|
||||
```
|
||||
1. Follow Manual.md — end-to-end setup guide
|
||||
@@ -854,6 +934,11 @@ If you're setting this up from scratch on two servers:
|
||||
bash fallback_test.sh when ready — uses iptables simulation, no real downtime
|
||||
```
|
||||
|
||||
**Do step 5.** Untested failover isn't redundancy, it's a belief. `fallback_test.sh` simulates
|
||||
the outage with iptables rather than actually pulling the other server down, so there's no
|
||||
excuse not to run it — and finding out your tier lists have a typo is a lot nicer on a Tuesday
|
||||
afternoon than at 2am when the power's actually out.
|
||||
|
||||
---
|
||||
|
||||
## ━━━ FOLDER README REFERENCE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
@@ -976,15 +1061,18 @@ Every one of these cost me something to learn. Reading them here is cheaper.
|
||||
# --dry-run --log first on a new system. README-Media.md has the full procedure.
|
||||
|
||||
# 9. Scripts never call OS commands directly.
|
||||
# All platform-specific operations go through plugin_*() functions defined in
|
||||
# All platform-specific operations go through platform_*() functions defined in
|
||||
# Plugin/$PLATFORM/adapter.sh. rc.d scripts, emhttp, dynamix, disks.ini — all
|
||||
# isolated in the adapter. This is what makes the codebase portable.
|
||||
# Adding a new OS = writing one adapter file, not patching dozens of scripts.
|
||||
|
||||
# 10. System_Essentials/ is platform-agnostic at the script level.
|
||||
# Scripts like server_reboot.sh, mover_stop.sh, and webgui_watchdog.sh call
|
||||
# adapter functions (platform_is_mover_running, platform_restart_service, etc.)
|
||||
# The adapter handles what those mean on the actual OS. The scripts are clean.
|
||||
# 10. Top-level System_Essentials/ is platform-agnostic. Plugin/unraid/ is not.
|
||||
# server_reboot.sh lives at the top level and calls adapter functions only —
|
||||
# platform_is_mover_running, platform_restart_service. It never names an OS.
|
||||
# Scripts that manipulate an Unraid subsystem directly — mover_stop.sh,
|
||||
# webgui_watchdog.sh, php_fpm_max_children.sh — live under Plugin/unraid/
|
||||
# instead, because there is no generic version of them to write.
|
||||
# Which folder a script is in tells you whether it survives a platform change.
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
@@ -996,4 +1084,13 @@ Every one of these cost me something to learn. Reading them here is cheaper.
|
||||
Name: Varaverk
|
||||
Repository: git@192.168.50.2:FailedProxy/Varaverk.git
|
||||
Install path: /boot/config/plugins/varaverk
|
||||
```
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
This is a home media stack for two households. It is not an enterprise product, it doesn't
|
||||
want to be one, and it makes trade-offs no enterprise would accept — because the thing it's
|
||||
actually optimising for is that nobody in either house has to know any of this exists.
|
||||
|
||||
The measure of success here isn't uptime percentages. It's that the power goes out 50 miles
|
||||
away, and the show keeps playing.
|
||||
Reference in New Issue
Block a user