Simplify config parser with dash prefixes and preserve group order
All checks were successful
Build-Publish / build (linux/amd64) (push) Successful in 4s
Build-Publish / build (linux/arm64) (push) Successful in 12s
Build-Publish / create-manifest (push) Successful in 2s
Build-Publish / publish-template (push) Successful in 15s

This commit is contained in:
j
2026-03-08 20:06:57 +13:00
parent cb946b2259
commit 7d7cd25518

View File

@@ -51,49 +51,51 @@ class Server(db.Model):
def parse_infrastructure_conf(): def parse_infrastructure_conf():
servers = [] servers = []
current_group = None current_group = None
current_host = None # track the last top-level host for nesting current_host = None # track the last host for nesting
try: try:
with open(INFRA_CONF_PATH) as f: with open(INFRA_CONF_PATH) as f:
for line in f: for line in f:
line = line.rstrip('\n') line = line.rstrip('\n')
if not line.strip() or line.strip().startswith('#'): stripped = line.strip()
if not stripped or stripped.startswith('#'):
continue continue
# Group header: no leading whitespace
if line[0] not in (' ', '\t'): if line[0] not in (' ', '\t'):
current_group = line.strip() current_group = stripped
current_host = None current_host = None
continue
# Detect prefix: -- child VM, - host
if stripped.startswith('--'):
is_child = True
rest = stripped[2:].strip()
elif stripped.startswith('-'):
is_child = False
rest = stripped[1:].strip()
else: else:
# Detect indent level: double indent = child VM # Legacy: no dash prefix, treat as host
# Normalize: count leading whitespace treating tab as 4 spaces is_child = False
raw_indent = 0 rest = stripped
for ch in line:
if ch == '\t':
raw_indent += 4
elif ch == ' ':
raw_indent += 1
else:
break
is_child = raw_indent >= 8
parts = line.strip().split(None, 1) parts = rest.split(None, 1)
entry = parts[0] if parts else '' entry = parts[0] if parts else ''
url = parts[1] if len(parts) > 1 else '' url = parts[1] if len(parts) > 1 else ''
if '@' in entry: if '@' in entry:
user, host = entry.split('@', 1) user, host = entry.split('@', 1)
else:
user, host = 'infmap', entry
if host:
parent = ''
if is_child and current_host:
parent = current_host
else: else:
user, host = 'infmap', entry current_host = host.strip()
if host: servers.append({
parent = '' 'group': current_group or 'Default',
if is_child and current_host: 'username': user.strip(),
parent = current_host 'hostname': host.strip(),
else: 'url': url.strip(),
current_host = host.strip() 'parent_hostname': parent,
servers.append({ })
'group': current_group or 'Default',
'username': user.strip(),
'hostname': host.strip(),
'url': url.strip(),
'parent_hostname': parent,
})
except FileNotFoundError: except FileNotFoundError:
logger.error("infrastructure.conf not found at %s", INFRA_CONF_PATH) logger.error("infrastructure.conf not found at %s", INFRA_CONF_PATH)
return servers return servers
@@ -284,7 +286,15 @@ def index():
for hostname in children_map: for hostname in children_map:
children_map[hostname].sort(key=lambda s: _ip_sort_key(s.primary_ip)) children_map[hostname].sort(key=lambda s: _ip_sort_key(s.primary_ip))
# Group parents # Get group order from config file
config_entries = parse_infrastructure_conf()
group_order = []
for e in config_entries:
g = e['group']
if g not in group_order:
group_order.append(g)
# Group parents, preserving config order
groups = {} groups = {}
for s in parents: for s in parents:
g = s.group_name or 'Default' g = s.group_name or 'Default'
@@ -292,6 +302,16 @@ def index():
groups[g] = [] groups[g] = []
groups[g].append(s) groups[g].append(s)
# Re-order groups to match config
ordered_groups = {}
for g in group_order:
if g in groups:
ordered_groups[g] = groups.pop(g)
# Append any remaining groups not in config
for g in groups:
ordered_groups[g] = groups[g]
groups = ordered_groups
# Sort servers within each group by IP (numerically) # Sort servers within each group by IP (numerically)
for g in groups: for g in groups:
groups[g].sort(key=lambda s: _ip_sort_key(s.primary_ip)) groups[g].sort(key=lambda s: _ip_sort_key(s.primary_ip))