feat(nh3-dev): /srv/nemi/books book drop (fiction/ nonfiction/ rejected/) for albok unit 8

This commit is contained in:
vh
2026-10-16 11:09:13 -07:00
parent d03e6353ab
commit eb2a0a532c
2 changed files with 50 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
# nh3-dev: /srv/nemi/books, the book drop Nemi validates into ~/library/<shelf>/ (albok unit 8; albok-dev 2026-10-16 after
# Prime: "build the books drop folder in nemi ... a rejection folder feels appropriate"). Same shape as /srv/nemi/inbox
# (playbooks/nh3-dev-nemi-inbox.yaml, which created group nemi-drop and /srv/nemi): Nemi moves each valid epub from
# fiction/ or nonfiction/ into ~/library/<shelf>/, and anything it refuses into rejected/ beside a reason file.
# scripts/elway infra-ops@10.100.10.50 --playbook playbooks/nh3-dev-nemi-books.yaml
# Writers: group nemi-drop (lkraven, infra-ops). Nemi runs as lkraven from the user manager, whose groups predate
# nemi-drop, so lkraven gets in through the u:lkraven ACL entries, NOT the group (see servers/nh3-dev/README.md).
steps:
- name: Prerequisites from the inbox playbook (group nemi-drop, /srv/nemi with u:lkraven:rx)
shell: |
getent group nemi-drop >/dev/null && test -d /srv/nemi && getfacl -p /srv/nemi | grep -q '^user:lkraven:r-x'
changed_when: "false"
- name: /srv/nemi/books and fiction/ nonfiction/ rejected/ (lkraven:nemi-drop 2770, same ACL as the inbox)
sudo: true
shell: |
for d in /srv/nemi/books /srv/nemi/books/fiction /srv/nemi/books/nonfiction /srv/nemi/books/rejected; do
install -d -o lkraven -g nemi-drop -m 2770 "$d"
setfacl -m u:lkraven:rwx,g:nemi-drop:rwx "$d"
setfacl -d -m u::rwX,u:lkraven:rwX,g::rwX,g:nemi-drop:rwX,o::--- "$d"
done
getfacl -p /srv/nemi/books
creates: /srv/nemi/books/rejected
verify:
- name: Nemi's own context (lkraven's systemd user manager, groups fixed at boot) can list every books dir
shell: runuser -u lkraven -- env XDG_RUNTIME_DIR=/run/user/1000 systemd-run --user --wait --pipe -q ls -ld /srv/nemi/books /srv/nemi/books/fiction /srv/nemi/books/nonfiction /srv/nemi/books/rejected
sudo: true
changed_when: "false"
- name: A file dropped by infra-ops into fiction/ is readable by lkraven, movable to rejected/, and removable
sudo: true
shell: |
set -e
f=/srv/nemi/books/fiction/.acl-probe-$$
r=/srv/nemi/books/rejected/.acl-probe-$$
runuser -u infra-ops -g nemi-drop -- sh -c "umask 077; echo probe > $f"
runuser -u lkraven -- cat "$f" >/dev/null
runuser -u lkraven -- mv "$f" "$r"
runuser -u lkraven -- rm -f "$r"
test ! -e "$f" && test ! -e "$r" && echo "infra-ops drop -> lkraven read+move+remove: ok"
changed_when: "false"
+11
View File
@@ -240,6 +240,17 @@ carries `u:lkraven:rx`.
for lkraven, NOT through the group. Do not "simplify" them away until lkraven's user manager has restarted. for lkraven, NOT through the group. Do not "simplify" them away until lkraven's user manager has restarted.
`playbooks/nh3-dev-nemi-inbox.yaml` verifies both paths. `playbooks/nh3-dev-nemi-inbox.yaml` verifies both paths.
## `/srv/nemi/books`: the book drop (2026-10-16)
albok unit 8 (albok-dev, after Prime asked for a books drop folder with a rejection folder). Drop an epub into `fiction/` or
`nonfiction/`. Nemi validates it and moves it into `~lkraven/library/<shelf>/`, writing its yaml and MANIFEST line, then walks it
the same hour. If it refuses the file, it moves it into `rejected/` beside a reason file. Files are examined only after
2 minutes unchanged, and temporary names (dotfiles, `.part`, `.crdownload`, `.tmp`, `~`, `.syncthing.*`) are ignored.
Same shape as the inbox: all four dirs are `lkraven:nemi-drop 2770` with the default ACL. Same filesystem as `~/library`
(`/dev/sda1`), so Nemi's move is a rename. There is no network share: drops are local writes or `scp`/`sftp` as lkraven, as
for the inbox. `playbooks/nh3-dev-nemi-books.yaml` provisions it and verifies an infra-ops drop is readable, movable
to `rejected/` and removable by lkraven.
## `/srv/nemi/vault`: Prime's notes for Nemi (2026-10-15) ## `/srv/nemi/vault`: Prime's notes for Nemi (2026-10-15)
A fresh clone of gitea `vh/VuongKB` (Prime's notes, which he syncs with git; his working copy is `/home/lkraven/kb`, never A fresh clone of gitea `vh/VuongKB` (Prime's notes, which he syncs with git; his working copy is `/home/lkraven/kb`, never