Compare commits

..

10 Commits

Author SHA1 Message Date
53f92032a4 feat(zbm): Add KCL to legacy BIOS ZBM (#6) 2023-11-03 01:40:24 +01:00
b160b4a1e1 feat(zbm): Prepare SSH in ZBM (#6) 2023-11-03 01:38:56 +01:00
1690518197 feat(zbm): Define Dropbear's SSH pub keys (#6) 2023-11-03 01:38:28 +01:00
732cc47405 feat(zbm): Add networking/IP addressing setup to ZBM (#6) 2023-11-03 01:38:11 +01:00
be668b1bdc feat(zbm): Add user's dropbear customizations (#6) 2023-11-03 01:37:38 +01:00
53ed730957 feat(zbm): Add dropbear hook files (#6) 2023-11-03 01:37:15 +01:00
9a89ce4f75 fix(os): Remove zfsbootmenu hook from ZFSBootMenu (#6)
While unintuitive this prevents us from having to
move this hook to the end of the HOOKS array.
If user wants SSH in ZBM we first append 'net' to
the HOOKS array then append 'dropbear'. At this
point the explicit 'zfsbootmenu' hook is no longer
last in line in 'HOOKS' array. This causes ZBM to
trip and to not correctly load net and dropbear.

Since the 'zfsbootmenu' hook is added implicitly
by generate-zbm we don't need the explicit hook
at all. Better remove it. This way it doesn't get in
the way.
2023-11-01 03:53:18 +01:00
3cb68406ed feat(os): Add SSH to ZBM if requested by user (#6) 2023-11-01 03:49:46 +01:00
33966071ce refactor(os): Simplify mkinitcpio.conf manipulation (#6) 2023-11-01 03:49:05 +01:00
4e734330da feat(os): Add helper functions to manipulate HOOKS array (#6) 2023-11-01 03:47:34 +01:00

151
setup.sh
View File

@@ -461,14 +461,44 @@ function set_locale () {
printf -- '%s\n' 'LANG=en_US.UTF-8' > '/mnt/etc/locale.conf' printf -- '%s\n' 'LANG=en_US.UTF-8' > '/mnt/etc/locale.conf'
} }
function in_file_in_array_insert_n_before_m () {
local arg_file arg_array arg_string arg_precede
arg_file="${1:?}"
arg_array="${2:?}"
arg_string="${3:?}"
arg_precede="${4:?}"
sed -ri \
-e 's'$'\x1''('"${arg_array}"'=)(.*?[( ])('"${arg_precede}"')([) ][^\r\n\f]*)'$'\x1''\1\2'"${arg_string}"' \3\4'$'\x1''g' \
"${arg_file}"
}
function in_file_in_array_insert_n_at_the_end () {
local arg_file arg_array arg_string
arg_file="${1:?}"
arg_array="${2:?}"
arg_string="${3:?}"
sed -ri \
-e 's'$'\x1''('"${arg_array}"'=)([^)]*)(\)[^\r\n\f]*)'$'\x1''\1\2 '"${arg_string}"'\3'$'\x1''g' \
"${arg_file}"
}
function in_file_in_array_remove_n () {
local arg_file arg_array arg_string
arg_file="${1:?}"
arg_array="${2:?}"
arg_string="${3:?}"
sed -ri \
-e 's'$'\x1''((\()('"${arg_string}"')(\)))'$'\x1''\2\4'$'\x1''g' \
-e 's'$'\x1''('"${arg_array}"'=.*?)([[:space:]]+'"${arg_string}"')([[:space:]]+|\))'$'\x1''\1\3'$'\x1''g' \
-e 's'$'\x1''('"${arg_array}"'=.*?)([[:space:]]+|\()('"${arg_string}"'[[:space:]]+)'$'\x1''\1\2'$'\x1''g' \
"${arg_file}"
}
function add_zfs_hook_to_initramfs () { function add_zfs_hook_to_initramfs () {
#1.16 #1.16
# Add zfs hook, remove fsck hook from initramfs. # Add zfs hook, remove fsck hook from initramfs.
sed -ri \ in_file_in_array_insert_n_before_m '/mnt/etc/mkinitcpio.conf' 'HOOKS' 'zfs' 'filesystems'
-e 's'$'\x1''(HOOKS=)(.*?[( ])(filesystems)([) ][^\r\n\f]*)'$'\x1''\1\2zfs \3\4'$'\x1''g' \ in_file_in_array_remove_n '/mnt/etc/mkinitcpio.conf' 'HOOKS' 'fsck'
-e 's'$'\x1''((\()(fsck)(\)))'$'\x1''\2\4'$'\x1''g' \
-e 's'$'\x1''(([[:space:]]+)(fsck)|(fsck)([[:space:]]+))'$'\x1'''$'\x1''g' \
'/mnt/etc/mkinitcpio.conf'
# Also unless encryption's unwanted add plain text key file into # Also unless encryption's unwanted add plain text key file into
# initramfs since it's living inside an encrypted pool anyway. # initramfs since it's living inside an encrypted pool anyway.
[[ ! "${ARCHZBM_ZFSPROPS_NO_ENCRYPTION}" ]] && sed -ri \ [[ ! "${ARCHZBM_ZFSPROPS_NO_ENCRYPTION}" ]] && sed -ri \
@@ -674,6 +704,7 @@ EOF
function configure_zfsbootmenu () { function configure_zfsbootmenu () {
#2.9 #2.9
paru_install 'zfsbootmenu' paru_install 'zfsbootmenu'
in_file_in_array_remove_n '/etc/mkinitcpio.conf' 'HOOKS' 'zfsbootmenu'
if [[ "${part_schema}" = 'gpt' ]]; then if [[ "${part_schema}" = 'gpt' ]]; then
cat > '/etc/zfsbootmenu/config.yaml' <<EOF cat > '/etc/zfsbootmenu/config.yaml' <<EOF
@@ -704,6 +735,7 @@ Components:
Versions: false Versions: false
ImageDir: /boot/syslinux/zfsbootmenu ImageDir: /boot/syslinux/zfsbootmenu
Kernel: Kernel:
CommandLine: ro loglevel=0 zbm.import_policy=hostid
Prefix: vmlinuz Prefix: vmlinuz
EOF EOF
fi fi
@@ -716,6 +748,112 @@ EOF
zfs set org.zfsbootmenu:commandline='rw nowatchdog rd.vconsole.keymap=de-latin1' "${zpool_name}"'/root/'"${zfs_arch_dataset_name}" zfs set org.zfsbootmenu:commandline='rw nowatchdog rd.vconsole.keymap=de-latin1' "${zpool_name}"'/root/'"${zfs_arch_dataset_name}"
} }
function get_dropbear_hooks () {
mkdir -p '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main'
git -C '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main' clone 'https://quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook.git' .
ln -s '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main/pacman-mkinitcpio-dropbear-hook.hook' '/usr/share/libalpm/hooks/pacman-mkinitcpio-dropbear-hook.hook'
ln -s '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main/pacman-mkinitcpio-dropbear-install.hook' '/usr/share/libalpm/hooks/pacman-mkinitcpio-dropbear-install.hook'
}
function customize_dropbear_hooks () {
local env_archzbm_ssh_port env_archzbm_ssh_keepalive_intvl
env_archzbm_ssh_port="${ARCHZBM_SSH_PORT:-22}"
env_archzbm_ssh_keepalive_intvl="${ARCHZBM_SSH_KEEPALIVE_INTVL:-1}"
if [[ "${env_archzbm_ssh_port}" -ne '22' ]] || [[ "${env_archzbm_ssh_keepalive_intvl}" -ne '1' ]]; then
paru_install 'rsync'
rsync -av '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main/dropbear_hook'{,'.override'}'.patch'
fi
if [[ "${env_archzbm_ssh_port}" -ne '22' ]]; then
sed -ri -e 's'$'\x1''-p [[:digit:]]+'$'\x1''-p '"${env_archzbm_ssh_port}"''$'\x1''g' '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main/dropbear_hook.override.patch'
fi
if [[ "${env_archzbm_ssh_keepalive_intvl}" -ne '1' ]]; then
sed -ri -e 's'$'\x1''-K [[:digit:]]+'$'\x1''-K '"${env_archzbm_ssh_keepalive_intvl}"''$'\x1''g' '/opt/git/quico.space/quico-os-setup/mkinitcpio-dropbear-pacman-hook/branches/main/dropbear_hook.override.patch'
fi
}
function ensure_ip_in_kcl () {
local zbm_config kcl_length kcl_string default_ip ip_addr_found new_kcl first_kcl_elem
local -a kcl
paru_install 'go-yq'
zbm_config='/etc/zfsbootmenu/config.yaml'
kcl_length="$(yq '.Kernel.CommandLine | length' "${zbm_config}")"
if [[ "${kcl_length}" -eq '0' ]]; then
>&3 printf -- '%s\n' \
'No .Kernel.CommandLine YAML element with content found in '"${zbm_config}"'. Exiting ...'
exit 77
else
kcl_string="$(yq '.Kernel.CommandLine' "${zbm_config}")"
fi
default_ip='ip='"${ARCHZBM_NET_CLIENT_IP}"':'"${ARCHZBM_NET_SERVER_IP}"':'"${ARCHZBM_NET_GATEWAY_IP}"':'"${ARCHZBM_NET_NETMASK}"':'"${ARCHZBM_NET_HOSTNAME}"':'"${ARCHZBM_NET_DEVICE}"':'"${ARCHZBM_NET_AUTOCONF}"
mapfile -t kcl < <(<<<"${kcl_string}" tr ' ' '\n' | sed '/^$/d')
for kcl_elem in "${!kcl[@]}"; do
if grep -Piq -- 'ip=' <<<"${kcl[$kcl_elem]}"; then
ip_addr_found='true'
kcl["${kcl_elem}"]="${default_ip}"
fi
done
if [[ ! "${ip_addr_found}" ]]; then
kcl+=("${default_ip}")
fi
new_kcl=''
first_kcl_elem='true'
for kcl_elem in "${kcl[@]}"; do
if [[ ! "${first_kcl_elem}" ]]; then
new_kcl+=' '"${kcl_elem}"
else
new_kcl+="${kcl_elem}"
unset -v first_kcl_elem
fi
done
yq -i '.Kernel.CommandLine = "'"${new_kcl}"'"' "${zbm_config}"
}
function set_pub_keys () {
local authorized_keys_file raw_pub_keys
authorized_keys_file="${1:?}"
raw_pub_keys="${2:?}"
:> "${authorized_keys_file}"
while IFS= read -r pub_key_line; do
printf -- '%s\n' "${pub_key_line}" >> "${authorized_keys_file}"
done < <(<<<"${raw_pub_keys}" sed -r -e 's/,,/\n/g')
sed -i '/^$/d' "${authorized_keys_file}"
}
function we_want_ssh () {
#2.10
if [[ "${ARCHZBM_NET_CLIENT_IP}" ]] || \
[[ "${ARCHZBM_NET_SERVER_IP}" ]] || \
[[ "${ARCHZBM_NET_GATEWAY_IP}" ]] || \
[[ "${ARCHZBM_NET_NETMASK}" ]] || \
[[ "${ARCHZBM_NET_HOSTNAME}" ]] || \
[[ "${ARCHZBM_NET_DEVICE}" ]] || \
[[ "${ARCHZBM_NET_AUTOCONF}" ]] || \
[[ "${ARCHZBM_SSH_PORT}" ]] || \
[[ "${ARCHZBM_SSH_KEEPALIVE_INTVL}" ]] || \
[[ "${ARCHZBM_SSH_AUTH_KEYS}" ]]; then
>&3 printf -- '%s\n' 'Installing SSH in ZFSBootMenu'
return 0
fi
>&3 printf -- '%s\n' 'Not installing SSH in ZFSBootMenu'
return 1
}
function configure_ssh_in_zbm () {
#2.11
get_dropbear_hooks
customize_dropbear_hooks
paru_install 'mkinitcpio-nfs-utils' 'dropbear' 'mkinitcpio-dropbear'
in_file_in_array_insert_n_at_the_end '/etc/zfsbootmenu/mkinitcpio.conf' 'HOOKS' 'net'
in_file_in_array_insert_n_at_the_end '/etc/zfsbootmenu/mkinitcpio.conf' 'HOOKS' 'dropbear'
for key_type in 'dss' 'ecdsa' 'ed25519' 'rsa'; do
dropbearkey -t "${key_type}" -f '/etc/dropbear/dropbear_'"${key_type}"'_host_key'
done
set_pub_keys '/etc/dropbear/root_key' "${ARCHZBM_SSH_AUTH_KEYS}"
ensure_ip_in_kcl
}
function add_syslinux_pacman_hook () { function add_syslinux_pacman_hook () {
mkdir -p '/opt/git/quico.space/quico-os-setup/zbm-syslinux-pacman-hook/branches/main' mkdir -p '/opt/git/quico.space/quico-os-setup/zbm-syslinux-pacman-hook/branches/main'
git -C '/opt/git/quico.space/quico-os-setup/zbm-syslinux-pacman-hook/branches/main' clone 'https://quico.space/quico-os-setup/zbm-syslinux-pacman-hook.git' . git -C '/opt/git/quico.space/quico-os-setup/zbm-syslinux-pacman-hook/branches/main' clone 'https://quico.space/quico-os-setup/zbm-syslinux-pacman-hook.git' .
@@ -769,6 +907,9 @@ function install_os_in_chroot () {
# Install ZFSBootMenu image # Install ZFSBootMenu image
configure_zfsbootmenu #2.9 configure_zfsbootmenu #2.9
if we_want_ssh; then #2.10
configure_ssh_in_zbm #2.11
fi
generate-zbm generate-zbm
# Yes, we do this twice so we immediately get a functional backup file # Yes, we do this twice so we immediately get a functional backup file