fix: apply_domain now removes all stale zone files when renaming
Previously the loop broke after processing the first zone file it found. If dev.zone already existed (created by apply_ip_range), it would be processed and the loop would stop — leaving any other zone files (e.g. cell.zone from an earlier domain) in place. get_dns_records() reads all .zone files so the stale zone appeared doubled in the UI. Fix: collect all non-local zone files first, write the target, then delete every file that is not the current domain's zone. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+19
-12
@@ -419,30 +419,37 @@ class NetworkManager(BaseServiceManager):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
warnings.append(f"Corefile domain update failed: {e}")
|
warnings.append(f"Corefile domain update failed: {e}")
|
||||||
|
|
||||||
# 3. Update zone file: rename and rewrite $ORIGIN / SOA
|
# 3. Update zone file: rename and rewrite $ORIGIN / SOA, remove stale zones
|
||||||
try:
|
try:
|
||||||
dns_data = os.path.join(self.data_dir, 'dns')
|
dns_data = os.path.join(self.data_dir, 'dns')
|
||||||
if os.path.isdir(dns_data):
|
if os.path.isdir(dns_data):
|
||||||
# Find existing primary zone file (anything not named 'local')
|
dst = os.path.join(dns_data, f'{domain}.zone')
|
||||||
for fname in os.listdir(dns_data):
|
# Find the best source: prefer a non-target zone (old domain) so we
|
||||||
if fname.endswith('.zone') and 'local' not in fname:
|
# can migrate its content; fall back to the target zone itself.
|
||||||
src = os.path.join(dns_data, fname)
|
zone_files = [
|
||||||
|
os.path.join(dns_data, f)
|
||||||
|
for f in os.listdir(dns_data)
|
||||||
|
if f.endswith('.zone') and 'local' not in f
|
||||||
|
]
|
||||||
|
src = next((p for p in zone_files if p != dst), dst)
|
||||||
|
if os.path.exists(src):
|
||||||
with open(src) as f:
|
with open(src) as f:
|
||||||
zone_content = f.read()
|
zone_content = f.read()
|
||||||
# Detect old domain from $ORIGIN line
|
|
||||||
m = re.search(r'^\$ORIGIN\s+(\S+)', zone_content, re.MULTILINE)
|
m = re.search(r'^\$ORIGIN\s+(\S+)', zone_content, re.MULTILINE)
|
||||||
old_origin = m.group(1).rstrip('.') if m else None
|
old_origin = m.group(1).rstrip('.') if m else None
|
||||||
if old_origin and old_origin != domain:
|
if old_origin and old_origin != domain:
|
||||||
zone_content = zone_content.replace(
|
zone_content = zone_content.replace(f'{old_origin}.', f'{domain}.')
|
||||||
f'{old_origin}.', f'{domain}.')
|
|
||||||
zone_content = re.sub(
|
zone_content = re.sub(
|
||||||
r'^\$ORIGIN\s+\S+', f'$ORIGIN {domain}.', zone_content, flags=re.MULTILINE)
|
r'^\$ORIGIN\s+\S+', f'$ORIGIN {domain}.', zone_content, flags=re.MULTILINE)
|
||||||
dst = os.path.join(dns_data, f'{domain}.zone')
|
|
||||||
with open(dst, 'w') as f:
|
with open(dst, 'w') as f:
|
||||||
f.write(zone_content)
|
f.write(zone_content)
|
||||||
if src != dst:
|
# Remove every zone file that is not the current domain's file
|
||||||
os.remove(src)
|
for zone_path in zone_files:
|
||||||
break
|
if zone_path != dst:
|
||||||
|
try:
|
||||||
|
os.remove(zone_path)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
warnings.append(f"zone file domain update failed: {e}")
|
warnings.append(f"zone file domain update failed: {e}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user