fix: split-horizon DNS zone uses WireGuard IP, not Docker bridge IP
Unit Tests / test (push) Successful in 7m31s
Unit Tests / test (push) Successful in 7m31s
VPN peers can reach Caddy via the host's WireGuard interface (10.0.0.1), not via the Docker bridge IP (172.20.0.2) which is unreachable outside the container network. _bootstrap_dns now calls _get_wg_server_ip() instead of ip_utils.get_service_ips() so the internal zone returns a routable address for service subdomains. Also log config save failures instead of silently swallowing them — the silent PermissionError/OSError was masking write failures and making it impossible to diagnose why installed services disappeared after container restarts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -260,6 +260,39 @@ class TestConfigManager(unittest.TestCase):
|
||||
"import must not inject zero-filled entries for absent services")
|
||||
|
||||
|
||||
class TestSaveAllConfigs(unittest.TestCase):
|
||||
"""_save_all_configs must log errors instead of silently swallowing them."""
|
||||
|
||||
def setUp(self):
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.config_file = os.path.join(self.temp_dir, 'cell_config.json')
|
||||
self.data_dir = os.path.join(self.temp_dir, 'data')
|
||||
os.makedirs(self.data_dir, exist_ok=True)
|
||||
self.cm = ConfigManager(self.config_file, self.data_dir)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
def test_save_failure_is_logged_not_silenced(self):
|
||||
"""When the config file cannot be written, _save_all_configs must log an error."""
|
||||
with patch('builtins.open', side_effect=OSError('disk full')):
|
||||
with self.assertLogs('config_manager', level='ERROR') as log:
|
||||
self.cm._save_all_configs()
|
||||
self.assertTrue(
|
||||
any('write failed' in msg or 'NOT persisted' in msg for msg in log.output),
|
||||
f'Expected error about write failure in logs, got: {log.output}',
|
||||
)
|
||||
|
||||
def test_save_success_does_not_log_error(self):
|
||||
"""A successful save must not produce error logs."""
|
||||
import logging
|
||||
with self.assertLogs('config_manager', level='DEBUG') as cm:
|
||||
logging.getLogger('config_manager').debug('sentinel')
|
||||
self.cm._save_all_configs()
|
||||
errors = [m for m in cm.output if 'ERROR' in m and 'write failed' in m]
|
||||
self.assertEqual(errors, [], 'Unexpected write-failure error on a successful save')
|
||||
|
||||
|
||||
class TestGetEffectiveDomain(unittest.TestCase):
|
||||
"""Tests for ConfigManager.get_effective_domain and get_internal_domain."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user