Hand cron over from youtube-automate, and script the rest

Cron now calls `ytstream run` hourly and ytstream's update-ytdlp.sh weekly.
Both inherit youtube-automate's healthchecks UUIDs and keep its schedules
unchanged: a check may be configured with a cron expression rather than a
simple period, so moving to the :23/04:50 slots the fragment proposed could
have alerted on a job that ran fine. Inheriting also means the placeholder
UUIDs never needed filling in.

The old service turned out to track only 2 channels, and one of them --
The Pyramid Podcast -- was sitting unresolved in ytstream's approval queue.
Decommissioning without checking would have silently dropped half of what
the old service existed to follow. Approved and backfilled.

decommission.sh does the two steps needing root (nginx repoint, disable the
unit) and refuses until an admin password is set, because the UI fails
closed and the hostname would otherwise serve a login nobody can pass.
Deleting the 2.0 GB of old downloads and touching the Jellyfin libraries
are left out on purpose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-08-13 10:53:48 +01:00
parent b35b6a3689
commit c7a80d200e
3 changed files with 165 additions and 7 deletions
+55
View File
@@ -1146,3 +1146,58 @@ budget only sums tracked sessions). The work root is a tmpfs, so that is leaked
until the next reboot — the restart that shipped the fix above would have stranded
1.56 GB. `reset_work_root()` now clears it at startup and logs what it reclaimed.
Session directories only; a stray file in the work root is left alone.
## 20. Decommissioning, done and outstanding — 2026-08-13
Started the same day the TTFB bug (§19) was fixed, which is earlier than §12 step 2
intended: that step says run both for a week, precisely so a bug like §19 surfaces
while the old service is still there to fall back on. Everything below is therefore
reversible, and the two irreversible steps are deliberately left undone.
### The old service was smaller than assumed
It tracked **2 channels** (Pitch Side, The Pyramid Podcast), 32 video rows, 9 files
on disk, 2.0 GB — not the 510 GB §12 step 6 estimated. All 32 fall inside
ytstream's 30-day window, so nothing in the old library is content ytstream cannot
reach.
**Pitch Side was already mirrored; The Pyramid Podcast was not** — it sat unresolved
in the approval queue, so decommissioning without checking would have silently
dropped one of the two channels the old service existed to follow. Approved, and it
backfilled 4 episodes. 11 channels now.
### Done
| step | what |
|---|---|
| §12.1 | Cron handed over: `youtube-automate run` → `ytstream run`, and `update-ytdlp.sh` repointed |
| §12.7 | `subs.db` copied to `/var/lib/ytstream/youtube-automate-subs.db.archived-20260813` |
| — | The Pyramid Podcast carried over |
**The two healthchecks UUIDs are inherited, not new,** and the schedules are
unchanged (`:17` hourly, Mondays `04:40`). A check may be configured with a cron
expression rather than a simple period, so moving to the `:23`/`04:50` slots the old
fragment proposed could have alerted on a job that ran fine. This also means no new
UUIDs were needed — the placeholder problem from §18 is gone. The checks are still
*named* after youtube-automate in the hc UI; renaming them there changes nothing.
First real proof of the rolling window, from that first run: **5 videos uploaded
2026-07-13 aged out** at 31 days, with 7 new ones discovered and materialised, in
7.5 s.
### Left for a human
`deploy/decommission.sh` does §12 steps 4 and 5 (nginx repoint to 8086, disable the
service) and **refuses to run until an admin password is set** — repointing a public
hostname at a UI that fails closed, as this one does with no password, produces a
site nobody can log into and an evening spent working out why.
Not scripted, because each destroys something:
* **`ytstream set-password`** — interactive, and blocks the above.
* **Jellyfin** (§12.3): remove *YouTube*, rename *YouTube (stream)* → *YouTube*.
Nothing in the code matches on the library *name* — `find_library()` matches on
path and `LIBRARY_NAME` is only `create_library`'s default — so the rename is safe
and the constant can stay as it is.
* **`/disks/Plex/YouTube`** (§12.6), 2.0 GB.
* **`/opt/youtube-automate`, its repo, `subs.db`, `specs.md`** — keep (§12.7).