Compare commits
10 Commits
22422b7f50
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 052a88cd3b | |||
| c5ea471a5a | |||
| 4085210dee | |||
| 4f366bcddd | |||
| 0a01479d24 | |||
| e49e2d3909 | |||
| 7d7938fcc7 | |||
| e6b8b5325c | |||
| 292047aac6 | |||
| 67019ec6ad |
+40
@@ -0,0 +1,40 @@
|
|||||||
|
Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
*.lib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
|
||||||
|
# Archives
|
||||||
|
*.zip
|
||||||
|
|
||||||
|
# Swap files
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Custom
|
||||||
|
|
||||||
|
*.iso
|
||||||
|
*.cfg
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# requires lorax, genisoimage: dnf install lorax genisoimage
|
|
||||||
|
|
||||||
mkksiso --ks=/var/www/kickstart/rocky-9.cfg Rocky-9.7-x86_64-minimal.iso custom.iso
|
|
||||||
|
|
||||||
|
|
||||||
Executable
+11
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import crypt
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('password')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print(crypt.crypt(args.password, crypt.mksalt(crypt.METHOD_SHA512)))
|
||||||
|
|
||||||
Executable
+35
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#============================================================================
|
||||||
|
# Title : make-iso
|
||||||
|
# Description : Make a custom Rocky Linux installable ISO
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# requires lorax, genisoimage: dnf install lorax genisoimage
|
||||||
|
|
||||||
|
die() { echo "$(basename $0): [die] $@" >&2 ; exit 1 ; }
|
||||||
|
|
||||||
|
test $(id -u) == 0 || die "Run as root (sudo $(basename $0) <opts>"
|
||||||
|
rpm -q --quiet lorax || die "lorax not installed"
|
||||||
|
rpm -q --quiet genisoimage || die "genisoimage not installed"
|
||||||
|
|
||||||
|
# Setup temp working directory - clean it up when program ends
|
||||||
|
readonly WORKDIR=$(/bin/mktemp --tmpdir -d)
|
||||||
|
cleanup() { /bin/rm -rf ${WORKDIR:-/none} ; }
|
||||||
|
trap "cleanup" INT TERM HUP EXIT
|
||||||
|
|
||||||
|
topdir=$(git rev-parse --show-toplevel)
|
||||||
|
echo $topdir
|
||||||
|
|
||||||
|
isopath=/nfs/sw/os/rocky/Rocky-9.7-x86_64-minimal.iso
|
||||||
|
target=/nfs/pve/template/iso/custom.iso
|
||||||
|
|
||||||
|
ks=$topdir/kickstart/rocky-9.cfg
|
||||||
|
custom=$topdir/custom
|
||||||
|
|
||||||
|
cp -r $custom $WORKDIR
|
||||||
|
cp $ks $WORKDIR
|
||||||
|
|
||||||
|
|
||||||
|
test -f $target && sudo rm -f $target
|
||||||
|
|
||||||
|
$topdir/bin/mkksiso -a $WORKDIR/custom --ks=$WORKDIR/$(basename $ks) --custom_cfg $topdir/kickstart/isolinux.cfg $isopath $target
|
||||||
|
|
||||||
Executable
+637
@@ -0,0 +1,637 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 2019 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
import argparse
|
||||||
|
from collections import OrderedDict
|
||||||
|
import logging as log
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import shlex
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
|
||||||
|
|
||||||
|
# Maximum filename length
|
||||||
|
MAX_FNAME = 253
|
||||||
|
|
||||||
|
|
||||||
|
def SplitCmdline(cmdline):
|
||||||
|
"""
|
||||||
|
Split the commandline into an OrderedDict of arguments
|
||||||
|
|
||||||
|
If the argument appears multiple times its entry will have a list of the values,
|
||||||
|
and its position in the dictionary will be that of the first occurrence.
|
||||||
|
If the argument has no value its entry will be [None]
|
||||||
|
Arguments with a single value will be [VALUE]
|
||||||
|
|
||||||
|
Quotes strings are maintained, and values may contain equals signs which
|
||||||
|
will be preserved.
|
||||||
|
"""
|
||||||
|
kernel_args = OrderedDict()
|
||||||
|
for a in shlex.split(cmdline):
|
||||||
|
if "=" in a:
|
||||||
|
k,v = a.split("=", 1)
|
||||||
|
else:
|
||||||
|
k, v = a, None
|
||||||
|
if k in kernel_args:
|
||||||
|
kernel_args[k].append(v)
|
||||||
|
else:
|
||||||
|
kernel_args[k] = [v]
|
||||||
|
|
||||||
|
return kernel_args
|
||||||
|
|
||||||
|
|
||||||
|
def quote(s):
|
||||||
|
"""
|
||||||
|
Return a quoted string if it contains spaces.
|
||||||
|
Otherwise just return the string.
|
||||||
|
"""
|
||||||
|
if " " in s:
|
||||||
|
return f"\"{s}\""
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def ListKernelArgs(kernel_args):
|
||||||
|
"""
|
||||||
|
Return a list of quoted kernel arguments and values
|
||||||
|
|
||||||
|
The dictionary is the output from SplitCmdline.
|
||||||
|
Values with spaces are quoted with ""
|
||||||
|
"""
|
||||||
|
kernel_cmdline = []
|
||||||
|
for k, vs in kernel_args.items():
|
||||||
|
for v in vs:
|
||||||
|
if v is None:
|
||||||
|
kernel_cmdline.append(f"{k}")
|
||||||
|
else:
|
||||||
|
kernel_cmdline.append(f"{k}={quote(v)}")
|
||||||
|
|
||||||
|
return kernel_cmdline
|
||||||
|
|
||||||
|
|
||||||
|
def JoinKernelArgs(kernel_args):
|
||||||
|
"""
|
||||||
|
Return a string of quoted kernel arguments and values
|
||||||
|
|
||||||
|
The dictionary is the output from SplitCmdline.
|
||||||
|
Values with spaces are quoted with ""
|
||||||
|
"""
|
||||||
|
return " ".join(ListKernelArgs(kernel_args))
|
||||||
|
|
||||||
|
|
||||||
|
def AlterKernelArgs(kernel_args, rm_args, add_args):
|
||||||
|
"""
|
||||||
|
Modify the kernel argument OrderedDict
|
||||||
|
|
||||||
|
This first removes all arguments listed in rm_args. It will ignore
|
||||||
|
arguments that are not present.
|
||||||
|
|
||||||
|
It then extends the arguments listed in the add_args dictionary if they are
|
||||||
|
already present, otherwise it adds them to kernel_args
|
||||||
|
|
||||||
|
It returns the modified kernel_args OrderedDict.
|
||||||
|
"""
|
||||||
|
# Remove arguments
|
||||||
|
for k in rm_args:
|
||||||
|
if k in kernel_args:
|
||||||
|
del kernel_args[k]
|
||||||
|
|
||||||
|
# Add new arguments and update existing ones
|
||||||
|
for k, vs in add_args.items():
|
||||||
|
if k in kernel_args:
|
||||||
|
kernel_args[k].extend(vs)
|
||||||
|
else:
|
||||||
|
kernel_args[k] = vs
|
||||||
|
|
||||||
|
return kernel_args
|
||||||
|
|
||||||
|
|
||||||
|
def WrapKernelArgs(kernel_args, width=80):
|
||||||
|
"""
|
||||||
|
Return a wordwrapped string
|
||||||
|
|
||||||
|
It breaks the lines at spaces inbetween commands,
|
||||||
|
preserving quoted strings verbatim.
|
||||||
|
"""
|
||||||
|
result = kernel_args[0]
|
||||||
|
cols = len(result)
|
||||||
|
for arg in kernel_args[1:]:
|
||||||
|
if 1 + cols + len(arg) > width:
|
||||||
|
result += "\n"
|
||||||
|
result += arg
|
||||||
|
cols = len(arg)
|
||||||
|
else:
|
||||||
|
result += " " + arg
|
||||||
|
cols = cols + len(arg) + 1
|
||||||
|
result += "\n"
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def GetISODetails(isopath):
|
||||||
|
"""
|
||||||
|
Use xorriso to list the contents of the iso and get the volume id
|
||||||
|
|
||||||
|
Metadata about the iso is output to stderr, file listing is sent to stdout.
|
||||||
|
|
||||||
|
Returns a tuple of volume id, and the list of files on the iso
|
||||||
|
"""
|
||||||
|
cmd = ["xorriso", "-indev", isopath, "-pkt_output", "on", "-find"]
|
||||||
|
out = subprocess.run(cmd, check=True, capture_output=True, env={"LANG": "C"})
|
||||||
|
|
||||||
|
volid = ""
|
||||||
|
for line in out.stderr.decode("utf-8").splitlines():
|
||||||
|
if line.startswith("Volume id"):
|
||||||
|
volid = shlex.split(line)[-1]
|
||||||
|
if not volid:
|
||||||
|
raise RuntimeError(f"{isopath} is missing a volume id")
|
||||||
|
|
||||||
|
# Files on the iso
|
||||||
|
# The files are on stdout and are prefixed with 'R:1:' for result lines with trailing newlines.
|
||||||
|
files = []
|
||||||
|
for line in out.stdout.decode("utf-8").splitlines():
|
||||||
|
if line.startswith("R:1:"):
|
||||||
|
files.append(os.path.normpath(shlex.split(line)[-1]))
|
||||||
|
|
||||||
|
return volid, files
|
||||||
|
|
||||||
|
|
||||||
|
def ExtractISOFiles(isopath, files, tmpdir):
|
||||||
|
"""
|
||||||
|
Extract the given files (which must exist on the iso) into the temporary
|
||||||
|
directory.
|
||||||
|
"""
|
||||||
|
# Make sure the user can write to any extracted directories using -chmod_r
|
||||||
|
cmd = ["osirrox", "-indev", isopath, "-chmod_r", "u+rwx", "/", "--"]
|
||||||
|
for f in files:
|
||||||
|
cmd.extend(["-extract", f, tmpdir + "/" + f])
|
||||||
|
cmd.extend(["-rollback_end"])
|
||||||
|
subprocess.run(cmd, check=True, capture_output=False, env={"LANG": "C"})
|
||||||
|
|
||||||
|
|
||||||
|
# From pylorax/treebuilder.py
|
||||||
|
# udev whitelist: 'a-zA-Z0-9#+.:=@_-' (see is_whitelisted in libudev-util.c)
|
||||||
|
udev_blacklist=' !"$%&\'()*,/;<>?[\\]^`{|}~' # ASCII printable, minus whitelist
|
||||||
|
udev_blacklist += ''.join(chr(i) for i in range(32)) # ASCII non-printable
|
||||||
|
def udev_escape(label):
|
||||||
|
"""
|
||||||
|
Escape the volume id label characters so they can be used on the ISO
|
||||||
|
"""
|
||||||
|
out = ''
|
||||||
|
for ch in label:
|
||||||
|
out += ch if ch not in udev_blacklist else '\\x%02x' % ord(ch)
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def CheckBigFiles(add_paths):
|
||||||
|
"""
|
||||||
|
Check file size and filename length for problems
|
||||||
|
|
||||||
|
Returns True if any file exceeds 4GiB
|
||||||
|
Raises a RuntimeError if any filename is longer than MAX_FNAME
|
||||||
|
This examines all the files included, so may take some time.
|
||||||
|
"""
|
||||||
|
big_file = False
|
||||||
|
for src in add_paths:
|
||||||
|
if os.path.isdir(src):
|
||||||
|
for top, dirs, files in os.walk(src):
|
||||||
|
for f in files + dirs:
|
||||||
|
if len(f) > MAX_FNAME:
|
||||||
|
raise RuntimeError("iso contains filenames that are too long: %s" % f)
|
||||||
|
if os.stat(top + "/" + f).st_size >= 4*1024**3:
|
||||||
|
big_file = True
|
||||||
|
else:
|
||||||
|
if len(src) > MAX_FNAME:
|
||||||
|
raise RuntimeError("iso contains filenames that are too long: %s" % f)
|
||||||
|
if os.stat(src).st_size >= 4*1024**3:
|
||||||
|
big_file = True
|
||||||
|
|
||||||
|
return big_file
|
||||||
|
|
||||||
|
|
||||||
|
def ImplantMD5(output_iso):
|
||||||
|
"""
|
||||||
|
Add md5 checksums to the final iso
|
||||||
|
"""
|
||||||
|
cmd = ["implantisomd5", output_iso]
|
||||||
|
log.debug(" ".join(cmd))
|
||||||
|
try:
|
||||||
|
subprocess.check_output(cmd)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
log.error(str(e))
|
||||||
|
raise RuntimeError("implantisomd5 failed")
|
||||||
|
|
||||||
|
|
||||||
|
def RebuildEFIBoot(input_iso, tmpdir):
|
||||||
|
"""
|
||||||
|
On x86 the efiboot.img needs to be rebuilt from the new /EFI/BOOT/ files
|
||||||
|
|
||||||
|
returns new efiboot.img file with a temporary name.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(tmpdir+"/EFI/BOOT"):
|
||||||
|
raise RuntimeError("Missing mkefiboot requirement: EFI/BOOT")
|
||||||
|
|
||||||
|
# Extract the EFI directory files from the iso
|
||||||
|
with tempfile.TemporaryDirectory(prefix="mkksiso-") as tmpefi:
|
||||||
|
ExtractISOFiles(input_iso, ["EFI"], tmpefi)
|
||||||
|
|
||||||
|
# Copy the modified config files over
|
||||||
|
shutil.copytree(tmpdir+"/EFI", tmpefi+"/EFI", dirs_exist_ok=True)
|
||||||
|
|
||||||
|
efibootimg = tempfile.NamedTemporaryFile(prefix="efibootimg-")
|
||||||
|
cmd = ["mkefiboot", "--label=ANACONDA"]
|
||||||
|
if log.root.level < log.INFO:
|
||||||
|
cmd.append("--debug")
|
||||||
|
cmd.extend([tmpefi + "/EFI/BOOT", efibootimg.name])
|
||||||
|
log.debug(" ".join(cmd))
|
||||||
|
try:
|
||||||
|
subprocess.check_output(cmd)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
log.error(str(e))
|
||||||
|
raise RuntimeError("Running mkefiboot")
|
||||||
|
|
||||||
|
return efibootimg
|
||||||
|
|
||||||
|
|
||||||
|
def RebuildS390CDBoot(tmpdir):
|
||||||
|
"""
|
||||||
|
On s390x the cdboot.img needs to be rebuilt with the new cmdline arguments
|
||||||
|
"""
|
||||||
|
# First check for the needed files
|
||||||
|
missing = []
|
||||||
|
for f in ["images/kernel.img", "images/initrd.img", "images/cdboot.prm"]:
|
||||||
|
if not os.path.exists(tmpdir + "/" + f):
|
||||||
|
log.debug("Missing file %s", f)
|
||||||
|
missing.append(f)
|
||||||
|
if missing:
|
||||||
|
raise RuntimeError("Missing requirement %s" % ", ".join(missing))
|
||||||
|
|
||||||
|
cmd = ["mk-s390image", tmpdir + "/images/kernel.img", tmpdir + "/images/cdboot.img",
|
||||||
|
"-r", tmpdir + "/images/initrd.img",
|
||||||
|
"-p", tmpdir + "/images/cdboot.prm"]
|
||||||
|
log.debug(" ".join(cmd))
|
||||||
|
try:
|
||||||
|
subprocess.check_output(cmd)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
log.error(str(e))
|
||||||
|
raise RuntimeError("Running mk-s390image")
|
||||||
|
|
||||||
|
|
||||||
|
def GetCmdline(line, commands):
|
||||||
|
"""
|
||||||
|
Get the cmdline portion of a line that starts with a command
|
||||||
|
|
||||||
|
returns the indented command prefix, and the cmdline.
|
||||||
|
"""
|
||||||
|
for c in commands:
|
||||||
|
if c not in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# The command must be the first non-whitespace word
|
||||||
|
first, _ = line.strip().split(" ", 1)
|
||||||
|
if first != c:
|
||||||
|
continue
|
||||||
|
|
||||||
|
indent, prefix, cmdline = line.partition(c)
|
||||||
|
return indent+prefix, cmdline.strip()
|
||||||
|
|
||||||
|
return "", line
|
||||||
|
|
||||||
|
|
||||||
|
def EditIsolinux(rm_args, add_args, replace_list, tmpdir, custom_cfg):
|
||||||
|
"""
|
||||||
|
Modify the cmdline for an isolinux.cfg
|
||||||
|
Remove args, add new arguments and change existing volid if requested
|
||||||
|
"""
|
||||||
|
orig_cfg = tmpdir + "/isolinux/isolinux.cfg"
|
||||||
|
if not os.path.exists(orig_cfg):
|
||||||
|
log.warning("No isolinux/isolinux.cfg file found")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Edit the config file, save the new one as .new
|
||||||
|
with open(orig_cfg, "r") as in_fp:
|
||||||
|
with open(orig_cfg + ".new", "w") as out_fp:
|
||||||
|
for line in in_fp:
|
||||||
|
for from_item, to_item in replace_list:
|
||||||
|
if from_item in line:
|
||||||
|
line = line.replace(from_item, to_item)
|
||||||
|
prefix, cmdline = GetCmdline(line, ["append"])
|
||||||
|
if prefix:
|
||||||
|
args = SplitCmdline(cmdline)
|
||||||
|
new_args = AlterKernelArgs(args, rm_args, add_args)
|
||||||
|
out_fp.write(prefix+" "+JoinKernelArgs(new_args))
|
||||||
|
out_fp.write("\n")
|
||||||
|
else:
|
||||||
|
out_fp.write(line)
|
||||||
|
out_fp.close()
|
||||||
|
os.replace(orig_cfg + ".new", orig_cfg)
|
||||||
|
|
||||||
|
if custom_cfg:
|
||||||
|
log.info('using custom config %s', custom_cfg)
|
||||||
|
with open(custom_cfg, 'r') as src, open(orig_cfg, 'w') as tgt:
|
||||||
|
tgt.write(src.read())
|
||||||
|
else:
|
||||||
|
log.info('using default config')
|
||||||
|
|
||||||
|
def EditGrub2(rm_args, add_args, replace_list, tmpdir):
|
||||||
|
"""
|
||||||
|
Modify the cmdline for GRUB2 UEFI and BIOS config files
|
||||||
|
Add the new arguments and change existing volid if requested
|
||||||
|
"""
|
||||||
|
grub_cfgs = ["EFI/BOOT/grub.cfg", "EFI/BOOT/BOOT.conf",
|
||||||
|
"boot/grub2/grub.cfg", "boot/grub/grub.cfg"]
|
||||||
|
|
||||||
|
if not any(os.path.exists(tmpdir + "/" + c) for c in grub_cfgs):
|
||||||
|
log.warning("No grub config files found")
|
||||||
|
return
|
||||||
|
|
||||||
|
for cfg in grub_cfgs:
|
||||||
|
orig_cfg = tmpdir + "/" + cfg
|
||||||
|
if not os.path.exists(orig_cfg):
|
||||||
|
continue
|
||||||
|
|
||||||
|
with open(orig_cfg, "r") as in_fp:
|
||||||
|
with open(orig_cfg + ".new", "w") as out_fp:
|
||||||
|
for line in in_fp:
|
||||||
|
for from_item, to_item in replace_list:
|
||||||
|
if from_item in line:
|
||||||
|
line = line.replace(from_item, to_item)
|
||||||
|
# Some start with linux (BIOS/aarch64), others with linuxefi (x86_64)
|
||||||
|
prefix, cmdline = GetCmdline(line, ["linuxefi", "linux"])
|
||||||
|
if prefix:
|
||||||
|
args = SplitCmdline(cmdline)
|
||||||
|
new_args = AlterKernelArgs(args, rm_args, add_args)
|
||||||
|
out_fp.write(prefix+" "+JoinKernelArgs(new_args))
|
||||||
|
out_fp.write("\n")
|
||||||
|
else:
|
||||||
|
out_fp.write(line)
|
||||||
|
out_fp.close()
|
||||||
|
os.replace(orig_cfg + ".new", orig_cfg)
|
||||||
|
|
||||||
|
|
||||||
|
def EditS390(rm_args, add_args, replace_list, tmpdir):
|
||||||
|
"""
|
||||||
|
Modify the cmdline for s390 config files
|
||||||
|
Add the new arguments and change existing volid if requested
|
||||||
|
"""
|
||||||
|
s390_cfgs = ["images/generic.prm", "images/cdboot.prm"]
|
||||||
|
|
||||||
|
if not any(os.path.exists(tmpdir + "/" + c) for c in s390_cfgs):
|
||||||
|
log.warning("No s390 config files found")
|
||||||
|
return
|
||||||
|
|
||||||
|
for cfg in s390_cfgs:
|
||||||
|
orig_cfg = tmpdir + "/" + cfg
|
||||||
|
if not os.path.exists(orig_cfg):
|
||||||
|
log.warning("No %s file found", cfg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
with open(orig_cfg, "r") as in_fp:
|
||||||
|
# Read the config file and turn it into a line
|
||||||
|
lines = in_fp.readlines()
|
||||||
|
|
||||||
|
cmdline = " ".join(l.strip() for l in lines)
|
||||||
|
# Replace the volid
|
||||||
|
for from_item, to_item in replace_list:
|
||||||
|
if from_item in cmdline:
|
||||||
|
cmdline = cmdline.replace(from_item, to_item)
|
||||||
|
args = SplitCmdline(cmdline)
|
||||||
|
new_args = AlterKernelArgs(args, rm_args, add_args)
|
||||||
|
|
||||||
|
cmdline = ListKernelArgs(new_args)
|
||||||
|
|
||||||
|
# Write the new config file, breaking at 80 columns
|
||||||
|
with open(orig_cfg + ".new", "w") as out_fp:
|
||||||
|
out_fp.write(WrapKernelArgs(cmdline, width=80))
|
||||||
|
out_fp.close()
|
||||||
|
os.replace(orig_cfg + ".new", orig_cfg)
|
||||||
|
|
||||||
|
|
||||||
|
def CheckDiscinfo(path):
|
||||||
|
"""
|
||||||
|
If the ISO contains a .discinfo file, check the arch against the host arch
|
||||||
|
|
||||||
|
Raises a RuntimeError if the arch does not match
|
||||||
|
"""
|
||||||
|
## TODO -- is this even needed with the new method of rebuilding the iso?
|
||||||
|
if os.path.exists(path):
|
||||||
|
with open(path) as f:
|
||||||
|
discinfo = [l.strip() for l in f.readlines()]
|
||||||
|
|
||||||
|
log.info("iso arch = %s", discinfo[2])
|
||||||
|
if os.uname().machine != discinfo[2]:
|
||||||
|
raise RuntimeError("iso arch does not match the host arch.")
|
||||||
|
|
||||||
|
|
||||||
|
def MakeKickstartISO(input_iso, output_iso, ks="", updates_image="", add_paths=None,
|
||||||
|
cmdline="", rm_args="", new_volid="", replace_list=None, implantmd5=True,
|
||||||
|
skip_efi=False, custom_cfg=None):
|
||||||
|
"""
|
||||||
|
Make a kickstart ISO from a boot.iso or dvd
|
||||||
|
"""
|
||||||
|
if add_paths is None:
|
||||||
|
add_paths = []
|
||||||
|
if replace_list is None:
|
||||||
|
replace_list = []
|
||||||
|
|
||||||
|
# Gather information about the input iso
|
||||||
|
old_volid, files = GetISODetails(input_iso)
|
||||||
|
if not old_volid and not new_volid:
|
||||||
|
raise RuntimeError("No volume id found, cannot create iso.")
|
||||||
|
|
||||||
|
log.debug("ISO files:")
|
||||||
|
for f in files:
|
||||||
|
log.debug(" %s", f)
|
||||||
|
|
||||||
|
# Extract files that match the known config files.
|
||||||
|
known_configs = set([".discinfo", "isolinux/isolinux.cfg",
|
||||||
|
"boot/grub2/grub.cfg", "boot/grub/grub.cfg",
|
||||||
|
"EFI/BOOT/BOOT.conf", "EFI/BOOT/grub.cfg",
|
||||||
|
"images/generic.prm", "images/cdboot.prm",
|
||||||
|
"images/kernel.img", "images/initrd.img"])
|
||||||
|
extract_files = set(files) & known_configs
|
||||||
|
with tempfile.TemporaryDirectory(prefix="mkksiso-") as tmpdir:
|
||||||
|
ExtractISOFiles(input_iso, extract_files, tmpdir)
|
||||||
|
CheckDiscinfo(tmpdir + "/.discinfo")
|
||||||
|
new_volid = new_volid or old_volid
|
||||||
|
log.info("Volume Id = %s", new_volid)
|
||||||
|
|
||||||
|
# Escape the volume ids
|
||||||
|
new_volid = udev_escape(new_volid)
|
||||||
|
old_volid = udev_escape(old_volid)
|
||||||
|
|
||||||
|
remove_args = rm_args.split(' ') if rm_args else []
|
||||||
|
add_args = SplitCmdline(cmdline)
|
||||||
|
|
||||||
|
if ks:
|
||||||
|
add_args["inst.ks"] = ["hd:LABEL=%s:/%s" % (new_volid or old_volid, os.path.basename(ks))]
|
||||||
|
add_paths.append(ks)
|
||||||
|
|
||||||
|
if updates_image:
|
||||||
|
add_args["inst.updates"] = ["hd:LABEL=%s:/%s" % (new_volid or old_volid, os.path.basename(updates_image))]
|
||||||
|
add_paths.append(updates_image)
|
||||||
|
|
||||||
|
replace_list.append((old_volid, new_volid))
|
||||||
|
log.debug(replace_list)
|
||||||
|
# Add kickstart command and optionally change the volid of the available config files
|
||||||
|
EditIsolinux(remove_args, add_args, replace_list, tmpdir, custom_cfg)
|
||||||
|
EditGrub2(remove_args, add_args, replace_list, tmpdir)
|
||||||
|
EditS390(remove_args, add_args, replace_list, tmpdir)
|
||||||
|
|
||||||
|
if os.uname().machine.startswith("s390"):
|
||||||
|
RebuildS390CDBoot(tmpdir)
|
||||||
|
|
||||||
|
# If this is a UEFI iso, rebuild the efiboot.img file and put it in /efiboot.img
|
||||||
|
efibootimg = None
|
||||||
|
if not skip_efi and ("EFI/BOOT/grub.cfg" in files or "EFI/BOOT/BOOT.conf" in files):
|
||||||
|
if os.getuid() != 0:
|
||||||
|
raise RuntimeError("mkefiboot requires root privileges")
|
||||||
|
|
||||||
|
efibootimg = RebuildEFIBoot(input_iso, tmpdir)
|
||||||
|
|
||||||
|
# Build the command to rebuild the iso with the changes and additions
|
||||||
|
cmd = ["xorriso", "-indev", input_iso, "-outdev", output_iso, "-boot_image", "any", "replay"]
|
||||||
|
if new_volid != old_volid:
|
||||||
|
cmd.extend(["-volid", new_volid])
|
||||||
|
|
||||||
|
# Replace the embedded efiboot.img on partition 2
|
||||||
|
if efibootimg:
|
||||||
|
cmd.extend(["-append_partition", "2", "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", efibootimg.name])
|
||||||
|
|
||||||
|
# Update the config files that were extracted and modified
|
||||||
|
for root, _, files in os.walk(tmpdir, topdown=False):
|
||||||
|
isoroot = root.replace(tmpdir, "")
|
||||||
|
for f in files:
|
||||||
|
cmd.extend(["-update", root + "/" + f, isoroot + "/" + f])
|
||||||
|
|
||||||
|
# Add the kickstart and the new files and directories
|
||||||
|
for p in add_paths:
|
||||||
|
cmd.extend(["-map", p, os.path.basename(p)])
|
||||||
|
|
||||||
|
check_paths = add_paths
|
||||||
|
if CheckBigFiles(check_paths):
|
||||||
|
if "-as" not in cmd:
|
||||||
|
cmd.extend(["-as", "mkisofs"])
|
||||||
|
cmd.extend(["-iso-level", "3"])
|
||||||
|
|
||||||
|
if os.uname().machine.startswith("ppc64le"):
|
||||||
|
if "-as" not in cmd:
|
||||||
|
cmd.extend(["-as", "mkisofs"])
|
||||||
|
cmd.extend(["-U"])
|
||||||
|
|
||||||
|
## NOTE: If any xorriso commands need to be added after this they need
|
||||||
|
## to be preceeded by an '--' entry to exit the '-as mkisofs' mode
|
||||||
|
|
||||||
|
log.debug("Running: %s", " ".join(cmd))
|
||||||
|
subprocess.run(cmd, check=True, capture_output=False, env={"LANG": "C"})
|
||||||
|
|
||||||
|
if implantmd5:
|
||||||
|
ImplantMD5(output_iso)
|
||||||
|
|
||||||
|
# Generate a report of the layout of the new iso
|
||||||
|
if log.root.level < log.INFO:
|
||||||
|
cmd = ["xorriso", "-indev", output_iso, "-report_el_torito", "plain", "-report_system_area", "plain"]
|
||||||
|
log.debug("Running: %s", " ".join(cmd))
|
||||||
|
subprocess.run(cmd, check=False, capture_output=False, env={"LANG": "C"})
|
||||||
|
|
||||||
|
|
||||||
|
def setup_arg_parser():
|
||||||
|
""" Return argparse.Parser object of cmdline."""
|
||||||
|
parser = argparse.ArgumentParser(description="Add a kickstart and files to an iso")
|
||||||
|
|
||||||
|
parser.add_argument("-a", "--add", action="append", dest="add_paths", default=[],
|
||||||
|
type=os.path.abspath,
|
||||||
|
help="File or directory to add to ISO (may be used multiple times)")
|
||||||
|
parser.add_argument("-c", "--cmdline", dest="cmdline", metavar="CMDLINE", default="",
|
||||||
|
help="Arguments to add to kernel cmdline")
|
||||||
|
parser.add_argument("-r", "--rm-args", dest="rm_args", metavar="ARGS", default="",
|
||||||
|
help="Space separated list of arguments to remove from the kernel cmdline")
|
||||||
|
parser.add_argument("--debug", action="store_const", const=log.DEBUG,
|
||||||
|
dest="loglevel", default=log.INFO,
|
||||||
|
help="print debugging info")
|
||||||
|
parser.add_argument("--no-md5sum", action="store_false", default=True,
|
||||||
|
help="Do not run implantisomd5 on the ouput iso")
|
||||||
|
parser.add_argument("--ks", type=os.path.abspath, metavar="KICKSTART",
|
||||||
|
help="Optional kickstart to add to the ISO (adding inst.ks automatically)")
|
||||||
|
parser.add_argument("-u", "--updates", type=os.path.abspath, metavar="IMAGE",
|
||||||
|
help="Optional updates image to add to the ISO (adding inst.updates automatically)")
|
||||||
|
parser.add_argument("-V", "--volid", dest="volid", help="Set the ISO volume id, defaults to input's", default=None)
|
||||||
|
parser.add_argument("-R", "--replace", nargs=2, action="append", metavar=("FROM", "TO"),
|
||||||
|
help="Replace string in grub.cfg. Can be used multiple times")
|
||||||
|
parser.add_argument("--skip-mkefiboot", action="store_true", dest="skip_efi",
|
||||||
|
help="Skip running mkefiboot")
|
||||||
|
|
||||||
|
parser.add_argument("ks_pos", nargs="?", type=os.path.abspath, metavar="KICKSTART",
|
||||||
|
help="Optional kickstart to add to the ISO")
|
||||||
|
parser.add_argument("input_iso", type=os.path.abspath, help="ISO to modify")
|
||||||
|
parser.add_argument("output_iso", type=os.path.abspath, help="Full pathname of iso to be created")
|
||||||
|
parser.add_argument("--custom_cfg", type=os.path.abspath, help="Full pathname of custom isolinux.cfg", metavar='CFG')
|
||||||
|
|
||||||
|
return parser
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = setup_arg_parser()
|
||||||
|
args = parser.parse_args()
|
||||||
|
log.basicConfig(format='%(levelname)s:%(message)s', level=args.loglevel)
|
||||||
|
|
||||||
|
try:
|
||||||
|
errors = False
|
||||||
|
for t in ["xorriso", "osirrox"]:
|
||||||
|
if not shutil.which(t):
|
||||||
|
log.error("%s binary is missing", t)
|
||||||
|
errors = True
|
||||||
|
|
||||||
|
files = [args.input_iso, *args.add_paths]
|
||||||
|
if args.ks or args.ks_pos:
|
||||||
|
files += [args.ks or args.ks_pos]
|
||||||
|
for f in files:
|
||||||
|
if not os.path.exists(f):
|
||||||
|
log.error("%s is missing", f)
|
||||||
|
errors = True
|
||||||
|
|
||||||
|
if os.path.exists(args.output_iso):
|
||||||
|
log.error("%s already exists", args.output_iso)
|
||||||
|
errors = True
|
||||||
|
|
||||||
|
if "=" in args.rm_args:
|
||||||
|
log.error("--rm-args should only list the arguments to remove, not values")
|
||||||
|
errors = True
|
||||||
|
|
||||||
|
if args.ks and args.ks_pos:
|
||||||
|
log.error("Use either --ks KICKSTART or positional KICKSTART but not both")
|
||||||
|
errors = True
|
||||||
|
|
||||||
|
if not any([args.ks or args.ks_pos, args.updates, args.add_paths, args.cmdline, args.rm_args, args.volid, args.replace]):
|
||||||
|
log.error("Nothing to do - pass one or more of --ks, --updates, --add, --cmdline, --rm-args, --volid, --replace")
|
||||||
|
errors = True
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
raise RuntimeError("Problems running %s" % sys.argv[0])
|
||||||
|
|
||||||
|
MakeKickstartISO(args.input_iso, args.output_iso, args.ks or args.ks_pos, args.updates,
|
||||||
|
args.add_paths, args.cmdline, args.rm_args,
|
||||||
|
args.volid, args.replace, args.no_md5sum, args.skip_efi, args.custom_cfg)
|
||||||
|
except RuntimeError as e:
|
||||||
|
log.error(str(e))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdE/iMpuqJUG6FC3hLqOD5uREa6v6xXR3HeMBg1NibGVYkr0WmfvsckVsStKYA0SF3PLFs+fWTTJ6iFTDJvcclzADKe0REekWWrR7kNJR5RHoDwo6/hzm22tyGMH5i5JnvRElDmlLgmeXChWtqLVo2IP1JZrGyT/GTl4ViSZjNfdgCHJNxzmBgHdp31Mv9I7/1vv3A7ucJ3BJpbIL4Ck6QidFz1fQUWIJrXtNsdqvO/9PcFl/v75etfQRNPQ3HLMbWiQu6hVcKpxuwj0qVaXA+WPQAn5GeBKIkRYMsjEVC2fUS1/IVp47kmnXsw0H3fgGXPmoAEsRKs9niVOwegvWj workstation
|
||||||
Executable
+5
@@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
dd if=/dev/zero of=/dev/sda bs=1M count=1000
|
||||||
|
|
||||||
|
poweroff
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#============================================================================
|
||||||
|
# Title : lab-firstboot
|
||||||
|
# Description : Open a postinstall session on tty8 and run post-install
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Prevent openvt "could not deallocate" issue by redirecting stdin and stderr
|
||||||
|
exec 1>/dev/null
|
||||||
|
exec 2>/dev/null
|
||||||
|
|
||||||
|
# Don't run if homelab is already installed
|
||||||
|
test -f /etc/postinstall && exit
|
||||||
|
|
||||||
|
openvt -c 8 -w -f -s /var/lib/misc/custom/post-install.sh
|
||||||
|
|
||||||
|
sleep 15
|
||||||
Executable
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#============================================================================
|
||||||
|
# Title : post-install
|
||||||
|
# Description :
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
rpm -q gpg-pubkey-350d275d-6279464b &>/dev/null || rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
|
||||||
|
dnf -y install epel-release bash-completion
|
||||||
|
|
||||||
|
test $(systemd-detect-virt) == "kvm" && dnf -y install qemu-guest-agent
|
||||||
|
systemctl is-active --quiet qemu-guest-agent || systemctl start qemu-guest-agent
|
||||||
|
|
||||||
|
dnf install -y dnf-automatic chrony langpacks-en glibc-langpack-nl screen wget tar bzip2 unzip lsof \
|
||||||
|
nscd nfs-utils tmpwatch autofs git nfs-utils net-tools sysstat bash-completion rsync vim atop htop iftop iotop pv dstat nmap
|
||||||
|
|
||||||
|
systemctl is-active --quiet autofs || systemctl enable --now autofs
|
||||||
|
|
||||||
|
touch /etc/postinstall
|
||||||
|
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#============================================================================
|
||||||
|
# Title : post-install
|
||||||
|
# Description : postinstall section for running by Anaconda kickstart
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
mkdir -p /root/.ssh
|
||||||
|
|
||||||
|
cp /var/lib/misc/custom/postinstall.service /etc/systemd/system
|
||||||
|
cp /var/lib/misc/custom/authorized_keys /root/.ssh
|
||||||
|
|
||||||
|
chmod 600 /root/.ssh/authorized_keys
|
||||||
|
|
||||||
|
systemctl enable postinstall
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Postinstaller at first boot
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/var/lib/misc/custom/firstboot.sh
|
||||||
|
TimeoutStartSec=0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
TZ=Europe/Amsterdam
|
||||||
|
REPO=http://kickstart.lan/iso/Rocky-9.4-x86_64-minimal/minimal/
|
||||||
|
ROOTPW='$6$1mQhye0V5LujdR4F$87zIHy3bMZgjt02xY/F59eWk58VXh5CDSL0t9AInj6QOjLmYF0TDVeGLJH/bIKaGqXrbVJAgDHYZ9uT1uTMRX.'
|
||||||
|
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
default vesamenu.c32
|
||||||
|
timeout 600
|
||||||
|
|
||||||
|
display boot.msg
|
||||||
|
|
||||||
|
# Clear the screen when exiting the menu, instead of leaving the menu displayed.
|
||||||
|
# For vesamenu, this means the graphical background is still displayed without
|
||||||
|
# the menu itself for as long as the screen remains in graphics mode.
|
||||||
|
menu clear
|
||||||
|
menu background splash.png
|
||||||
|
menu title Rocky Linux Minimal 9.7
|
||||||
|
menu vshift 8
|
||||||
|
menu rows 18
|
||||||
|
menu margin 8
|
||||||
|
#menu hidden
|
||||||
|
menu helpmsgrow 15
|
||||||
|
menu tabmsgrow 13
|
||||||
|
|
||||||
|
# Border Area
|
||||||
|
menu color border * #00000000 #00000000 none
|
||||||
|
|
||||||
|
# Selected item
|
||||||
|
menu color sel 0 #ffffffff #00000000 none
|
||||||
|
|
||||||
|
# Title bar
|
||||||
|
menu color title 0 #ff7ba3d0 #00000000 none
|
||||||
|
|
||||||
|
# Press [Tab] message
|
||||||
|
menu color tabmsg 0 #ff3a6496 #00000000 none
|
||||||
|
|
||||||
|
# Unselected menu item
|
||||||
|
menu color unsel 0 #84b8ffff #00000000 none
|
||||||
|
|
||||||
|
# Selected hotkey
|
||||||
|
menu color hotsel 0 #84b8ffff #00000000 none
|
||||||
|
|
||||||
|
# Unselected hotkey
|
||||||
|
menu color hotkey 0 #ffffffff #00000000 none
|
||||||
|
|
||||||
|
# Help text
|
||||||
|
menu color help 0 #ffffffff #00000000 none
|
||||||
|
|
||||||
|
# A scrollbar of some type? Not sure.
|
||||||
|
menu color scrollbar 0 #ffffffff #ff355594 none
|
||||||
|
|
||||||
|
# Timeout msg
|
||||||
|
menu color timeout 0 #ffffffff #00000000 none
|
||||||
|
menu color timeout_msg 0 #ffffffff #00000000 none
|
||||||
|
|
||||||
|
# Command prompt text
|
||||||
|
menu color cmdmark 0 #84b8ffff #00000000 none
|
||||||
|
menu color cmdline 0 #ffffffff #00000000 none
|
||||||
|
|
||||||
|
# Do not display the actual menu unless the user presses a key. All that is displayed is a timeout message.
|
||||||
|
|
||||||
|
menu tabmsg Press Tab for full configuration options on menu items.
|
||||||
|
|
||||||
|
menu separator # insert an empty line
|
||||||
|
menu separator # insert an empty line
|
||||||
|
|
||||||
|
label linux
|
||||||
|
menu label ^Install Rocky Linux Minimal 9.7 (Homelab)
|
||||||
|
menu default
|
||||||
|
kernel vmlinuz
|
||||||
|
append initrd=initrd.img inst.stage2=hd:LABEL=Rocky-9-7-x86_64-dvd quiet inst.ks=hd:LABEL=Rocky-9-7-x86_64-dvd:/rocky-9.cfg
|
||||||
|
|
||||||
|
label check
|
||||||
|
menu label Test this ^media & install Rocky Linux Minimal 9.7
|
||||||
|
kernel vmlinuz
|
||||||
|
append initrd=initrd.img inst.stage2=hd:LABEL=Rocky-9-7-x86_64-dvd rd.live.check quiet inst.ks=hd:LABEL=Rocky-9-7-x86_64-dvd:/rocky-9.cfg
|
||||||
|
|
||||||
|
label fips
|
||||||
|
menu label ^Install Rocky Linux Minimal 9.7 in FIPS mode
|
||||||
|
kernel vmlinuz
|
||||||
|
append initrd=initrd.img inst.stage2=hd:LABEL=Rocky-9-7-x86_64-dvd quiet fips=1 inst.ks=hd:LABEL=Rocky-9-7-x86_64-dvd:/rocky-9.cfg
|
||||||
|
|
||||||
|
menu separator # insert an empty line
|
||||||
|
|
||||||
|
# utilities submenu
|
||||||
|
menu begin ^Troubleshooting
|
||||||
|
menu title Troubleshooting
|
||||||
|
|
||||||
|
label text
|
||||||
|
menu indent count 5
|
||||||
|
menu label Install Rocky Linux Minimal 9.7 using ^text mode
|
||||||
|
text help
|
||||||
|
Try this option out if you're having trouble installing
|
||||||
|
Rocky Linux Minimal 9.7.
|
||||||
|
endtext
|
||||||
|
kernel vmlinuz
|
||||||
|
append initrd=initrd.img inst.stage2=hd:LABEL=Rocky-9-7-x86_64-dvd inst.text quiet inst.ks=hd:LABEL=Rocky-9-7-x86_64-dvd:/rocky-9.cfg
|
||||||
|
|
||||||
|
label rescue
|
||||||
|
menu indent count 5
|
||||||
|
menu label ^Rescue a Rocky Linux Minimal system
|
||||||
|
text help
|
||||||
|
If the system will not boot, this lets you access files
|
||||||
|
and edit config files to try to get it booting again.
|
||||||
|
endtext
|
||||||
|
kernel vmlinuz
|
||||||
|
append initrd=initrd.img inst.stage2=hd:LABEL=Rocky-9-7-x86_64-dvd inst.rescue quiet inst.ks=hd:LABEL=Rocky-9-7-x86_64-dvd:/rocky-9.cfg
|
||||||
|
|
||||||
|
label memtest
|
||||||
|
menu label Run a ^memory test
|
||||||
|
text help
|
||||||
|
If your system is having issues, a problem with your
|
||||||
|
system's memory may be the cause. Use this utility to
|
||||||
|
see if the memory is working correctly.
|
||||||
|
endtext
|
||||||
|
kernel memtest
|
||||||
|
|
||||||
|
menu separator # insert an empty line
|
||||||
|
|
||||||
|
label local
|
||||||
|
menu label Boot from ^local drive
|
||||||
|
localboot 0xffff
|
||||||
|
|
||||||
|
menu separator # insert an empty line
|
||||||
|
menu separator # insert an empty line
|
||||||
|
|
||||||
|
label returntomain
|
||||||
|
menu label Return to ^main menu
|
||||||
|
menu exit
|
||||||
|
|
||||||
|
menu end
|
||||||
+17
-34
@@ -8,8 +8,6 @@ firewall --service=ssh
|
|||||||
selinux --disabled
|
selinux --disabled
|
||||||
zerombr
|
zerombr
|
||||||
|
|
||||||
repo --name="AppStream" --baseurl=http://atc-mgt01.dell-atc.lan/iso/Rocky-9.7-x86_64-minimal/Minimal
|
|
||||||
|
|
||||||
%include /tmp/settings
|
%include /tmp/settings
|
||||||
|
|
||||||
reboot
|
reboot
|
||||||
@@ -28,29 +26,23 @@ reboot
|
|||||||
# Handling commandline options #
|
# Handling commandline options #
|
||||||
# configuring repositories and setting up install packages #
|
# configuring repositories and setting up install packages #
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
%pre --log=/tmp/ks-pre.log
|
%pre --log=/tmp/ks-pre.log --interpreter=/bin/bash
|
||||||
#!/bin/bash
|
|
||||||
echo Kickstart preinstall script
|
echo Kickstart preinstall script
|
||||||
|
source /mnt/install/repo/custom/settings
|
||||||
touch /tmp/rpms /tmp/settings
|
touch /tmp/rpms /tmp/settings
|
||||||
|
|
||||||
# Settings from config file
|
# Settings from config file
|
||||||
rootpw='$6$OJEdzUbqfQR72WjX$SFMnDZ0MXM7JfYKPvvN0nJIPetzrWQw/0q360xgR9mwJVwrme4dt9hhtH95yytn8Ln0.0koVCno6vskylJFm5.'
|
echo "repo --name=\"AppStream\" --baseurl=${REPO:-NO_REPO}" >> /tmp/settings
|
||||||
|
echo "rootpw --iscrypted ${ROOTPW:-NO_ROOTPW}" >> /tmp/settings
|
||||||
tz='Europe/Amsterdam'
|
echo "timezone ${TZ:-Europe/Amsterdam}" >> /tmp/settings
|
||||||
|
|
||||||
set -- `cat /proc/cmdline`
|
set -- `cat /proc/cmdline`
|
||||||
for I in $*; do case "$I" in *=*) eval ${I//inst\./} ;; esac; done
|
for I in $*; do case "$I" in *=*) eval ${I//inst\./} ;; esac; done
|
||||||
|
|
||||||
grep -qws "debug" /proc/cmdline && bash
|
|
||||||
|
|
||||||
# Get release by probing libc
|
|
||||||
# EL 6 does not support bootdisk on XFS, only use it for everything else
|
|
||||||
case $(ls /lib64/libc-*|head -1) in
|
|
||||||
*2.12*) fs=ext4 ; mp=/mnt/source ;;
|
|
||||||
*) fs=xfs ; mp=/run/install/repo ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# boot disk detection
|
# boot disk detection
|
||||||
|
lsblk -bSo name,type,ro,hotplug,size,vendor,model,serial
|
||||||
|
bd=$(lsblk -nbSo name,type,ro,hotplug,size | awk 'NR==1 && $2=="disk" && $3==0 && $4==0 && $5>500 {print $1}')
|
||||||
|
|
||||||
printf "%-10s%10s%10s%10s\n" dev size removable inuse
|
printf "%-10s%10s%10s%10s\n" dev size removable inuse
|
||||||
for dev in $(find /sys/block/ -name "sd?" -o -name "xvd?" -o -name "vd?"|sort); do
|
for dev in $(find /sys/block/ -name "sd?" -o -name "xvd?" -o -name "vd?"|sort); do
|
||||||
devname=${dev##*/}
|
devname=${dev##*/}
|
||||||
@@ -62,8 +54,6 @@ for dev in $(find /sys/block/ -name "sd?" -o -name "xvd?" -o -name "vd?"|sort);
|
|||||||
done
|
done
|
||||||
test -z "$bootdisk" && echo "No bootdisk detected" || echo "Bootdisk = $bootdisk"
|
test -z "$bootdisk" && echo "No bootdisk detected" || echo "Bootdisk = $bootdisk"
|
||||||
|
|
||||||
echo "rootpw --iscrypted $rootpw" >> /tmp/settings
|
|
||||||
|
|
||||||
if test -d /sys/firmware/efi; then
|
if test -d /sys/firmware/efi; then
|
||||||
cat <<- EOF >> /tmp/settings
|
cat <<- EOF >> /tmp/settings
|
||||||
reqpart --add-boot
|
reqpart --add-boot
|
||||||
@@ -71,18 +61,17 @@ if test -d /sys/firmware/efi; then
|
|||||||
else
|
else
|
||||||
cat <<- EOF >> /tmp/settings
|
cat <<- EOF >> /tmp/settings
|
||||||
bootloader --location=mbr
|
bootloader --location=mbr
|
||||||
part /boot --fstype=$fs --size=768
|
part /boot --fstype=xfs --size=1024
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<- EOF >> /tmp/settings
|
cat <<- EOF >> /tmp/settings
|
||||||
timezone ${tz:---utc UTC}
|
|
||||||
ignoredisk --only-use=${bootdisk:-none}
|
ignoredisk --only-use=${bootdisk:-none}
|
||||||
part pv.2 --grow --size=200 --maxsize=65536
|
part pv.2 --grow --size=200 --maxsize=65536
|
||||||
volgroup rvg --pesize=4096 pv.2
|
volgroup rvg --pesize=4096 pv.2
|
||||||
logvol / --fstype=$fs --name=root --vgname=rvg --size=1024
|
logvol / --fstype=xfs --name=root --vgname=rvg --size=1024
|
||||||
logvol /opt --fstype=xfs --name=opt --vgname=rvg --size=512
|
logvol /opt --fstype=xfs --name=opt --vgname=rvg --size=512
|
||||||
logvol /var --fstype=xfs --name=var --vgname=rvg --size=2048
|
logvol /var --fstype=xfs --name=var --vgname=rvg --size=4096
|
||||||
logvol /usr --fstype=xfs --name=usr --vgname=rvg --size=4096
|
logvol /usr --fstype=xfs --name=usr --vgname=rvg --size=4096
|
||||||
logvol /home --fstype=xfs --name=home --vgname=rvg --size=1024
|
logvol /home --fstype=xfs --name=home --vgname=rvg --size=1024
|
||||||
logvol /tmp --fstype=xfs --name=tmp --vgname=rvg --size=1024
|
logvol /tmp --fstype=xfs --name=tmp --vgname=rvg --size=1024
|
||||||
@@ -99,29 +88,23 @@ set > /tmp/environment
|
|||||||
#######################################################################################
|
#######################################################################################
|
||||||
# Post (no chroot) script #
|
# Post (no chroot) script #
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
%post --nochroot --log=/mnt/sysimage/var/log/ks-post-nochroot.log
|
%post --nochroot --log=/mnt/sysimage/var/log/ks-post-nochroot.log --interpreter=/bin/bash
|
||||||
|
|
||||||
# Save kickstart and cmdline settings for later reference
|
# Save kickstart and cmdline settings for later reference
|
||||||
cp /proc/cmdline /tmp/{settings,environment,rpms,ks-pre.log} /mnt/sysimage/var/lib/misc/
|
cp /proc/cmdline /tmp/{settings,environment,rpms,ks-pre.log} /mnt/sysimage/var/lib/misc/
|
||||||
|
|
||||||
|
# Prepare post-install
|
||||||
|
cp -r /mnt/install/repo/custom /mnt/sysimage/var/lib/misc/
|
||||||
|
|
||||||
%end
|
%end
|
||||||
|
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
# Post (chroot) script (optional customization) #
|
# Post (chroot) script (optional customization) #
|
||||||
#######################################################################################
|
#######################################################################################
|
||||||
%post --log=/var/log/ks-post-chroot.log --interpreter=/bin/bash
|
%post --log=/var/log/ks-post-chroot.log --interpreter=/bin/bash
|
||||||
mkdir -p /root/.ssh
|
|
||||||
cat <<- EOF >> /root/.ssh/authorized_keys
|
|
||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdE/iMpuqJUG6FC3hLqOD5uREa6v6xXR3HeMBg1NibGVYkr0WmfvsckVsStKYA0SF3PLFs+fWTTJ6iFTDJvcclzADKe0REekWWrR7kNJR5RHoDwo6/hzm22tyGMH5i5JnvRElDmlLgmeXChWtqLVo2IP1JZrGyT/GTl4ViSZjNfdgCHJNxzmBgHdp31Mv9I7/1vv3A7ucJ3BJpbIL4Ck6QidFz1fQUWIJrXtNsdqvO/9PcFl/v75etfQRNPQ3HLMbWiQu6hVcKpxuwj0qVaXA+WPQAn5GeBKIkRYMsjEVC2fUS1/IVp47kmnXsw0H3fgGXPmoAEsRKs9niVOwegvWj /home/bart/.ssh/id_rsa
|
|
||||||
EOF
|
|
||||||
chmod 400 /root/.ssh/authorized_keys
|
|
||||||
|
|
||||||
chvt 2
|
# Run post-install script
|
||||||
iotty=$(tty)
|
/var/lib/misc/custom/post-setup.sh
|
||||||
exec > "$iotty" 2>&1 < "$iotty"
|
|
||||||
|
|
||||||
read -p "Enter hostname: " hn
|
|
||||||
hostnamectl hostname $hn
|
|
||||||
|
|
||||||
%end
|
%end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user