libvirt/scripts/merge-systemd-units.py
Andrea Bolognani ee86c2add3 systemd: Allow comments at the top of units
Currently the script will reject any type of contents outside
of a section, but we want to be able to have some useful
comments at the top of each file to help users understand how
they are processed.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2023-10-25 12:19:32 +02:00

105 lines
2.1 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2023 Red Hat, Inc.
# SPDX-License-Identifier: LGPL-2.1-or-later
import sys
SECTIONS = [
"[Unit]",
"[Service]",
"[Socket]",
"[Install]",
]
def parse_unit(unit_path):
unit = {}
current_section = "[Invalid]"
with open(unit_path) as f:
for line in f:
line = line.strip()
if line == "":
continue
# Comments at the very top of the file, outside of any
# section, are allowed and will not show up in the output
if line[0] == "#" and current_section == "[Invalid]":
continue
if line[0] == "[" and line[-1] == "]":
if line not in SECTIONS:
print("Unknown section {}".format(line))
sys.exit(1)
current_section = line
continue
if current_section not in unit:
unit[current_section] = []
unit[current_section].append(line)
if "[Invalid]" in unit:
print("Contents found outside of any section")
sys.exit(1)
return unit
def format_unit(unit):
lines = []
for section in SECTIONS:
if section not in unit:
continue
lines.append(section)
for line in unit[section]:
lines.append(line)
lines.append("")
return "\n".join(lines)
def merge_units(base, extra):
merged = {}
for section in SECTIONS:
if section in extra and section not in base:
print("Section {} in extra but not in base".format(section))
sys.exit(1)
if section not in base:
continue
merged[section] = base[section]
if section not in extra:
continue
merged[section].extend(extra[section])
return merged
prog = sys.argv[0]
args = sys.argv[1:]
if len(args) < 1:
print("usage: {} BASE [EXTRA]...".format(prog))
sys.exit(1)
merged = parse_unit(args[0])
for arg in args[1:]:
extra = parse_unit(arg)
merged = merge_units(merged, extra)
sys.stdout.write(format_unit(merged))