Commit 2fbd6a8
fix: replace cron with systemd for demo server (prevents process leak) (#1110)
* fix(internal): replace cron with systemd for demo server to prevent process leaks
Weekly cron was spawning new hamcp-test-env processes without killing old ones,
accumulating 60+ zombie processes over 34 days (one new process per week per cron run).
Systemd service ensures a single instance via ExecStart, auto-restarts on failure,
and the weekly timer triggers a clean restart via ExecStartPost.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(internal): add sudoers rule and use sudo in update service for hamcp-demo restart
Without the sudoers rule, the weekly update timer (running as SETUP_USER) cannot
restart the systemd service. ExecStartPost also needs explicit sudo to cross the
privilege boundary since it inherits the User= context from ExecStart.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(internal): guard against SETUP_USER=root and rewrite README for fresh VM setup
Script now exits early with a clear error if run as root directly instead of via sudo,
preventing silent misconfiguration where everything ends up under /root.
README updated: added VM specs (2vCPU/4GB/20GB), clarified sudo vs su- requirement,
replaced stale crontab references with systemd commands, corrected log path
(/tmp/hamcp.log -> /var/log/hamcp-demo.log), and added full reset procedure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(internal): extend HA wait to 15 min and make timeout a warning not an error
On first install the HA image (~600MB) must be pulled before the container starts,
which takes ~10 minutes. The previous 3-minute wait caused a false failure exit.
Now waits up to 15 minutes (180 × 5s) and on timeout emits a warning instead of
exiting 1, since the service continues running and HA will come up on its own.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(internal): address Gemini review comments on update service and logging
- Run update service as root with sudo -u for git pull (cleaner than sudoers rule;
ExecStartPost can then call systemctl restart directly without privilege escalation)
- Add network-online.target dependency to update service (git pull needs network)
- Remove sudoers rule (no longer needed now update service runs as root)
- Drop file logging from both services (systemd journal handles rotation automatically;
unbounded /var/log/hamcp-demo.log was a disk exhaustion risk)
- Add pkill on migration to clean up any leaked hamcp-test-env processes from old setup
- Update README and success output to remove stale log file references
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(internal): address second round of Gemini review comments
- Remove Requires= from timer unit (caused service to trigger on timer start,
defeating the OnCalendar schedule; timer auto-triggers matching service by name)
- Use sudo -i -u instead of sudo -u for git pull (ensures $HOME is set correctly)
- Add docker image prune -af to update service (old cron pruned images; without
this unused images accumulate and fill disk over time)
- Remove stale sudoers rule step from README and renumber (rule was dropped in
previous commit when update service moved to running as root)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(internal): use image column to find container name in success banner
The ancestor filter returns empty immediately after systemctl restart
because Docker hasn't finished registering image metadata for the new
container. Grep the image column instead, which is always populated.
* fix(internal): send SIGINT to hamcp-test-env on service stop
hamcp-test-env only handles KeyboardInterrupt (SIGINT) for cleanup.
systemd's default stop signal is SIGTERM, which Python does not convert
to KeyboardInterrupt, so the HA container was left running after restart.
KillSignal=SIGINT ensures the cleanup path runs on every stop/restart.
* fix(internal): avoid creating empty crontab on fresh hosts during migration
On a host with no existing crontab, crontab -l exits 1 with empty stdout,
grep -v outputs nothing, and crontab - installs a blank crontab as a side
effect. Only rewrite the crontab when the old hamcp-test-env entries are
actually present.
* fix(internal): add Wants=network-online.target and stop before cleanup
Two fixes from Patch76 follow-up:
- Add Wants=network-online.target to hamcp-demo.service so the unit
pulls the target on cold boot (After= alone only orders, doesn't pull)
- systemctl stop hamcp-demo before pkill on re-runs, preventing systemd
from auto-restarting the unit while cleanup is in progress
* fix(internal): use sudo -i -u for uv install to ensure correct \$HOME
sudo -u without -i doesn't reset \$HOME when always_set_home is off,
causing uv to install to /root/.local/bin instead of the target user's
home. The check for an existing install then always fails on those hosts.
* fix(internal): handle pipefail on crontab migration and fix README
- Wrap grep -v in { ... || true; } so pipefail doesn't abort when the
legacy crontab contains only hamcp-test-env lines (grep exits 1 with
no output, which is exactly the migration target case)
- Clarify README timing: 3-10 min on re-runs, up to 15 min on first
install when the ~600MB HA image must be pulled
- Fix full-reset snippet: filter by ancestor image instead of stopping
all containers, matching what step 9 of the script already does
* fix(internal): run demo update timer daily instead of weekly
Daily git pull ensures the demo server picks up new releases within 24h
rather than waiting up to 7 days.
* docs(internal): update README timer frequency to daily
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent d4d9d0a commit 2fbd6a8
2 files changed
Lines changed: 152 additions & 76 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
5 | 13 | | |
6 | 14 | | |
7 | 15 | | |
8 | | - | |
| 16 | + | |
| 17 | + | |
9 | 18 | | |
10 | 19 | | |
11 | 20 | | |
12 | 21 | | |
13 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
14 | 31 | | |
15 | 32 | | |
16 | 33 | | |
17 | 34 | | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
36 | 45 | | |
37 | | - | |
| 46 | + | |
38 | 47 | | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
| 48 | + | |
44 | 49 | | |
45 | | - | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
46 | 55 | | |
47 | | - | |
48 | | - | |
49 | | - | |
| 56 | + | |
50 | 57 | | |
51 | | - | |
52 | | - | |
53 | | - | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
54 | 61 | | |
55 | | - | |
| 62 | + | |
| 63 | + | |
56 | 64 | | |
57 | | - | |
| 65 | + | |
| 66 | + | |
58 | 67 | | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
64 | 72 | | |
65 | 73 | | |
66 | 74 | | |
67 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
68 | 79 | | |
69 | 80 | | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | 81 | | |
74 | 82 | | |
75 | 83 | | |
76 | 84 | | |
77 | | - | |
| 85 | + | |
78 | 86 | | |
79 | | - | |
| 87 | + | |
80 | 88 | | |
81 | 89 | | |
82 | 90 | | |
83 | 91 | | |
84 | 92 | | |
85 | | - | |
86 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
87 | 96 | | |
88 | 97 | | |
89 | 98 | | |
90 | 99 | | |
91 | | - | |
92 | | - | |
| 100 | + | |
| 101 | + | |
93 | 102 | | |
94 | | - | |
95 | | - | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
96 | 110 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
66 | 67 | | |
67 | 68 | | |
68 | 69 | | |
69 | | - | |
| 70 | + | |
70 | 71 | | |
71 | 72 | | |
72 | 73 | | |
| |||
82 | 83 | | |
83 | 84 | | |
84 | 85 | | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
94 | 150 | | |
95 | 151 | | |
96 | 152 | | |
| |||
146 | 202 | | |
147 | 203 | | |
148 | 204 | | |
149 | | - | |
150 | | - | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
151 | 208 | | |
| 209 | + | |
| 210 | + | |
152 | 211 | | |
153 | 212 | | |
154 | | - | |
155 | | - | |
156 | | - | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
157 | 216 | | |
158 | 217 | | |
159 | 218 | | |
160 | | - | |
161 | | - | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
162 | 224 | | |
| 225 | + | |
163 | 226 | | |
164 | 227 | | |
165 | 228 | | |
166 | | - | |
| 229 | + | |
167 | 230 | | |
168 | 231 | | |
169 | 232 | | |
170 | 233 | | |
171 | | - | |
172 | | - | |
173 | | - | |
174 | | - | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
175 | 237 | | |
176 | 238 | | |
177 | 239 | | |
| |||
183 | 245 | | |
184 | 246 | | |
185 | 247 | | |
186 | | - | |
| 248 | + | |
187 | 249 | | |
188 | 250 | | |
189 | 251 | | |
190 | | - | |
191 | | - | |
192 | | - | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
193 | 255 | | |
0 commit comments