mirror of
https://github.com/nchevsky/systemrescue-zfs.git
synced 2026-01-01 22:30:10 +01:00
Implement the primary configuration processing script in lua (#251)
This commit is contained in:
parent
0d0438d8ad
commit
ca6bcd6548
|
|
@ -9,6 +9,7 @@ SystemRescue ChangeLog
|
|||
* Optimized the initramfs compression to reduce the size of the ISO (Gerd v. Egidy)
|
||||
* Added development build option: faster build times but lower compression (Gerd v. Egidy)
|
||||
* Remove Q-Logic Fibrechannel/Infiniband HBA firmware to save space (#256)
|
||||
* Implemented a script to determine the effective configuration from yaml files (#251)
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
9.00 (2022-01-16):
|
||||
|
|
|
|||
14
airootfs/etc/initcpio/install/sysrescuecfg
Normal file
14
airootfs/etc/initcpio/install/sysrescuecfg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
build() {
|
||||
add_file "/usr/bin/sysrescue-configuration.lua"
|
||||
add_binary "/usr/bin/lua"
|
||||
add_full_dir "/usr/lib/lua"
|
||||
add_full_dir "/usr/share/lua"
|
||||
}
|
||||
|
||||
help() {
|
||||
cat <<HELPEOF
|
||||
This hook allows the configuration processing script to be installed with all its dependencies
|
||||
HELPEOF
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
# 2021-07-07: Alexander Mahr --> added 'ar_attempts'
|
||||
# 2022-01-09: Francois Dupoux --> added support for yaml configuration
|
||||
# 2022-01-09: Francois Dupoux --> option 'autoruns=' renamed 'ar_suffixes='
|
||||
# 2022-01-23: Francois Dupoux --> use the generated effective configuration file
|
||||
#
|
||||
# ----------------------- autorun exec rules: ---------------------------------
|
||||
# - pass 'ar_source=/dev/fd#' to request floppy device test
|
||||
|
|
@ -29,7 +30,7 @@
|
|||
# - if option 'ar_ignorefail' is used, do not stop autorun if a script failed
|
||||
# - if option 'ar_disable' is used, absolutely no autorun script will be run
|
||||
|
||||
import sys, os, re, subprocess, logging, time, glob, yaml
|
||||
import sys, os, re, subprocess, logging, time, glob, json
|
||||
|
||||
# ------------------------ initialize internal variables -----------------------
|
||||
pidfile='/run/autorun.pid'
|
||||
|
|
@ -38,18 +39,9 @@ autorunlog=basedir+'/log'
|
|||
autorunmnt=basedir+'/mnt'
|
||||
autoruntmp=basedir+'/tmp'
|
||||
defaultsrc=['/run/archiso/bootmnt/autorun','/run/archiso/bootmnt','/run/archiso/copytoram/autorun','/run/archiso/copytoram','/var/autorun/cdrom','/root','/usr/share/sys.autorun']
|
||||
effectivecfg="/etc/sysrescue/sysrescue-effective-config.json"
|
||||
autorunfiles=[]
|
||||
|
||||
# ------------------------ default autorun parameters --------------------------
|
||||
config = {
|
||||
'ar_disable': False,
|
||||
'ar_nowait': False,
|
||||
'ar_nodel': False,
|
||||
'ar_ignorefail': False,
|
||||
'ar_attempts': 1,
|
||||
'ar_source': '',
|
||||
'ar_suffixes': ','.join(list('0123456789ABCDEF')),
|
||||
}
|
||||
config = {}
|
||||
|
||||
# ----------------------- functions definitions --------------------------------
|
||||
def writemsg(message):
|
||||
|
|
@ -103,54 +95,24 @@ def search_autoruns(dirname, suffixes, copyfilefct):
|
|||
found+=1
|
||||
return found
|
||||
|
||||
def parse_config_file(yamlfile):
|
||||
logging.info(f"Parsing yaml file: {yamlfile} ...")
|
||||
with open(yamlfile) as myfile:
|
||||
try:
|
||||
curconfig = yaml.safe_load(myfile)
|
||||
if 'autorun' in curconfig:
|
||||
curautorun = curconfig['autorun']
|
||||
for entry in config:
|
||||
if entry in curautorun:
|
||||
config[entry] = curautorun[entry]
|
||||
return True
|
||||
except yaml.YAMLError as err:
|
||||
writemsg(err)
|
||||
return False
|
||||
|
||||
def main():
|
||||
errcnt=0 # in case no autorun executed
|
||||
logging.basicConfig(filename='/var/log/sysrescue-autorun.log', format='%(asctime)s %(message)s', level=logging.DEBUG)
|
||||
writemsg('Initializing autorun ...')
|
||||
|
||||
# ---- parse options passed in the configuration file
|
||||
writemsg(f"Loading configuration from yaml files located on the boot device ...")
|
||||
yamlconfdirs = ["/run/archiso/bootmnt/sysrescue.d", "/run/archiso/copytoram/sysrescue.d"]
|
||||
for yamlconfdir in yamlconfdirs:
|
||||
if os.path.isdir(yamlconfdir):
|
||||
conffiles = glob.glob(os.path.join(yamlconfdir, '*.[Yy][Aa][Mm][Ll]'), recursive=True)
|
||||
conffiles.sort() # Load yaml files in the alphabetical order
|
||||
for curfile in conffiles:
|
||||
parse_config_file(curfile)
|
||||
# ---- read the effective configuration file
|
||||
if os.path.exists(effectivecfg) == False:
|
||||
print (f"Failed to find effective configuration file in {effectivecfg}")
|
||||
sys.exit(1)
|
||||
with open(effectivecfg) as file:
|
||||
fullcfg = json.load(file)
|
||||
config = fullcfg['autorun']
|
||||
#print(json.dumps(config, indent=4))
|
||||
|
||||
# ---- parse options passed on the boot command line
|
||||
# ---- parse legacy options passed on the boot command line
|
||||
for curopt in open("/proc/cmdline","r").read().split():
|
||||
if re.match('^ar_nowait$', curopt):
|
||||
config['ar_nowait'] = True
|
||||
if re.match('^ar_nodel$', curopt):
|
||||
config['ar_nodel'] = True
|
||||
if re.match('^ar_ignorefail$', curopt):
|
||||
config['ar_ignorefail'] = True
|
||||
if re.match('^ar_disable$', curopt):
|
||||
config['ar_disable'] = True
|
||||
if re.match('^ar_source=', curopt):
|
||||
config['ar_source'] = curopt.replace('ar_source=','')
|
||||
if re.match(r'^ar_attempts=\d+$', curopt):
|
||||
config['ar_attempts'] = int(curopt.replace('ar_attempts=',''))
|
||||
if re.match('^autoruns=', curopt): # Legacy name for 'ar_suffixes'
|
||||
if re.match('^autoruns=', curopt): # "autoruns" is the legacy name for 'ar_suffixes'
|
||||
config['ar_suffixes'] = curopt.replace('autoruns=','')
|
||||
if re.match('^ar_suffixes=', curopt): # New name for 'autoruns'
|
||||
config['ar_suffixes'] = curopt.replace('ar_suffixes=','')
|
||||
|
||||
# ---- show the effective configuration
|
||||
logging.info(f"Showing the effective autorun configuration ...")
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import subprocess
|
||||
import yaml
|
||||
import json
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
|
|
@ -16,131 +16,28 @@ print(f"====> Script {sys.argv[0]} starting ...")
|
|||
errcnt = 0
|
||||
|
||||
# ==============================================================================
|
||||
# Define the default configuration
|
||||
# Read the effective configuration file
|
||||
# ==============================================================================
|
||||
config_global = {
|
||||
'dostartx': False,
|
||||
'dovnc': False,
|
||||
'noautologin': False,
|
||||
'nofirewall': False,
|
||||
'rootshell': None,
|
||||
'rootpass': None,
|
||||
'rootcryptpass': None,
|
||||
'setkmap': None,
|
||||
'vncpass': None,
|
||||
}
|
||||
print(f"====> Read the effective configuration file ...")
|
||||
effectivecfg = "/etc/sysrescue/sysrescue-effective-config.json"
|
||||
if os.path.exists(effectivecfg) == False:
|
||||
print (f"Failed to find effective configuration file in {effectivecfg}")
|
||||
sys.exit(1)
|
||||
|
||||
config_ca_trust = { }
|
||||
|
||||
# ==============================================================================
|
||||
# Load configuration from the yaml files
|
||||
# ==============================================================================
|
||||
print(f"====> Loading configuration from yaml files located on the boot device ...")
|
||||
yamlconfdirs = ["/run/archiso/bootmnt/sysrescue.d", "/run/archiso/copytoram/sysrescue.d"]
|
||||
|
||||
def parse_config_file(yamlfile):
|
||||
print(f"Parsing yaml file: {yamlfile} ...")
|
||||
with open(yamlfile) as myfile:
|
||||
try:
|
||||
curconfig = yaml.safe_load(myfile)
|
||||
if 'global' in curconfig:
|
||||
curglobal = curconfig['global']
|
||||
for entry in config_global:
|
||||
if entry in curglobal:
|
||||
config_global[entry] = curglobal[entry]
|
||||
if 'ca-trust' in curconfig:
|
||||
# later yaml files take precedence, overwrite if existing
|
||||
for key, value in curconfig['ca-trust'].items():
|
||||
config_ca_trust[key] = value
|
||||
return True
|
||||
except yaml.YAMLError as err:
|
||||
print(err)
|
||||
errcnt+=1
|
||||
return False
|
||||
|
||||
for yamlconfdir in yamlconfdirs:
|
||||
if os.path.isdir(yamlconfdir):
|
||||
conffiles = glob.glob(os.path.join(yamlconfdir, '*.[Yy][Aa][Mm][Ll]'), recursive=True)
|
||||
conffiles.sort() # Load yaml files in the alphabetical order
|
||||
for curfile in conffiles:
|
||||
parse_config_file(curfile)
|
||||
|
||||
# ==============================================================================
|
||||
# Load configuration from the boot command line
|
||||
# ==============================================================================
|
||||
print(f"====> Parsing configuration from the boot command line ...")
|
||||
|
||||
bootcmdline = open("/proc/cmdline","r").readline()
|
||||
bootopts = bootcmdline.split()
|
||||
|
||||
for curopt in bootopts:
|
||||
|
||||
# Configure keyboard layout
|
||||
match = re.search(r"^setkmap=(\S+)$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option '{curopt}' on the boot command line")
|
||||
config_global['setkmap'] = match.group(1)
|
||||
|
||||
# Configure root login shell
|
||||
match = re.search(r"^rootshell=(\S+)$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option '{curopt}' on the boot command line")
|
||||
config_global['rootshell'] = match.group(1)
|
||||
|
||||
# Set the system root password from a clear password
|
||||
match = re.search(r"^rootpass=(\S+)$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option 'rootpass=******' on the boot command line")
|
||||
config_global['rootpass'] = match.group(1)
|
||||
|
||||
# Set the system root password from an encrypted password
|
||||
match = re.search(r"^rootcryptpass=(\S+)$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option 'rootcryptpass=******' on the boot command line")
|
||||
config_global['rootcryptpass'] = match.group(1)
|
||||
|
||||
# Disable the firewall
|
||||
match = re.search(r"^nofirewall$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option '{curopt}' on the boot command line")
|
||||
config_global['nofirewall'] = True
|
||||
|
||||
# Auto-start the graphical environment (tty1 only), dovnc implies dostartx
|
||||
match = re.search(r"^dostartx$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option '{curopt}' on the boot command line")
|
||||
config_global['dostartx'] = True
|
||||
|
||||
# Require authenticated console access
|
||||
match = re.search(r"^noautologin$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option '{curopt}' on the boot command line")
|
||||
config_global['noautologin'] = True
|
||||
|
||||
# Set the VNC password from a clear password
|
||||
match = re.search(r"^vncpass=(\S+)$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option 'vncpass=******' on the boot command line")
|
||||
config_global['vncpass'] = match.group(1)
|
||||
|
||||
# Auto-start x11vnc with the graphical environment, "dovnc" implies "dostartx"
|
||||
match = re.search(r"^dovnc$", curopt)
|
||||
if match != None:
|
||||
print(f"Found option '{curopt}' on the boot command line")
|
||||
config_global['dovnc'] = True
|
||||
config_global['dostartx'] = True
|
||||
with open(effectivecfg) as file:
|
||||
config = json.load(file)
|
||||
|
||||
# ==============================================================================
|
||||
# Show the effective configuration
|
||||
# ==============================================================================
|
||||
print(f"====> Showing the effective global configuration (except clear passwords) ...")
|
||||
print(f"config['setkmap']={config_global['setkmap']}")
|
||||
print(f"config['rootshell']={config_global['rootshell']}")
|
||||
print(f"config['rootcryptpass']={config_global['rootcryptpass']}")
|
||||
print(f"config['nofirewall']={config_global['nofirewall']}")
|
||||
print(f"config['dostartx']={config_global['dostartx']}")
|
||||
print(f"config['noautologin']={config_global['noautologin']}")
|
||||
print(f"config['dovnc']={config_global['dovnc']}")
|
||||
print(f"config['global']['setkmap']='{config['global']['setkmap']}'")
|
||||
print(f"config['global']['rootshell']='{config['global']['rootshell']}'")
|
||||
print(f"config['global']['rootcryptpass']='{config['global']['rootcryptpass']}'")
|
||||
print(f"config['global']['nofirewall']={config['global']['nofirewall']}")
|
||||
print(f"config['global']['dostartx']={config['global']['dostartx']}")
|
||||
print(f"config['global']['noautologin']={config['global']['noautologin']}")
|
||||
print(f"config['global']['dovnc']={config['global']['dovnc']}")
|
||||
|
||||
# ==============================================================================
|
||||
# Apply the effective configuration
|
||||
|
|
@ -148,8 +45,9 @@ print(f"config['dovnc']={config_global['dovnc']}")
|
|||
print(f"====> Applying configuration ...")
|
||||
|
||||
# Configure keyboard layout if requested in the configuration
|
||||
if config_global['setkmap'] != None:
|
||||
p = subprocess.run(["localectl", "set-keymap", config_global['setkmap']], text=True)
|
||||
setkmap = config['global']['setkmap']
|
||||
if (setkmap != None) and (setkmap != ""):
|
||||
p = subprocess.run(["localectl", "set-keymap", setkmap], text=True)
|
||||
if p.returncode == 0:
|
||||
print (f"Have changed the keymap successfully")
|
||||
else:
|
||||
|
|
@ -157,8 +55,9 @@ if config_global['setkmap'] != None:
|
|||
errcnt+=1
|
||||
|
||||
# Configure root login shell if requested in the configuration
|
||||
if config_global['rootshell'] != None:
|
||||
p = subprocess.run(["chsh", "--shell", config_global['rootshell'], "root"], text=True)
|
||||
rootshell = config['global']['rootshell']
|
||||
if (rootshell != None) and (rootshell != ""):
|
||||
p = subprocess.run(["chsh", "--shell", rootshell, "root"], text=True)
|
||||
if p.returncode == 0:
|
||||
print (f"Have changed the root shell successfully")
|
||||
else:
|
||||
|
|
@ -166,8 +65,9 @@ if config_global['rootshell'] != None:
|
|||
errcnt+=1
|
||||
|
||||
# Set the system root password from a clear password
|
||||
if config_global['rootpass'] != None:
|
||||
p = subprocess.run(["chpasswd", "--crypt-method", "SHA512"], text=True, input=f"root:{config_global['rootpass']}")
|
||||
rootpass = config['global']['rootpass']
|
||||
if (rootpass != None) and (rootpass != ""):
|
||||
p = subprocess.run(["chpasswd", "--crypt-method", "SHA512"], text=True, input=f"root:{rootpass}")
|
||||
if p.returncode == 0:
|
||||
print (f"Have changed the root password successfully")
|
||||
else:
|
||||
|
|
@ -177,8 +77,9 @@ if config_global['rootpass'] != None:
|
|||
# Set the system root password from an encrypted password
|
||||
# A password can be encrypted using a one-line python3 command such as:
|
||||
# python3 -c 'import crypt; print(crypt.crypt("MyPassWord123", crypt.mksalt(crypt.METHOD_SHA512)))'
|
||||
if config_global['rootcryptpass'] != None:
|
||||
p = subprocess.run(["chpasswd", "--encrypted"], text=True, input=f"root:{config_global['rootcryptpass']}")
|
||||
rootcryptpass = config['global']['rootcryptpass']
|
||||
if (rootcryptpass != None) and (rootcryptpass != ""):
|
||||
p = subprocess.run(["chpasswd", "--encrypted"], text=True, input=f"root:{rootcryptpass}")
|
||||
if p.returncode == 0:
|
||||
print (f"Have changed the root password successfully")
|
||||
else:
|
||||
|
|
@ -186,7 +87,7 @@ if config_global['rootcryptpass'] != None:
|
|||
errcnt+=1
|
||||
|
||||
# Disable the firewall
|
||||
if config_global['nofirewall'] == True:
|
||||
if config['global']['nofirewall'] == True:
|
||||
# The firewall service(s) must be in the Before-section of sysrescue-initialize.service
|
||||
p = subprocess.run(["systemctl", "disable", "--now", "iptables.service", "ip6tables.service"], text=True)
|
||||
if p.returncode == 0:
|
||||
|
|
@ -196,7 +97,7 @@ if config_global['nofirewall'] == True:
|
|||
errcnt+=1
|
||||
|
||||
# Auto-start the graphical environment (tty1 only)
|
||||
if config_global['dostartx'] == True:
|
||||
if config['global']['dostartx'] == True:
|
||||
str = '[[ ! $DISPLAY ]] && [[ ! $SSH_TTY ]] && [[ $XDG_VTNR == 1 ]] && startx'
|
||||
if (os.path.exists("/root/.bash_profile") == False) or (open("/root/.bash_profile", 'r').read().find(str) == -1):
|
||||
file1 = open("/root/.bash_profile", "a")
|
||||
|
|
@ -207,7 +108,7 @@ if config_global['dostartx'] == True:
|
|||
file2.close()
|
||||
|
||||
# Require authenticated console access
|
||||
if config_global['noautologin'] == True:
|
||||
if config['global']['noautologin'] == True:
|
||||
p = subprocess.run(["systemctl", "revert", "getty@.service", "serial-getty@.service"], text=True)
|
||||
if p.returncode == 0:
|
||||
print (f"Have enabled authenticated console access successfully")
|
||||
|
|
@ -216,9 +117,10 @@ if config_global['noautologin'] == True:
|
|||
errcnt+=1
|
||||
|
||||
# Set the VNC password from a clear password
|
||||
if config_global['vncpass'] != None:
|
||||
vncpass = config['global']['vncpass']
|
||||
if (vncpass != None) and (vncpass != ""):
|
||||
os.makedirs("/root/.vnc", exist_ok = True)
|
||||
p = subprocess.run(["x11vnc", "-storepasswd", config_global['vncpass'], "/root/.vnc/passwd"], text=True)
|
||||
p = subprocess.run(["x11vnc", "-storepasswd", vncpass, "/root/.vnc/passwd"], text=True)
|
||||
if p.returncode == 0:
|
||||
print (f"Have changed the vnc password successfully")
|
||||
else:
|
||||
|
|
@ -226,7 +128,7 @@ if config_global['vncpass'] != None:
|
|||
errcnt+=1
|
||||
|
||||
# Auto-start x11vnc with the graphical environment
|
||||
if config_global['dovnc'] == True:
|
||||
if config['global']['dovnc'] == True:
|
||||
print (f"Enabling VNC Server in /root/.xprofile ...")
|
||||
file = open("/root/.xprofile", "w")
|
||||
file.write("""[ -f ~/.vnc/passwd ] && pwopt="-usepw" || pwopt="-nopw"\n""")
|
||||
|
|
@ -238,10 +140,10 @@ if config_global['dovnc'] == True:
|
|||
# ==============================================================================
|
||||
ca_anchor_path = "/etc/ca-certificates/trust-source/anchors/"
|
||||
|
||||
if config_ca_trust:
|
||||
if config['ca-trust']:
|
||||
print(f"====> Adding trusted CA certificates ...")
|
||||
|
||||
for name, cert in sorted(config_ca_trust.items()):
|
||||
for name, cert in sorted(config['ca-trust'].items()):
|
||||
print (f"Adding certificate '{name}' ...")
|
||||
with open(os.path.join(ca_anchor_path, name + ".pem"), "w") as certfile:
|
||||
certfile.write(cert)
|
||||
|
|
|
|||
11
airootfs/etc/systemd/system/sysrescue-configuration.service
Normal file
11
airootfs/etc/systemd/system/sysrescue-configuration.service
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[Unit]
|
||||
Description=Determine SystemRescue effective configuration
|
||||
Before=sysrescue-initialize
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/sysrescue-configuration.lua
|
||||
RemainAfterExit=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -34,6 +34,7 @@ systemctl enable ip6tables.service
|
|||
systemctl enable pacman-init.service
|
||||
systemctl enable choose-mirror.service
|
||||
systemctl enable sshd.service
|
||||
systemctl enable sysrescue-configuration.service
|
||||
systemctl enable sysrescue-initialize.service
|
||||
systemctl enable sysrescue-autorun.service
|
||||
systemctl enable qemu-guest-agent.service
|
||||
|
|
|
|||
171
airootfs/usr/bin/sysrescue-configuration.lua
Executable file
171
airootfs/usr/bin/sysrescue-configuration.lua
Executable file
|
|
@ -0,0 +1,171 @@
|
|||
#!/usr/bin/env lua
|
||||
--
|
||||
-- Author: Francois Dupoux
|
||||
-- SPDX-License-Identifier: GPL-3.0-or-later
|
||||
--
|
||||
-- SystemRescue configuration processing script
|
||||
--
|
||||
-- This script uses the SystemRescue yaml configuration files and the options
|
||||
-- passed on the boot command line to override the default configuration.
|
||||
-- It processes yaml configuration files in the alphabetical order, and each option
|
||||
-- found in a file override the options defined earlier. Options passed on the
|
||||
-- boot command like take precedence over configuration options defined in files.
|
||||
-- At the end it writes the effective configuration to a JSON file which is meant
|
||||
-- to be ready by any initialisation script which needs to know the configuration.
|
||||
-- Shell scripts can read values from the JSON file using a command such as:
|
||||
-- jq --raw-output '.global.copytoram' /etc/sysrescue/sysrescue-effective-config.json
|
||||
-- This script requires the following lua packages to run on Arch Linux:
|
||||
-- sudo pacman -Sy lua lua-yaml lua-dkjson
|
||||
|
||||
-- ==============================================================================
|
||||
-- Import modules
|
||||
-- ==============================================================================
|
||||
local lfs = require('lfs')
|
||||
local yaml = require('yaml')
|
||||
local json = require("dkjson")
|
||||
|
||||
-- ==============================================================================
|
||||
-- Utility functions
|
||||
-- ==============================================================================
|
||||
function read_file_contents(path)
|
||||
local file = io.open(path, "rb")
|
||||
if not file then
|
||||
return nil
|
||||
end
|
||||
local content = file:read("*a")
|
||||
file:close()
|
||||
return content
|
||||
end
|
||||
|
||||
function list_config_files(path)
|
||||
local results = {}
|
||||
for curfile in lfs.dir(path) do
|
||||
fullpath = path.."/"..curfile
|
||||
filetype = lfs.attributes(fullpath, "mode")
|
||||
if filetype == "file" and curfile:match(".[Yy][Aa][Mm][Ll]$") then
|
||||
table.insert(results, fullpath)
|
||||
end
|
||||
end
|
||||
table.sort(results)
|
||||
return results
|
||||
end
|
||||
|
||||
-- ==============================================================================
|
||||
-- Define the default configuration
|
||||
-- ==============================================================================
|
||||
print ("====> Define the default configuration ...")
|
||||
config = {
|
||||
["global"] = {
|
||||
['copytoram'] = false,
|
||||
['checksum'] = false,
|
||||
['loadsrm'] = false,
|
||||
['dostartx'] = false,
|
||||
['dovnc'] = false,
|
||||
['noautologin'] = false,
|
||||
['nofirewall'] = false,
|
||||
['rootshell'] = "",
|
||||
['rootpass'] = "",
|
||||
['rootcryptpass'] = "",
|
||||
['setkmap'] = "",
|
||||
['vncpass'] = "",
|
||||
},
|
||||
["autorun"] = {
|
||||
['ar_disable'] = false,
|
||||
['ar_nowait'] = false,
|
||||
['ar_nodel'] = false,
|
||||
['ar_ignorefail'] = false,
|
||||
['ar_attempts'] = false,
|
||||
['ar_source'] = "",
|
||||
['ar_suffixes'] = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F",
|
||||
},
|
||||
["ca-trust"] = {},
|
||||
}
|
||||
|
||||
-- ==============================================================================
|
||||
-- Override the configuration with values from yaml files
|
||||
-- ==============================================================================
|
||||
print ("====> Overriding the default configuration with values from yaml files ...")
|
||||
yamlconfdirs = {"/run/archiso/bootmnt/sysrescue.d", "/run/archiso/copytoram/sysrescue.d"}
|
||||
for _, confdir in ipairs(yamlconfdirs) do
|
||||
if lfs.attributes(confdir, "mode") == "directory" then
|
||||
print("Searching for yaml configuration files in "..confdir.." ...")
|
||||
for _, curfile in ipairs(list_config_files(confdir)) do
|
||||
print("Processing yaml configuration file: "..curfile.." ...")
|
||||
local curconfig = yaml.loadpath(curfile)
|
||||
--print("++++++++++++++\n"..yaml.dump(curconfig).."++++++++++++++\n")
|
||||
if curconfig ~= nil then
|
||||
-- Override specific pre-defined options
|
||||
for _, scope in ipairs({"global", "autorun"}) do
|
||||
for key, val in pairs(config[scope]) do
|
||||
if (curconfig[scope] ~= nil) and (curconfig[scope][key] ~= nil) then
|
||||
print("- Overriding config['"..scope.."']['"..key.."'] with the value from the yaml file")
|
||||
config[scope][key] = curconfig[scope][key]
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Populate additional items
|
||||
for _, scope in ipairs({"ca-trust"}) do
|
||||
if curconfig[scope] ~= nil then
|
||||
for key, val in pairs(curconfig[scope]) do
|
||||
print("- Setting config['"..scope.."']['"..key.."'] with the value from the yaml file")
|
||||
config[scope][key] = val
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
print("Directory "..confdir.." was not found so it has been ignored")
|
||||
end
|
||||
end
|
||||
|
||||
-- ==============================================================================
|
||||
-- Override the configuration with values passed on the boot command line
|
||||
-- ==============================================================================
|
||||
print ("====> Overriding the configuration with options passed on the boot command line ...")
|
||||
local cmdline = read_file_contents("/proc/cmdline");
|
||||
for curopt in cmdline:gmatch("%S+") do
|
||||
--print ("Found option on the boot command line: "..curopt)
|
||||
for _, scope in ipairs({"global", "autorun"}) do
|
||||
for key,val in pairs(config[scope]) do
|
||||
optmatch1 = string.match(curopt, "^"..key.."$")
|
||||
_, _, optmatch2 = string.find(curopt, "^"..key.."=([^%s]+)$")
|
||||
if type(val) == "boolean" then
|
||||
if (optmatch1 ~= nil) or (optmatch2 == 'y') or (optmatch2 == 'yes') or (optmatch2 == 'true') then
|
||||
print("- Option '"..key.."' has been enabled on the boot command line")
|
||||
config[scope][key] = true
|
||||
elseif (optmatch2 == 'n') or (optmatch2 == 'no') or (optmatch2 == 'false') then
|
||||
print("- Option '"..key.."' has been disabled on the boot command line")
|
||||
config[scope][key] = false
|
||||
end
|
||||
else
|
||||
if optmatch2 ~= nil then
|
||||
print("- Option '"..key.."' has been defined on the boot command line")
|
||||
config[scope][key] = optmatch2
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ==============================================================================
|
||||
-- Print the effective configuration
|
||||
-- ==============================================================================
|
||||
print ("====> Printing the effective configuration")
|
||||
local jsoncfgtxt = json.encode (config, { indent = true })
|
||||
print (jsoncfgtxt)
|
||||
|
||||
-- ==============================================================================
|
||||
-- Write the effective configuration to a JSON file
|
||||
-- ==============================================================================
|
||||
print ("====> Writing the effective configuration to a JSON file ...")
|
||||
output_location = "/etc/sysrescue"
|
||||
output_filename = "sysrescue-effective-config.json"
|
||||
output_fullpath = output_location.."/"..output_filename
|
||||
lfs.mkdir(output_location)
|
||||
jsoncfgfile = io.open(output_fullpath, "w")
|
||||
jsoncfgfile:write(jsoncfgtxt)
|
||||
jsoncfgfile:close()
|
||||
os.execute("chmod 700 "..output_location)
|
||||
os.execute("chmod 600 "..output_fullpath)
|
||||
print ("Effective configuration has been written to "..output_fullpath)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
MODULES=(fuse)
|
||||
BINARIES=(aq jq mount.ntfs)
|
||||
HOOKS=(base udev memdisk findroot archiso archiso_loop_mnt archiso_pxe_common archiso_pxe_nbd archiso_pxe_http archiso_pxe_nfs archiso_kms block mdadm_udev modconf encrypt lvm2 filesystems keyboard)
|
||||
BINARIES=(jq mount.ntfs)
|
||||
HOOKS=(base udev memdisk sysrescuecfg findroot archiso archiso_loop_mnt archiso_pxe_common archiso_pxe_nbd archiso_pxe_http archiso_pxe_nfs archiso_kms block mdadm_udev modconf encrypt lvm2 filesystems keyboard)
|
||||
COMPRESSION_RELEASE="xz"
|
||||
COMPRESSION_OPTIONS_RELEASE="--threads=0 --lzma2=preset=9e,dict=128MiB --verbose"
|
||||
COMPRESSION_DEVEL="zstd"
|
||||
|
|
|
|||
4
packages
4
packages
|
|
@ -1,4 +1,3 @@
|
|||
aq
|
||||
alsa-utils
|
||||
amd-ucode
|
||||
archinstall
|
||||
|
|
@ -97,6 +96,7 @@ ipw2100-fw
|
|||
ipw2200-fw
|
||||
irssi
|
||||
jfsutils
|
||||
jq
|
||||
keepassxc
|
||||
less
|
||||
lftp
|
||||
|
|
@ -113,6 +113,8 @@ lshw
|
|||
lsof
|
||||
lsscsi
|
||||
lua
|
||||
lua-dkjson
|
||||
lua-yaml
|
||||
lvm2
|
||||
lz4
|
||||
lzip
|
||||
|
|
|
|||
|
|
@ -1,42 +1,36 @@
|
|||
diff --git a/archiso/initcpio/hooks/archiso b/archiso/initcpio/hooks/archiso
|
||||
index 51dfcc1..fe709cf 100644
|
||||
index 853652e..53215eb 100644
|
||||
--- a/archiso/initcpio/hooks/archiso
|
||||
+++ b/archiso/initcpio/hooks/archiso
|
||||
@@ -197,6 +197,38 @@ archiso_mount_handler() {
|
||||
@@ -197,6 +197,32 @@ archiso_mount_handler() {
|
||||
fi
|
||||
fi
|
||||
|
||||
+ msg ":: Attempt to read configuration from yaml files ..."
|
||||
+
|
||||
+ if ls -l /run/archiso/bootmnt/sysrescue.d/*.[Yy][Aa][Mm][Ll] >/dev/null 2>/dev/null
|
||||
|
||||
+ msg ":: Execute the configuration processing script ..."
|
||||
+ jsonconfig="/etc/sysrescue/sysrescue-effective-config.json"
|
||||
+ if ! /usr/bin/sysrescue-configuration.lua > /tmp/sysrescue-configuration.log 2>&1
|
||||
+ then
|
||||
+ echo "Found yaml files in /run/archiso/bootmnt/sysrescue.d"
|
||||
+ for curfile in /run/archiso/bootmnt/sysrescue.d/*.[Yy][Aa][Mm][Ll]
|
||||
+ do
|
||||
+ echo "Parsing ${curfile} ..."
|
||||
+ shortname=$(basename ${curfile})
|
||||
+
|
||||
+ # Attempt to find boolean entries in the yaml configuration file
|
||||
+ for curentry in "copytoram" "checksum" "loadsrm"
|
||||
+ do
|
||||
+ if value=$(cat ${curfile} | aq -i yaml -o toml ".global.${curentry}" 2>/dev/null)
|
||||
+ then
|
||||
+ if [[ "${value}" == 'true' ]] || [[ "${value}" == 'y' ]] || [[ "${value}" == 'yes' ]]
|
||||
+ then
|
||||
+ echo "Entry '.global.${curentry}' enabled in config: value='${value}'"
|
||||
+ eval "${curentry}='y'"
|
||||
+ elif [[ "${value}" == 'false' ]] || [[ "${value}" == 'n' ]] || [[ "${value}" == 'no' ]]
|
||||
+ then
|
||||
+ echo "Entry '.global.${curentry}' disabled in config: value='${value}'"
|
||||
+ # Do not change curentry as this would override values passed using the boot command line
|
||||
+ else
|
||||
+ echo "ERROR: Found invalid value for '.global.${curentry}': value='${value}'"
|
||||
+ sleep 8
|
||||
+ fi
|
||||
+ fi
|
||||
+ done
|
||||
+ done
|
||||
+ echo "ERROR: The configuration processing script has failed"
|
||||
+ cat /tmp/sysrescue-configuration.log
|
||||
+ sleep 20
|
||||
+ fi
|
||||
+
|
||||
+ msg ":: Define early boot options based on the configuration ..."
|
||||
+ for curentry in "copytoram" "checksum" "loadsrm"
|
||||
+ do
|
||||
+ if value=$(jq --raw-output ".global.${curentry}" ${jsonconfig} 2>/dev/null)
|
||||
+ then
|
||||
+ if [[ "${value}" == 'true' ]]; then
|
||||
+ echo "Entry '.global.${curentry}' enabled in config: value='${value}'"
|
||||
+ eval "${curentry}='y'"
|
||||
+ elif [[ "${value}" == 'false' ]]; then
|
||||
+ echo "Entry '.global.${curentry}' disabled in config: value='${value}'"
|
||||
+ else
|
||||
+ echo "ERROR: Found invalid value for '.global.${curentry}': value='${value}'"
|
||||
+ sleep 8
|
||||
+ fi
|
||||
+ fi
|
||||
+ done
|
||||
+
|
||||
if [[ "${checksum}" == "y" ]]; then
|
||||
if [[ -f "/run/archiso/bootmnt/${archisobasedir}/${arch}/airootfs.sha512" ]]; then
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@ autorun:
|
|||
ar_nodel: false
|
||||
ar_attempts: 1
|
||||
ar_ignorefail: false
|
||||
ar_suffixes: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
|
||||
ar_suffixes: "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F"
|
||||
|
|
|
|||
Loading…
Reference in a new issue