diff --git a/documentation/audits/rehearsal-2026-10-20/A6-plan/order.md b/documentation/audits/rehearsal-2026-10-20/A6-plan/order.md index f3c3b6d1..fa7a9dcb 100644 --- a/documentation/audits/rehearsal-2026-10-20/A6-plan/order.md +++ b/documentation/audits/rehearsal-2026-10-20/A6-plan/order.md @@ -30,3 +30,13 @@ Method: `random.Random(20261020)`; shuffle the ★ list [1..10], then shuffle th - **7** (DST) and **8** (wrong clock) change the VM's clock; they run after the off-site and restore work they could disturb, but in this drawn order relative to each other. - Anything that needs off-site (2, 5, 6) is SKIPPED, not reordered, if Tester4's off-site is still off when its slot comes. + +## Amendment written 2026-10-20 ~15:45 UTC — BEFORE scenario 5 runs (no result seen) + +- **5** (slow, lossy internet during the first big off-site run): the first big run is started by the household's + „Távoli mentés most" this evening, with `tc netem` 1 Mbit/s up + 5 % loss on the VM's tap for its FIRST 30 MINUTES; + then the shaping is removed and the run must finish (or resume) by itself. Reason: at 1 Mbit/s the ~3.7 GB first copy + needs ~8 h, and B7 (box died) needs a complete off-site copy by the morning. What is measured: progress, what the + page and the hub say while slow, and whether the run finishes or resumes after. +- The box froze twice under ordinary uploads (R-1192). Every heavy scenario now runs ALONE, with the health watch + beside it; a freeze during a scenario is recorded as such, not as the scenario's own result. diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/backup-now.txt b/documentation/audits/rehearsal-2026-10-20/B4-use/backup-now.txt new file mode 100644 index 00000000..5861e7dd --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/backup-now.txt @@ -0,0 +1,2 @@ +run 200 {'ok': True, 'message': 'Mentés elindítva'} +120 s {"db_dump": {"count": 4, "duration": "1m58.175464265s", "last_run": "2026-10-20T16:30:58.136294428Z", "success": true}, "enabled": true, "running": false} diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/films-watch.txt b/documentation/audits/rehearsal-2026-10-20/B4-use/films-watch.txt new file mode 100644 index 00000000..c2f11633 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/films-watch.txt @@ -0,0 +1,60 @@ +15:26:05 health=200 0.011492 +15:26:35 health=200 0.013093 +15:27:05 health=200 0.325949 +15:27:55 health=000 20.002381 +15:28:45 health=000 20.002064 +15:29:35 health=000 20.002874 +15:30:26 health=000 20.002573 +15:31:16 health=000 20.002897 +15:32:06 health=000 20.002446 +15:32:56 health=000 20.002815 +15:33:46 health=000 20.002487 +15:34:36 health=000 20.002728 +15:35:26 health=000 20.002934 +15:36:16 health=000 20.003039 +15:37:06 health=000 20.002029 +15:37:56 health=000 20.002896 +15:38:46 health=000 20.002072 +15:39:36 health=000 20.002908 +15:40:26 health=000 20.002099 +15:41:16 health=000 20.001909 +15:42:06 health=000 20.002225 +15:42:56 health=000 20.002048 +15:43:46 health=000 20.003050 +15:44:36 health=000 20.001694 +15:45:26 health=000 20.002376 +15:46:16 health=000 20.002820 +15:47:06 health=000 20.002634 +15:47:56 health=000 20.002259 +15:48:46 health=000 20.002093 +15:49:36 health=000 20.002486 +15:50:26 health=000 20.001753 +15:51:16 health=000 20.001476 +15:52:06 health=000 20.002140 +15:52:56 health=000 20.002111 +15:53:46 health=000 20.002107 +15:54:36 health=000 20.002294 +15:55:26 health=000 20.002923 +15:56:16 health=000 20.002691 +15:57:06 health=000 20.002300 +15:57:56 health=000 20.002884 +15:58:46 health=000 20.002233 +15:59:36 health=000 20.001755 +16:00:26 health=000 20.002217 +16:01:16 health=000 20.002917 +16:02:06 health=000 20.001900 +16:02:41 health=200 4.333646 +16:03:31 health=000 20.002229 +16:04:21 health=000 20.002154 +16:05:11 health=000 20.002066 +16:06:01 health=000 20.002208 +16:06:51 health=000 20.002962 +16:07:41 health=000 20.001192 +16:08:31 health=000 20.002116 +16:09:21 health=000 20.002092 +16:10:11 health=000 20.002032 +16:11:01 health=000 20.002964 +16:11:51 health=000 20.002792 +16:12:41 health=000 20.001994 +16:13:31 health=000 20.002290 +16:14:21 health=000 20.002875 diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/health-log.txt b/documentation/audits/rehearsal-2026-10-20/B4-use/health-log.txt new file mode 100644 index 00000000..87b82776 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/health-log.txt @@ -0,0 +1,26 @@ +2026-10-20T16:03:26 health=000 20.001467 diskread=250GB +2026-10-20T16:04:47 health=000 20.002188 diskread=257GB +2026-10-20T16:06:08 health=000 20.002982 diskread=263GB +2026-10-20T16:07:30 health=000 20.001529 diskread=271GB +2026-10-20T16:08:51 health=000 20.001679 diskread=278GB +2026-10-20T16:10:12 health=000 20.002149 diskread=285GB +2026-10-20T16:11:33 health=000 20.002090 diskread=294GB +2026-10-20T16:12:55 health=000 20.002713 diskread=301GB +2026-10-20T16:14:16 health=000 20.002244 diskread=0GB +2026-10-20T16:15:21 health=000 3.052227 diskread=0GB +2026-10-20T16:16:23 health=200 0.028660 diskread=3GB +2026-10-20T16:17:24 health=200 0.011805 diskread=4GB +2026-10-20T16:18:26 health=200 0.011279 diskread=4GB +2026-10-20T16:19:28 health=200 0.011336 diskread=4GB +2026-10-20T16:20:29 health=200 0.010931 diskread=4GB +2026-10-20T16:21:31 health=200 0.010568 diskread=4GB +2026-10-20T16:22:32 health=200 0.012190 diskread=4GB +2026-10-20T16:23:34 health=200 0.009670 diskread=4GB +2026-10-20T16:24:36 health=200 0.011174 diskread=4GB +2026-10-20T16:25:37 health=200 0.010032 diskread=4GB +2026-10-20T16:26:39 health=200 0.010610 diskread=4GB +2026-10-20T16:27:40 health=200 0.010425 diskread=4GB +2026-10-20T16:28:42 health=200 0.012126 diskread=4GB +2026-10-20T16:29:44 health=200 0.010823 diskread=7GB +2026-10-20T16:30:45 health=200 0.009510 diskread=9GB +2026-10-20T16:31:47 health=200 0.259351 diskread=10GB diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/immich-upload-2.log b/documentation/audits/rehearsal-2026-10-20/B4-use/immich-upload-2.log new file mode 100644 index 00000000..d529d8f3 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/immich-upload-2.log @@ -0,0 +1,49 @@ +15:26:49 +Traceback (most recent call last): + File "/root/work/apps.py", line 206, in + fn(*sys.argv[2:]) + ~~^^^^^^^^^^^^^^^ + File "/root/work/apps.py", line 168, in immich + st, out, _ = http("POST", base + "/api/assets", body, dict(tok, **{"Content-Type": ct})) + ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/root/work/apps.py", line 34, in http + with urllib.request.urlopen(req, context=CTX, timeout=timeout) as r: + ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/usr/lib/python3.13/urllib/request.py", line 189, in urlopen + return opener.open(url, data, timeout) + ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^ + File "/usr/lib/python3.13/urllib/request.py", line 489, in open + response = self._open(req, data) + File "/usr/lib/python3.13/urllib/request.py", line 506, in _open + result = self._call_chain(self.handle_open, protocol, protocol + + '_open', req) + File "/usr/lib/python3.13/urllib/request.py", line 466, in _call_chain + result = func(*args) + File "/usr/lib/python3.13/urllib/request.py", line 1367, in https_open + return self.do_open(http.client.HTTPSConnection, req, + ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + context=self._context) + ^^^^^^^^^^^^^^^^^^^^^^ + File "/usr/lib/python3.13/urllib/request.py", line 1323, in do_open + r = h.getresponse() + File "/usr/lib/python3.13/http/client.py", line 1459, in getresponse + response.begin() + ~~~~~~~~~~~~~~^^ + File "/usr/lib/python3.13/http/client.py", line 336, in begin + version, status, reason = self._read_status() + ~~~~~~~~~~~~~~~~~^^ + File "/usr/lib/python3.13/http/client.py", line 297, in _read_status + line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1") + ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^ + File "/usr/lib/python3.13/socket.py", line 719, in readinto + return self._sock.recv_into(b) + ~~~~~~~~~~~~~~~~~~~~^^^ + File "/usr/lib/python3.13/ssl.py", line 1304, in recv_into + return self.read(nbytes, buffer) + ~~~~~~~~~^^^^^^^^^^^^^^^^ + File "/usr/lib/python3.13/ssl.py", li15:26:50Z immich admin-sign-up 400 b'{"message":"Admin setup is not available"}' +ne 1138, in read + return self._sslobj.read(len, buffer) + ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ +TimeoutError: The read operation timed out +15:32:07 diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/memwatch.txt b/documentation/audits/rehearsal-2026-10-20/B4-use/memwatch.txt new file mode 100644 index 00000000..bceede3c --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/memwatch.txt @@ -0,0 +1,32 @@ +16:16:15Z used=3638MB avail=458MB load1=4.61 cpu=67% nextcloud-db:270/512MB 29% | immich-server:232/3072MB 25% | traefik:184/4096MB 26% | nextcloud:157/1024MB 0% | filebrowser:145/256MB 0% | immich-postgres:134/768MB 0% | actualbudget:130/256MB 27% | immich-machine-learning:106/2048MB 29% +16:16:46Z used=3638MB avail=458MB load1=4.47 cpu=3% nextcloud-db:270/512MB 29% | immich-server:232/3072MB 25% | traefik:184/4096MB 26% | nextcloud:157/1024MB 0% | filebrowser:145/256MB 0% | immich-postgres:134/768MB 0% | actualbudget:130/256MB 27% | immich-machine-learning:106/2048MB 29% +16:17:16Z used=3638MB avail=458MB load1=4.59 cpu=74% immich-server:1094/3072MB 0% | mealie:215/1000MB 0% | immich-machine-learning:173/2048MB 0% | paperless-webserver:148/1280MB 175% | nextcloud-db:118/512MB 0% | bookstack-db:104/256MB 0% | immich-postgres:78/768MB 0% | filebrowser:64/256MB 0% +16:17:46Z used=3638MB avail=458MB load1=3.6 cpu=3% immich-server:1094/3072MB 0% | mealie:215/1000MB 0% | immich-machine-learning:173/2048MB 0% | paperless-webserver:148/1280MB 175% | nextcloud-db:118/512MB 0% | bookstack-db:104/256MB 0% | immich-postgres:78/768MB 0% | filebrowser:64/256MB 0% +16:18:16Z used=3638MB avail=458MB load1=4.3 cpu=7% immich-server:1018/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:220/1000MB 0% | immich-machine-learning:134/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:98/256MB 0% | immich-postgres:90/768MB 0% | felhom-controller:89/4096MB 26% +16:18:46Z used=3638MB avail=458MB load1=2.92 cpu=5% immich-server:1018/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:220/1000MB 0% | immich-machine-learning:134/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:98/256MB 0% | immich-postgres:90/768MB 0% | felhom-controller:89/4096MB 26% +16:19:16Z used=3638MB avail=458MB load1=2.47 cpu=6% immich-server:778/3072MB 0% | paperless-webserver:545/1280MB 0% | mealie:218/1000MB 0% | immich-machine-learning:136/2048MB 0% | nextcloud-db:101/512MB 6% | bookstack-db:97/256MB 0% | felhom-controller:90/4096MB 20% | immich-postgres:90/768MB 0% +16:19:47Z used=3638MB avail=458MB load1=1.65 cpu=5% immich-server:778/3072MB 0% | paperless-webserver:545/1280MB 0% | mealie:218/1000MB 0% | immich-machine-learning:136/2048MB 0% | nextcloud-db:101/512MB 6% | bookstack-db:97/256MB 0% | felhom-controller:90/4096MB 20% | immich-postgres:90/768MB 0% +16:20:17Z used=3638MB avail=458MB load1=1.52 cpu=7% immich-server:778/3072MB 0% | paperless-webserver:545/1280MB 0% | mealie:218/1000MB 0% | immich-machine-learning:136/2048MB 0% | nextcloud-db:102/512MB 6% | bookstack-db:97/256MB 0% | felhom-controller:92/4096MB 26% | immich-postgres:90/768MB 0% +16:20:47Z used=3638MB avail=458MB load1=1.06 cpu=8% immich-server:778/3072MB 0% | paperless-webserver:545/1280MB 0% | mealie:218/1000MB 0% | immich-machine-learning:136/2048MB 0% | nextcloud-db:102/512MB 6% | bookstack-db:97/256MB 0% | felhom-controller:92/4096MB 26% | immich-postgres:90/768MB 0% +16:21:17Z used=3638MB avail=458MB load1=1.22 cpu=9% immich-server:780/3072MB 2% | paperless-webserver:550/1280MB 0% | mealie:218/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 149% | immich-postgres:90/768MB 0% +16:21:47Z used=3638MB avail=458MB load1=1.04 cpu=6% immich-server:780/3072MB 2% | paperless-webserver:550/1280MB 0% | mealie:218/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 149% | immich-postgres:90/768MB 0% +16:22:17Z used=3638MB avail=458MB load1=0.96 cpu=9% immich-server:781/3072MB 1% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 23% | immich-postgres:90/768MB 0% +16:22:47Z used=3638MB avail=458MB load1=0.8 cpu=6% immich-server:781/3072MB 1% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 23% | immich-postgres:90/768MB 0% +16:23:17Z used=3638MB avail=458MB load1=0.71 cpu=9% immich-server:781/3072MB 1% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:102/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:95/4096MB 6% | immich-postgres:90/768MB 0% +16:23:47Z used=3638MB avail=458MB load1=0.65 cpu=7% immich-server:781/3072MB 1% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:102/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:95/4096MB 6% | immich-postgres:90/768MB 0% +16:24:18Z used=3638MB avail=458MB load1=0.58 cpu=9% immich-server:783/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 21% | immich-postgres:90/768MB 0% +16:24:48Z used=3638MB avail=458MB load1=0.35 cpu=7% immich-server:783/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 21% | immich-postgres:90/768MB 0% +16:25:18Z used=3638MB avail=458MB load1=0.29 cpu=8% immich-server:782/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:95/4096MB 6% | immich-postgres:90/768MB 0% +16:25:48Z used=3638MB avail=458MB load1=0.4 cpu=6% immich-server:782/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:95/4096MB 6% | immich-postgres:90/768MB 0% +16:26:18Z used=3638MB avail=458MB load1=0.78 cpu=8% immich-server:782/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 145% | immich-postgres:90/768MB 0% +16:26:48Z used=3638MB avail=458MB load1=0.55 cpu=5% immich-server:782/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 145% | immich-postgres:90/768MB 0% +16:27:18Z used=3638MB avail=458MB load1=0.47 cpu=8% immich-server:783/3072MB 0% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:102/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 12% | immich-postgres:90/768MB 0% +16:27:48Z used=3638MB avail=458MB load1=0.48 cpu=6% immich-server:783/3072MB 0% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:102/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 12% | immich-postgres:90/768MB 0% +16:28:18Z used=3638MB avail=458MB load1=0.43 cpu=9% immich-server:785/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 23% | immich-postgres:90/768MB 0% +16:28:49Z used=3638MB avail=458MB load1=0.26 cpu=6% immich-server:785/3072MB 0% | paperless-webserver:550/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:96/4096MB 23% | immich-postgres:90/768MB 0% +16:29:19Z used=3638MB avail=458MB load1=0.99 cpu=32% immich-server:784/3072MB 0% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:97/4096MB 6% | immich-postgres:90/768MB 0% +16:29:49Z used=3638MB avail=458MB load1=2.24 cpu=21% immich-server:784/3072MB 0% | paperless-webserver:551/1280MB 0% | mealie:254/1000MB 0% | immich-machine-learning:137/2048MB 0% | nextcloud-db:101/512MB 0% | bookstack-db:97/256MB 0% | felhom-controller:97/4096MB 6% | immich-postgres:90/768MB 0% +16:30:19Z used=3288MB avail=808MB load1=3.46 cpu=46% paperless-webserver:533/1280MB 0% | immich-server:502/3072MB 12% | immich-machine-learning:431/2048MB 1% | immich-postgres:132/768MB 3% | bookstack:131/512MB 0% | felhom-controller:116/4096MB 46% | mealie:103/1000MB 87% | bookstack-db:97/256MB 0% +16:30:50Z used=3638MB avail=458MB load1=2.35 cpu=23% paperless-webserver:533/1280MB 0% | immich-server:502/3072MB 12% | immich-machine-learning:431/2048MB 1% | immich-postgres:132/768MB 3% | bookstack:131/512MB 0% | felhom-controller:116/4096MB 46% | mealie:103/1000MB 87% | bookstack-db:97/256MB 0% +16:31:20Z used=3638MB avail=458MB load1=4.47 cpu=95% immich-server:908/3072MB 0% | mealie:244/1000MB 0% | immich-machine-learning:168/2048MB 0% | felhom-controller:166/4096MB 126% | nextcloud:162/1024MB 0% | nextcloud-db:131/512MB 0% | paperless-webserver:114/1280MB 66% | actualbudget:85/256MB 0% +16:31:50Z used=3438MB avail=658MB load1=3.84 cpu=44% immich-server:908/3072MB 0% | mealie:244/1000MB 0% | immich-machine-learning:168/2048MB 0% | felhom-controller:166/4096MB 126% | nextcloud:162/1024MB 0% | nextcloud-db:131/512MB 0% | paperless-webs \ No newline at end of file diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/nextcloud-upload-2.log b/documentation/audits/rehearsal-2026-10-20/B4-use/nextcloud-upload-2.log index 81376301..925c3a80 100644 --- a/documentation/audits/rehearsal-2026-10-20/B4-use/nextcloud-upload-2.log +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/nextcloud-upload-2.log @@ -1 +1,16 @@ 14:23:57 +15:20:50Z nextcloud rclone rc=1 + 2026/10/20 14:23:59 NOTICE: Config file "/root/.config/rclone/rclone.conf" not found - using defaults + 2026/10/20 14:23:59 NOTICE: Csalad/Kulonleges_nevek/link_a_nagy_fajlra: Can't follow symlink without -L/--copy-links + 2026/10/20 14:24:00 NOTICE: Csalad/Kulonleges_nevek/Ödön születésnapja – fénykép lista.txt: Duplicate object found in source - ignoring + 2026/10/20 14:24:04 ERROR : Csalad/nagy_fajl_1_5GB.bin: Failed to copy: + 2026/10/20 15:20:25 ERROR : Attempt 1/3 failed with 1 errors and: + 2026/10/20 15:20:26 NOTICE: Csalad/Kulonleges_nevek/link_a_nagy_fajlra: Can't follow symlink without -L/--copy-links + 2026/10/20 15:20:27 NOTICE: Csalad/Kulonleges_nevek/Ödön születésnapja – fénykép lista.txt: Duplicate object found in source - ignoring + 2026/10/20 15:20:34 ERROR : Csalad/nagy_fajl_1_5GB.bin: Failed to copy: + 2026/10/20 15:20:38 ERROR : Attempt 2/3 failed with 1 errors and: + 2026/10/20 15:20:39 NOTICE: Csalad/Kulonleges_nevek/link_a_nagy_fajlra: Can't follow symlink without -L/--copy-links + 2026/10/20 15:20:40 NOTICE: Csalad/Kulonleges_nevek/Ödön születésnapja – fénykép lista.txt: Duplicate object found in source - ignoring + 2026/10/20 15:20:45 ERROR : Csalad/nagy_fajl_1_5GB.bin: Failed to copy: + 2026/10/20 15:20:50 ERROR : Attempt 3/3 failed with 1 errors and: +15:20:50 diff --git a/documentation/audits/rehearsal-2026-10-20/B4-use/resume-watch.txt b/documentation/audits/rehearsal-2026-10-20/B4-use/resume-watch.txt index a26c114c..311d493a 100644 --- a/documentation/audits/rehearsal-2026-10-20/B4-use/resume-watch.txt +++ b/documentation/audits/rehearsal-2026-10-20/B4-use/resume-watch.txt @@ -19,3 +19,102 @@ 14:33:22 diskread=4GB health=200 0.013962 14:33:53 diskread=4GB health=200 0.011101 14:34:24 diskread=4GB health=200 0.012738 +14:34:55 diskread=4GB health=200 0.011132 +14:35:27 diskread=4GB health=200 0.017582 +14:35:58 diskread=4GB health=200 0.009786 +14:36:30 diskread=4GB health=200 0.011178 +14:37:01 diskread=4GB health=200 0.011017 +14:37:32 diskread=4GB health=200 0.009835 +14:38:03 diskread=4GB health=200 0.011396 +14:38:35 diskread=4GB health=200 0.011475 +14:39:06 diskread=4GB health=200 0.010567 +14:39:37 diskread=4GB health=200 0.010764 +14:40:09 diskread=4GB health=200 0.011841 +14:40:40 diskread=4GB health=200 0.012188 +14:41:11 diskread=4GB health=200 0.010514 +14:41:42 diskread=4GB health=200 0.010198 +14:42:14 diskread=4GB health=200 0.008837 +14:42:45 diskread=4GB health=200 0.013116 +14:43:16 diskread=4GB health=200 0.015796 +14:43:48 diskread=4GB health=200 0.011376 +14:44:19 diskread=4GB health=200 0.013047 +14:44:51 diskread=4GB health=200 0.011553 +14:45:22 diskread=4GB health=200 0.014702 +14:45:53 diskread=4GB health=200 0.011081 +14:46:24 diskread=4GB health=200 0.010798 +14:46:56 diskread=5GB health=200 0.016907 +14:47:27 diskread=5GB health=200 0.009167 +14:47:59 diskread=5GB health=200 0.011809 +14:48:30 diskread=5GB health=200 0.021601 +14:49:01 diskread=5GB health=200 0.012060 +14:49:33 diskread=5GB health=200 0.010723 +14:50:04 diskread=5GB health=200 0.010155 +14:50:35 diskread=5GB health=200 0.015786 +14:51:07 diskread=5GB health=200 0.010058 +14:51:38 diskread=5GB health=200 0.009848 +14:52:09 diskread=5GB health=200 0.009929 +14:52:41 diskread=5GB health=200 0.010351 +14:53:12 diskread=5GB health=200 0.009107 +14:53:43 diskread=5GB health=200 0.011299 +14:54:14 diskread=5GB health=200 0.009412 +14:54:46 diskread=5GB health=200 0.012795 +14:55:17 diskread=5GB health=200 0.010044 +14:55:48 diskread=5GB health=200 0.011059 +14:56:20 diskread=5GB health=200 0.013508 +14:56:51 diskread=5GB health=200 0.013017 +14:57:23 diskread=5GB health=200 0.011061 +14:57:54 diskread=5GB health=200 0.010914 +14:58:25 diskread=5GB health=200 0.010145 +14:58:57 diskread=5GB health=200 0.010722 +14:59:28 diskread=5GB health=200 0.015195 +14:59:59 diskread=5GB health=200 0.011767 +15:00:31 diskread=5GB health=200 0.011621 +15:01:02 diskread=5GB health=200 0.010509 +15:01:33 diskread=5GB health=200 0.010722 +15:02:04 diskread=5GB health=200 0.009856 +15:02:36 diskread=5GB health=200 0.010521 +15:03:07 diskread=5GB health=200 0.013668 +15:03:38 diskread=5GB health=200 0.012826 +15:04:10 diskread=5GB health=200 0.011463 +15:04:41 diskread=5GB health=200 0.011157 +15:05:12 diskread=5GB health=200 0.010431 +15:05:43 diskread=5GB health=200 0.010361 +15:06:15 diskread=5GB health=200 0.011914 +15:06:46 diskread=5GB health=200 0.021984 +15:07:17 diskread=5GB health=200 0.013204 +15:07:49 diskread=5GB health=200 0.010710 +15:08:20 diskread=5GB health=200 0.009754 +15:08:51 diskread=5GB health=200 0.011999 +15:09:23 diskread=5GB health=200 0.010382 +15:09:54 diskread=5GB health=200 0.011156 +15:10:25 diskread=5GB health=200 0.010280 +15:10:57 diskread=5GB health=200 0.011247 +15:11:28 diskread=5GB health=200 0.010959 +15:11:59 diskread=5GB health=200 0.009834 +15:12:31 diskread=5GB health=200 0.013080 +15:13:02 diskread=5GB health=200 0.010975 +15:13:33 diskread=5GB health=200 0.009572 +15:14:04 diskread=5GB health=200 0.010632 +15:14:36 diskread=5GB health=200 0.011168 +15:15:07 diskread=5GB health=200 0.011665 +15:15:38 diskread=5GB health=200 0.009601 +15:16:09 diskread=5GB health=200 0.010077 +15:16:41 diskread=5GB health=200 0.011031 +15:17:12 diskread=5GB health=200 0.009288 +15:17:43 diskread=5GB health=200 0.017476 +15:18:15 diskread=5GB health=200 0.013927 +15:18:46 diskread=5GB health=200 0.011434 +15:19:17 diskread=5GB health=200 0.009776 +15:19:48 diskread=5GB health=200 0.010952 +15:20:20 diskread=5GB health=200 0.011278 +15:20:51 diskread=5GB health=200 0.010643 +15:21:23 diskread=5GB health=200 0.011549 +15:21:54 diskread=5GB health=200 0.009613 +15:22:26 diskread=5GB health=200 0.011846 +15:22:58 diskread=5GB health=200 0.011471 +15:23:29 diskread=5GB health=200 0.010358 +15:24:01 diskread=5GB health=200 0.011769 +15:24:32 diskread=5GB health=200 0.011816 +15:25:03 diskread=5GB health=200 0.010058 +15:25:34 diskread=5GB health=200 0.011328 +15:26:06 diskread=5GB health=200 0.010774 diff --git a/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/01-netem-on.txt b/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/01-netem-on.txt new file mode 100644 index 00000000..55f7e507 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/01-netem-on.txt @@ -0,0 +1,4 @@ +16:31:28 +qdisc netem 8002: root refcnt 2 limit 1000 loss 5% seed 5004686564210070363 +qdisc ingress ffff: parent ffff:fff1 ---------------- +qdisc netem 8001: root refcnt 2 limit 1000 loss 5% rate 1Mbit seed 8660933106302401915 diff --git a/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/02-run-pressed.txt b/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/02-run-pressed.txt new file mode 100644 index 00000000..0121cb39 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/02-run-pressed.txt @@ -0,0 +1,2 @@ +16:31:37Z run ('302', {'_raw': ''}) +16:31:59Z status 200 {"last_duration": "", "last_error": "", "last_run": "", "orphaned": false, "progress": {"active": true, "current_app": "", "percent": 0, "bytes_done": 0, "total_bytes": 0, "done_human": "", "total_human": "", "files_done": 0, "total_files": 0, "current_file": "", "elapsed_sec": 0, "phase": "dump"}, "repo_size_human": "", "snapshots": 0, "status": "running"} diff --git a/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/03-progress-slow.txt b/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/03-progress-slow.txt new file mode 100644 index 00000000..f567e7d6 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/B6-failures/s5-slow-net/03-progress-slow.txt @@ -0,0 +1 @@ +16:32:09Z running pha \ No newline at end of file diff --git a/documentation/audits/rehearsal-2026-10-20/B9-words/words.md b/documentation/audits/rehearsal-2026-10-20/B9-words/words.md index dedfeb72..3236b73f 100644 --- a/documentation/audits/rehearsal-2026-10-20/B9-words/words.md +++ b/documentation/audits/rehearsal-2026-10-20/B9-words/words.md @@ -8,3 +8,20 @@ | W4 | bind page after a wrong try | „A megadott adatok nem megfelelőek. Ellenőrizd a párosító kódot és a tulajdonosi jelmondatot, majd próbáld újra." | does not say how many of the 5 tries are left; the 5th locks the link and only support can help | add „Még N próbálkozásod van." | | W5 | an old (replaced) bind link | „Ez a hivatkozás érvénytelen vagy lejárt." + „Új linket kérek" | a household with two mails may press „Új linket kérek" on the OLD one and invalidate the newer link they were about to use | say „Ha van újabb leveled, azt használd." above the button | | W6 | console after first boot vs the guide | console „Ezen a gépen most nincs dolgod…"; guide „Ezen a képernyőn nincs teendőd…" | the guide quotes a sentence the box does not show | guide edit (allowed, §3.7) | +| W7 | console after bind | „Felhom — a doboz össze van kötve. V" | a stray „V" (an unrenderable tick); the spent pairing code stays readable in the console's scroll-back | drop the glyph; clear the screen when bound | +| W8 | guide §4 note | „a doboz képernyője az összekötés után is a párosító kódot mutatja — ez ismert hiba" | no longer true: the console now says „össze van kötve" | guide edit (§3.7) | +| W9 | dashboard yellow bar | link „Helyreállítási kód létrehozása →" in default bright blue on dark | unstyled, low contrast (design rule) | style as the design-system link | +| W10 | recovery code page | „Mentési tároló (PBS) beállítva — felhom-pbs", „Helyreállítási (DR) szint aktív", „Titkosító eszköz telepítve — /usr/bin/age", „Rendszerjogosultság engedélyezve"; step numbers 1 → 5 → 6 | operator jargon; numbering gap | one plain line „Minden előfeltétel rendben" (details behind a toggle); renumber | +| W11 | Távoli mentés page | „restic + SFTP", „u629488-sub5@u629488-sub5.your-storagebox.de /home/felhom-repo" | jargon and a provider login shown to the household | „Felhom távoli tárhely (Németország)" | +| W12 | family card | „A név 1–32 karakter: kisbetű, szám, pont, kötőjel vagy aláhúzás." | refuses „Ödön", „Írisz" — a Hungarian family's own names; no hint to write „odon" | accept accented names (normalise the login) or say „ékezet nélkül: odon" | +| W13 | storage init | required „Csatlakoztatási név * /mnt/ … A meghajtó a /mnt/ útvonalra kerül." with an empty box | a household does not know what to type; the button silently does nothing (browser tooltip) | pre-fill `hdd_1`; say „Hagyd így, ha nem tudod" | +| W14 | storage page | „local · local-lvm lvmthin · pve/data · felhom-pbs … 10.77.0.1:felhom-offsite#c6:07:28:…" | operator detail on the household's page | hide behind „Részletek" | +| W15 | every install page | „Az alkalmazások csúcsterhelése meghaladhatja a rendelkezésre álló memóriát. Normál használat mellett ez nem okoz problémát." | **a promise the product did not keep** (R-1192): normal first-day use froze the box | remove the second sentence; refuse earlier | +| W16 | Immich „Első lépések" | „Külső könyvtár (opcionális): Administration → External Libraries → add /external/photos" | English inside Hungarian steps | translate or name the Hungarian menu | +| W17 | Paperless „Első lépések" | „Lépj be: felhasználó \"admin\"…" | wrong when the household set its own admin name (irisz) | read the installed value | +| W18 | Vaultwarden „Első lépések" | „A regisztráció alapból le van zárva…" | wrong when the household opened sign-up at install | depend on the chosen value | +| W19 | Mealie „Első lépések" | „Nyisd meg a mealie.tester4.test címet" | **wrong address**: the app is at recipes.tester4.test (R-498 shape) | use the installed subdomain | +| W20 | Jellyfin refusal | „Nincs elég memória … telepítés után 4150 MB kellene, a gép 3712 MB-ot tud adni. Távolíts el egy alkalmazást…" | clear; no link to a page that helps choose | link to the apps list sorted by memory | +| W21 | sharing page after „switch on" | „Beállítás mentve. A megosztási szolgáltatás előkészítése folyamatban…" | the service waits for the share PASSWORD, which the page does not say (log: „deploy skipped — household SMB password not set yet"); stays „Állapot: áll" for ever | „Állíts be egy megosztási jelszót — enélkül nem indul el." | +| W22 | a failed local restore | „Visszaállítás sikertelen: starting rallly after restore from unit: starting stack rallly: exit code 1 stderr: ...twork rallly_rallly-internal Creating …" (9202, R-1177) | raw English Docker output | a Hungarian sentence + what to do | +| W23 | Actual Budget | the whole app is English (v26.9.0) and shows „A new version of Actual is available!" | English; an upgrade nag the household cannot act on | catalog note | diff --git a/documentation/audits/rehearsal-2026-10-20/journal.md b/documentation/audits/rehearsal-2026-10-20/journal.md index 4c4f7fa4..eb5060bc 100644 --- a/documentation/audits/rehearsal-2026-10-20/journal.md +++ b/documentation/audits/rehearsal-2026-10-20/journal.md @@ -43,3 +43,19 @@ | 12:59:52 | B4 | Immich upload through `/api/assets`: the FIRST photo hangs 300 s and times out | | ~13:05 → | B4 | **THE BOX STOPS ANSWERING.** The dashboard's `/api/health` gives no answer in 10–15 s; the VM reads ~4 GB/min from its disk (158 GB → 209 GB in 15 min) while network traffic stands still; ping fine. 13:12 the upload stopped (the family gives up) — no recovery 10 min later. **The hub reads the box ONLINE / OK all along** (host memory 39 %, controller OK, 13:22). Likely: the apps' own background work after the uploads (Paperless OCR of 53 PDFs, Immich's analysis, Nextcloud) on a guest booked to 98 % of its memory — NOT measured (no shell in the box) | | 13:24 | B4 | no inside view of the box — tried: root SSH with the install-time password → „Permission denied" (replaced at step 4b, by design); DooPlex's key → denied; the hub-vaulted recovery password → operator-only reveal (the token is refused); the agent's local API token → only on the box. So the stall is described from outside only | +| 14:00:01 | B4 | the box answers again by itself (~55 min after the freeze began) — and freezes again within minutes (14:05–14:10, 4 GB/min of disk reads) | +| 14:11:06 | B4 | **the family pulls the plug** (VM power off 15 s, on) → `/api/health` 200 at 14:13:43 (2 min 22 s); the box's own history: load 139–152 at 13:33/13:55, no samples 12:57–13:33; the guest has 4096 MB in all, 3638 MB booked by the 8 apps | +| 14:23 | B4 | what survived: Paperless 47 documents (8 failed: the 100-page, the password-protected, the scanned image-only PDF, and 5 ordinary invoices); Immich 149 photos; Nextcloud 251 of 3 393 files | +| 14:24–15:20 | B4 | gentle resume (one transfer at a time): Nextcloud tree complete except the 1.5 GiB file; health stayed 200 for 60 min | +| 14:42–14:58 | B4 | Vaultwarden: Ödön's account through the web vault (the page then shows an English extension ad); 50 logins in 4 folders + 2 attachments through the official `bw` CLI (2024.9 was refused 422 — the CLI must match the server; 2026.7.0 worked). Folder SHARED between two members: NOT done (needs an organisation). BookStack: API token made on the admin's own page; a book + 5 pages, each with an image. Actual Budget (English-only UI, v26.9.0): server password, „Start budgeting", account „Családi számla", 200 transactions through its CSV dialog → −17 326 000 Ft = the CSV's sum | +| 15:00 | B4 | phone + computer walk: launcher, dashboard, app pages and „Útmutató" of Immich, Paperless, Vaultwarden, backups page — no sideways scroll; the backups page says honestly that it cannot prove the second drive is another disk (in a VM) | +| 15:11–15:24 | B4 | network share: the first „switch on" was a harness slip; then „Beállítás mentve. A megosztási szolgáltatás előkészítése folyamatban…" — but the service waits for the share PASSWORD (log: „deploy skipped — household SMB password not set yet") and the page never says so; password set → „Állapot: fut". The new share „Filmek" on the data disk has **Felhőmentés ON by default** | +| 15:26 | B4 | the two films (1.9 GB) copied onto the share over SMB in 35 s | +| 15:27 | B4 | Nextcloud 1.5 GiB file: a single WebDAV PUT is refused 413 „Request Entity Too Large" after 2 MB (a Windows/Mac WebDAV drive mount would fail on any file over ~1 GB); chunked upload started | +| 15:27:55 | B4 | **SECOND FREEZE** — one Immich upload + one chunked Nextcloud upload running; the Immich upload times out; disk reads since the reboot 5 GB → 91 GB. Uploads stopped by the family | +| 15:28–16:02 | B4 | the second freeze lasted ~35 min; back 16:02:49 — and froze again within a minute (the family's next look: an Immich login + a Nextcloud file count) | +| 16:13:36 | B4 | **plug pulled a second time** → health 200 at 16:16:06 (2 min 16 s). From now on `B4-use/memwatch.txt` records the box's own per-app memory/CPU every 30 s and `B4-use/health-log.txt` the health every minute | +| 16:16–16:28 | B4 | after the reboot: Immich server jumps to ~1.1 GB, Paperless to ~550 MB (re-reading its PDFs), load ~4.6 → calm (< 1) by 16:20; the real per-app total ~2.5 GB of the guest's 4 GB | +| 16:28:59 | B4 | „Mentés most" (guide §9): 2 min (the guide says ~20 s for two apps), 4 database dumps, success | +| 16:31:28 | B6 #5 | `tc netem` on the VM's own tap (demo-hp): upload 1 Mbit/s + 5 % loss both ways — harness note: this slows the LAN answers too, which a real slow internet line would not | +| 16:31:37 | B6 #5 | „Távoli mentés most" pressed (all 8 apps are ON for off-site by default; the share „Filmek" too) → status running, phase dump. The page also shows the household an SSH-key / known_hosts form („no blind TOFU", „ssh-keyscan") | diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-1-first-open-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-1-first-open-desktop-hu.png new file mode 100644 index 00000000..91ab52ad Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-1-first-open-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-2-now-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-2-now-desktop-hu.png new file mode 100644 index 00000000..ad2dfb33 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-2-now-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-3-signed-in-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-3-signed-in-desktop-hu.png new file mode 100644 index 00000000..3d8d3663 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-3-signed-in-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-4-budget-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-4-budget-desktop-hu.png new file mode 100644 index 00000000..e437f7d4 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-4-budget-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-5-account-dialog-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-5-account-dialog-desktop-hu.png new file mode 100644 index 00000000..caa46df4 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-5-account-dialog-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-6-account-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-6-account-desktop-hu.png new file mode 100644 index 00000000..5b2a9bcd Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-6-account-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-7-import-dialog-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-7-import-dialog-desktop-hu.png new file mode 100644 index 00000000..b2d63e1c Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-7-import-dialog-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-8-after-import-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-8-after-import-desktop-hu.png new file mode 100644 index 00000000..fe96a1e8 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-8-after-import-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-9-imported-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-9-imported-desktop-hu.png new file mode 100644 index 00000000..e16787ee Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-actual-9-imported-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-1-signup-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-1-signup-desktop-hu.png new file mode 100644 index 00000000..25a970c7 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-1-signup-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-2-after-continue-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-2-after-continue-desktop-hu.png new file mode 100644 index 00000000..447d3600 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-2-after-continue-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-3-master-filled-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-3-master-filled-desktop-hu.png new file mode 100644 index 00000000..1b74bf84 Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-3-master-filled-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-4-after-create-desktop-hu.png b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-4-after-create-desktop-hu.png new file mode 100644 index 00000000..1bdfe82f Binary files /dev/null and b/documentation/audits/rehearsal-2026-10-20/screens/b4-actual/b4-vault-4-after-create-desktop-hu.png differ diff --git a/documentation/audits/rehearsal-2026-10-20/tools/actual_fill.py b/documentation/audits/rehearsal-2026-10-20/tools/actual_fill.py new file mode 100644 index 00000000..095380f6 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/actual_fill.py @@ -0,0 +1,56 @@ +#!/opt/pw/bin/python +"""actual_fill.py — Kata signs in to Actual Budget, starts a fresh budget, adds a bank account and imports the 200 +synthetic HUF transactions through Actual's own „Import" dialog (B4). Env PW. Prints each step; screenshots each step.""" +import os, re, sys, time +from playwright.sync_api import sync_playwright + +OUT = "/root/shots/b4-actual" +n = [0] + + +def shot(pg, name): + n[0] += 1 + pg.evaluate("document.querySelectorAll('input[type=password]').forEach(e => e.value = '')") + pg.screenshot(path=f"{OUT}-{n[0] + 2}-{name}-desktop-hu.png", full_page=True) + + +def text(pg): + return re.sub(r"\s+", " ", pg.inner_text("body"))[:400] + + +with sync_playwright() as p: + b = p.chromium.launch(executable_path="/usr/bin/chromium", args=["--no-sandbox"]) + ctx = b.new_context(locale="hu-HU", ignore_https_errors=True, viewport={"width": 1366, "height": 768}, + storage_state="/root/work/state-dash.json") + pg = ctx.new_page() + pg.goto("https://budget.tester4.test/", wait_until="load"); pg.wait_for_timeout(5000) + pg.fill("input[type=password]", os.environ["PW"]); pg.keyboard.press("Enter"); pg.wait_for_timeout(6000) + print("1 after sign-in:", text(pg)); shot(pg, "signed-in") + for label in ("Start budgeting", "Start fresh", "Create new file", "Start using Actual"): + loc = pg.get_by_text(label, exact=False) + if loc.count(): + loc.first.click(); pg.wait_for_timeout(6000); print("2 pressed", repr(label), "->", text(pg)); break + shot(pg, "budget") + for label in ("Add account", "Add an account", "+ Add account"): + loc = pg.get_by_text(label, exact=False) + if loc.count(): + loc.first.click(); pg.wait_for_timeout(2500); print("3 pressed", repr(label), "->", text(pg)); break + for label in ("Create a local account", "Create local account", "Add local account"): + loc = pg.get_by_text(label, exact=False) + if loc.count(): + loc.first.click(); pg.wait_for_timeout(2000); break + shot(pg, "account-dialog") + inputs = pg.locator("[role=dialog] input, .modal input, input[name=name]") + print("4 dialog inputs:", inputs.count()) + if inputs.count(): + inputs.first.fill("Családi számla") + pg.get_by_role("button", name=re.compile("Create", re.I)).last.click(); pg.wait_for_timeout(4000) + print("5 after create:", text(pg)); shot(pg, "account") + with pg.expect_file_chooser(timeout=20000) as fc: + pg.get_by_role("button", name=re.compile("^Import", re.I)).first.click() + fc.value.set_files("/root/data/actual/tranzakciok.csv"); pg.wait_for_timeout(5000) + print("6 import dialog:", text(pg)); shot(pg, "import-dialog") + btn = pg.get_by_role("button", name=re.compile(r"^Import\b", re.I)) + btn.last.click(); pg.wait_for_timeout(8000) + print("7 after import:", text(pg)); shot(pg, "after-import") + b.close() diff --git a/documentation/audits/rehearsal-2026-10-20/tools/actual_import.py b/documentation/audits/rehearsal-2026-10-20/tools/actual_import.py new file mode 100644 index 00000000..83c478bd --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/actual_import.py @@ -0,0 +1,27 @@ +#!/opt/pw/bin/python +"""actual_import.py — the import step of actual_fill.py alone (the first run's click hit the account header's +„Import", not the dialog's): sign in, open „Családi számla", Import → the CSV → the dialog's own Import button.""" +import os, re +from playwright.sync_api import sync_playwright +with sync_playwright() as p: + b = p.chromium.launch(executable_path="/usr/bin/chromium", args=["--no-sandbox"]) + pg = b.new_context(locale="hu-HU", ignore_https_errors=True, viewport={"width": 1366, "height": 900}, + storage_state="/root/work/state-dash.json").new_page() + pg.goto("https://budget.tester4.test/", wait_until="load"); pg.wait_for_timeout(5000) + if pg.locator("input[type=password]").count(): + pg.fill("input[type=password]", os.environ["PW"]); pg.keyboard.press("Enter"); pg.wait_for_timeout(6000) + print("after sign-in:", re.sub(r"\s+", " ", pg.inner_text("body"))[:300]) + if not pg.get_by_text("Családi számla").count() and pg.get_by_text("My Finances").count(): + pg.get_by_text("My Finances").first.click(); pg.wait_for_timeout(8000) + pg.get_by_text("Családi számla").first.click(); pg.wait_for_timeout(3000) + with pg.expect_file_chooser(timeout=20000) as fc: + pg.get_by_role("button", name=re.compile("^Import", re.I)).first.click() + fc.value.set_files("/root/data/actual/tranzakciok.csv"); pg.wait_for_timeout(5000) + dlg = pg.locator("[role=dialog]").last + btns = dlg.locator("button").evaluate_all("els => els.map(e => e.innerText.trim())") + print("dialog buttons:", btns) + dlg.locator("button", has_text=re.compile(r"Import", re.I)).last.click() + pg.locator("[role=dialog]").last.wait_for(state="detached", timeout=180000); pg.wait_for_timeout(5000) + print("after import:", re.sub(r"\s+", " ", pg.inner_text("body"))[:300]) + pg.screenshot(path="/root/shots/b4-actual-9-imported-desktop-hu.png", full_page=True) + b.close() diff --git a/documentation/audits/rehearsal-2026-10-20/tools/apps.py b/documentation/audits/rehearsal-2026-10-20/tools/apps.py index 18f3b4c0..0216b733 100644 --- a/documentation/audits/rehearsal-2026-10-20/tools/apps.py +++ b/documentation/audits/rehearsal-2026-10-20/tools/apps.py @@ -177,6 +177,30 @@ def immich(sub, email_env, pw_env, name="Kovács Ödön"): say(f"immich: {ok} created, {dup} duplicates, {bad} refused") +# ---------------------------------------------------------------- BookStack (wiki, class B) — its own REST API +def bookstack(sub, tok_env): + base = f"https://{sub}.{DOMAIN}" + tid, tsec = os.environ[tok_env].split(":", 1) + H = {"Authorization": f"Token {tid}:{tsec}"} + st, out, _ = http("POST", base + "/api/books", {"name": "Családi wiki", "description": "A ház dolgai (szintetikus)"}, H) + book = json.loads(out)["id"] if st == 200 else None + say("bookstack book", st, book) + for r in manifest("bookstack"): + if not r["path"].endswith(".md"): + continue + md = open(os.path.join(DATA, r["path"]), encoding="utf-8").read() + name = md.splitlines()[0].lstrip("# ").strip() + st, out, _ = http("POST", base + "/api/pages", {"book_id": book, "name": name, "markdown": md}, H) + page = json.loads(out)["id"] if st == 200 else None + img = open(os.path.join(DATA, r["path"].replace("oldal_", "kep_").replace(".md", ".png")), "rb").read() + body, ct = multipart({"type": "gallery", "uploaded_to": page, "name": "kep.png"}, [("image", "kep.png", img, "image/png")]) + st2, out2, _ = http("POST", base + "/api/image-gallery", body, dict(H, **{"Content-Type": ct})) + url = json.loads(out2).get("url") if st2 == 200 else None + if url: + st3, _, _ = http("PUT", base + f"/api/pages/{page}", {"markdown": md + f"\n\n![kép]({url})\n"}, H) + say("bookstack page", name, st, "image", st2, "linked", st3 if url else "-") + + if __name__ == "__main__": fn = globals()[sys.argv[1]] fn(*sys.argv[2:]) diff --git a/documentation/audits/rehearsal-2026-10-20/tools/bookstack_token.py b/documentation/audits/rehearsal-2026-10-20/tools/bookstack_token.py new file mode 100644 index 00000000..a8883d43 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/bookstack_token.py @@ -0,0 +1,27 @@ +#!/opt/pw/bin/python +"""bookstack_token.py — the admin logs in to BookStack and creates an API token on his own account page (B4). +Env PW = the admin password. Token id + secret go to /root/work/bs-token (0600), never printed.""" +import os, re +from playwright.sync_api import sync_playwright +with sync_playwright() as p: + b = p.chromium.launch(executable_path="/usr/bin/chromium", args=["--no-sandbox"]) + pg = b.new_context(locale="hu-HU", ignore_https_errors=True, viewport={"width": 1366, "height": 768}).new_page() + pg.goto("https://wiki.tester4.test/login", wait_until="networkidle") + pg.fill("input[name=email]", "admin@admin.com"); pg.fill("input[name=password]", os.environ["PW"]) + pg.press("input[name=password]", "Enter"); pg.wait_for_load_state("networkidle") + print("after login:", pg.url) + for u in ("https://wiki.tester4.test/my-account/auth", "https://wiki.tester4.test/users/1"): + pg.goto(u, wait_until="networkidle") + print(u, "token links:", pg.locator("a").evaluate_all("els => els.map(e => e.getAttribute('href')).filter(h => h && /token/i.test(h))")) + link = pg.locator("a[href*='token'][href*='create']") + if link.count(): + break + print("create-token link found:", link.count()) + link.first.click(); pg.wait_for_load_state("networkidle") + pg.fill("input[name=name]", "csaladi-feltoltes") + pg.locator("main form button, #content form button").last.click(); pg.wait_for_load_state("networkidle") + vals = [v for v in pg.locator("input[readonly]").evaluate_all("els => els.map(e => e.value)") if v] + print("readonly values on the token page:", len(vals)) + fd = os.open("/root/work/bs-token", os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600) + os.write(fd, ("\n".join(vals[:2])).encode()); os.close(fd) + b.close() diff --git a/documentation/audits/rehearsal-2026-10-20/tools/films_put.sh b/documentation/audits/rehearsal-2026-10-20/tools/films_put.sh new file mode 100755 index 00000000..1ad21545 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/films_put.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# films_put.sh — the family copies its two films onto the „Filmek" share (SMB, user felhom; password in env PW). +cd /root/data/jellyfin/Filmek || exit 1 +for d in */; do + f=$(ls "$d"*.mkv); smbclient //felhom.tester4.test/Filmek -U felhom --password="$PW" -m SMB3 \ + -c "mkdir \"${d%/}\"; cd \"${d%/}\"; put \"$f\" \"$(basename "$f")\"" 2>&1 | grep -v "^Try\|^$" | tail -2 +done +smbclient //felhom.tester4.test/Filmek -U felhom --password="$PW" -m SMB3 -c "recurse ON; ls" 2>&1 | grep -i mkv diff --git a/documentation/audits/rehearsal-2026-10-20/tools/memwatch.py b/documentation/audits/rehearsal-2026-10-20/tools/memwatch.py new file mode 100644 index 00000000..0d508ca9 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/memwatch.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +"""memwatch.py — every 30 s, the box's own per-container memory/CPU (/api/metrics/containers/summary) + system memory +(/api/system/info), one line each, until killed. Run under sec (dashboard password). Diagnoses R-1192 from outside.""" +import json, os, sys, time +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))); import ctl +while True: + t = time.strftime("%H:%M:%SZ", time.gmtime()) + try: + c, d = ctl.call("GET", "/api/system/info", timeout=25); s = (d.get("data") or {}).get("system") or {} + c2, d2 = ctl.call("GET", "/api/metrics/containers/summary", timeout=25) + top = sorted(d2.get("data") or [], key=lambda x: -x.get("mem_usage_mb", 0))[:8] + print(t, f"used={s.get('used_mem_mb')}MB avail={s.get('avail_mem_mb')}MB load1={s.get('load_avg_1')} cpu={round(s.get('cpu_percent') or 0)}%", + " | ".join(f"{x['name']}:{round(x['mem_usage_mb'])}/{x['mem_limit_mb']}MB {round(x['cpu_percent'])}%" for x in top), flush=True) + except Exception as e: # noqa: BLE001 + print(t, "NO ANSWER", type(e).__name__, flush=True) + time.sleep(30) diff --git a/documentation/audits/rehearsal-2026-10-20/tools/nc_bigchunk.sh b/documentation/audits/rehearsal-2026-10-20/tools/nc_bigchunk.sh new file mode 100755 index 00000000..e9c28713 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/nc_bigchunk.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# the 1.5 GiB file via Nextcloud's chunked-upload v2 (what its own clients do): MKCOL an upload dir, PUT numbered +# 50 MB chunks, MOVE .file onto the target. Prints status codes only. +set -u +U=odon; B=https://cloud.tester4.test/remote.php/dav; F=/root/data/nextcloud/Csalad/nagy_fajl_1_5GB.bin +ID=rehearsal-$(date +%s); D=$B/files/$U/Csalad/nagy_fajl_1_5GB.bin +c() { curl -sk -u "$U:$PW" -o /dev/null -w "%{http_code}" "$@"; } +echo "MKCOL $(c -X MKCOL -H "Destination: $D" "$B/uploads/$U/$ID")" +SIZE=$(stat -c %s "$F"); CH=$((50*1024*1024)); n=0; off=0; codes="" +while [ $off -lt $SIZE ]; do + n=$((n+1)); name=$(printf '%05d' $n) + code=$(dd if="$F" bs=$CH skip=$((n-1)) count=1 status=none | c -X PUT -H "Destination: $D" -H "OC-Total-Length: $SIZE" --data-binary @- "$B/uploads/$U/$ID/$name") + codes="$codes $code"; off=$((off+CH)) +done +echo "PUT $n chunks:$(echo $codes | tr ' ' '\n' | sort | uniq -c | tr '\n' ' ')" +echo "MOVE $(c -X MOVE -H "Destination: $D" -H "OC-Total-Length: $SIZE" "$B/uploads/$U/$ID/.file")" diff --git a/documentation/audits/rehearsal-2026-10-20/tools/nc_bigput.sh b/documentation/audits/rehearsal-2026-10-20/tools/nc_bigput.sh new file mode 100755 index 00000000..f9e55837 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/nc_bigput.sh @@ -0,0 +1,5 @@ +#!/bin/bash +# one WebDAV PUT of the 1.5 GiB file, as a browser or client would send it; print only the answer's status + title +curl -sk -u "odon:$PW" -T /root/data/nextcloud/Csalad/nagy_fajl_1_5GB.bin --max-time 120 -o /root/work/bigput.out -w "%{http_code} after %{time_total}s, sent %{size_upload} B\n" \ + "https://cloud.tester4.test/remote.php/dav/files/odon/Csalad/nagy_fajl_1_5GB.bin" +grep -o "[^<]*\|

[^<]*

" /root/work/bigput.out | head -3; rm -f /root/work/bigput.out diff --git a/documentation/audits/rehearsal-2026-10-20/tools/offpoll.py b/documentation/audits/rehearsal-2026-10-20/tools/offpoll.py new file mode 100644 index 00000000..256bf11f --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/offpoll.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 +"""offpoll.py N SECONDS — print the off-site run's own status (the page's /backup/offbox/status) every SECONDS, N times.""" +import json, os, sys, time +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))); import ctl +for i in range(int(sys.argv[1])): + t = time.strftime("%H:%M:%SZ", time.gmtime()) + try: + c, d = ctl.call("GET", "/backup/offbox/status", timeout=90) + p = d.get("progress") or {} + print(t, d.get("status"), f"phase={p.get('phase')} app={p.get('current_app')} {p.get('percent')}% {p.get('done_human')}/{p.get('total_human')}" + f" files {p.get('files_done')}/{p.get('total_files')} snaps={d.get('snapshots')} last_err={str(d.get('last_error'))[:160]!r}", flush=True) + except Exception as e: # noqa: BLE001 + print(t, "NO ANSWER", type(e).__name__, flush=True) + time.sleep(int(sys.argv[2])) diff --git a/documentation/audits/rehearsal-2026-10-20/tools/share_setup.py b/documentation/audits/rehearsal-2026-10-20/tools/share_setup.py new file mode 100644 index 00000000..0bb4cfd0 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/share_setup.py @@ -0,0 +1,34 @@ +#!/opt/pw/bin/python +"""share_setup.py — the household's „Hálózati megosztás" page: sharing on, the share password, a „Filmek" share on the +data disk (B4). Env PW = the share password. Prints the page's answer after each act; screenshots with fields blank.""" +import os, re +from playwright.sync_api import sync_playwright +OUT = "/root/shots/b4-share" +def txt(pg): return re.sub(r"\s+", " ", pg.inner_text("main") if pg.locator("main").count() else pg.inner_text("body")) +with sync_playwright() as p: + b = p.chromium.launch(executable_path="/usr/bin/chromium", args=["--no-sandbox"]) + pg = b.new_context(locale="hu-HU", ignore_https_errors=True, viewport={"width": 1366, "height": 900}, + storage_state="/root/work/state-dash.json").new_page() + pg.goto("https://felhom.tester4.test/sharing", wait_until="networkidle") + cb = pg.get_by_label(re.compile("Megosztás engedélyezése")) + if not cb.is_checked(): + cb.check() + pg.get_by_role("button", name="Mentés").first.click(); pg.wait_for_load_state("networkidle"); pg.wait_for_timeout(4000) + print("1 enabled:", re.search(r"Állapot: \S+", txt(pg)).group(0) if re.search(r"Állapot: \S+", txt(pg)) else txt(pg)[:200]) + pw = pg.locator("input[type=password]") + for i in range(pw.count()): + pw.nth(i).fill(os.environ["PW"]) + pg.get_by_role("button", name="Jelszó mentése").click(); pg.wait_for_load_state("networkidle"); pg.wait_for_timeout(3000) + print("2 password saved; page says:", [m for m in re.findall(r"(?:jelszó[^.]{0,80}\.)", txt(pg))][:2]) + pg.get_by_label(re.compile("Megosztás neve")).fill("Filmek") + pg.get_by_label(re.compile("Tárhely")).select_option(label=re.compile("Családi adatlemez")) if False else None + sel = pg.locator("select").last + opts = sel.locator("option").evaluate_all("els => els.map(e => [e.value, e.textContent.trim()])") + val = [v for v, t in opts if "Családi" in t][0] + sel.select_option(val) + pg.get_by_role("button", name="Megosztás létrehozása").click(); pg.wait_for_load_state("networkidle"); pg.wait_for_timeout(4000) + t = txt(pg); i = t.find("Megosztott mappák") + print("3 shares:", t[i:i + 400]) + pg.evaluate("document.querySelectorAll('input[type=password]').forEach(e => e.value = '')") + pg.screenshot(path=f"{OUT}-2-after-setup-desktop-hu.png", full_page=True) + b.close() diff --git a/documentation/audits/rehearsal-2026-10-20/tools/ui.py b/documentation/audits/rehearsal-2026-10-20/tools/ui.py index 832ce0c8..62bae587 100644 --- a/documentation/audits/rehearsal-2026-10-20/tools/ui.py +++ b/documentation/audits/rehearsal-2026-10-20/tools/ui.py @@ -52,7 +52,7 @@ with sync_playwright() as p: for s in spec["steps"]: try: if "goto" in s: - r = pg.goto(s["goto"], wait_until="networkidle", timeout=60000) + r = pg.goto(s["goto"], wait_until=s.get("until", "networkidle"), timeout=60000) print(f"goto {mask(pg.url)} -> {r.status if r else '-'} {pg.title()!r}") elif "fill" in s: v = os.environ[s["env"]] if "env" in s else s["value"] @@ -68,7 +68,10 @@ with sync_playwright() as p: nav_next = False else: target.first.click() - pg.wait_for_load_state("networkidle", timeout=60000) + try: + pg.wait_for_load_state("networkidle", timeout=15000) + except Exception: # an app that keeps a live connection never goes idle — not a failure + pass print(f"click {s.get('click') or s.get('click_text')!r} -> {mask(pg.url)} status={resp['s']}") elif "expect_nav" in s: nav_next = True diff --git a/documentation/audits/rehearsal-2026-10-20/tools/vault_fill.sh b/documentation/audits/rehearsal-2026-10-20/tools/vault_fill.sh new file mode 100755 index 00000000..59e601f0 --- /dev/null +++ b/documentation/audits/rehearsal-2026-10-20/tools/vault_fill.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# vault_fill.sh — Ödön's 50 logins (folders from logins.json) + 2 attachments into Vaultwarden via the official bw CLI. +# Env: EM (account e-mail), PW (master password). Site passwords are random per item (synthetic sites) and not kept. +set -u +export NODE_TLS_REJECT_UNAUTHORIZED=0 BITWARDENCLI_APPDATA_DIR=/root/work/bwdata +BW=/usr/local/bin/bw +rm -rf /root/work/bwdata; mkdir -p -m 700 /root/work/bwdata +$BW config server https://vault.tester4.test >/dev/null +export BW_SESSION=$($BW login "$EM" --passwordenv PW --raw 2>/dev/null) +[ -n "$BW_SESSION" ] || { echo "bw login FAILED"; exit 1; } +echo "bw login ok" +python3 - > /root/work/vw-import.json <<'PY' +import json, secrets, string, uuid +L = json.load(open("/root/data/vaultwarden/logins.json", encoding="utf-8")) +folders = sorted({x["folder"] for x in L}); fid = {f: str(uuid.uuid4()) for f in folders} +a = string.ascii_letters + string.digits +items = [{"type": 1, "name": x["name"], "folderId": fid[x["folder"]], "favorite": False, "notes": None, "login": {"username": x["username"], + "password": "".join(secrets.choice(a) for _ in range(18)), "uris": [{"uri": x["uri"]}]}} for x in L] +print(json.dumps({"encrypted": False, "folders": [{"id": fid[f], "name": f} for f in folders], "items": items})) +PY +$BW import bitwardenjson /root/work/vw-import.json > /root/work/imp.out 2>&1; grep -oE "[^<]*|[0-9]{3} [A-Z][a-z ]+|Imported[^\n]*|error[^\n]{0,120}" /root/work/imp.out | head -5; head -c 300 /root/work/imp.out; echo; rm -f /root/work/imp.out +shred -u /root/work/vw-import.json +$BW sync >/dev/null +for k in 0 1; do + id=$($BW list items --search "bank" 2>/dev/null | python3 -c "import json,sys; print(json.load(sys.stdin)[$k]['id'])" 2>/dev/null) + [ -n "$id" ] && $BW create attachment --file /root/data/vaultwarden/melleklet_$k.pdf --itemid "$id" >/dev/null 2>&1 && echo "attachment $k on item $id" +done +echo "items now: $($BW list items 2>/dev/null | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))') folders: $($BW list folders 2>/dev/null | python3 -c 'import json,sys; print(len(json.load(sys.stdin)))')" +$BW logout >/dev/null 2>&1; rm -rf /root/work/bwdata