feat: SIGHUP hot reload for headless config updates

Add signal handler that calls rehash() on SIGHUP, logging results
instead of sending to a client. Useful for systemd and container
environments where no IRC client is attached. Update docs with
channel key config, hot reload section, and roadmap checkoffs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-21 19:03:35 +01:00
parent c11bd5555a
commit 2ab5f95476
6 changed files with 91 additions and 9 deletions

View File

@@ -364,6 +364,7 @@ port = 6697 # server port (default: 6697 if tls, 6667 otherwise)
tls = true # use TLS for server connection
nick = "mynick" # desired IRC nick (set after probation)
channels = ["#test"] # channels to join (after probation)
channel_keys = { "#secret" = "hunter2" } # keys for +k channels (optional)
autojoin = true # auto-join channels on ready (default: true)
password = "" # IRC server password (optional, for PASS command)
```
@@ -488,10 +489,11 @@ Responses arrive as NOTICE messages from `*bouncer`.
| `REHASH` | Reload config file, add/remove/reconnect networks |
| `ADDNETWORK <name> key=val ...` | Create a network at runtime |
| `DELNETWORK <name>` | Stop and remove a network |
| `AUTOJOIN <network> +/-#channel` | Add or remove channel from autojoin list |
| `AUTOJOIN <network> +#channel [key]` | Add channel (with optional key for +k channels) |
| `AUTOJOIN <network> -#channel` | Remove channel from autojoin list |
**ADDNETWORK keys:** `host` (required), `port`, `tls` (yes/no), `nick`,
`channels` (comma-separated), `password`.
`channels` (comma-separated), `channel_keys` (`#chan=key,...`), `password`.
### NickServ
@@ -536,6 +538,7 @@ Responses arrive as NOTICE messages from `*bouncer`.
/msg *bouncer ADDNETWORK oftc host=irc.oftc.net port=6697 tls=yes channels=#test
/msg *bouncer DELNETWORK oftc
/msg *bouncer AUTOJOIN libera +#newchannel
/msg *bouncer AUTOJOIN libera +#secret hunter2
/msg *bouncer AUTOJOIN libera -#oldchannel
/msg *bouncer IDENTIFY libera
/msg *bouncer REGISTER libera
@@ -625,6 +628,62 @@ farm_interval = 3600 # seconds between attempts per network
farm_max_accounts = 10 # stop farming when this many verified accounts exist
```
## Channel Keys
Channels with mode `+k` require a key to join. Configure keys in TOML:
```toml
[networks.libera]
channels = ["#secret", "#public"]
channel_keys = { "#secret" = "hunter2" }
```
Keys are used automatically during autojoin and KICK rejoin. To add a keyed
channel at runtime:
```
/msg *bouncer AUTOJOIN libera +#secret hunter2
```
Removing a channel also clears its key:
```
/msg *bouncer AUTOJOIN libera -#secret
```
## Hot Reload
The bouncer reloads its config file on `SIGHUP` or via the `REHASH` command.
Both use the same logic: re-read TOML, diff networks (add/remove/reconnect),
and update mutable fields (channels, channel_keys, nick, password).
### SIGHUP
```bash
kill -HUP $(pidof bouncer)
```
Results are logged (no client connection needed). Useful for headless
operation (systemd, containers).
### REHASH command
```
/msg *bouncer REHASH
```
Results are sent back as NOTICE messages.
### What changes on reload
| Field | Effect |
|-------|--------|
| Network host/port/tls/proxy | Network reconnected |
| channels, channel_keys, nick, password | Updated in-place |
| notify_url, notify_cooldown, etc. | Notifier recreated |
| farm_enabled, farm_interval, etc. | Farm started/stopped |
| bind, port, password, client_tls | Warning logged (restart required) |
## Stopping
Press `Ctrl+C` or send `SIGTERM`. The bouncer shuts down gracefully, closing