diff --git a/archlinux.sh b/archlinux.sh index b042ee8..c81be6c 100644 --- a/archlinux.sh +++ b/archlinux.sh @@ -19,8 +19,8 @@ extract_image() { # symlink to latest archlinux-bootstrap local archlinux_bootstrap_archive="$SCRIPTPATH/../archlinux/archlinux-bootstrap-latest-x86_64.tar.gz" - local archlinux_mirror='https://mirror.hetzner.de/archlinux' - local archlinux_packages='base btrfs-progs cronie cryptsetup gptfdisk grub haveged linux linux-firmware lvm2 mdadm net-tools openssh python rsync vim wget xfsprogs' + local archlinux_mirror='https://mirror.hetzner.com/archlinux' + local archlinux_packages='base btrfs-progs cronie cryptsetup gptfdisk grub haveged linux linux-firmware lvm2 mdadm net-tools openssh python rsync vim wget xfsprogs inetutils' # dont extract archlinux-bootstrap to system memory but the target disk local hdd_dir="$FOLD/hdd" @@ -142,9 +142,11 @@ extract_image() { local resolv_conf="$hdd_dir/etc/resolv.conf" debug "# create /etc/resolv.conf" { - for ip in $(shuf -e "${NAMESERVER[@]}") $(shuf -e "${DNSRESOLVER_V6[@]}"); do - echo "nameserver $ip" - done + echo "### $COMPANY installimage" + echo '# nameserver config' + while read nsaddr; do + echo "nameserver $nsaddr" + done < <(randomized_nsaddrs) } > "$resolv_conf" || return 1 diff -Naur /dev/null "$resolv_conf" | debugoutput diff --git a/centos.sh b/centos.sh index 031e16e..63c9de9 100644 --- a/centos.sh +++ b/centos.sh @@ -3,114 +3,10 @@ # # CentOS specific functions # -# (c) 2008-2018, Hetzner Online GmbH +# (c) 2008-2021, Hetzner Online GmbH # -# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" -setup_network_config() { - if [ -n "$1" ] && [ -n "$2" ]; then - # good we have a device and a MAC - if [ -f "$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" ]; then - UDEVFILE="$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" - else - UDEVFILE="/dev/null" - fi - { - echo "### $COMPANY - installimage" - echo "# device: $1" - printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", KERNEL=="eth*", NAME="%s"\n' "$2" "$1" - } > "$UDEVFILE" - - local upper_mac; upper_mac="$(echo "$2" | awk '{ print toupper($0) }')" - - NETWORKFILE="$FOLD/hdd/etc/sysconfig/network" - { - echo "### $COMPANY - installimage" - echo "# general networking" - echo "NETWORKING=yes" - } > "$NETWORKFILE" - - rm -f "$FOLD/hdd/etc/sysconfig/network-scripts/ifcfg-en*" - - CONFIGFILE="$FOLD/hdd/etc/sysconfig/network-scripts/ifcfg-$1" - ROUTEFILE="$FOLD/hdd/etc/sysconfig/network-scripts/route-$1" - - { - echo "### $COMPANY - installimage" - echo "#" - } > "$CONFIGFILE" - - if ! is_private_ip "$3" && ! isVServer; then - { - echo "# Note for customers who want to create bridged networking for virtualisation:" - echo "# Gateway is set in separate file" - echo "# Do not forget to change interface in file route-$1 and rename this file" - } >> "$CONFIGFILE" - fi - { - echo "#" - echo "# device: $1" - echo "DEVICE=$1" - echo "ONBOOT=yes" - echo "HWADDR=$upper_mac" - } >> "$CONFIGFILE" - - if [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ]; then - if is_private_ip "$6" && isVServer; then - echo "BOOTPROTO=dhcp" >> "$CONFIGFILE" - else - { - echo "BOOTPROTO=none" >> "$CONFIGFILE" - echo "IPADDR=$3" - } >> "$CONFIGFILE" - if is_private_ip "$3" || isVServer; then - { - echo "NETMASK=$5" - echo "GATEWAY=$6" - } >> "$CONFIGFILE" - else - { - echo "NETMASK=255.255.255.255" - echo "SCOPE=\"peer $6\"" - } >> "$CONFIGFILE" - - { - echo "### $COMPANY - installimage" - echo "# routing for eth0" - echo "ADDRESS0=0.0.0.0" - echo "NETMASK0=0.0.0.0" - echo "GATEWAY0=$6" - } > "$ROUTEFILE" - fi - fi - fi - - if [ -n "$8" ] && [ -n "$9" ] && [ -n "${10}" ]; then - debug "setting up ipv6 networking $8/$9 via ${10}" - echo "NETWORKING_IPV6=yes" >> "$NETWORKFILE" - { - echo "IPV6INIT=yes" - echo "IPV6ADDR=$8/$9" - echo "IPV6_DEFAULTGW=${10}" - echo "IPV6_DEFAULTDEV=$1" - } >> "$CONFIGFILE" - fi - - # set duplex/speed - if ! isNegotiated && ! isVServer; then - echo 'ETHTOOL_OPTS="speed 100 duplex full autoneg off"' >> "$CONFIGFILE" - fi - - # remove all hardware info from image (CentOS 5) - if [ -f "$FOLD/hdd/etc/sysconfig/hwconf" ]; then - echo "" > "$FOLD/hdd/etc/sysconfig/hwconf" - fi - - return 0 - fi -} - # generate_config_mdadm "NIL" generate_config_mdadm() { if [ -n "$1" ]; then @@ -131,68 +27,33 @@ generate_new_ramdisk() { # pick the latest kernel VERSION="$(find "$FOLD/hdd/boot/" -name "vmlinuz-*" | cut -d '-' -f 2- | sort -V | tail -1)" - if [ "$IMG_VERSION" -lt 60 ] ; then - local modulesfile="$FOLD/hdd/etc/modprobe.conf" - # previously we added an alias for eth0 based on the niclist (static - # pci-id->driver mapping) of the old rescue. But the new rescue mdev/udev - # So we only add aliases for the controller - { - echo "### $COMPANY - installimage" - echo "# load all modules" - echo "" - echo "# hdds" - } > "$modulesfile" - - HDDDEV="" - for hddmodule in $MODULES; do - if [ "$hddmodule" != "powernow-k8" ] && [ "$hddmodule" != "via82cxxx" ] && [ "$hddmodule" != "atiixp" ]; then - echo "alias scsi_hostadapter$HDDDEV $hddmodule" >> "$modulesfile" - HDDDEV="$((HDDDEV + 1))" - fi - done - echo "" >> "$modulesfile" - elif [ "$IMG_VERSION" -ge 60 ] ; then - # blacklist some kernel modules due to bugs and/or stability issues or annoyance - local blacklist_conf="$FOLD/hdd/etc/modprobe.d/blacklist-$C_SHORT.conf" - { - echo "### $COMPANY - installimage" - echo "### silence any onboard speaker" - echo "blacklist pcspkr" - echo "### i915 driver blacklisted due to various bugs" - echo "### especially in combination with nomodeset" - echo "blacklist i915" - echo "blacklist sm750fb" - } > "$blacklist_conf" - fi - - if [ "$IMG_VERSION" -ge 70 ] && ((IMG_VERSION != 610)); then - local dracutfile="$FOLD/hdd/etc/dracut.conf.d/99-$C_SHORT.conf" - { - echo "### $COMPANY - installimage" - echo 'add_dracutmodules+="lvm mdraid"' - echo 'add_drivers+="raid0 raid1 raid10 raid456"' - #echo 'early_microcode="no"' - echo 'hostonly="no"' - echo 'hostonly_cmdline="no"' - echo 'lvmconf="yes"' - echo 'mdadmconf="yes"' - echo 'persistent_policy="by-uuid"' - } > "$dracutfile" - fi - - if [ "$IMG_VERSION" -ge 70 ] && ((IMG_VERSION != 610)); then - execute_chroot_command "dracut -f --kver $VERSION" - declare -i EXITCODE=$? - else - if [ "$IMG_VERSION" -ge 60 ] ; then - execute_chroot_command "/sbin/new-kernel-pkg --mkinitrd --dracut --depmod --install $VERSION" - declare -i EXITCODE=$? - else - rm "${FOLD}/hdd/boot/grub/grub.conf" |& debugoutput - execute_chroot_command "/sbin/new-kernel-pkg --package kernel --mkinitrd --depmod --install $VERSION" - declare -i EXITCODE=$? - fi - fi + # blacklist some kernel modules due to bugs and/or stability issues or annoyance + local blacklist_conf="$FOLD/hdd/etc/modprobe.d/blacklist-$C_SHORT.conf" + { + echo "### $COMPANY - installimage" + echo "### silence any onboard speaker" + echo "blacklist pcspkr" + echo "### i915 driver blacklisted due to various bugs" + echo "### especially in combination with nomodeset" + echo "blacklist i915" + echo "blacklist sm750fb" + } > "$blacklist_conf" + + local dracutfile="$FOLD/hdd/etc/dracut.conf.d/99-$C_SHORT.conf" + { + echo "### $COMPANY - installimage" + echo 'add_dracutmodules+="lvm mdraid"' + echo 'add_drivers+="raid0 raid1 raid10 raid456"' + #echo 'early_microcode="no"' + echo 'hostonly="no"' + echo 'hostonly_cmdline="no"' + echo 'lvmconf="yes"' + echo 'mdadmconf="yes"' + echo 'persistent_policy="by-uuid"' + } > "$dracutfile" + + execute_chroot_command "dracut -f --kver $VERSION" + declare -i EXITCODE=$? return "$EXITCODE" fi } @@ -200,39 +61,7 @@ generate_new_ramdisk() { setup_cpufreq() { if [ -n "$1" ]; then - if isVServer; then - debug "no powersaving on virtual machines" return 0 - fi - if [ "$IMG_VERSION" -ge 70 ] && ((IMG_VERSION != 610)); then - #https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sec-Persistent_Module_Loading.html - #local CPUFREQCONF="$FOLD/hdd/etc/modules-load.d/cpufreq.conf" - debug "no cpufreq configuration necessary" - else - #https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Persistent_Module_Loading.html - local cpufreqconf="$FOLD/hdd/etc/sysconfig/modules/cpufreq.modules" - { - echo "#!/bin/sh" - echo "### $COMPANY - installimage" - echo "# cpu frequency scaling" - echo "# this gets started by /etc/rc.sysinit" - } > "$cpufreqconf" - - if [ "$(check_cpu)" = "intel" ]; then - debug "# Setting: cpufreq modprobe to intel" - { - echo "modprobe intel_pstate >> /dev/null 2>&1" - echo "modprobe acpi-cpufreq >> /dev/null 2>&1" - } >> "$cpufreqconf" - else - debug "# Setting: cpufreq modprobe to amd" - echo "modprobe powernow-k8 >> /dev/null 2>&1" >> "$cpufreqconf" - fi - echo "cpupower frequency-set --governor $1 >> /dev/null 2>&1" >> "$cpufreqconf" - chmod a+x "$cpufreqconf" 2>> "$DEBUGFILE" - - return 0 - fi fi } @@ -245,13 +74,9 @@ generate_config_grub() { [ -n "$1" ] || return # we should not have to do anything, as grubby (new-kernel-pkg) should have # already generated a grub.conf - if [ "$IMG_VERSION" -lt 70 ] || ((IMG_VERSION == 610)); then - DMAPFILE="$FOLD/hdd/boot/grub/device.map" - else - # even though grub2-mkconfig will generate a device.map on the fly, the - # anaconda installer still creates this - DMAPFILE="$FOLD/hdd/boot/grub2/device.map" - fi + # even though grub2-mkconfig will generate a device.map on the fly, the + # anaconda installer still creates this + DMAPFILE="$FOLD/hdd/boot/grub2/device.map" [ -f "$DMAPFILE" ] && rm "$DMAPFILE" local -i i=0 @@ -267,113 +92,44 @@ generate_config_grub() { elevator='elevator=noop' fi - if [ "$IMG_VERSION" -lt 70 ] || ((IMG_VERSION == 610)); then - # we do add a symlink to boot because we always point to /boot/vmlinuz-* - # in the grub.conf below even if /boot is a separate partition - execute_chroot_command "cd /boot; rm -rf boot; ln -s . boot >> /dev/null 2>&1" - execute_chroot_command "mkdir -p /boot/grub/" - #execute_chroot_command "grub-install --no-floppy $DRIVE1 2>&1"; EXITCODE=$? + local grub_cmdline_linux='biosdevname=0 crashkernel=auto' + isVServer && grub_cmdline_linux+=' elevator=noop' + grub_cmdline_linux+=' nomodeset rd.auto=1 consoleblank=0' - BFILE="$FOLD/hdd/boot/grub/grub.conf" - PARTNUM=$(echo "$SYSTEMBOOTDEVICE" | rev | cut -c1) - - if [ "$SWRAID" = "0" ]; then - PARTNUM="$((PARTNUM - 1))" - fi - - rm -rf "$FOLD/hdd/boot/grub/*" >> /dev/null 2>&1 - - { - echo "#" - echo "# $COMPANY - installimage" - echo "# GRUB bootloader configuration file" - echo "#" - echo '' - echo "timeout 5" - echo "default 0" - echo >> "$BFILE" - echo "title CentOS ($1)" - echo "root (hd0,$PARTNUM)" - } > "$BFILE" 2>> "$DEBUGFILE" + if has_threadripper_cpu; then + grub_cmdline_linux+=' pci=nommconf' + fi - # disable pcie active state power management. does not work as it should, - # and causes problems with Intel 82574L NICs (onboard-NIC Asus P8B WS - EX6/EX8, addon NICs) - lspci -n | grep -q '8086:10d3' && aspm='pcie_aspm=off' || aspm='' + if is_dell_r6415; then + grub_cmdline_linux=${grub_cmdline_linux/nomodeset } + fi - if has_threadripper_cpu; then - aspm='pci=nommconf' - fi + sed -i "s/GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"$grub_cmdline_linux\"/" "$FOLD/hdd/etc/default/grub" - if [ "$IMG_VERSION" -ge 60 ]; then - echo "kernel /boot/vmlinuz-$1 ro root=$SYSTEMROOTDEVICE rd_NO_LUKS rd_NO_DM nomodeset $elevator $aspm consoleblank=0" >> "$BFILE" - else - echo "kernel /boot/vmlinuz-$1 ro root=$SYSTEMROOTDEVICE nomodeset consoleblank=0" >> "$BFILE" - fi - INITRD='' - if [ -f "$FOLD/hdd/boot/initrd-$1.img" ]; then - INITRD="initrd" - fi - if [ -f "$FOLD/hdd/boot/initramfs-$1.img" ]; then - INITRD="initramfs" - fi - if [ -n "$INITRD" ]; then - echo "initrd /boot/$INITRD-$1.img" >> "$BFILE" - fi - echo "" >> "$BFILE" - # TODO: add grubby stuff (SYSFONT, LANG, KEYTABLE) + rm -f "$FOLD/hdd/boot/grub2/grub.cfg" + if [ "$UEFI" -eq 1 ]; then + execute_chroot_command "grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg 2>&1"; declare -i EXITCODE="$?" else - local grub_cmdline_linux='biosdevname=0 crashkernel=auto' - isVServer && grub_cmdline_linux+=' elevator=noop' - if ((IMG_VERSION < 73)) || ((IMG_VERSION == 610)); then - grub_cmdline_linux+=' net.ifnames=0' - fi - grub_cmdline_linux+=' nomodeset rd.auto=1 consoleblank=0' - - if has_threadripper_cpu; then - grub_cmdline_linux+=' pci=nommconf' - fi - - if is_dell_r6415; then - grub_cmdline_linux=${grub_cmdline_linux/nomodeset } - fi - - sed -i "s/GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"$grub_cmdline_linux\"/" "$FOLD/hdd/etc/default/grub" - - rm -f "$FOLD/hdd/boot/grub2/grub.cfg" - if [ "$UEFI" -eq 1 ]; then - execute_chroot_command "grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg 2>&1"; declare -i EXITCODE="$?" - else - execute_chroot_command "grub2-mkconfig -o /boot/grub2/grub.cfg 2>&1"; declare -i EXITCODE="$?" - fi + execute_chroot_command "grub2-mkconfig -o /boot/grub2/grub.cfg 2>&1"; declare -i EXITCODE="$?" fi uuid_bugfix return "$EXITCODE" } write_grub() { - if [ "$IMG_VERSION" -ge 70 ] && ((IMG_VERSION != 610)); then - if [ "$UEFI" -eq 1 ]; then - # we must NOT use grub2-install here. This will replace the prebaked - # grubx64.efi (which looks for grub.cfg in ESP) with a new one, which - # looks for in in /boot/grub2 (which may be more difficult to read) - rm -f "$FOLD/hdd/boot/grub2/grubenv" - execute_chroot_command "ln -s /boot/efi/EFI/centos/grubenv /boot/grub2/grubenv" - declare -i EXITCODE=$? - else - # only install grub2 in mbr of all other drives if we use swraid - for ((i=1; i<=COUNT_DRIVES; i++)); do - if [ "$SWRAID" -eq 1 ] || [ "$i" -eq 1 ] ; then - local disk; disk="$(eval echo "\$DRIVE"$i)" - execute_chroot_command "grub2-install --no-floppy --recheck $disk 2>&1" - declare -i EXITCODE=$? - fi - done - fi + if [ "$UEFI" -eq 1 ]; then + # we must NOT use grub2-install here. This will replace the prebaked + # grubx64.efi (which looks for grub.cfg in ESP) with a new one, which + # looks for in in /boot/grub2 (which may be more difficult to read) + rm -f "$FOLD/hdd/boot/grub2/grubenv" + execute_chroot_command "ln -s /boot/efi/EFI/centos/grubenv /boot/grub2/grubenv" + declare -i EXITCODE=$? else + # only install grub2 in mbr of all other drives if we use swraid for ((i=1; i<=COUNT_DRIVES; i++)); do if [ "$SWRAID" -eq 1 ] || [ "$i" -eq 1 ] ; then local disk; disk="$(eval echo "\$DRIVE"$i)" - execute_chroot_command "echo -e \"device (hd0) $disk\nroot (hd0,$PARTNUM)\nsetup (hd0)\nquit\" | grub --batch >> /dev/null 2>&1" + execute_chroot_command "grub2-install --no-floppy --recheck $disk 2>&1" declare -i EXITCODE=$? fi done @@ -413,11 +169,6 @@ run_os_specific_functions() { execute_chroot_command 'yum -y install polkit' || return 1 fi - # Workaround https://bugs.centos.org/view.php?id=17255 for CentOS 81 minimal - if [[ -e "$FOLD/hdd/lib/modules/4.18.0-147.3.1.el8_1.x86_64/vmlinuz" ]]; then - execute_chroot_command 'kernel-install add 4.18.0-147.3.1.el8_1.x86_64 /lib/modules/4.18.0-147.3.1.el8_1.x86_64/vmlinuz' || return 1 - fi - return 0 } diff --git a/config.sh b/config.sh index c47e7b9..b7ba414 100644 --- a/config.sh +++ b/config.sh @@ -38,11 +38,12 @@ export LOCKFILE='/run/lock/installimage' export SYSTEMD_NSPAWN_TMP_DIR="$FOLD/systemd_nspawn" export MODULES="virtio_pci virtio_blk via82cxxx sata_via sata_sil sata_nv sd_mod ahci atiixp raid0 raid1 raid5 raid6 raid10 3w-xxxx 3w-9xxx aacraid powernow-k8" -export STATSSERVER="88.198.31.148" +export STATSSERVER4="88.198.31.148" +export STATSSERVER6="[2a01:4f8:0:a0a1::bad:1]" export HDDMINSIZE="7000000" -export NAMESERVER=("213.133.98.98" "213.133.99.99" "213.133.100.100") -export DNSRESOLVER_V6=("2a01:4f8:0:1::add:9898" "2a01:4f8:0:1::add:9999" "2a01:4f8:0:1::add:1010") +export DNSRESOLVER=("185.12.64.1" "185.12.64.2") +export DNSRESOLVER_V6=("2a01:4ff:ff00::add:1" "2a01:4ff:ff00::add:2") export NTPSERVERS=("ntp1.hetzner.de" "ntp2.hetzner.com" "ntp3.hetzner.net") export AUTH_DNS1="ns1.first-ns.de" export AUTH_DNS2="robotns2.second-ns.de" @@ -61,8 +62,6 @@ export DEFAULTLVM="0" export DEFAULTLOADER="grub" export DEFAULTGOVERNOR="ondemand" -export V6ONLY="0" - export UEFI="0" declare -x -i BTRFS=0 @@ -80,12 +79,12 @@ export OSMENULIST=( export PROXMOX4_BASE_IMAGE="Debian-811-jessie-64-minimal" export PROXMOX5_BASE_IMAGE="Debian-913-stretch-64-minimal" -export PROXMOX6_BASE_IMAGE="Debian-107-buster-64-minimal" +export PROXMOX6_BASE_IMAGE="Debian-1010-buster-64-minimal" -export CPANEL_INSTALLER_SRC=http://mirror.hetzner.de/tools/cpanelinc/cpanel +export CPANEL_INSTALLER_SRC=http://mirror.hetzner.com/tools/cpanelinc/cpanel -export PLESK_INSTALLER_SRC=http://mirror.hetzner.de/tools/parallels/plesk -export PLESK_MIRROR=http://mirror.hetzner.de/plesk +export PLESK_INSTALLER_SRC=http://mirror.hetzner.com/tools/parallels/plesk +export PLESK_MIRROR=http://mirror.hetzner.com/plesk export PLESK_STD_VERSION=PLESK_18_0_33 export PLESK_DOWNLOAD_RETRY_COUNT=999 export PLESK_COMPONENTS=( diff --git a/configs/proxmox6 b/configs/proxmox6 index 954376a..a46d5b3 100644 --- a/configs/proxmox6 +++ b/configs/proxmox6 @@ -17,4 +17,4 @@ PART lvm vg0 all LV vg0 root / ext4 15G LV vg0 swap swap swap 6G -IMAGE /root/images/Debian-109-buster-64-minimal.tar.gz +IMAGE /root/images/Debian-1010-buster-64-minimal.tar.gz diff --git a/configs/simple-debian64-noraid b/configs/simple-debian64-noraid index 20ad87e..c846508 100644 --- a/configs/simple-debian64-noraid +++ b/configs/simple-debian64-noraid @@ -8,10 +8,10 @@ SWRAIDLEVEL 1 BOOTLOADER grub -HOSTNAME Debian-109-buster-64-minimal +HOSTNAME Debian-1100-bullseye-amd64-base PART swap swap 8G PART /boot ext3 512M PART / ext4 all -IMAGE /root/images/Debian-109-buster-64-minimal.tar.gz +IMAGE /root/images/Debian-1100-bullseye-amd64-base.tar.gz diff --git a/configs/simple-debian64-raid b/configs/simple-debian64-raid index c5a16ce..2bbe00c 100644 --- a/configs/simple-debian64-raid +++ b/configs/simple-debian64-raid @@ -7,10 +7,10 @@ SWRAIDLEVEL 1 BOOTLOADER grub -HOSTNAME Debian-109-buster-64-minimal +HOSTNAME Debian-1100-bullseye-amd64-base PART swap swap 2G PART /boot ext3 512M PART / ext4 all -IMAGE /root/images/Debian-109-buster-64-minimal.tar.gz +IMAGE /root/images/Debian-1100-bullseye-amd64-base.tar.gz diff --git a/configs/simple-debian64-raid-lvm b/configs/simple-debian64-raid-lvm index 254d38c..d7e3f14 100644 --- a/configs/simple-debian64-raid-lvm +++ b/configs/simple-debian64-raid-lvm @@ -7,7 +7,7 @@ SWRAIDLEVEL 1 BOOTLOADER grub -HOSTNAME Debian-109-buster-64-minimal +HOSTNAME Debian-1100-bullseye-amd64-base PART /boot ext3 512M PART lvm vg0 all @@ -15,4 +15,4 @@ PART lvm vg0 all LV vg0 root / ext4 20G LV vg0 swap swap swap 4G -IMAGE /root/images/Debian-109-buster-64-minimal.tar.gz +IMAGE /root/images/Debian-1100-bullseye-amd64-base.tar.gz diff --git a/coreos.sh b/coreos.sh deleted file mode 100644 index eba3d38..0000000 --- a/coreos.sh +++ /dev/null @@ -1,371 +0,0 @@ -#!/bin/bash - -# -# CoreOS specific functions -# -# (c) 2014-2018, Hetzner Online GmbH -# -# This file isn't ready for production! -# - -# SCRIPTPATH will be exported in config.sh -# shellcheck disable=SC2153 -export IMAGE_PUBKEY="$SCRIPTPATH/gpg/coreos-pubkey.asc" - -# create partitons on the given drive -# create_partitions "DRIVE" -create_partitions() { - touch "$FOLD/fstab" - return 0 -} - -make_swraid() { - return 0 -} - - -mount_partitions() { - return 0 -} - -make_lvm() { - return 0 -} - -format_partitions() { - return 0 -} - - -# validate image with detached signature -#validate_image() { -# # no detached sign found -# return 2 -#} - -# extract image file to hdd -extract_image() { - local COMPRESSION="" - if [ -n "$1" ] && [ -n "$2" ]; then - case "$2" in - bin) - COMPRESSION="" - ;; - bgz) - COMPRESSION="gzip" - ;; - bbz) - COMPRESSION="bzip2" - ;; - bxz) - COMPRESSION="xz" - ;; - *)return 1;; - esac - - # extract image with given compression - if [ -n "$COMPRESSION" ]; then - $COMPRESSION -d --stdout $EXTRACTFROM > "${DRIVE1}" - EXITCODE=$? - else - # or write binary file directly to disk - dd if="$EXTRACTFROM" of="${DRIVE1}" bs=1M - EXITCODE=$? - fi - - if [ "$EXITCODE" -eq "0" ]; then - debug "# sucess" - # inform the OS of partition table changes - blockdev --rereadpt "${DRIVE1}" - return 0 - else -# wipefs --all "${DRIVE1}" - return 1 - fi - fi -} - -setup_network_config() { - return 0 -} - - -# generate_config_mdadm "NIL" -generate_config_mdadm() { - return 0 -} - - -# generate_new_ramdisk "NIL" -generate_new_ramdisk() { - return 0 -} - - -set_udev_rules() { - return 0 -} - -# copy_mtab "NIL" -copy_mtab() { - return 0 -} - -generate_new_sshkeys() { - return 0 -} - -generate_ntp_config() { - if [ -f "$CLOUDINIT" ]; then - { - echo "write_files:" - echo " - path: /etc/ntp.conf" - echo " content: |" - echo " # $C_SHORT ntp servers" - for i in "${NTPSERVERS[@]}"; do - echo " server $i offline iburst" - done - echo " # - Allow only time queries, at a limited rate." - echo " # - Allow all local queries (IPv4, IPv6)" - echo " restrict default nomodify nopeer noquery limited kod" - echo " restrict 127.0.0.1" - echo " restrict [::1]" - } >> "$CLOUDINIT" | debugoutput - return 0 - else - return 1 - fi -} - -set_hostname() { - if [ -f "$CLOUDINIT" ]; then - { - echo "hostname: $1" - echo "" - } >> "$CLOUDINIT" - return 0 - else - return 1 - fi -} - -setup_cpufreq() { - return 0 -} - -generate_resolvconf() { - { - echo "write_files:" - echo " - path: /etc/resolv.conf" - echo " permissions: 0644" - echo " owner: root" - echo " content: |" - - # IPV4 - if [ "$V6ONLY" -eq 1 ]; then - debug "# skipping IPv4 DNS resolvers" - else - for index in $(shuf --input-range=0-$(( ${#NAMESERVER[*]} - 1 )) | tr '\n' ' ') ; do - echo " nameserver ${NAMESERVER[$index]}" - done - fi - - # IPv6 - if [ -n "$DOIPV6" ]; then - for index in $(shuf --input-range=0-$(( ${#DNSRESOLVER_V6[*]} - 1 )) | tr '\n' ' ') ; do - echo " nameserver ${DNSRESOLVER_V6[$index]}" - done - fi - } >> "$CLOUDINIT" - return 0 -} - -generate_hosts() { - return 0 -} - -generate_sysctlconf() { - return 0 -} - -set_rootpassword() { - if [ -n "$1" ] && [ -n "$2" ]; then - if [ "$2" != '*' ]; then - { - echo "users:" - echo " - name: core" - echo " passwd: $2" - echo " - name: root" - echo " passwd: $2" - } >> "$CLOUDINIT" - fi - return 0 - else - return 1 - fi -} - -# set sshd PermitRootLogin -set_ssh_rootlogin() { - if [ -n "$1" ]; then - local permit="$1" - case "$permit" in - yes|no|without-password|forced-commands-only) - cat << EOF >> "$CLOUDINIT" -write_files: - - path: /etc/ssh/sshd_config - permissions: 0600 - owner: root:root - content: | - # Use most defaults for sshd configuration. - UsePrivilegeSeparation sandbox - Subsystem sftp internal-sftp - - PermitRootLogin "$permit" - PasswordAuthentication yes -EOF - ;; - *) - debug "invalid option for PermitRootLogin" - return 1 - ;; - esac - else - return 1 - fi -} - -# copy_ssh_keys $OPT_SSHKEYS_URL -copy_ssh_keys() { - echo 'ssh_authorized_keys:' >> "$CLOUDINIT" - while read -r line; do - echo " - $line" >> "$CLOUDINIT" - done < "$FOLD/authorized_keys" -} - -# generate_config_grub -generate_config_grub() { - return 0 -} - -write_grub() { - return 0 -} - -add_coreos_oem_scripts() { - if [ -n "$1" ]; then - local mntpath=$1 - - # add netname simplify script (use eth names) - local scriptpath="$mntpath/bin" - local scriptfile="$scriptpath/netname.sh" - if [ ! -d "$scriptpath" ]; then - mkdir -p "$scriptpath" - fi - cat << EOF >> "$scriptfile" -#! /bin/bash - -IFINDEX=\$1 -echo "ID_NET_NAME_SIMPLE=eth\$((\${IFINDEX} - 2))" -EOF - chmod a+x "$scriptfile" - scriptfile="$scriptpath/rename-interfaces.sh" - cat << EOF >> "$scriptfile" -#! /bin/bash - -INTERFACES=\$(ip link show | gawk -F ':' '/^[0-9]+/ { print \$2 }' | tr -d ' ' | sed 's/lo//') -for iface in \${INTERFACES}; do - ip link set \${iface} down - udevadm test /sys/class/net/\${iface} -done -EOF - chmod a+x "$scriptfile" - fi -} - -add_coreos_oem_cloudconfig() { - if [ -n "$1" ]; then - local mntpath=$1 - local cloudconfig="$mntpath/cloud-config.yml" - echo "#cloud-config" > "$cloudconfig" - if ! isVServer; then - cat << EOF >> "$cloudconfig" -write_files: - - path: /run/udev/rules.d/79-netname.rules - permissions: 444 - content: | - SUBSYSTEM!="net", GOTO="netname_end" - ACTION!="add", GOTO="netname_end" - ENV{ID_BUS}!="pci", GOTO="netname_end" - - IMPORT{program}="/usr/share/oem/bin/netname.sh \$env{IFINDEX}" - - NAME=="", ENV{ID_NET_NAME_SIMPLE}!="", NAME="\$env{ID_NET_NAME_SIMPLE}" - - LABEL="netname_end" - -coreos: - units: - - name: rename-network-interfaces.service - command: start - runtime: yes - content: | - [Unit] - Before=user-config.target - - [Service] - Type=oneshot - RemainAfterExit=yes - ExecStart=/usr/bin/systemctl stop systemd-networkd - ExecStart=/usr/share/oem/bin/rename-interfaces.sh - ExecStart=/usr/bin/systemctl start systemd-networkd - oem: - id: baremetal - name: Hetzner Cloud on Root - home-url: http://www.hetzner.com - bug-report-url: https://github.com/coreos/bugs/issues -EOF - else - cat << EOF >> "$cloudconfig" - oem: - id: vserver - name: Hetzner vServer - home-url: http://www.hetzner.com - bug-report-url: https://github.com/coreos/bugs/issues -EOF - fi - fi -} - -# -# os specific functions -# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP -# -run_os_specific_functions() { - local ROOT_DEV; ROOT_DEV=$(blkid -t "LABEL=ROOT" -o device "${DRIVE1}"*) - local OEM_DEV; OEM_DEV=$(blkid -t "LABEL=OEM" -o device "${DRIVE1}"*) - local is_ext4; is_ext4=$(blkid -o value "$ROOT_DEV" | grep ext4) - if [ -n "$is_ext4" ]; then - mount "${ROOT_DEV}" "$FOLD/hdd" 2>&1 | debugoutput ; EXITCODE=$? - else - mount -t btrfs -o subvol=root "${ROOT_DEV}" "$FOLD/hdd" 2>&1 | debugoutput ; EXITCODE=$? - fi - [ "$EXITCODE" -ne "0" ] && return 1 - - # mount OEM partition as well - mount "${OEM_DEV}" "$FOLD/hdd/usr" 2>&1 | debugoutput ; EXITCODE=$? - [ "$EXITCODE" -ne "0" ] && return 1 - - if ! isVServer; then - add_coreos_oem_scripts "$FOLD/hdd/usr" - fi - add_coreos_oem_cloudconfig "$FOLD/hdd/usr" - - mkdir -p "$FOLD/hdd/var/lib/coreos-install" - debugoutput < "$CLOUDINIT" - cp "$CLOUDINIT" "$FOLD/hdd/var/lib/coreos-install/user_data" - - return 0 -} - -# vim: ai:ts=2:sw=2:et diff --git a/cpanel.functions.sh b/cpanel.functions.sh index 2c5b06d..75578dc 100644 --- a/cpanel.functions.sh +++ b/cpanel.functions.sh @@ -16,16 +16,31 @@ is_cpanel_install() { cpanel_setup_mainip() { local mainip_file=/var/cpanel/mainip - debug "# setting up ${mainip_file}" - echo -n "${IPADDR}" > "${FOLD}/hdd/${mainip_file}" - debug "set up ${mainip_file}" + local v4_main_ip + v4_main_ip="$(v4_main_ip)" + if [[ -n "$v4_main_ip" ]]; then + debug "# setting up ${mainip_file}" + echo -n "$(ip_addr_without_suffix "$v4_main_ip")" > "${FOLD}/hdd/${mainip_file}" + return + fi + + debug "fatal: no IPv4 main IP: not setting up $mainip_file" + return 1 } # cpanel_setup_wwwacct_conf() cpanel_setup_wwwacct_conf() { local wwwacct_conf; wwwacct_conf=/etc/wwwacct.conf + local v4_main_ip + v4_main_ip="$(v4_main_ip)" + if [[ -z "$v4_main_ip" ]]; then + debug "fatal: no IPv4 main IP: can not set up $wwwacct_conf" + return 1 + fi + debug "# setting up ${wwwacct_conf}" + sed --expression='/^ADDR\s/d' \ --expression='/^HOST\s/d' \ --expression='/^NS[[:digit:]]*\s/d' \ @@ -33,14 +48,13 @@ cpanel_setup_wwwacct_conf() { { echo echo "### ${COMPANY} installimage" - echo "ADDR ${IPADDR}" + echo "ADDR $(ip_addr_without_suffix "$v4_main_ip")" echo "HOST ${NEWHOSTNAME}" echo "NS ${AUTH_DNS1}" echo "NS2 ${AUTH_DNS2}" echo "NS3 ${AUTH_DNS3}" echo 'NS4' } >> "${FOLD}/hdd/${wwwacct_conf}" - debug "set up ${wwwacct_conf}" } # randomize_cpanel_passwords() @@ -87,7 +101,7 @@ randomize_cpanel_passwords() { setup_cpanel() { debug '# setting up cpanel' cpanel_setup_mainip - cpanel_setup_wwwacct_conf + cpanel_setup_wwwacct_conf || return 1 randomize_cpanel_passwords || return 1 debug 'set up cpanel' } @@ -127,7 +141,7 @@ install_cpanel() { fi debug '# setting up cpanel' - cpanel_setup_wwwacct_conf + cpanel_setup_wwwacct_conf || return 1 debug 'set up cpanel' debug 'installed cpanel' } diff --git a/debconf.functions.sh b/debconf.functions.sh index 7291f4b..4548833 100644 --- a/debconf.functions.sh +++ b/debconf.functions.sh @@ -26,14 +26,36 @@ debconf_set_grub_install_devices() { echo ' ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n"' } > /etc/udev/rules.d/99-installimage.rules udevadm control -R && udevadm trigger && udevadm settle - local paths; paths=() + local paths; paths=(); local part; local path_number while read drive; do - paths+=("$(drive_disk_by_id_path "$drive")") + # check if ESP partition exsists and then add ESP partition to path, or if not add the whole drive to the path + path_number+=("$(drive_disk_by_id_path "$drive")") + + path_raw=$(sgdisk -p $path_number 2>&1) + part="$(echo "${path_raw}" | grep 'EF00' | awk '{print $1;}')" + echo "${path_raw}" | debugoutput + + if [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -ge 2004 ] && [ "$UEFI" -eq 1 ] && [ -n "$(echo $part)" ] ; then + paths+=("$(drive_disk_by_id_path "$drive")-part$part") + else + paths+=("$(drive_disk_by_id_path "$drive")") + fi done < <(grub_install_devices) - local value; value='' + # Generate a random MS-DOS serial for for all ESP partions + local value; value=''; local uuidefi; uuidefi="$(uuidgen | head -c8)" for path in "${paths[@]}"; do [[ -z "$path" ]] && return 1 value+="$path, " + # Change the MS-DOS label of all existing ESP partitions to the same serial + if [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -ge 2004 ] && [ "$UEFI" -eq 1 ] && [ -n "$(echo $part)" ]; then + mlabel -N $uuidefi -i $path + fi done - debconf_set "grub-pc grub-pc/install_devices multiselect ${value::-2}" + # set install_devices for grub-efi and run dpkg-reconfigure to install grub on all ESPs listed + if [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -ge 2004 ] && [ "$UEFI" -eq 1 ] && [ -n "$(echo $part)" ]; then + debconf_set "grub-efi-amd64 grub-efi/install_devices string ${value::-2}" + execute_chroot_command "dpkg-reconfigure -f noninteractive grub-efi-amd64" + else + debconf_set "grub-pc grub-pc/install_devices multiselect ${value::-2}" + fi } diff --git a/debian.sh b/debian.sh index a396cf0..f09e11d 100644 --- a/debian.sh +++ b/debian.sh @@ -3,85 +3,10 @@ # # Debian specific functions # -# (c) 2008-2018, Hetzner Online GmbH +# (c) 2008-2021, Hetzner Online GmbH # -# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" -setup_network_config() { - if [ -n "$1" ] && [ -n "$2" ]; then - - # - # good we have a device and a MAC - # - CONFIGFILE="$FOLD/hdd/etc/network/interfaces" - if [ -f "$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" ]; then - UDEVFILE="$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" - else - UDEVFILE="/dev/null" - fi - { - echo "### $COMPANY - installimage" - echo "# device: $1" - printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="%s"\n' "$2" "$1" - } > "$UDEVFILE" - - { - echo "### $COMPANY - installimage" - echo "# Loopback device:" - echo "auto lo" - echo "iface lo inet loopback" - echo "iface lo inet6 loopback" - echo "" - } > "$CONFIGFILE" - - if [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ]; then - echo "# device: $1" >> "$CONFIGFILE" - if is_private_ip "$6" && isVServer; then - { - echo "auto $1" - echo "iface $1 inet dhcp" - } >> "$CONFIGFILE" - else - { - echo "auto $1" - echo "iface $1 inet static" - echo " address $3" - echo " netmask $5" - echo " gateway $6" - if ! is_private_ip "$3" || ! isVServer; then - echo " # default route to access subnet" - echo " up route add -net $7 netmask $5 gw $6 $1" - fi - } >> "$CONFIGFILE" - fi - fi - - if [ -n "$8" ] && [ -n "$9" ] && [ -n "${10}" ]; then - debug "setting up ipv6 networking $8/$9 via ${10}" - { - echo "" - echo "iface $1 inet6 static" - echo " address $8" - echo " netmask $9" - echo " gateway ${10}" - } >> "$CONFIGFILE" - fi - - # - # set duplex speed - # - if ! isNegotiated && ! isVServer; then - { - echo " # force full-duplex for ports without auto-neg" - echo " post-up mii-tool -F 100baseTx-FD $1" - } >> "$CONFIGFILE" - fi - - return 0 - fi -} - # generate_config_mdadm "NIL" generate_config_mdadm() { local mdadmconf="/etc/mdadm/mdadm.conf" @@ -132,7 +57,7 @@ generate_new_ramdisk() { # apparently sometimes the mdadm assembly bugfix introduced with the recent mdadm release does not work # however, the problem is limited to H8SGL boards # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=784070 - if [ "$IMG_VERSION" -ge 80 ] && [ "$IMG_VERSION" != 710 ] && [ "$IMG_VERSION" != 711 ] && [ "$MBTYPE" = 'H8SGL' ]; then + if [ "$MBTYPE" = 'H8SGL' ]; then local script="$FOLD/hdd/usr/share/initramfs-tools/scripts/local-block/mdadmpatch" cp "$SCRIPTPATH/h8sgl-deb8-md.sh" "$script" chmod a+x "$script" @@ -203,8 +128,8 @@ generate_config_grub() { rm "$FOLD/hdd/boot/grub/grub.cfg" if [ "$UEFI" -eq 1 ]; then - execute_chroot_command "echo 'set grub2/update_nvram false' | debconf-communicate" - execute_chroot_command "echo 'set grub2/force_efi_extra_removable true' | debconf-communicate" + execute_chroot_command "echo 'set grub2/update_nvram false' | debconf-communicate -f noninteractive" + execute_chroot_command "echo 'set grub2/force_efi_extra_removable true' | debconf-communicate -f noninteractive" fi execute_chroot_command "grub-mkconfig -o /boot/grub/grub.cfg 2>&1" @@ -256,8 +181,6 @@ run_os_specific_functions() { setup_hetzner_lamp || return 1 fi - (( "${IMG_VERSION}" >= 80 )) && (( "${IMG_VERSION}" != 710 )) && (( "${IMG_VERSION}" != 711 )) && debian_udev_finish_service_fix - [[ -e "$FOLD/hdd/var/spool/exim4/input" ]] && find "$FOLD/hdd/var/spool/exim4/input" -type f -delete disable_resume @@ -295,21 +218,4 @@ debian_grub_fix() { rm "$tempfile" } -debian_udev_finish_service_fix() { - local unit_file="${FOLD}/hdd/lib/systemd/system/udev-finish.service" - local override_dir="${FOLD}/hdd/etc/systemd/system/udev-finish.service.d" - local override_file="${override_dir}/override.conf" - if ! [[ -f "${unit_file}" ]]; then - debug '# udev-finish.service not found. not installing override' - return - fi - debug '# install udev-finish.service override' - mkdir "${override_dir}" - { - echo "### ${COMPANY} - installimage" - echo '[Unit]' - echo 'After=basic.target' - } > "${override_file}" -} - # vim: ai:ts=2:sw=2:et diff --git a/functions.sh b/functions.sh index b4ecd0d..19365bc 100644 --- a/functions.sh +++ b/functions.sh @@ -31,6 +31,7 @@ BOOTLOADER="" GOVERNOR="" CRYPT="" CRYPTPASSWORD="" +IPV4_ONLY=0 declare -i BTRFS_VOL_COUNT=0 declare -a BTRFS_VOL_NAME declare -a BTRFS_VOL_SIZE @@ -53,18 +54,6 @@ SYSTEMBOOTDEVICE="" SYSTEMREALBOOTDEVICE="" EXTRACTFROM="" -export ETHDEV="" -export HWADDR="" -export IPADDR="" -export CIDR="" -export BROADCAST="" -export SUBNETMASK="" -export GATEWAY="" -export NETWORK="" -export IP6ADDR="" -export IP6PREFLEN="" -export IP6GATEWAY="" - ROOTHASH="" ERROREXIT="0" @@ -126,6 +115,10 @@ generate_menu() { if [ "$(uname -m)" != "x86_64" ]; then RAWLIST="$(echo "$RAWLIST" |tr ' ' '\n' |grep -v "\-64\-[a-zA-Z]")" fi + + # order by image version desc + RAWLIST="$(sort -k 1,1 -k 2,2hr -t '-' <<< "$RAWLIST")" + # generate formatted list for usage with "dialog" for i in $RAWLIST; do TEMPVAR="$i" @@ -322,8 +315,6 @@ create_config() { fi # hostname - get_active_eth_dev - gather_network_information { echo "" echo "## ==========" @@ -347,6 +338,17 @@ create_config() { echo "HOSTNAME $DEFAULT_HOSTNAME" >> "$CNF" echo "" >> "$CNF" + # network config + { + echo + echo "## ================" + echo "## NETWORK CONFIG:" + echo "## ================" + echo + echo "# IPV4_ONLY no" + echo + } >> "$CNF" + ## Calculate how much hardisk space at raid level 0,1,5,6,10 RAID0=0 local small_hdd; small_hdd="$(smallest_hd)" @@ -544,11 +546,6 @@ create_config() { # use /var instead of /home for all partition when installing plesk is_plesk_install && DEFAULTPARTS_BIG="${DEFAULTPARTS_BIG//home/var}" - if [ "$IAM" = "coreos" ]; then - echo "## NOTICE: This image does not support custom partition sizes." >> "$CNF" - echo "## NOTICE: Please keep the following lines unchanged. They are just placeholders." >> "$CNF" - fi - if [ "$DRIVE_SIZE" -gt "$LIMIT" ]; then if [ "$DRIVE_SIZE" -gt "$THREE_TB" ]; then [ "$OPT_PARTS" ] && echo -e "$OPT_PARTS" >> "$CNF" || echo -e "$DEFAULTPARTS_LARGE" >> "$CNF" @@ -601,6 +598,7 @@ create_config() { echo "IMAGE $FINALIMAGEPATH$1.$IMAGESEXT" >> "$CNF" fi fi + echo "" >> "$CNF" fi @@ -880,6 +878,11 @@ if [ -n "$1" ]; then export OPT_SSHKEYS_URL='/root/.ssh/robot_user_keys' export OPT_USE_SSHKEYS=1 fi + + # IPV4_ONLY setting (y/n) + if [[ "$(tac "$1" | grep -m1 ^IPV4_ONLY | awk '{print $2}')" =~ ^y ]]; then + export IPV4_ONLY=1 + fi fi } @@ -900,8 +903,12 @@ validate_vars() { # test if PATHTYPE is a supported type CHECK="$(echo $IMAGE_PATH_TYPE |grep -i -e "^http$\|^nfs$\|^local$")" if [ -z "$CHECK" ]; then - graph_error "ERROR: No valid PATHTYPE" - return 1 + if [[ "$OPT_AUTOMODE" == 1 ]] || [[ -e /autosetup ]]; then + echo "ERROR: $IMAGE_PATH_TYPE is no valid PATHTYPE for images" | debugoutput + else + graph_error "ERROR: $IMAGE_PATH_TYPE is no valid PATHTYPE for images" + fi + return 1 fi # test if IMAGEFILE is given @@ -925,8 +932,12 @@ validate_vars() { # test if FILETYPE is a supported type CHECK="$(echo $IMAGE_FILE_TYPE |grep -i -e "^tar$\|^tgz$\|^tbz$\|^txz$\|^bin$\|^bbz$")" if [ -z "$CHECK" ]; then - graph_error "ERROR: $IMAGE_FILE_TYPE is no valid FILETYPE for images" - return 1 + if [[ "$OPT_AUTOMODE" == 1 ]] || [[ -e /autosetup ]]; then + echo "ERROR: $IMAGE_FILE_TYPE is no valid FILETYPE for images" | debugoutput + else + graph_error "ERROR: $IMAGE_FILE_TYPE is no valid FILETYPE for images" + fi + return 1 fi whoami "$IMAGE_FILE" @@ -1170,7 +1181,7 @@ validate_vars() { return 1 fi if [ "${PART_SIZE[$i]}" -lt "256" ]; then - graph_error "ERROR: Your /boot/efi partition has to be at least 256M (current size: ${PART_SIZE[$i]})" + graph_error "ERROR: EFI System Partition (ESP) partition has to be at least 256M (current size: ${PART_SIZE[$i]})" return 1 fi fi @@ -1225,34 +1236,15 @@ validate_vars() { fi fi - if [ "$BOOTLOADER" = "grub" ]; then - if [ "${PART_MOUNT[$i]}" = "/boot" -a "${PART_FS[$i]}" = "xfs" ]; then - graph_error "ERROR: /boot partition will not work properly with xfs" - return 1 - fi - - if [ "${PART_MOUNT[$i]}" = "/" -a "${PART_FS[$i]}" = "xfs" ]; then - TMPCHECK="0" - if [ "$IAM" = "centos" -a "$IMG_ARCH" = "32" ]; then - graph_error "ERROR: CentOS 32bit doesn't support xfs on partition /" - return 1 - fi - for ((j=1; j<=PART_COUNT; j++)); do - if [ "${PART_MOUNT[$j]}" = "/boot" ]; then - TMPCHECK="1" - fi - done - if [ "$TMPCHECK" = "0" ]; then - graph_error "ERROR: / partition will not work properly with xfs with no /boot partition" - return 1 - fi - fi - fi - done if [ "$UEFI" -eq 1 ] && [ "$espcount" -ne 1 ]; then - graph_error "ERROR: ESP missing or multiple ESP found" + if [[ "$OPT_AUTOMODE" == 1 ]] || [[ -e /autosetup ]]; then + echo "ERROR: ESP missing or multiple ESP found" | debugoutput + return 1 + else + graph_error "ERROR: ESP missing or multiple ESP found" + fi fi else @@ -1302,15 +1294,15 @@ validate_vars() { lv_vg="${LVM_LV_VG[$lv_id]}" - # test if the mountpoint is valid (start with / or swap) - CHECK="$(echo "$lv_mountp" | grep -e "^/\|^swap$")" + # test if the mountpoint is valid (start with /, swap or none) + CHECK="$(echo "$lv_mountp" | grep -e "^/\|^swap$\|^none$")" if [ -z "$CHECK" ]; then graph_error "ERROR: Mountpoint for LV '${LVM_LV_NAME[$lv_id]}' is not correct" return 1 fi # test if the filesystem is one of our supportet types (ext2/ext3/reiserfs/xfs/swap) - CHECK="$(echo "$lv_fs" |grep -e "^btrfs$\|^ext2$\|^ext3$\|^ext4$\|^reiserfs$\|^xfs$\|^swap$")" + CHECK="$(echo "$lv_fs" |grep -e "^btrfs$\|^ext2$\|^ext3$\|^ext4$\|^reiserfs$\|^xfs$\|^swap$\|^none$")" if [ -z "$CHECK" ]; then graph_error "ERROR: Filesystem for LV '${LVM_LV_NAME[$lv_id]}' is not correct" return 1 @@ -1461,7 +1453,9 @@ validate_vars() { # append all logical volume mountpoints to $mounts_as_string for ((i=1; i<=LVM_LV_COUNT; i++)); do - mounts_as_string="$mounts_as_string${LVM_LV_MOUNT[$i]}\n" + if [ "${LVM_LV_MOUNT[$i]}" != "none" ]; then + mounts_as_string="$mounts_as_string${LVM_LV_MOUNT[$i]}\n" + fi done # append all btrfs subvolme mountpoints to $mounts_as_string @@ -1563,23 +1557,6 @@ validate_vars() { fi # TODO: add check for valid hostname (e.g. no underscores) - if [ "$MBTYPE" = "D3401-H1" ] || [ "$MBTYPE" = "D3417-B1" ]; then - if [ "$IAM" = "debian" ] && [ "$IMG_VERSION" -lt 82 -o "$IMG_VERSION" = '710' -o "$IMG_VERSION" = '711' ]; then - if [ "$OPT_AUTOMODE" = 1 ] || [ -e /autosetup ]; then - echo "WARNING: Debian versions older than Debian 8.2 have no support for the Intel i219 NIC of this board." | debugoutput - else - graph_notice "WARNING: Debian versions older than Debian 8.2 have no support for the Intel i219 NIC of this board." - fi - fi - if [ "$IAM" = "centos" ] && [ "$IMG_VERSION" -ge 70 ] && [ "$IMG_VERSION" -lt 72 ]; then - if [ "$OPT_AUTOMODE" = 1 ] || [ -e /autosetup ]; then - echo "WARNING: CentOS 7.0 and 7.1 have no support for the Intel i219 NIC of this board." | debugoutput - else - graph_notice "WARNING: CentOS 7.0 and 7.1 have no support for the Intel i219 NIC of this board." - fi - fi - fi - fi return 0 } @@ -1632,11 +1609,6 @@ whoami() { *CentOS*|*centos*|*Centos*)IAM="centos";; *Ubuntu*|*ubuntu*)IAM="ubuntu";; Arch*|arch*)IAM="archlinux";; - CoreOS*|coreos*) - IAM="coreos" - CLOUDINIT="$FOLD/cloud-config" - echo -e "#cloud-config\n" > "$CLOUDINIT" - ;; esac fi @@ -1743,7 +1715,7 @@ function get_end_of_extended() { local limit=2199023255040 # get sector limit local sectorlimit=$(( (limit / sectorsize) - 1)) - local startsec; startsec=$(sgdisk --first-aligned-in-largest "$1" | tail -n1) + local startsec; startsec=$(sgdisk --first-aligned-in-largest "$1" 2>/dev/null | tail -n1) for ((i=1; i<=3; i++)); do sum=$((sum + ${PART_SIZE[$i]})) @@ -1821,8 +1793,13 @@ create_partitions() { local sectorsize; sectorsize=$(blockdev --getss $1) local crypt_part is_crypted - # write standard entries to fstab - echo "proc /proc proc defaults 0 0" > "$FOLD/fstab" + # write standard entries to fstab + all ESPs if multiple are supported by grub-efi-amd64 + if [ -f "$FOLD/fstab" ] && [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -ge 2004 ] && [ "$UEFI" -eq 1 ]; then + echo "$(grep "/boot/efi" "$FOLD/fstab")" > "$FOLD/fstab" + echo "proc /proc proc defaults 0 0" >> "$FOLD/fstab" + else + echo "proc /proc proc defaults 0 0" > "$FOLD/fstab" + fi # add fstab entries for devpts, sys and shm in CentOS as they are not # automatically mounted by init skripts like in Debian/Ubuntu and OpenSUSE if [ "$IAM" = "centos" ]; then @@ -1894,7 +1871,9 @@ create_partitions() { # start at 2MiB so we have 1 MiB left for BIOS Boot Partition START=$((2097152 / sectorsize)) if [ $i -gt 1 ]; then - START=$(sgdisk --first-aligned-in-largest $1 | tail -n1) + SGDISK_RAW_OUTPUT=$(sgdisk --first-aligned-in-largest $1 2>/dev/null) + START="$(echo "${SGDISK_RAW_OUTPUT}" | tail -n1)" + echo "${SGDISK_RAW_OUTPUT}" | debugoutput fi END=$(sgdisk --end-of-largest $1 | tail -n 1) local gpt_part_size='' @@ -1927,7 +1906,9 @@ create_partitions() { PCOUNT="$i" if [ "$i" -gt "1" ]; then - START=$(sgdisk --first-aligned-in-largest $1 | tail -n1) + SGDISK_RAW_OUTPUT=$(sgdisk --first-aligned-in-largest $1 2>/dev/null) + START="$(echo "${SGDISK_RAW_OUTPUT}" | tail -n1)" + echo "${SGDISK_RAW_OUTPUT}" | debugoutput fi # determine the end sector of the partition @@ -2109,8 +2090,10 @@ make_swraid() { dmsetup remove_all + md_count=0 count=0 PARTNUM=0 + EFIPART=0 LASTDRIVE="$(eval echo \$DRIVE${COUNT_DRIVES})" SEDHDD="$(echo $LASTDRIVE | sed 's/\//\\\//g')" @@ -2148,18 +2131,28 @@ make_swraid() { while read line ; do PARTNUM="$(next_partnum $count)" echo "Line is: \"$line\"" | debugoutput - if [ -n "$(echo "$line" | grep "/boot")" -a "$metadata_boot" == "--metadata=0.90" ] || [ "$metadata" == "--metadata=0.90" ]; then + # If multiple ESPs are supported by grub-efi-amd64, a workaround for the fstab is necessary in order to create the RAID array correctly + if [ -n "$(echo "$line" | grep "/boot/efi")" ] && [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -ge 2004 ] && [ "$UEFI" -eq 1 ]; then + if [ "$EFIPART" -eq 0 ] && [ -n "$(echo $line | grep $LASTDRIVE)" ]; then + EFIPART="$[$EFIPART+1]" + count="$[$count+1]" + echo $line >> $fstab + else + echo $line >> $fstab + fi + continue + elif [ -n "$(echo "$line" | grep "/boot")" -a "$metadata_boot" == "--metadata=0.90" ] || [ "$metadata" == "--metadata=0.90" ]; then # update fstab - replace /dev/sdaX with /dev/mdY - echo $line | sed "s/$SEDHDD\(p\)\?[0-9]\+/\/dev\/md$count/g" >> $fstab + echo $line | sed "s/$SEDHDD\(p\)\?[0-9]\+/\/dev\/md$md_count/g" >> $fstab else # update fstab - replace /dev/sdaX with /dev/md/Y - echo $line | sed "s/$SEDHDD\(p\)\?[0-9]\+/\/dev\/md\/$count/g" >> $fstab + echo $line | sed "s/$SEDHDD\(p\)\?[0-9]\+/\/dev\/md\/$md_count/g" >> $fstab fi # create raid array if echo $line | grep $LASTDRIVE >/dev/null ; then - local raid_device="/dev/md/$count" + local raid_device="/dev/md/$md_count" local components="" local n=0 for n in $(seq 1 $COUNT_DRIVES) ; do @@ -2203,6 +2196,7 @@ make_swraid() { yes | mdadm -q -C $raid_device -l$array_raidlevel -n$n $array_metadata $array_layout $can_assume_clean $components 2>&1 | debugoutput ; EXITCODE=$? count="$[$count+1]" + md_count="$[$md_count+1]" fi done < $fstab.tmp @@ -2329,9 +2323,11 @@ make_lvm() { # create fstab-entries for i in $(seq 1 $LVM_LV_COUNT) ; do - echo -n "/dev/${LVM_LV_VG[$i]}/${LVM_LV_NAME[$i]} " >>$fstab - echo -n "${LVM_LV_MOUNT[$i]} ${LVM_LV_FS[$i]} " >>$fstab - echo "defaults 0 0" >>$fstab + if [ "${LVM_LV_MOUNT[$i]}" != "none" ]; then + echo -n "/dev/${LVM_LV_VG[$i]}/${LVM_LV_NAME[$i]} " >>$fstab + echo -n "${LVM_LV_MOUNT[$i]} ${LVM_LV_FS[$i]} " >>$fstab + echo "defaults 0 0" >>$fstab + fi done else @@ -2358,7 +2354,7 @@ format_partitions() { local xfs_force_v4=0 if [[ "$FS" == 'xfs' ]]; then if [[ "$IAM" == 'centos' ]]; then - if ((IMG_VERSION < 70)) || ((IMG_VERSION == 610)); then + if ((IMG_VERSION <= 79)) || ((IMG_VERSION == 610)); then xfs_force_v4=1 fi elif [[ "$IAM" == 'debian' ]]; then @@ -2374,6 +2370,8 @@ format_partitions() { dd if=/dev/zero of=$DEV bs=256 count=8 &> /dev/null # then write swap information mkswap $DEV 2>&1 | debugoutput ; EXITCODE=$? + elif [ "$FS" = "none" ]; then + : elif [ "$FS" = "ext2" -o "$FS" = "ext3" -o "$FS" = "ext4" ]; then if [[ "$FS" == 'ext4' ]] && [[ "$IAM" == 'centos' ]]; then if ((IMG_VERSION < 70)) || ((IMG_VERSION == 610)); then @@ -2576,6 +2574,7 @@ get_image_info() { nfs) mount -t "nfs" "$1" "$FOLD/nfs" 2>&1 | debugoutput ; EXITCODE=$? if [ "$EXITCODE" -ne "0" -o ! -e "$FOLD/nfs/$3" ]; then + debug "Error: Image not found!" return 1 else EXTRACTFROM="$FOLD/nfs/$3" @@ -2611,6 +2610,7 @@ get_image_info() { IMAGE_PUBKEY="${1}public-key.asc" fi else + debug "Error: Image not found!" return 1 fi ;; @@ -2638,6 +2638,7 @@ get_image_url() { fi return 0 else + debug "Error: Image not found!" return 1 fi } @@ -2717,8 +2718,7 @@ extract_image() { # only need to restore selinux attributes and capabilities. GNUtar could # save&restore these using the following options, but not if archive was # created by bsdtar - # --xattrs --xattrs-include=security.capability --xattrs-include=security.selinux - local tar_options=(-x --anchored --numeric-owner --exclude 'sys' --exclude 'proc' --exclude 'dev') + local tar_options=(-x --anchored --numeric-owner --xattrs --xattrs-include=security.capability --xattrs-include=security.selinux --exclude 'sys' --exclude 'proc' --exclude 'dev') local bsdtar_options=(-x --numeric-owner --exclude '^sys' --exclude '^proc' --exclude '^dev') # extract ESP content first, so we can still use bsdtar later @@ -2751,199 +2751,11 @@ extract_image() { fi } -function get_active_eth_dev() { - local nic="" - for nic in /sys/class/net/eth*; do - # remove path from ethX so we only have "ethX" - nic=${nic##*/} - #test if the interface has a ipv4 adress - iptest=$(ip addr show dev "$nic" | grep "$nic"$ | awk '{print $2}') - if [ -n "$iptest" ]; then - ETHDEV="$nic" - break - fi - done -} - -# gather_network_information -gather_network_information_old() { - HWADDR="$(ifconfig $ETHDEV |grep HWaddr |tr -s ' ' |cut -d " " -f5 |tr [:upper:] [:lower:])" - IPADDR="$(ifconfig $ETHDEV |grep "inet addr" |tr -s ' ' |cut -d " " -f3 |cut -d ":" -f2)" - BROADCAST="$(ifconfig $ETHDEV |grep "inet addr" |tr -s ' ' |cut -d " " -f4 |cut -d ":" -f2)" - SUBNETMASK="$(ifconfig $ETHDEV |grep "inet addr" |tr -s ' ' |cut -d " " -f5 |cut -d ":" -f2)" - GATEWAY="$(route -n |tr -s ' ' |grep " UG .*. $ETHDEV" |cut -d " " -f2 | head -n1)" - NETWORK="$(route -n |tr -s ' ' |grep "$SUBNETMASK U .*. $ETHDEV" |cut -d " " -f1)" -} - -# gather_network_information "$ETH" -gather_network_information() { - # requires ipcalc from centos/rhel - HWADDR=$(ip link show dev $ETHDEV | grep 'link/ether' | awk '{print $2}' | tr [:upper:] [:lower:]) - INETADDR=$(ip addr show dev $ETHDEV | grep "inet\ " | awk '{print $2}' ) -# IPADDR=$(ip addr show dev $ETHDEV | grep "inet\ " | awk '{print $2}' | cut -d"/" -f1) - # check for a RFC6598 address, and don't set the v4 vars if we have one - local FIRST=$(echo $INETADDR | cut -d "/" -f 1 | cut -d "." -f 1) - if [ $FIRST = "100" ]; then - debug "not configuring RFC6598 address" - V6ONLY=1 - else - IPADDR=$(echo $INETADDR | cut -d "/" -f1) - CIDR=$(echo $INETADDR | cut -d "/" -f2) - # subnetmask calculation for rhel ipcalc - SUBNETMASK=$(ipcalc -m $INETADDR | cut -d "=" -f 2) -# BROADCAST=$(ip addr show dev $ETHDEV | grep "inet\ " | awk '{print $4}') - BROADCAST=$(ipcalc -b $INETADDR | cut -d "=" -f 2) - GATEWAY=$(ip route | grep "default\ via" | awk '{print $3}') - NETWORK=$(ipcalc -n $INETADDR | cut -d"=" -f2) - fi - - # ipv6 - # check for non-link-local ipv6 - DOIPV6=$(ip -6 addr show dev $ETHDEV | grep -v fe80 | grep -m1 'inet6') - if [ -n "$DOIPV6" ]; then - local INET6ADDR=$(ip -6 addr show dev $ETHDEV | grep -v fe80 | grep -m1 'inet6' | awk '{print $2}') - IP6ADDR=$(echo $INET6ADDR | cut -d"/" -f1) - IP6PREFLEN=$(echo $INET6ADDR | cut -d'/' -f2) - # we can get default route from here, but we could also assume fe80::1 for now - IP6GATEWAY=$(ip -6 route show default | awk '{print $3}') - else - if [ "$V6ONLY" -eq 1 ]; then - debug "no valid IPv6 adress, but v6 only because of RFC6598 IPv4 address" - # we need to do this more graceful - exit 1 - fi - fi -} - -# setup_network_config "ETH" "HWADDR" "IPADDR" "BROADCAST" "SUBNETMASK" "GATEWAY" "NETWORK" -setup_network_config() { - if [ "$1" ] && [ "$2" ] && [ "$3" ] && [ "$4" ] && [ "$5" ] && [ "$6" ] && [ "$7" ]; then - return 1 - fi -} - -# setup_network_config_template "ETH" "HWADDR" "IPADDR" "BROADCAST" "SUBNETMASK" "GATEWAY" "NETWORK" "IPADDR6" "NETMASK6" "GATEWAY6" -setup_network_config_template() { - local eth="$1" - local hwaddr="$2" - - local ipaddr="$3" - local broadcast="$4" - local netmask="$5" - local gateway="$6" - local network="$7" - - local ipaddr6="$8" - local netmask6="$9" - local gateway6="${10}" - - # copy network template of distro to $FOLD - local tpl_net_load="$SCRIPTPATH/templates/network/$IAM.tpl" - local tpl_net="$FOLD/network" - cp $tpl_net_load $tpl_net - - # copy udev template of distro to $FOLD - local tpl_udev_load="$SCRIPTPATH/templates/network/udev.tpl" - local tpl_udev="$FOLD/udev" - cp $tpl_udev_load $tpl_udev - - # replace necessary network information - if [ -n "$eth" -a -n "$hwaddr" ] ; then - # replace network information in udev template - template_replace "ETH" "$eth" $tpl_udev - template_replace "HWADDR" "$hwaddr" $tpl_udev - - # replace network information in network template - if [ -n "$ipaddr" -a -n "$broadcast" -a -n "$netmask" -a -n "$gateway" -a -n "$network" ] ; then - template_replace "ETH" "$eth" $tpl_net - template_replace "HWADDR" "$hwaddr" $tpl_net - template_replace "IPADDR" "$ipaddr" $tpl_net - template_replace "BROADCAST" "$broadcast" $tpl_net - template_replace "NETMASK" "$netmask" $tpl_net - template_replace "GATEWAY" "$gateway" $tpl_net - template_replace "NETWORK" "$network" $tpl_net - - template_replace "GROUP_IP4" $tpl_net - else - template_replace "GROUP_IP4" $tpl_net "yes" - fi - - # replace ipv6 information in network template if given - if [ -n "$ipaddr6" -a -n "$netmask6" -a -n "$gateway6" ] ; then - template_replace "IPADDR6" "$ipaddr6" $tpl_net - template_replace "NETMASK6" "$netmask6" $tpl_net - template_replace "GATEWAY6" "$gateway6" $tpl_net - - template_replace "GROUP_IP6" $tpl_net - else - template_replace "GROUP_IP6" $tpl_net "yes" - fi - fi - - # replace duplex settings in network template if given - if ! isNegotiated && ! isVServer; then - template_replace "GROUP_DUPLEX" $tpl_net - else - template_replace "GROUP_DUPLEX" $tpl_net "yes" - fi - - # get specified extra files from template - local tpl_files=$(grep -e "%%% FILE_.*_START %%%" $tpl_net | sed 's/%%% FILE_\(.*\)_START %%%/\1/g') - for file in $tpl_files ; do - local filename="$FOLD/network_$(echo "$file" | tr [[:upper:]] [[:lower:]])" - # get content of extra file - local content="$(sed -n "/%%% FILE_${file}_START %%%/,/%%% FILE_${file}_END %%%/p" $tpl_net)" - - # create extra file - echo "$content" > $filename - # remove extra file from template - template_replace "FILE_${file}" $tpl_net "yes" - # remove file patterns from extra file - template_replace "FILE_${file}" $filename - done - - return 0 -} - -# template_replace -# variant 1: template_replace "SEARCH" "FILE" -# - this remove lines with SEARCH -# - also removes both GROUP lines if specified -# variant 2: template_replace "SEARCH" "REPLACE" "FILE" -# - replace SEARCH with REPLACE -# variant 3: template_replace "SEARCH" "FILE" "yes" -# - replace whole block specified -function template_replace() { - local search="$1" - if [ $# -eq 2 ] ; then - # if just 2 params set, remove lines - local file="$2" - if [ -n "$(echo "$search" | egrep "GROUP|FILE")" ] ; then - # if search contains GROUP or FILE, remove both group lines - search="${search}_\(START\|\END\)" - fi - sed -i "/%%% $search %%%/d" $file - elif [ $# -eq 3 ] ; then - if [ "$3" = "yes" ] ; then - # if 3rd param set yes, remove group including content - local file="$2" - sed -i "/%%% ${search}_START %%%/,/%%% ${search}_END %%%/d" $file - else - # replace pattern with content - local replace="$2" - local file="$3" - sed -i "s/%%% $search %%%/$replace/g" $file - fi - fi - - return 0 -} - # # generate_resolvconf # # Generate /etc/resolv.conf by adding the nameservers defined in the array -# $NAMESERVER in a random order. +# $DNSRESOLVER in a random order. # generate_resolvconf() { if [ "$IAM" = "suse" ] && [ "$IMG_VERSION" -ge 122 ]; then @@ -2951,56 +2763,32 @@ generate_resolvconf() { sed -i -e \ "s/^NETCONFIG_DNS_POLICY=\".*\"/NETCONFIG_DNS_POLICY=\"\"/" \ "$FOLD/hdd/etc/sysconfig/network/config" + fi -# if [ "$V6ONLY" -eq 1 ]; then -# debug "# skipping IPv4 DNS resolvers" -# else -# nameservers=$(echo ${NAMESERVER[@]} | sed -e "s/\./\\\./g") -# fi -# if [ -n "$DOIPV6" ]; then -# # a bit pointless as netconfig will only add the first three DNS resolvers -# nameservers=$(echo -n "$nameservers "; echo ${DNSRESOLVER_V6[@]}) -# fi -# -# debug "#DNS $nameservers" -# sed -i -e \ -# "s/^NETCONFIG_DNS_STATIC_SERVERS=\".*\"/NETCONFIG_DNS_STATIC_SERVERS=\"$nameservers\"/" \ -# $FOLD/hdd/etc/sysconfig/network/config -# execute_chroot_command "netconfig update -f" + if [[ -L "$FOLD/hdd/etc/resolv.conf" ]]; then + DNSRESOLVERFILE="$FOLD/hdd/etc/resolvconf/resolv.conf.d/base" + else + DNSRESOLVERFILE="$FOLD/hdd/etc/resolv.conf" fi -# else - if [[ -L "$FOLD/hdd/etc/resolv.conf" ]]; then - NAMESERVERFILE="$FOLD/hdd/etc/resolvconf/resolv.conf.d/base" - else - NAMESERVERFILE="$FOLD/hdd/etc/resolv.conf" - fi - echo -e "### $COMPANY installimage" > $NAMESERVERFILE - echo -e "# nameserver config" >> $NAMESERVERFILE - # IPV4 - if [ "$V6ONLY" -eq 1 ]; then - debug "# skipping IPv4 DNS resolvers" - else - for index in $(shuf --input-range=0-$(( ${#NAMESERVER[*]} - 1 )) | tr '\n' ' ') ; do - echo "nameserver ${NAMESERVER[$index]}" >> $NAMESERVERFILE - done - fi + echo -e "### $COMPANY installimage" > $DNSRESOLVERFILE + echo -e "# nameserver config" >> $DNSRESOLVERFILE + while read nsaddr; do + echo "nameserver $nsaddr" >> "$DNSRESOLVERFILE" + done < <(randomized_nsaddrs) - # IPv6 - if [ -n "$DOIPV6" ]; then - for index in $(shuf --input-range=0-$(( ${#DNSRESOLVER_V6[*]} - 1 )) | tr '\n' ' ') ; do - echo "nameserver ${DNSRESOLVER_V6[$index]}" >> $NAMESERVERFILE - done - fi -# fi + diff -Naur /dev/null "$FOLD/hdd/etc/resolv.conf" | debugoutput return 0 } # set_hostname "HOSTNAME" set_hostname() { - if [ "$1" -a "$2" ]; then - local sethostname="$1" + local hostname="$1" + local ip4="$2" + local ip6="$3" + if [[ -n "$hostname" && ( -n "$ip4" || -n "$ip6" ) ]]; then + local sethostname="$hostname" local mailname="$sethostname" local hostnamefile="$FOLD/hdd/etc/hostname" @@ -3042,13 +2830,17 @@ set_hostname() { fi check_fqdn "$mailname" - [ $? -eq 1 ] && mailname="$(create_hostname $IPADDR)" - if [ -f $mailnamefile ]; then - echo "$mailname" > $mailnamefile - debug "# set new mailname '$mailname' in $mailnamefile" + if (( $? == 1 )) && [[ -f "$mailnamefile" ]]; then + local v4_main_ip + v4_main_ip="$(v4_main_ip)" + if [[ -n "$v4_main_ip" ]]; then + if mailname="$(create_hostname "$(ip_addr_without_suffix "$v4_main_ip")")"; then + echo "$mailname" > $mailnamefile + debug "# set new mailname '$mailname' in $mailnamefile" + fi + fi fi - if [ -f $machinefile ]; then # clear machine-id from image echo -n > $machinefile @@ -3079,20 +2871,18 @@ set_hostname() { fi echo "### $COMPANY installimage" > $hostsfile - echo "# nameserver config" >> $hostsfile - echo "# IPv4" >> $hostsfile echo "127.0.0.1 localhost.localdomain localhost" >> $hostsfile - echo "$2 $fqdn_name $shortname" >> $hostsfile - echo "#" >> $hostsfile - echo "# IPv6" >> $hostsfile + if [[ -n "$ip4" ]]; then + echo "$ip4 $fqdn_name $shortname" | xargs >> $hostsfile + fi echo "::1 ip6-localhost ip6-loopback" >> $hostsfile echo "fe00::0 ip6-localnet" >> $hostsfile echo "ff00::0 ip6-mcastprefix" >> $hostsfile echo "ff02::1 ip6-allnodes" >> $hostsfile echo "ff02::2 ip6-allrouters" >> $hostsfile echo "ff02::3 ip6-allhosts" >> $hostsfile - if [ "$3" ]; then - echo "$3 $fqdn_name $shortname" >> $hostsfile + if [ "$ip6" ]; then + echo "$ip6 $fqdn_name $shortname" | xargs >> $hostsfile fi return 0 @@ -3607,14 +3397,8 @@ generate_ntp_config() { debug "# using systemd-timesyncd" local cfgdir="$FOLD/hdd/$CFGTIMESYNCD.d" local cfgparam='NTP' - # jessie systemd does not recognize drop-ins for systemd-timesyncd - if [ "$IAM" = "debian" ] && [ "$debian_version" -eq 8 ]; then - cfgparam='Servers' - CFG="$FOLD/hdd/$CFGTIMESYNCD" - else - mkdir -p "$cfgdir" - CFG="$cfgdir/$C_SHORT.conf" - fi + mkdir -p "$cfgdir" + CFG="$cfgdir/$C_SHORT.conf" { echo "[Time]" echo -n "$cfgparam=" @@ -3765,6 +3549,8 @@ install_robot_report_script() { local link_service=1 elif debian_buster_image; then local link_service=1 + elif debian_bullseye_image; then + local link_service=1 else local link_service=0 fi @@ -3783,6 +3569,7 @@ install_robot_report_script() { echo 'Description=Report installation to Robot' echo '[Service]' echo "ExecStart=$robot_report_script" + # TODO: KillMode=none is deprecated echo 'KillMode=none' echo 'Type=forking' } > "$FOLD/hdd/$robot_report_service" @@ -3836,15 +3623,24 @@ install_robot_report_script() { # cleanup() { debug 'cleaning up' + unset_raid0_default_layout - mysql_running && stop_mysql - systemd_nspawn_booted && poweroff_systemd_nspawn + + if systemd_nspawn_booted; then + # mysql cant be running without nspawn + mysql_running && stop_mysql + poweroff_systemd_nspawn + fi + + # try umount -R + umount -R "${FOLD}/hdd" |& debugoutput while read entry; do while read subentry; do umount --lazy --verbose "$(echo "${subentry}" | awk '{print $2}')" &> /dev/null # |& debugoutput done < <(echo "${entry}" | grep "${FOLD}/hdd") done < <(tac /proc/mounts) rm --force --recursive --verbose "${FOLD}" &> /dev/null # |& debugoutput + resume_swraid_resync } @@ -3947,9 +3743,14 @@ uuid_bugfix() { sed -n 's|^/dev/\(md\/[0-9]\+\).*|\1|p' < "$FOLD/hdd/etc/fstab" >> "$TEMPFILE" while read LINE; do UUID="$(blkid -o value -s UUID "/dev/$LINE")" + local fstype="$(blkid -o value -s TYPE "/dev/$LINE")" # not quite perfect. We need to match /dev/sda1 but not /dev/sda10. # device name may not always be followed by whitespace + # skip duplicate partitions with the same UUID (Multi-ESP) except for btrfs + [ -n "$(grep -e "$UUID" "$FOLD/hdd/etc/fstab")" ] && [ "$fstype" != 'btrfs' ] && sed -i "0,/$UUID/d" "$FOLD/hdd/etc/fstab" [ -e "$FOLD/hdd/etc/fstab" ] && sed -i "s|^/dev/${LINE} |# /dev/${LINE}\nUUID=${UUID} |" "$FOLD/hdd/etc/fstab" + # if multiple ESPs are supported by grub-efi-amd64, adjust the fstab entry, as all ESP partitions have the same UUID + [ ${#UUID} -eq 9 ] && [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -ge 2004 ] && [ "$UEFI" -eq 1 ] && sed -i "s=#\s/dev/$LINE=#\ efi-boot-partiton=g" "$FOLD/hdd/etc/fstab" [ -e "$FOLD/hdd/boot/grub/grub.cfg" ] && sed -i "s|/dev/${LINE} |UUID=${UUID} |" "$FOLD/hdd/boot/grub/grub.cfg" [ -e "$FOLD/hdd/boot/grub/grub.conf" ] && sed -i "s|/dev/${LINE} |UUID=${UUID} |" "$FOLD/hdd/boot/grub/grub.conf" [ -e "$FOLD/hdd/boot/grub/menu.lst" ] && sed -i "s|/dev/${LINE} |UUID=${UUID} |" "$FOLD/hdd/boot/grub/menu.lst" @@ -3996,22 +3797,6 @@ function hdinfo() { esac } -# function to check if we got autonegotiated speed with NIC or if the rescue system set speed to fix 100MBit FD -# returns 0 if we are auto negotiated and 1 if not -function isNegotiated() { -# search for first NIC which has an IP -for i in $(ifconfig -a | grep eth | cut -d " " -f 1); do - if ip a show "$i" | grep -q "inet [1-9]"; then - #check if we got autonegotiated - if echo $(mii-tool 2>/dev/null) | grep -q "negotiated"; then - return 0 - else - return 1 - fi - fi -done -} - # function to check if we are in a kvm-qemu vServer environment # returns 0 if we are in a vServer env otherwise 1 function isVServer() { @@ -4178,74 +3963,6 @@ function check_dos_partitions() { [ "$output" != "no_output" ] && echo $result } -# -# Set udev rules -# -set_udev_rules() { - # at this point we have configured networking for one and only one - # active interface and written a udev rule for this device. - # Normally, we could just rename that single interface. - # But when the system boots, the other interface are found and numbered. - # The system then tries to rename the interface to match the udev rules. - # Under certain situations with more than two NICs, this may not end as - # expected leaving some interfaces half-renamed (e.g. eth3-eth0) - # So we copy the already generated udev rules from the rescue system in order - # to have rules for all devices, no matter in which order they are found - # during boot. - local udevpath udevsrcfile udevtgtfile - udevpath="/etc/udev/rules.d" - udevsrcfile="$udevpath/70-persistent-net.rules" - if [ -f "$FOLD/hdd$udevsrcfile" ]; then - udevtgtfile="$udevsrcfile" - elif [ -f "$FOLD/hdd$udevpath/80-net-setup-link.rules" ]; then - udevtgtfile="$udevpath/80-net-setup-link.rules" - else - udevtgtfile="" - fi - - local ethcount; ethcount="$(find /sys/class/net/ -name eth* | wc -l)" - if [ "$ethcount" -gt 1 ]; then - # virtual servers with multiple nics may not have a net.rules files - if [ -n "$udevtgtfile" ] && [ -f "$udevsrcfile" ]; then - cp "$udevsrcfile" "$FOLD/hdd$udevtgtfile" - #Testeinbau - if [ "$IAM" = "centos" ]; then - # need to remove these parts of the rule for centos, - # otherwise we get new rules with the old interface name again - # plus a new ifcfg- for the new rule, which duplicates - # the config but does not match the MAC of the interface - # after renaming. Terrible mess. - sed -i 's/ ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL==\"eth\*\"//g' "$FOLD/hdd$udevtgtfile" - fi - fi - for nic in /sys/class/net/*; do - local interface; interface=${nic##*/} - #test if the interface has a ipv4 adress - iptest=$(ip addr show dev "$interface" | grep "$interface"$ | awk '{print $2}' | cut -d "." -f 1,2) - #iptest=$(ifconfig $INTERFACE | grep "inet addr" | cut -d ":" -f2 | cut -d " " -f1 | cut -d "." -f1,2) - #Separate udev-rules for openSUSE 12.3 in function "suse_fix" below !!! - - # skip eth0, lo and 192.168.x - [[ "${interface}" == "eth0" ]] && continue - [[ "${interface}" == "idrac" ]] && continue - [[ "${interface}" == "lo" ]] && continue - [[ -n "${iptest}" ]] || continue - [[ "${iptest}" == "192.168" ]] && continue - # skip IPMI NICs - udev_info="$(udevadm info --path "/sys/class/net/${interface}")" - echo "${udev_info}" | grep --quiet 'ID_MODEL=iDRAC_Virtual_NIC_USB_Device' && continue - - debug "# renaming active $interface to eth0 via udev in installed system" - sed -i "s/$interface/dummy/" "$FOLD/hdd$udevtgtfile" - sed -i "s/eth0/$interface/" "$FOLD/hdd$udevtgtfile" - sed -i "s/dummy/eth0/" "$FOLD/hdd$udevtgtfile" - fix_eth_naming "$interface" - done - [ "$IAM" = 'suse' ] && suse_version="$IMG_VERSION" - [ "$suse_version" == "123" ] && suse_netdev_fix - fi -} - # Rename eth device (ethX to eth0) # fix_eth_naming() { diff --git a/imageinfo.functions.sh b/imageinfo.functions.sh index 13418ff..54673f0 100644 --- a/imageinfo.functions.sh +++ b/imageinfo.functions.sh @@ -7,7 +7,13 @@ # debian_buster_image() { - [[ "${IAM,,}" == 'debian' ]] && ((IMG_VERSION >= 100)) && ((IMG_VERSION < 710)) + [[ "${IAM,,}" == 'debian' ]] || return 1 + ( ((IMG_VERSION >= 100)) && ((IMG_VERSION <= 109)) ) || ( ((IMG_VERSION >= 1010)) && ((IMG_VERSION < 1100)) ) +} + +debian_bullseye_image() { + [[ "${IAM,,}" == 'debian' ]] || return 1 + ((IMG_VERSION >= 1100)) && ((IMG_VERSION <= 1200)) } # vim: ai:ts=2:sw=2:et diff --git a/install.sh b/install.sh index 5056e7c..26ef006 100644 --- a/install.sh +++ b/install.sh @@ -3,7 +3,7 @@ # # install - installation commands # -# (c) 2007-2018, Hetzner Online GmbH +# (c) 2007-2021, Hetzner Online GmbH # @@ -72,13 +72,6 @@ echo_bold " $COMPANY - installimage\n" echo_bold " Your server will be installed now, this will take some minutes" echo_bold " You can abort at any time with CTRL+C ...\n" -# -# get active nic and gather network information -# -get_active_eth_dev -gather_network_information - - # # Read configuration # @@ -322,46 +315,23 @@ status_busy "Extracting image ($IMAGE_PATH_TYPE)" extract_image "$IMAGE_PATH_TYPE" "$IMAGE_FILE_TYPE" status_donefailed $? +# Verify that systemd-nspawn works +if installed_os_uses_systemd; then + debug '# verify that systemd-nspawn works' + if ! systemd_nspawn_wo_debug '/usr/bin/env true' |& debugoutput; then + exit_function + exit 1 + fi +fi + # # Setup network # inc_step -if [[ "$IAM" == 'centos' ]] || [[ "$IAM" == 'debian' ]] || [[ "$IAM" == 'archlinux' ]]; then - status_busy "Setting up network config" - setup_network_config_new - status_donefailed $? -elif [[ "$IAM" == 'ubuntu' ]] && ((IMG_VERSION == 1404)); then - status_busy "Setting up network config" - setup_network_config_new - status_donefailed $? -elif [[ "$IAM" == 'ubuntu' ]] && ((IMG_VERSION >= 1604)); then - status_busy "Setting up network config" - setup_network_config_new - status_donefailed $? -elif [[ "$IAM" == 'suse' ]] && ((IMG_VERSION >= 422)); then - status_busy "Setting up network config" - setup_network_config_new - status_donefailed $? -else - status_busy "Setting up network for $ETHDEV" - setup_network_config "$ETHDEV" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" - status_donefailed $? -fi - -if [[ "$IAM" == 'centos' ]] && ((IMG_VERSION >= 70)) && ((IMG_VERSION != 610)); then - : -elif [[ "$IAM" == 'debian' ]] && ((IMG_VERSION >= 80)) && ((IMG_VERSION != 710)) && ((IMG_VERSION != 711)); then - : -elif [[ "$IAM" == 'ubuntu' ]] && ((IMG_VERSION >= 1604)); then - : -elif [[ "$IAM" == 'suse' ]] && ((IMG_VERSION >= 422)); then - : -else - # - # Set udev rules - # - set_udev_rules -fi +status_busy "Setting up network config" +((IPV4_ONLY == 1)) && debug '# IPV4_ONLY flag set. ignoring IPv6' +setup_network_config +status_donefailed $? # # chroot commands @@ -373,8 +343,9 @@ copy_mtab "NIL" status_busy_nostep " Setting hostname" debug "# Setting hostname" -#set_hostname "$NEWHOSTNAME" || status_failed -set_hostname "$NEWHOSTNAME" "$IPADDR" "$IP6ADDR" || status_failed +v4_main_ip="$(v4_main_ip)" +v6_main_ip="$(v6_main_ip)" +set_hostname "$NEWHOSTNAME" "$(ip_addr_without_suffix "$v4_main_ip")" "$(ip_addr_without_suffix "$v6_main_ip")" || status_failed status_done if [[ "$GENERATE_NEW_SSH_HOST_KEYS" == no ]]; then @@ -416,8 +387,6 @@ setup_cpufreq "$GOVERNOR" || { } #status_donefailed $? - - # # Set up misc files # @@ -428,8 +397,6 @@ if [[ "$IAM" == 'ubuntu' ]] && ((IMG_VERSION >= 1804)); then else generate_resolvconf || status_failed fi -# already done in set_hostname -#generate_hosts "$IPADDR" "$IP6ADDR" || status_failed generate_sysctlconf || status_failed status_done diff --git a/installimage b/installimage index 17e4b24..dce7214 100755 --- a/installimage +++ b/installimage @@ -71,9 +71,7 @@ fi mkdir -p "$FOLD/hdd" } >/dev/null 2>&1 cd "$FOLD" || exit 1 -#myip=$(ifconfig eth0 | grep "inet addr" | cut -d: -f2 | cut -d ' ' -f1) -myip=$(ip a s eth0 | grep 'inet ' | awk '{ print $2 }' | cut -d / -f 1) -debug "# starting installimage on [ $myip ]" +debug "# starting installimage" # log hardware data diff --git a/network_config.functions.sh b/network_config.functions.sh index 50475c8..14de509 100644 --- a/network_config.functions.sh +++ b/network_config.functions.sh @@ -3,7 +3,7 @@ # # network config functions # -# (c) 2017-2018, Hetzner Online GmbH +# (c) 2017-2021, Hetzner Online GmbH # # setup /etc/sysconfig/network @@ -101,6 +101,12 @@ ipv4_addr_is_shared_addr() { network_contains_ipv4_addr 100.64.0.0/10 "$ipv4_addr" } +# check if ipv4 addr is reserved for future use +ipv4_addr_is_reserved_for_future_use() { + local ipv4_addr="$1" + network_contains_ipv4_addr 240.0.0.0/4 "$ipv4_addr" +} + # get network interface ipv4 addrs # $1 network_interface_ipv4_addrs() { @@ -110,6 +116,8 @@ network_interface_ipv4_addrs() { local ipv4_addr="${BASH_REMATCH[1]}" # ignore shared addrs ipv4_addr_is_shared_addr "$ipv4_addr" && continue + # ignore addrs reserved for future use + ipv4_addr_is_reserved_for_future_use "$ipv4_addr" && continue echo "$ipv4_addr" done < <(ip -4 a s "$network_interface") } @@ -124,6 +132,9 @@ ipv6_addr_is_link_local_unicast_addr() { # get network interface ipv6 addrs # $1 network_interface_ipv6_addrs() { + # "hide" v6 if IPV4_ONLY set + ((IPV4_ONLY == 1)) && return + local network_interface="$1" while read line; do [[ "$line" =~ ^\ *inet6\ ([^\ ]+) ]] || continue @@ -136,10 +147,9 @@ network_interface_ipv6_addrs() { # check whether to use predictable network interface names use_predictable_network_interface_names() { - [[ "$IAM" == 'centos' ]] && ((IMG_VERSION >= 73)) && ((IMG_VERSION != 610)) && return - [[ "$IAM" == 'debian' ]] && ((IMG_VERSION >= 90)) && ((IMG_VERSION <= 700)) && return - [[ "$IAM" == 'debian' ]] && ((IMG_VERSION >= 900)) && return - [[ "$IAM" == 'ubuntu' ]] && ((IMG_VERSION >= 1710)) && return + [[ "$IAM" == 'centos' ]] && return + [[ "$IAM" == 'debian' ]] && return + [[ "$IAM" == 'ubuntu' ]] && return [[ "$IAM" == 'archlinux' ]] && return return 1 } @@ -233,31 +243,33 @@ gen_ifcfg_script_centos() { fi # static config - if ! ipv4_addr_is_private "$gateway" || ! isVServer; then - local address="$(ip_addr_without_suffix "${ipv4_addrs[0]}")" - # ! pointtopoint - if ipv4_addr_is_private "$gateway" || isVServer; then - local netmask="$(ip_addr_suffix "${ipv4_addrs[0]}")" - # pointtopoint - else - local netmask='32' - fi - - echo "configuring ipv4 addr ${ipv4_addrs[0]} for $predicted_network_interface_name" >&2 - echo "IPADDR=$address" - echo "PREFIX=$netmask" - if [[ -n "$gateway" ]]; then - # pointtopoint - # only for centos < 8 - if ! ipv4_addr_is_private "$gateway" && ! isVServer && ( ((IMG_VERSION < 80)) || ((IMG_VERSION == 610)) || is_cpanel_install ); then - local network="$(ipv4_addr_network "${ipv4_addrs[0]}")" - - echo "configuring host route $network via $gateway" >&2 - echo "SCOPE=\"peer $gateway\"" + if ((${#ipv4_addrs[@]} > 0)); then + if ! ipv4_addr_is_private "$gateway" || ! isVServer; then + local address="$(ip_addr_without_suffix "${ipv4_addrs[0]}")" # ! pointtopoint + if ipv4_addr_is_private "$gateway" || isVServer; then + local netmask="$(ip_addr_suffix "${ipv4_addrs[0]}")" + # pointtopoint else - echo "configuring ipv4 gateway $gateway for $predicted_network_interface_name" >&2 - echo "GATEWAY=$gateway" + local netmask='32' + fi + + echo "configuring ipv4 addr ${ipv4_addrs[0]} for $predicted_network_interface_name" >&2 + echo "IPADDR=$address" + echo "PREFIX=$netmask" + if [[ -n "$gateway" ]]; then + # pointtopoint + # only for centos < 8 + if ! ipv4_addr_is_private "$gateway" && ! isVServer && ( ((IMG_VERSION < 80)) || ((IMG_VERSION == 610)) || is_cpanel_install ); then + local network="$(ipv4_addr_network "${ipv4_addrs[0]}")" + + echo "configuring host route $network via $gateway" >&2 + echo "SCOPE=\"peer $gateway\"" + # ! pointtopoint + else + echo "configuring ipv4 gateway $gateway for $predicted_network_interface_name" >&2 + echo "GATEWAY=$gateway" + fi fi fi fi @@ -348,23 +360,25 @@ gen_ifcfg_script_suse() { echo 'DHCLIENT_SET_HOSTNAME="no"' # static config else - local ipaddr="$(ip_addr_without_suffix "${ipv4_addrs[0]}")" - # ! pointtopoint - if ipv4_addr_is_private "$gateway" || isVServer; then - local netmask="$(ip_addr_suffix "${ipv4_addrs[0]}")" - # pointtopoint - else - local netmask='32' - fi - echo "configuring ipv4 addr $ipaddr/$netmask for $predicted_network_interface_name" >&2 - echo "IPADDR=\"$ipaddr/$netmask\"" + if ((${#ipv4_addrs[@]} > 0)); then + local ipaddr="$(ip_addr_without_suffix "${ipv4_addrs[0]}")" + # ! pointtopoint + if ipv4_addr_is_private "$gateway" || isVServer; then + local netmask="$(ip_addr_suffix "${ipv4_addrs[0]}")" + # pointtopoint + else + local netmask='32' + fi + echo "configuring ipv4 addr $ipaddr/$netmask for $predicted_network_interface_name" >&2 + echo "IPADDR=\"$ipaddr/$netmask\"" - # pointtopoint - if [[ -n "$gateway" ]] && ! ipv4_addr_is_private "$gateway" && ! isVServer; then - local network="$(ipv4_addr_network "${ipv4_addrs[0]}")" + # pointtopoint + if [[ -n "$gateway" ]] && ! ipv4_addr_is_private "$gateway" && ! isVServer; then + local network="$(ipv4_addr_network "${ipv4_addrs[0]}")" - echo "configuring host route $network via $gateway" >&2 - echo "REMOTE_IPADDR=\"$gateway\"" + echo "configuring host route $network via $gateway" >&2 + echo "REMOTE_IPADDR=\"$gateway\"" + fi fi fi @@ -616,7 +630,7 @@ gen_etc_netplan_01_netcfg_yaml_entry() { esac [[ "$dhcp4" == true ]] && echo ' dhcp4: true' # ! pointtopoint - if [[ "$gateway4" != false ]]; then + if [[ -n "$gateway4" ]] && [[ "$gateway4" != false ]]; then if ipv4_addr_is_private "$gateway4" || isVServer; then echo " gateway4: $gateway4" else @@ -634,20 +648,9 @@ gen_etc_netplan_01_netcfg_yaml_entry() { if [[ "$gateway4" != false ]]; then echo ' nameservers:' echo ' addresses:' - # IPV4 - if [ "$V6ONLY" -eq 1 ]; then - debug "# skipping IPv4 DNS resolvers" - else - for index in $(shuf --input-range=0-$(( ${#NAMESERVER[*]} - 1 )) | tr '\n' ' ') ; do - echo " - ${NAMESERVER[$index]}" - done - fi - # IPv6 - if [ -n "$DOIPV6" ]; then - for index in $(shuf --input-range=0-$(( ${#DNSRESOLVER_V6[*]} - 1 )) | tr '\n' ' ') ; do - echo " - ${DNSRESOLVER_V6[$index]}" - done - fi + while read nsaddr; do + echo " - $nsaddr" + done < <(randomized_nsaddrs) fi } @@ -727,7 +730,7 @@ setup_etc_systemd_network_files() { } # setup network config -setup_network_config_new() { +setup_network_config() { debug '# setup network config' case "$IAM" in @@ -759,4 +762,192 @@ setup_network_config_new() { fi } +# get BOOTIF mac from kernel cmdline +bootif_mac() { + xargs -a /proc/cmdline -n 1 | grep ^BOOTIF= | cut -d '-' -f 2- | tr '-' ':' +} + +# get bootif via kernel commandline BOOTIF mac +bootif() { + local bootif_mac + bootif_mac="$(bootif_mac)" + while read network_interface; do + [[ "$(network_interface_mac "$network_interface")" == "$bootif_mac" ]] || continue + + echo "$network_interface" + break + done < <(physical_network_interfaces) +} + +# get v4 main network interface +v4_main_network_interface() { + # prefer bootif + local bootif + bootif="$(bootif)" + if [[ -n "$bootif" ]]; then + echo "$bootif" + return + fi + + # legacy behaviour. use first netif with an IPv4 + local ipv4_addrs + while read network_interface; do + ipv4_addrs=($(network_interface_ipv4_addrs "$network_interface")) + ((${#ipv4_addrs[@]} == 0)) && continue + + debug "v4 main netif lookup: using v4 main netif $network_interface found via legacy lookup loop" + echo "$network_interface" + break + done < <(physical_network_interfaces) +} + +# get v6 main network interface +v6_main_network_interface() { + # prefer bootif + local bootif + bootif="$(bootif)" + if [[ -n "$bootif" ]]; then + echo "$bootif" + return + fi + + # legacy behaviour. use first netif with an IPv6 + local ipv6_addrs + while read network_interface; do + ipv6_addrs=($(network_interface_ipv6_addrs "$network_interface")) + ((${#ipv6_addrs[@]} == 0)) && continue + + debug "v6 main netif lookup: using v6 main netif $network_interface found via legacy lookup loop" + echo "$network_interface" + break + done < <(physical_network_interfaces) +} + +# get main mac from either v4 main netif or v6 main netif +main_mac() { + local v4_main_network_interface + v4_main_network_interface="$(v4_main_network_interface)" + local mac="$(network_interface_mac "$v4_main_network_interface")" + if [[ -n "$mac" ]]; then + echo "$mac" + return + fi + + local v6_main_network_interface + v6_main_network_interface="$(v6_main_network_interface)" + local mac="$(network_interface_mac "$v6_main_network_interface")" + if [[ -n "$mac" ]]; then + echo "$mac" + return + fi + + debug "fatal: dont know main MAC" + return 1 +} + +# first ipv4 of main v4 netif +v4_main_ip() { + local v4_main_network_interface + v4_main_network_interface="$(v4_main_network_interface)" + local ipv4_addrs + ipv4_addrs=($(network_interface_ipv4_addrs "$v4_main_network_interface")) + echo "${ipv4_addrs[0]}" +} + +# first ipv6 of main v6 netif +v6_main_ip() { + local v6_main_network_interface + v6_main_network_interface="$(v6_main_network_interface)" + local ipv6_addrs + ipv6_addrs=($(network_interface_ipv6_addrs "$v6_main_network_interface")) + echo "${ipv6_addrs[0]}" +} + +has_no_public_ip() { + local ipv6_addrs + while read network_interface; do + ipv6_addrs=($(network_interface_ipv6_addrs "$network_interface")) + ((${#ipv6_addrs[@]} > 1)) && return 1 + + while read ip; do + ipv4_addr_is_private "$ip" || return 1 + done < <(network_interface_ipv4_addrs "$network_interface") + done < <(physical_network_interfaces) + + return 0 +} + +has_no_ipv6() { + local ipv6_addrs + while read network_interface; do + ipv6_addrs=($(network_interface_ipv6_addrs "$network_interface")) + ((${#ipv6_addrs[@]} > 0)) && return 1 + done < <(physical_network_interfaces) + + return 0 +} + +has_no_ipv4() { + local ipv4_addrs + while read network_interface; do + ipv4_addrs=($(network_interface_ipv4_addrs "$network_interface")) + ((${#ipv4_addrs[@]} > 0)) && return 1 + done < <(physical_network_interfaces) + + return 0 +} + +has_dualstack() { + !has_no_ipv6 && !has_no_ipv4 +} + +v6_first() { + # force v4 first + ((IPV4_ONLY == 1)) && return 1 + + # dont use v6 first for dualstack yet + has_no_ipv4 # || has_dualstack +} + +v4_first() { + # force v4 first + ((IPV4_ONLY == 1)) && return 0 + + has_no_public_ip || has_no_ipv6 +} + +randomized_nsaddrs() { + local v6_nsaddrs=($(shuf -e "${DNSRESOLVER_V6[@]}")) + local v4_nsaddrs=($(shuf -e "${DNSRESOLVER[@]}")) + + if v6_first; then + first_pool=("${v6_nsaddrs[@]}") + second_pool=("${v4_nsaddrs[@]}") + else + first_pool=("${v4_nsaddrs[@]}") + second_pool=("${v6_nsaddrs[@]}") + fi + + local nsaddrs=() + local maxns=4 + local i=-1 + local nsaddr + until (( ${#nsaddrs[@]} == $maxns || (${#first_pool[@]} == 0 && ${#second_pool[@]} == 0) )); do + i=$((i + 1)) + + nsaddr="${first_pool[$i]}" + if [[ -n "$nsaddr" ]]; then + nsaddrs+=("$nsaddr") + first_pool=("${first_pool[@]:$i}") + fi + + nsaddr="${second_pool[$i]}" + if [[ -z "$nsaddr" ]] || (( ${#nsaddrs[@]} == $maxns )); then continue; fi + nsaddrs+=("$nsaddr") + second_pool=("${second_pool[@]:$i}") + done + + for nsaddr in "${nsaddrs[@]}"; do echo "$nsaddr"; done +} + # vim: ai:ts=2:sw=2:et diff --git a/post-install/proxmox5 b/post-install/proxmox5 index 5e8d2e2..f86f228 100755 --- a/post-install/proxmox5 +++ b/post-install/proxmox5 @@ -34,7 +34,7 @@ aptitude -q -y purge linux-image-amd64 linux-image-4.9.0-4-amd64 echo -e "\n----- Add Proxmox repo to APT sources -----\n" echo -e "\n\n# PVE packages provided by proxmox.com" >>/etc/apt/sources.list.d/proxmox.list -echo -e "deb http://mirror.hetzner.de/debian/pve stretch pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list +echo -e "deb http://mirror.hetzner.com/debian/pve stretch pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list echo -e "deb http://download.proxmox.com/debian/pve stretch pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list wget -q "http://download.proxmox.com/debian/proxmox-ve-release-5.x.gpg" -O /etc/apt/trusted.gpg.d/proxmox-ve-release-5.x.gpg diff --git a/post-install/proxmox6 b/post-install/proxmox6 index ad31f08..043cc8c 100755 --- a/post-install/proxmox6 +++ b/post-install/proxmox6 @@ -34,7 +34,7 @@ aptitude -q -y purge linux-image-amd64 linux-image-4.19.0-5-amd64 echo -e "\n----- Add Proxmox repo to APT sources -----\n" echo -e "\n\n# PVE packages provided by proxmox.com" >>/etc/apt/sources.list.d/proxmox.list -echo -e "deb http://mirror.hetzner.de/debian/pve buster pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list +echo -e "deb http://mirror.hetzner.com/debian/pve buster pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list echo -e "deb http://download.proxmox.com/debian/pve buster pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list wget -q "http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg" -O /etc/apt/trusted.gpg.d/proxmox-ve-release-6.x.gpg diff --git a/report.functions.sh b/report.functions.sh index f997851..27aa391 100644 --- a/report.functions.sh +++ b/report.functions.sh @@ -17,13 +17,20 @@ filter_install_conf() { report_install() { filter_install_conf < "$FOLD/install.conf" > "$FOLD/install.conf.filtered" + local main_mac + main_mac="$(main_mac)" || return 1 + if has_no_ipv4; then + local statsserver="$STATSSERVER6" + else + local statsserver="$STATSSERVER4" + fi curl --data-urlencode "config@$FOLD/install.conf.filtered" \ - --data-urlencode "mac=$HWADDR" \ + --data-urlencode "mac=$main_mac" \ -k \ -m 10 \ -s \ -D "$FOLD/install_report.headers" \ - "https://$STATSSERVER/api/v1/installimage/installations" > "$FOLD/install_report.response" + "https://$statsserver/api/v1/installimage/installations" > "$FOLD/install_report.response" debug "Sent install.conf to statsserver: $(head -n 1 "$FOLD/install_report.headers")" local image_id="$(cat "$FOLD/install_report.response")" @@ -36,7 +43,7 @@ report_install() { -T "$FOLD/debug.txt.filtered" \ -D "$FOLD/install_report.headers" \ -X POST \ - "https://$STATSSERVER/api/v1/installimage/installations/$image_id/logs" > /dev/null + "https://$statsserver/api/v1/installimage/installations/$image_id/logs" > /dev/null debug "Sent debug.txt to statsserver: $(head -n 1 "$FOLD/install_report.headers")" } diff --git a/setup.sh b/setup.sh index e38c1f7..220e814 100644 --- a/setup.sh +++ b/setup.sh @@ -48,7 +48,10 @@ if [ "$OPT_AUTOMODE" ] ; then VALIDATED="true" else debug "=> FAILED" - mcedit "$FOLD/install.conf" + # dont show editor in automode. print to stdout + echo "Abort: invalid config or parameters. See $DEBUGFILE for details" + # mcedit "$FOLD/install.conf" + exit 1 fi done diff --git a/suse.sh b/suse.sh index bc561d7..d3740eb 100644 --- a/suse.sh +++ b/suse.sh @@ -3,95 +3,10 @@ # # OpenSUSE specific functions # -# (c) 2007-2018, Hetzner Online GmbH +# (c) 2007-2021, Hetzner Online GmbH # -# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" -setup_network_config() { - if [ -n "$1" ] && [ -n "$2" ]; then - # good we have a device and a MAC - - ROUTEFILE="$FOLD/hdd/etc/sysconfig/network/routes" - if [ -f "$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" ]; then - UDEVFILE="$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" - else - UDEVFILE="/dev/null" - fi - # Delete network udev rules -# rm "$FOLD"/hdd/etc/udev/rules.d/*-persistent-net.rules 2>&1 | debugoutput - - { - echo "### $COMPANY - installimage" - echo "# device: $1" - printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", KERNEL=="eth*", NAME="%s"\n' "$2" "$1" - } > "$UDEVFILE" - - # remove any other existing config files - find "$FOLD/hdd/etc/sysconfig/network/" -name "*-eth*" -delete - - CONFIGFILE="$FOLD/hdd/etc/sysconfig/network/ifcfg-$1" - - { - echo "### $COMPANY - installimage" - echo "# device: $1" - echo "MTU=''" - echo "STARTMODE='auto'" - echo "UNIQUE=''" - echo "USERCONTROL='no'" - } > "$CONFIGFILE" - - if [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ]; then - if is_private_ip "$6" && isVServer; then - { - echo "BOOTPROTO=dhcp" - echo "DHCLIENT_SET_HOSTNAME='no'" - } >> "$CONFIGFILE" - else - { - echo "BOOTPROTO='static'" - echo "BROADCAST='$4'" - echo "IPADDR='$3'" - } >> "$CONFIGFILE" - if is_private_ip "$3" || isVServer; then - { - echo "NETMASK='$5'" - } >> "$CONFIGFILE" - else - { - echo "NETMASK=255.255.255.255" - echo "REMOTE_IPADDR='$6'" - } >> "$CONFIGFILE" - fi - { - echo "### $COMPANY - installimage" - echo "# routing for eth0" -# echo "$7 $6 $5 $1" -# echo "$6 - 255.255.255.255 $1" - echo "default $6 - -" - } > "$ROUTEFILE" - fi - fi - - if [ -n "$8" ] && [ -n "$9" ] && [ -n "${10}" ]; then - debug "setting up ipv6 networking $8/$9 via ${10}" - if [ -n "$3" ]; then - # add v6 addr as an alias, if we have a v4 addr - echo "IPADDR_0='$8/$9'" >> "$CONFIGFILE" - else - echo "IPADDR='$8/$9'" >> "$CONFIGFILE" - fi - echo "default ${10} - $1" >> "$ROUTEFILE" - fi - - if ! isNegotiated && ! isVServer; then - echo 'ETHTOOL_OPTIONS="speed 100 duplex full autoneg off"' >> "$CONFIGFILE" - fi - - return 0 - fi -} - # generate_mdadmconf "NIL" generate_config_mdadm() { if [ -n "$1" ]; then diff --git a/swraid.functions.sh b/swraid.functions.sh index b15b6ae..826a9b5 100644 --- a/swraid.functions.sh +++ b/swraid.functions.sh @@ -13,6 +13,7 @@ suspend_swraid_resync() { set_raid0_default_layout() { modprobe raid0 + [[ -e /sys/module/raid0/parameters/default_layout ]] || return (($(< /sys/module/raid0/parameters/default_layout) == 0)) || return echo 2 > /sys/module/raid0/parameters/default_layout } diff --git a/systemd.functions.sh b/systemd.functions.sh index b9d3365..3e2e2b4 100644 --- a/systemd.functions.sh +++ b/systemd.functions.sh @@ -18,4 +18,9 @@ installed_os_uses_systemd() { installed_os_systemd_version &> /dev/null } +# get rescue systemd version +rescue_systemd_version() { + [[ "$(systemctl --version)" =~ systemd\ ([0-9]+) ]] && echo "${BASH_REMATCH[1]}" +} + # vim: ai:ts=2:sw=2:et diff --git a/systemd_nspawn.functions.sh b/systemd_nspawn.functions.sh index 3f7ab3c..fd28076 100644 --- a/systemd_nspawn.functions.sh +++ b/systemd_nspawn.functions.sh @@ -3,9 +3,42 @@ # # systemd_nspawn functions # -# (c) 2015-2018, Hetzner Online GmbH +# (c) 2015-2021, Hetzner Online GmbH # +# protect files from systemd +polite_nspawn() { + if ! [[ -L "$FOLD/hdd/etc/resolv.conf" ]] && ! [[ -e "$FOLD/hdd/etc/resolv.conf" ]]; then + systemd-nspawn "$@" + return $? + fi + + # prepare nspawn_resolv.conf + if [[ -L "$FOLD/hdd/etc/resolv.conf" ]] && ! [[ -e "$FOLD/hdd/etc/resolv.conf" ]]; then + cp /etc/resolv.conf "$FOLD/nspawn_resolv.conf" + else + cp "$FOLD/hdd/etc/resolv.conf" "$FOLD/nspawn_resolv.conf" + fi + + # choose protection strategy + if [[ -L "$FOLD/hdd/etc/resolv.conf" ]]; then + mv "$FOLD/hdd/etc/resolv.conf" "$FOLD/resolv.bak" + cp "$FOLD/nspawn_resolv.conf" "$FOLD/hdd/etc/resolv.conf" + else + mount --bind "$FOLD/nspawn_resolv.conf" "$FOLD/hdd/etc/resolv.conf" + fi + + systemd-nspawn "$@" + + # restore + if [[ -L "$FOLD/resolv.bak" ]]; then + rm "$FOLD/hdd/etc/resolv.conf" + mv "$FOLD/resolv.bak" "$FOLD/hdd/etc/resolv.conf" + else + umount "$FOLD/hdd/etc/resolv.conf" + fi +} + # systemd_nspawn_booted() { [[ -e "$FOLD/.#hdd.lck" ]]; } systemd_nspawn_booted() { pkill -0 systemd-nspawn; } @@ -34,7 +67,7 @@ boot_systemd_nspawn() { echo 'Type=forking' } > "$SYSTEMD_NSPAWN_TMP_DIR/systemd_nspawn-runner.service" ln -s ../systemd_nspawn-runner.service "$FOLD/hdd/etc/systemd/system/multi-user.target.wants" - systemd-nspawn -b \ + polite_nspawn -b \ --bind-ro=/etc/resolv.conf:/run/resolvconf/resolv.conf \ --bind-ro=/etc/resolv.conf:/run/systemd/resolve/stub-resolv.conf \ --bind-ro="$SYSTEMD_NSPAWN_TMP_DIR/command.fifo:/var/lib/systemd_nspawn/command.fifo" \ @@ -51,23 +84,25 @@ boot_systemd_nspawn() { systemd_nspawn_wo_debug() { if ! systemd_nspawn_booted; then - local restore_resolv_conf=0 - if [[ -e "$FOLD/hdd/etc/resolv.conf" ]]; then - cp "$FOLD/hdd/etc/resolv.conf" "$FOLD/hdd/etc/resolv.conf.bak" || return 1 - restore_resolv_conf=1 - fi - systemd-nspawn --bind=/dev --bind-ro=/etc/resolv.conf:/run/resolvconf/resolv.conf \ + # only bind mount block devices + local dev_bind_args=() + while read f; do + stat "$f" &> /dev/null || continue + f="$(echo "$f" | sed s/:/\\\\:/g)" + dev_bind_args+=("--bind=$f") + done < <(find /dev -xtype b) + + # systemd > 241 added and requires --pipe to not use Windows line breaks 🤡 + local gt_241_args='' + (( $(rescue_systemd_version) > 241 )) && gt_241_args='--pipe' + + polite_nspawn "${dev_bind_args[@]}" --bind-ro=/etc/resolv.conf:/run/resolvconf/resolv.conf \ --bind-ro=/etc/resolv.conf:/run/systemd/resolve/stub-resolv.conf \ -D "$FOLD/hdd" \ '--property=DeviceAllow=block-* rwm' \ '--property=DeviceAllow=/dev/mapper/control rwm' \ - -q /usr/bin/env bash -c "$*" + -q $gt_241_args /usr/bin/env bash -c "$*" r=$? - if [[ -e "$FOLD/hdd/etc/resolv.conf.bak" ]]; then - if ((restore_resolv_conf == 1)); then - mv "$FOLD/hdd/etc/resolv.conf.bak" "$FOLD/hdd/etc/resolv.conf" || return 1 - fi - fi return $r fi echo "$@" > "$SYSTEMD_NSPAWN_TMP_DIR/command.fifo" diff --git a/ubuntu.sh b/ubuntu.sh index aac84ea..d1b77bc 100644 --- a/ubuntu.sh +++ b/ubuntu.sh @@ -3,132 +3,9 @@ # # Ubuntu specific functions # -# (c) 2007-2018, Hetzner Online GmbH +# (c) 2007-2021, Hetzner Online GmbH # -# setup_network_config "$ETH" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" -setup_network_config() { - if [ -n "$1" ] && [ -n "$2" ]; then - if [ -f "$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" ]; then - UDEVFILE="$FOLD/hdd/etc/udev/rules.d/70-persistent-net.rules" - elif [ -f "$FOLD/hdd/etc/udev/rules.d/80-net-setup-link.rules" ]; then - UDEVFILE="$FOLD/hdd/etc/udev/rules.d/80-net-setup-link.rules" - else - UDEVFILE="/dev/null" - fi - { - echo "### $COMPANY - installimage" - echo "# device: $1" - printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="%s"\n' "$2" "$1" - } > "$UDEVFILE" - - [ -d "$FOLD/hdd/etc/systemd/network" ] && rm -f "$FOLD"/hdd/etc/systemd/network/* - - if [ "$IMG_VERSION" -ne 1510 ]; then - CONFIGFILE="$FOLD/hdd/etc/network/interfaces" - - { - echo "### $COMPANY - installimage" - echo "# Loopback device:" - echo "auto lo" - echo "iface lo inet loopback" - echo "iface lo inet6 loopback" - echo "" - } > "$CONFIGFILE" - if [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ]; then - echo "# device: $1" >> "$CONFIGFILE" - if is_private_ip "$6" && isVServer; then - { - echo "auto $1" - echo "iface $1 inet dhcp" - } >> "$CONFIGFILE" - else - { - echo "auto $1" - echo "iface $1 inet static" - echo " address $3" - echo " netmask $5" - echo " gateway $6" - if ! is_private_ip "$3" || ! isVServer; then - echo " # default route to access subnet" - echo " up route add -net $7 netmask $5 gw $6 $1" - fi - } >> "$CONFIGFILE" - fi - fi - - if [ -n "$8" ] && [ -n "$9" ] && [ -n "${10}" ]; then - debug "setting up ipv6 networking $8/$9 via ${10}" - { - echo "" - echo "iface $1 inet6 static" - echo " address $8" - echo " netmask $9" - echo " gateway ${10}" - } >> "$CONFIGFILE" - fi - - # - # set duplex speed - # - if ! isNegotiated && ! isVServer; then - { - echo " # force full-duplex for ports without auto-neg" - echo " post-up mii-tool -F 100baseTx-FD $1" - } >> "$CONFIGFILE" - fi - - return 0 - else - CONFIGFILE="$FOLD/hdd/etc/systemd/network/50-$C_SHORT.network" - - { - echo "### $COMPANY - installimage" - echo "# device: $1" - echo "[Match]" - echo "MACAddress=$2" - echo "" - } > "$CONFIGFILE" - - echo "[Network]" >> "$CONFIGFILE" - if [ -n "$8" ] && [ -n "$9" ] && [ -n "${10}" ]; then - debug "setting up ipv6 networking $8/$9 via ${10}" - { - echo "Address=$8/$9" - echo "Gateway=${10}" - echo "" - } >> "$CONFIGFILE" - fi - - if [ -n "$3" ] && [ -n "$4" ] && [ -n "$5" ] && [ -n "$6" ] && [ -n "$7" ]; then - debug "setting up ipv4 networking $3/$5 via $6" - if is_private_ip "$6" && isVServer; then - { - echo "DHCP=ipv4" - } >> "$CONFIGFILE" - else - { - echo "Address=$3/$CIDR" - echo "Gateway=$6" - echo "" - } >> "$CONFIGFILE" - if ! is_private_ip "$3" || ! isVServer; then - { - echo "[Route]" - echo "Destination=$7/$CIDR" - echo "Gateway=$6" - } >> "$CONFIGFILE" - fi - fi - fi - - execute_chroot_command "systemctl enable systemd-networkd.service" - - return 0 - fi - fi -} - # generate_config_mdadm "NIL" generate_config_mdadm() { local mdadmconf="/etc/mdadm/mdadm.conf" @@ -294,7 +171,7 @@ generate_config_grub() { if [ "$UEFI" -eq 1 ]; then # ubuntu always installs to removable path as well (which is what we want) # unless grub2/no_efi_extra_removable is set to true - execute_chroot_command "echo 'set grub2/update_nvram false' | debconf-communicate" + execute_chroot_command "echo 'set grub2/update_nvram false' | debconf-communicate -f noninteractive" fi # create /run/lock if it didn't exist because it is needed by grub-mkconfig