mirror of
https://github.com/nchevsky/systemrescue-zfs.git
synced 2026-01-23 09:00:50 +01:00
Example config:
sysconfig:
hosts:
"192.168.1.1": "example.net.lan"
"192.168.1.10": "foo.net.lan foo"
151 lines
5.9 KiB
Python
Executable file
151 lines
5.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
#
|
|
# initialize SystemRescue, do the parts that must be finished before networking is started
|
|
# Keep as short as possible, move non-critical parts to -whilenet to not block the boot unnecessarily
|
|
#
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import subprocess
|
|
import json
|
|
import glob
|
|
import os
|
|
import sys
|
|
import re
|
|
import tempfile
|
|
import functools
|
|
import configparser
|
|
|
|
# flush stdout buffer after each print call: immediately show the user what is going on
|
|
print = functools.partial(print, flush=True)
|
|
|
|
def strtobool (val):
|
|
"""Convert a string representation of truth to true (1) or false (0).
|
|
|
|
True values are 'y', 'yes', 't', 'true', 'on', '1', '1.0'; false values
|
|
are 'n', 'no', 'f', 'false', 'off', '0', '0.0'. Raises ValueError if
|
|
'val' is anything else.
|
|
|
|
Function adapted from Pythons distutils.util.py because it will be deprecated soon
|
|
Copyright (c) Python Software Foundation; All Rights Reserved
|
|
"""
|
|
val = str(val).lower()
|
|
if val in ('y', 'yes', 't', 'true', 'on', '1', '1.0'):
|
|
return True
|
|
elif val in ('n', 'no', 'f', 'false', 'off', '0', '0.0'):
|
|
return False
|
|
else:
|
|
raise ValueError("invalid truth value %r" % (val,))
|
|
|
|
# ==============================================================================
|
|
# Initialization
|
|
# ==============================================================================
|
|
print(f"====> Script {sys.argv[0]} starting ...")
|
|
errcnt = 0
|
|
|
|
# ==============================================================================
|
|
# Read the effective configuration file
|
|
# ==============================================================================
|
|
print(f"====> Read the effective configuration file ...")
|
|
effectivecfg = "/run/archiso/config/sysrescue-effective-config.json"
|
|
if os.path.exists(effectivecfg) == False:
|
|
print (f"Failed to find effective configuration file in {effectivecfg}")
|
|
sys.exit(1)
|
|
|
|
with open(effectivecfg) as file:
|
|
config = json.load(file)
|
|
|
|
# ==============================================================================
|
|
# Sanitize config, initialize variables
|
|
# Make sysrescue-initialize work safely without them being defined or have a wrong type
|
|
# Also show the effective configuration
|
|
# ==============================================================================
|
|
print(f"====> Showing the effective global configuration (except clear passwords) ...")
|
|
|
|
def read_cfg_value(scope, name, defaultval, printval):
|
|
if not scope in config:
|
|
val = defaultval
|
|
elif name in config[scope]:
|
|
chkval = config[scope][name]
|
|
try:
|
|
if isinstance(chkval, list) or isinstance(chkval, dict):
|
|
raise TypeError(f"must be a {type(defaultval)}, not a {type(chkval)}")
|
|
elif isinstance(defaultval, bool) and not isinstance(chkval, bool):
|
|
val = strtobool(chkval)
|
|
else:
|
|
val = type(defaultval)(chkval)
|
|
except (TypeError, ValueError) as e:
|
|
if printval:
|
|
print(f"config['{scope}']['{name}'] with {chkval} is not the same type as defaultval: {e}")
|
|
else:
|
|
print(f"config['{scope}']['{name}'] is not the same type as defaultval: {e}")
|
|
val = defaultval
|
|
else:
|
|
val = defaultval
|
|
|
|
if printval:
|
|
print(f"config['{scope}']['{name}']={val}")
|
|
|
|
return val
|
|
|
|
nofirewall = read_cfg_value('global','nofirewall', False, True)
|
|
|
|
# ==============================================================================
|
|
# Apply the effective configuration
|
|
# ==============================================================================
|
|
print(f"====> Applying pre-network configuration ...")
|
|
|
|
# Disable the firewall
|
|
if nofirewall == True:
|
|
# The firewall service(s) must be in the Before-section of sysrescue-initialize-prenet.service
|
|
p = subprocess.run(["systemctl", "disable", "--now", "iptables.service", "ip6tables.service"], text=True)
|
|
if p.returncode == 0:
|
|
print (f"Have disabled the firewall successfully")
|
|
else:
|
|
print (f"Failed to disable the firewall")
|
|
errcnt+=1
|
|
|
|
# ==============================================================================
|
|
# customize sysctl
|
|
# Should be pre-network to allow tweaking network-specific sysctls
|
|
# ==============================================================================
|
|
|
|
if 'sysconfig' in config and 'sysctl' in config['sysconfig'] and \
|
|
config['sysconfig']['sysctl'] and isinstance(config['sysconfig']['sysctl'], dict):
|
|
print(f"====> Customizing sysctl options ...")
|
|
sysctllines = ""
|
|
for key, value in config['sysconfig']['sysctl'].items():
|
|
sysctllines+=f"{key} = {value}\n"
|
|
|
|
# pipe config into sysctl
|
|
p = subprocess.run(["sysctl", "--load=-"], text=True, input=sysctllines)
|
|
if p.returncode != 0:
|
|
print (f"Some or all sysctl options couldn't be set")
|
|
errcnt+=1
|
|
|
|
# ==============================================================================
|
|
# configure hosts file
|
|
# Should be pre-network to be available throughout the whole network setup
|
|
# ==============================================================================
|
|
|
|
if 'sysconfig' in config and 'hosts' in config['sysconfig'] and \
|
|
config['sysconfig']['hosts'] and isinstance(config['sysconfig']['hosts'], dict):
|
|
print(f"====> Configuring /etc/hosts ...")
|
|
|
|
try:
|
|
# append all our entries to the hosts file
|
|
with open("/etc/hosts", "a") as hostsfile:
|
|
# key is the IPv4/IPv6, value the hostname(s)
|
|
for ip, hostname in config['sysconfig']['hosts'].items():
|
|
hostsfile.write(f"{ip}\t{hostname}\n")
|
|
hostsfile.close()
|
|
|
|
except Exception as e:
|
|
print(e)
|
|
errcnt+=1
|
|
|
|
# ==============================================================================
|
|
# End of the script
|
|
# ==============================================================================
|
|
print(f"====> Script {sys.argv[0]} completed with {errcnt} errors ...")
|
|
sys.exit(errcnt)
|