feat: Settings changes now apply to real service config files and restart containers
Each service manager now has apply_config() that writes to the actual config:
- network: dhcp_range → dnsmasq.conf (reload cell-dhcp), ntp_servers → chrony.conf
(restart cell-ntp), domain → dnsmasq.conf domain= line
- email: domain → mailserver.env OVERRIDE_HOSTNAME + POSTMASTER_ADDRESS,
restart cell-mail
- wireguard: port/address/private_key → wg0.conf ListenPort/Address/PrivateKey,
restart cell-wireguard
- calendar: port → radicale config hosts=, restart cell-radicale
PUT /api/config now calls apply_config() after persisting JSON, and returns
{restarted: [...], warnings: [...]} so Settings UI can show which containers
were restarted. _restart_container() helper added to BaseServiceManager.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -158,6 +158,49 @@ class WireGuardManager(BaseServiceManager):
|
||||
f.write(content)
|
||||
self._syncconf()
|
||||
|
||||
def apply_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Update wg0.conf interface fields and restart cell-wireguard."""
|
||||
restarted = []
|
||||
warnings = []
|
||||
cf = self._config_file()
|
||||
if not os.path.exists(cf):
|
||||
warnings.append('wg0.conf not found — skipping')
|
||||
return {'restarted': restarted, 'warnings': warnings}
|
||||
try:
|
||||
with open(cf) as f:
|
||||
lines = f.readlines()
|
||||
|
||||
def _set_iface_field(lines, key, value):
|
||||
result = []
|
||||
for l in lines:
|
||||
if l.strip().startswith(f'{key} =') or l.strip().startswith(f'{key}='):
|
||||
result.append(f'{key} = {value}\n')
|
||||
else:
|
||||
result.append(l)
|
||||
return result
|
||||
|
||||
changed = False
|
||||
if 'port' in config and config['port']:
|
||||
lines = _set_iface_field(lines, 'ListenPort', config['port'])
|
||||
changed = True
|
||||
if 'address' in config and config['address']:
|
||||
lines = _set_iface_field(lines, 'Address', config['address'])
|
||||
changed = True
|
||||
if 'private_key' in config and config['private_key']:
|
||||
lines = _set_iface_field(lines, 'PrivateKey', config['private_key'])
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
with open(cf, 'w') as f:
|
||||
f.writelines(lines)
|
||||
self._restart_container('cell-wireguard')
|
||||
restarted.append('cell-wireguard')
|
||||
except Exception as e:
|
||||
warnings.append(f"wg0.conf update failed: {e}")
|
||||
logger.error(f"apply_config error: {e}")
|
||||
|
||||
return {'restarted': restarted, 'warnings': warnings}
|
||||
|
||||
def _syncconf(self):
|
||||
"""Sync live WireGuard peers using 'wg set' — never touches [Interface] settings.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user