Fix: prevent wg0.conf truncation when remove_peer splits blocks
Unit Tests / test (push) Successful in 7m46s
Unit Tests / test (push) Successful in 7m46s
_write_config() was stripping trailing newlines, causing the next
add_cell_peer() to create a single-newline separator between [Interface]
and [Peer] blocks instead of the required blank line. On the following
remove_peer() call, split('\n\n') treated both sections as one block,
matched the PublicKey filter, and wrote an empty string — destroying the
[Interface] section and reverting to the hardcoded SERVER_ADDRESS fallback.
Two-part fix:
1. _write_config() always ends content with a newline
2. remove_peer() normalises single-newline [Peer] headers to blank-line
separators before splitting, and refuses to write if [Interface] would
be lost
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -294,6 +294,8 @@ class WireGuardManager(BaseServiceManager):
|
||||
return self.generate_config()
|
||||
|
||||
def _write_config(self, content: str):
|
||||
if content and not content.endswith('\n'):
|
||||
content += '\n'
|
||||
with open(self._config_file(), 'w') as f:
|
||||
f.write(content)
|
||||
self._syncconf()
|
||||
@@ -805,12 +807,20 @@ class WireGuardManager(BaseServiceManager):
|
||||
"""Remove the [Peer] block matching public_key from wg0.conf."""
|
||||
try:
|
||||
content = self._read_config()
|
||||
# Split on blank lines between blocks
|
||||
raw_blocks = ('\n' + content).split('\n\n')
|
||||
# Normalise to ensure blank-line block separators before splitting.
|
||||
# Without this, a file written without trailing newline will merge
|
||||
# [Interface] and the first [Peer] into one block, and the filter
|
||||
# below would then delete [Interface] together with the peer.
|
||||
normalised = content.replace('\n[Peer]', '\n\n[Peer]')
|
||||
raw_blocks = ('\n' + normalised).split('\n\n')
|
||||
new_blocks = [
|
||||
b for b in raw_blocks
|
||||
if not (f'PublicKey = {public_key}' in b and '[Peer]' in b)
|
||||
]
|
||||
# Never write an empty file — that would destroy the [Interface] block.
|
||||
if not any('[Interface]' in b for b in new_blocks):
|
||||
logger.error('remove_peer: [Interface] block would be lost — aborting write')
|
||||
return False
|
||||
self._write_config('\n\n'.join(new_blocks).lstrip('\n'))
|
||||
return True
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user