docs: topic notes 2026-07-09 (keys-wire, ipv6, castopod, …)

This commit is contained in:
Hernâni Marques 2026-07-09 22:54:08 +02:00
parent 547f0e27ce
commit 86502f5ced
No known key found for this signature in database
11 changed files with 520 additions and 0 deletions

View file

@ -0,0 +1,27 @@
# Agent rule: no hanging around (Castopod session lessons)
When automating on koopa (or any remote), **never leave a command without a deadline**.
## Required patterns
1. **HTTP:** always
`curl --connect-timeout 10 --max-time 120` (adjust intentionally).
2. **Long jobs:** wrap with
`timeout --kill-after=15s 600s <cmd>`
(image pulls, compose up, big uploads).
3. **Interactive CLIs:** do not pipe blindly and hope. Prefer:
- non-interactive flags, or
- direct SQL / API, or
- `printf 'y\n'` / `yes y | head` with a **known** prompt count.
4. **Poll loops:** max tries + sleep; exit non-zero on give-up (print last status).
5. **Background only** after starting with timeout/logging; never “wait forever” on silent pull.
## Castopod-specific
- `shield:user activate` **prompts** → use SQL activate (`scripts/castopod/lib.sh``cp_activate_users`).
- Episode create: empty `transcript_file` / `chapters_file` fail validation; `location_name` must be `''` or a string (null crashes).
- `custom_rss` must be a string (empty `" "` / `""`), not omitted → null TypeError.
## Scripts
See `scripts/castopod/` (`lib.sh`, `up.sh`, `status.sh`).

View file

@ -0,0 +1,48 @@
# Amount ladder bench — partial results (interrupted 2026-07-09)
Scratch (local): `koopa-admin-log/.tmp/amount-bench-20260709-101102/`
## Setup
| Item | Value |
|------|-------|
| Bank user | `bench-fat` |
| Password file (koopa host) | `/root/bank-bench-fat-password.txt` |
| Admin credit | GOA:100000 |
| Withdraw | GOA:25000 → wallet available GOA:25000 |
| Merchant instance | `goa-demo-cp4zqk` |
| Free-amount template | `goa-free` |
| Fixed template (legacy) | `goa` amount GOA:5 fixed-order |
| Withdraw wall time | ~393 s (confirm path issues) |
## Payments (all failed — template URL 404)
| # | Amount | handle (s) | rud (s) | total (s) | status | loadavg |
|--:|--------|----------:|--------:|----------:|--------|--------:|
| 1 | `GOA:0.000001` | 0.209 | 0.168 | **0.377** | error | 2.17 |
| 2 | `GOA:0.001` | 0.234 | 0.17 | **0.404** | error | 2.06 |
| 3 | `GOA:0.05` | 0.203 | 0.168 | **0.371** | error | 2.21 |
| 4 | `GOA:0.5` | 0.199 | 0.169 | **0.369** | error | 2.17 |
| 5 | `GOA:1` | 0.204 | 0.167 | **0.37** | error | 2.07 |
| 6 | `GOA:3` | 0.201 | 0.168 | **0.37** | error | 2.22 |
| 7 | `GOA:7` | 0.198 | 0.168 | **0.366** | error | 2.18 |
| 8 | `GOA:10` | 0.286 | 0.17 | **0.456** | error | 2.23 |
| 9 | `GOA:25` | 0.204 | 0.167 | **0.372** | error | 2.21 |
| 10 | `GOA:50` | 0.204 | 0.167 | **0.372** | error | 2.41 |
| 11 | `GOA:100` | 0.279 | 0.166 | **0.445** | error | 2.27 |
| 12 | `GOA:250` | 0.294 | 0.168 | **0.462** | error | 2.23 |
| 13 | `GOA:500` | 0.21 | 0.165 | **0.375** | error | 2.12 |
| 14 | `GOA:1000` | 0.202 | 0.169 | **0.37** | error | 2.33 |
| 15 | `GOA:2500` | 0.198 | 0.164 | **0.362** | error | 2.31 |
| 16 | `GOA:5000` | 0.201 | 0.167 | **0.368** | error | 2.43 |
### Failure
Wallet requested:
```
GET https://taler.hacktivism.ch/instances/goa-demo-cp4zqk/goa-free/templates/
→ 404
```
URI used: `taler://pay-template/taler.hacktivism.ch/instances/goa-demo-cp4zqk/goa-free/?amount=…&summary=…`
Fix next: correct pay-template path / merchant public template endpoint.
## Planned amount ladder (not all run)
`GOA:0.000001 0.001 0.05 0.5 1 3 7 10 25 50 100 250 500 1000 2500 5000`

View file

@ -0,0 +1,57 @@
# Bonfire ground zero + FOSS posts + gitbot (2026-07-09)
## Stack
| Item | Value |
|------|--------|
| Path | `/home/hernani/koopa-bonfire/` |
| Containers | `koopa-bonfire`, `koopa-bonfire-db` |
| Port | **9021** → Caddy `bonfire.hacktivism.ch` |
| Image | `bonfirenetworks/bonfire:1.0.5-social-amd64` |
| Env | secrets **64** chars; `DB_MIGRATE_INDEXES_CONCURRENTLY=false` |
Ground zero: wiped volume + dir, clean migrate (import_me `20200828094944` applied, ~109 migrations, identity tables present).
## Accounts
| Login | Role |
|-------|------|
| `foss` / `foss@bonfire.hacktivism.ch` | FOSS posts |
| character `gitbot` | same account (multi-profile) |
Passwords: `/home/hernani/koopa-bonfire/users.env` (mode 600).
Public: https://bonfire.hacktivism.ch/
## FOSS posts (as @foss)
Topics: NGI0 dossiers, SM dossier, Castopod pilot, git.ngi-0.eu, four freedoms — linking **https://dossiers.ngi-0.eu/** and **https://git.ngi-0.eu/**.
## Commit mirror bot
- Script: `~/koopa-bonfire/bin/gitbot-mirror.py`
- State: `~/koopa-bonfire/gitbot-state.json` (seen SHAs)
- Loop: every **300s**, pidfile `~/koopa-bonfire/gitbot.pid`, log `~/koopa-bonfire/gitbot.log`
- Source: Forgejo API `https://git.ngi-0.eu/api/v1/repos/search` + `…/commits`
```bash
# status
ps -p "$(cat ~/koopa-bonfire/gitbot.pid)" -o pid,cmd
tail -20 ~/koopa-bonfire/gitbot.log
# one-shot
python3 ~/koopa-bonfire/bin/gitbot-mirror.py
# restart loop
kill "$(cat ~/koopa-bonfire/gitbot.pid)"; \
nohup python3 ~/koopa-bonfire/bin/gitbot-mirror.py --loop >>~/koopa-bonfire/gitbot.log 2>&1 & \
echo $! >~/koopa-bonfire/gitbot.pid
```
Note: occasional `URI.parse/1` errors on some commit messages (special chars / URLs); bot skips and retries later.
## Lessons
- First boot needs **≥64-byte** `SECRET_KEY_BASE`.
- Migrations: **`DB_MIGRATE_INDEXES_CONCURRENTLY=false`** on empty DB (avoids concurrent index in txn).
- Partial DB → wipe volume and ground zero rather than patch half-migrated state.

View file

@ -0,0 +1,63 @@
# Castopod pilot content — FOSS Airwaves (2026-07-09)
Public: **https://castopod.hacktivism.ch/@foss**
RSS: **https://castopod.hacktivism.ch/@foss/feed.xml**
## Users
| Username | Email | Role | Notes |
|----------|-------|------|--------|
| `admin` | `admin@castopod.hacktivism.ch` | instance **superadmin** | install account |
| `ngi` | `ngi@castopod.hacktivism.ch` | group **podcaster** + podcast `@foss` **author** | content account |
Passwords: **not in admin-log** — host
`/home/hernani/koopa-castopod/users.env` (mode 600).
Login: https://castopod.hacktivism.ch/cp-auth/login
## Podcast
| Field | Value |
|-------|--------|
| Title | **FOSS Airwaves** |
| Handle | `@foss` |
| Category | Technology (+ Tech News, Education) |
| Copyright / license line | Text **CC BY-SA 4.0**; cover graphics **CC BY-SA 4.0**; audio beds SoundHelix free demo music |
| Owner | NGI FOSS Airwaves / `ngi@…` |
## Episodes (published)
| # | Slug | Title | License of show notes |
|---|------|-------|------------------------|
| 1 | `four-freedoms` | Four Freedoms: Why Free Software Matters | **CC BY-SA 4.0** |
| 2 | `free-licenses` | Copyleft vs Permissive Free Licenses | **CC BY-SA 4.0** |
| 3 | `free-culture-fediverse` | Free Culture Podcasting on the Fediverse | **CC BY-SA 4.0** |
Public episode URLs:
- https://castopod.hacktivism.ch/@foss/episodes/four-freedoms
- https://castopod.hacktivism.ch/@foss/episodes/free-licenses
- https://castopod.hacktivism.ch/@foss/episodes/free-culture-fediverse
### Content themes (free software / free culture)
1. **Four Freedoms** — FSF definition; GPLv3 / AGPLv3 / MIT / Apache-2.0
2. **License comparison** — copyleft vs permissive; Creative Commons for non-software
3. **Fediverse podcasting** — Castopod (AGPL), ActivityPub, CC BY/SA notes
### Media notes
- Episode audio: **SoundHelix** free demo music (free use for projects) as placeholder bed; not a full spoken episode.
- Transcript stubs (.srt) and JSON chapters attached as placeholders.
- Cover/banner: generated art marked **CC BY-SA 4.0**.
## Ops
```bash
# as hernani
cd ~/koopa-castopod && podman-compose ps
# secrets / passwords
ls -la ~/koopa-castopod/{.env,users.env}
```
Stack: `koopa-castopod` + mariadb + redis, Caddy → **9020**.

View file

@ -0,0 +1,201 @@
# Exchange snapshot + restore (GOA) — 2026-07-09
**Scope:** local on host **koopa** only. No registry, no upload, no public internet publish.
Container was **stopped** then **committed/saved**. Live name: `taler-exchange-hacktivism`.
---
## 1. What was stored (local files)
Directory (hernani on koopa):
```text
/home/hernani/images/taler-stack-20260709-snapshot/
```
| File | Role | Size (approx.) |
|------|------|----------------|
| `taler-exchange-hacktivism-live-20260709-snapshot.tar` | full exchange image archive | **~1.6G** |
| `taler-hacktivism-live-20260709-snapshot.tar` | merchant archive (partial earlier run) | ~2.4G |
| `SHA256SUMS` | checksums for completed saves | |
**Podman images (local store only):**
| Image | Tag | Notes |
|-------|-----|--------|
| `localhost/taler-exchange-hacktivism-live` | `20260709-snapshot` | committed from stopped container |
| `localhost/taler-exchange-hacktivism-live` | `9011` | previous live tag (still present) |
| `localhost/taler-hacktivism-live` | `20260709-snapshot` | merchant (if commit kept) |
| `localhost/taler-bank-hacktivism-live` | `20260709-snapshot` | bank (if commit kept) |
Verify:
```bash
# as hernani@koopa
ls -lh /home/hernani/images/taler-stack-20260709-snapshot/
sha256sum -c /home/hernani/images/taler-stack-20260709-snapshot/SHA256SUMS
podman images | grep exchange
podman ps -a --filter name=taler-exchange-hacktivism
```
Expected container state after stop:
```text
taler-exchange-hacktivism Exited (…) localhost/taler-exchange-hacktivism-live:9011 0.0.0.0:9011->9011/tcp
```
---
## 2. How the snapshot was made
```bash
# as hernani@koopa — local only
podman stop taler-exchange-hacktivism
TAG=20260709-snapshot
OUT=/home/hernani/images/taler-stack-$TAG
mkdir -p "$OUT"
podman commit taler-exchange-hacktivism \
localhost/taler-exchange-hacktivism-live:$TAG
podman save -o "$OUT/taler-exchange-hacktivism-live-$TAG.tar" \
localhost/taler-exchange-hacktivism-live:$TAG
sha256sum "$OUT/taler-exchange-hacktivism-live-$TAG.tar" | tee -a "$OUT/SHA256SUMS"
```
`-p` on commit pauses the container if still running; after `stop` it is optional.
---
## 3. Restore from image (same host)
### A. From local image tag (fast)
```bash
podman rm -f taler-exchange-hacktivism # only if replacing dead/exited
podman run -d --name taler-exchange-hacktivism \
--network pasta \
-p 9011:9011 \
--label org.hacktivism.service=taler-exchange \
--label org.hacktivism.host_port=9011 \
--label org.hacktivism.site=exchange.hacktivism.ch \
--label org.hacktivism.currency=GOA \
--label org.hacktivism.managed_by=koopa-admin \
localhost/taler-exchange-hacktivism-live:20260709-snapshot \
sleep infinity
```
### B. From tar (if image store was wiped)
```bash
podman load -i /home/hernani/images/taler-stack-20260709-snapshot/taler-exchange-hacktivism-live-20260709-snapshot.tar
# then same podman run as above
```
### C. Start services (manual model, no systemd)
Inside container as **root**, then app user:
```bash
podman exec -u root -it taler-exchange-hacktivism bash
# 1) base: postgres, runtime dirs, secmods, wire helpers
/root/start_base_services_for_taler_exchange.sh --no-shell
# 2) httpd
runuser -u taler-exchange-httpd -- /usr/local/bin/start_exchange.sh --restart
# 3) health
/usr/local/bin/check_exchange-health.sh
```
Host / public checks:
```bash
curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9011/config
curl -sS -o /dev/null -w "%{http_code}\n" https://exchange.hacktivism.ch/config
curl -sS -o /dev/null -w "%{http_code}\n" https://exchange.hacktivism.ch/keys
```
Caddy already proxies `exchange.hacktivism.ch` → host `:9011` (see `configs/caddy/`, `configs/ports.md`).
---
## 4. GOA configuration (authoritative tree)
**Do not** edit package `taler-exchange.conf` defaults by hand. Site config lives in overrides + coins (merchant pattern).
| In container | In admin-log repo |
|--------------|-------------------|
| `/etc/taler-exchange/exchange-overrides.conf` | `configs/taler-exchange/exchange-overrides.conf` |
| `/etc/taler-exchange/conf.d/exchange-coins.conf` | `configs/taler-exchange/conf.d-exchange-coins.conf` |
| secrets (wire gateway) | **not** in admin-log → `koopa-admin-secrets` |
| start scripts | `scripts/taler-exchange/` |
GOA essentials in overrides:
- `CURRENCY = GOA`, `BASE_URL = https://exchange.hacktivism.ch/`
- `SERVE = tcp`, `PORT = 9011`
- `[currency-goa]` ENABLED + unit names (Yotta…Atomic)
- `[exchange-account-1]` payto `x-taler-bank/bank.hacktivism.ch/exchange`
- Terms stubs: `TERMS_ETAG` / `PRIVACY_ETAG` = `no-terms-v0` / `no-privacy-v0`
Deploy overrides from the local machine (example):
```bash
# from laptop, secrets never committed to admin-log
scp configs/taler-exchange/exchange-overrides.conf \
hernani@koopa:/tmp/exchange-overrides.conf
scp configs/taler-exchange/conf.d-exchange-coins.conf \
hernani@koopa:/tmp/exchange-coins.conf
ssh hernani@koopa 'podman cp /tmp/exchange-overrides.conf taler-exchange-hacktivism:/etc/taler-exchange/exchange-overrides.conf
podman cp /tmp/exchange-coins.conf taler-exchange-hacktivism:/etc/taler-exchange/conf.d/exchange-coins.conf'
```
Greenfield (empty Debian + packages) only:
`scripts/taler-exchange/archive/exchange-bootstrap.sh` **as root inside** container — generates a **new** master key; not the same as restoring this snapshot.
After config change:
```bash
runuser -u taler-exchange-httpd -- /usr/local/bin/start_exchange.sh --restart
# optional offline keys / wire:
# scripts/taler-exchange/wire-enable-and-upload.sh
# scripts/taler-exchange/offline-sign-upload-keys.sh
# /usr/local/bin/install_no_terms.sh
```
---
## 5. Ansible
There is **no** Ansible playbook in `koopa-admin-log` / this monorepo path for the exchange.
Operational model is: **podman** + **manual start scripts** + **GOA overrides** as above.
If an external Ansible tree is added later, it should only:
1. `podman load` / ensure image tag
2. `podman run` with pasta + `9011:9011` + labels above
3. copy GOA configs from `configs/taler-exchange/`
4. run `start_base``start_exchange`
5. never push images to a public registry without explicit request
---
## 6. Related docs
| Doc | Content |
|-----|---------|
| `configs/taler-exchange/README.md` | GOA site notes, terms, ports |
| `scripts/taler-exchange/archive/README.md` | bootstrap vs daily start |
| `configs/ports.md` | 9011 pasta |
| `ops/ROOT_HYGIENE.md` | secrets layout |
---
## 7. Session note (2026-07-09)
- Exchange **stopped** on request (`Exited 137`).
- Snapshot **local only** under `/home/hernani/images/…`.
- Known pre-stop issue: wirewatch had died after Postgres ownership/outage → bank confirms OK but wallet “Geld von Bank abheben…” could hang until wirewatch imports credits. After restore, always verify **wirewatch** is live (`check_exchange-health.sh`).

View file

@ -0,0 +1,34 @@
# 2026-07-09 — IPv6 `:15d6` reachability
## Symptom
`https://exchange.hacktivism.ch/config` failed with `ERR_ADDRESS_UNREACHABLE`
when clients preferred AAAA `2a02:168:53a8:0:d584:9e34:13cf:15d6`.
IPv4 `212.51.151.254` worked (HTTP 200).
## Path comparison
| | IPv4 | IPv6 |
|--|------|------|
| Public endpoint | WAN IP DNAT | Host global `:15d6` |
| VeciGate | dstnat 443→9001 | forward 443 (no NAT) |
| Host listener | Caddy `:9001` | `https-proxy.socket` `:443` → 9001 |
| firewalld needed | 9001 | **443** (+ 80 for ACME) |
## Fix applied
```bash
# on koopa (root)
firewall-cmd --permanent --zone=public --add-port=443/tcp
firewall-cmd --reload
```
VeciGate: confirmed IPv6 filter allow 443; added explicit allow **80** for ACME.
## Verify
```bash
curl -6 -sS -o /dev/null -w '%{http_code} %{remote_ip}\n' \
https://exchange.hacktivism.ch/config
# 200 2a02:168:53a8:0:d584:9e34:13cf:15d6
```

View file

@ -0,0 +1,17 @@
# 2026-07-09 — `/keys` + Wire + Merchant GOA
## Done
1. **Exchange `/keys`:** was suspended (no wire accounts → then no online signing keys).
- `enable-account` + `wire-fee` + `global-fee` → offline **upload** (local `BASE_URL=http://127.0.0.1:9011/`)
- `download``sign``upload` for denoms + signkeys
- Result: `GET /keys` **200**, ~1MB, currency GOA, master `TW6K5FXF…`
2. **Merchant health:** `check_merchant-health.sh` includes exchange `/keys` + MASTER_KEY match → **ALL CRITICAL PASSED** (GOA via `host.containers.internal:9011` fallback).
3. **Wire helpers:** secret `exchange-accountcredentials-1.secret.conf` needs group `taler-exchange-db` mode 640; then aggregator/closer/wirewatch/transfer OK.
4. **Smoke:** local+public `/keys` 200; bank wire-gateway config as `exchange` → 200 on `:9012`; bank SPA public earlier (LE cert). Full phone Withdraw is manual (wallet app).
5. **Admin-log:** docs diagram keys/wire; scripts `wire-enable-and-upload.sh`, `offline-sign-upload-keys.sh`, `start_wire_helpers.sh`; merchant overrides GOA; ports 9012 noted.
## Manual withdraw (phone)
1. https://bank.hacktivism.ch/ → login `explorer` (pw host `/root/bank-explorer-password.txt`)
2. Withdraw GOA → open in Taler Wallet (exchange.hacktivism.ch `/keys` must stay 200)

View file

@ -0,0 +1,43 @@
# koopa-prime — Jellyfin + qBittorrent (2026-07-09)
## Containers (podman-compose)
Path: `/home/hernani/koopa-prime/`
| Container | Role | Host port |
|-----------|------|-----------|
| `koopa-prime-jellyfin` | Video library (Jellyfin) | **9022** |
| `koopa-prime-qbittorrent` | BitTorrent client | **9023** WebUI, **6881** BT |
## Media wiring
| Host path | Jellyfin | qBittorrent |
|-----------|----------|-------------|
| `/home/hernani/Downloads` | `/media/downloads` **ro** (library) | `/downloads` **rw** (save path) |
Downloads land in the same folder Jellyfin scans.
## Auth (login required)
- **Jellyfin:** admin account created via Startup API; library access needs login.
- **qBittorrent:** WebUI password required (401 without session).
Credentials: `~/koopa-prime/users.env` (mode 600).
## Public / Caddy
| Host | Backend |
|------|---------|
| `prime.hacktivism.ch` | `127.0.0.1:9022` |
| `torrent.prime.hacktivism.ch` | `127.0.0.1:9023` (needs DNS CNAME) |
See session notes for Caddy snippets. BT port **6881** may need firewall/VeciGate if peers should connect.
## Ops
```bash
cd ~/koopa-prime
podman-compose ps
podman-compose logs -f jellyfin
podman-compose up -d
```

View file

@ -0,0 +1,8 @@
# 2026-07-09 — Merchant demo + bank link
1. Disabled mandatory SMS/email TAN on merchant (`MANDATORY_TAN_CHANNELS` empty).
2. Self-provisioned instance `goa-demo-cp4zqk` via `POST /instances` (HTTP 200, no challenge).
3. Created bank user `goa-demo-cp4zqk`, credited **GOA:5000**.
4. Linked payto to merchant: `POST .../private/accounts` → active wire account.
See `configs/taler-merchant/demo-instance-goa-demo-cp4zqk.md`.