diff --git a/.vimproject b/.vimproject new file mode 100644 index 0000000..21ab656 --- /dev/null +++ b/.vimproject @@ -0,0 +1,15 @@ +Installimage=~/work/installimage/ CD=~/work/installimage/ filter="*" { + README + autosetup.sh + centos.sh + config.sh + debian.sh + functions.sh + get_options.sh + install.sh + installimage + installimage.in_screen + setup.sh + suse.sh + ubuntu.sh +} diff --git a/README b/README new file mode 100755 index 0000000..2bddd94 --- /dev/null +++ b/README @@ -0,0 +1,5 @@ + +this directory contains +all the scripts for installimage + + diff --git a/arch.sh b/arch.sh new file mode 100755 index 0000000..74356aa --- /dev/null +++ b/arch.sh @@ -0,0 +1,176 @@ +#!/bin/bash + +# +# Archlinux specific functions +# +# originally written by Markus Schade +# (c) 2013-2015, Hetzner Online AG +# + + +# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" +setup_network_config() { + if [ "$1" -a "$2" ]; then + # good we have a device and a MAC + CONFIGFILE="$FOLD/hdd/etc/systemd/network/50-hetzner.network" + UDEVFILE="$FOLD/hdd/etc/udev/rules.d/80-net-setup-link.rules" + + echo -e "### Hetzner Online AG - installimage" > $UDEVFILE + echo -e "# device: $1" >> $UDEVFILE + echo -e "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$2\", ATTR{dev_id}==\"0x0\", ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"$1\"" >> $UDEVFILE + + echo -e "### Hetzner Online AG - installimage" > $CONFIGFILE + echo -e "# device: $1" >> $CONFIGFILE + echo -e "[Match]" >> $CONFIGFILE + echo -e "MACAddress=$2" >> $CONFIGFILE + echo -e "" >> $CONFIGFILE + + echo -e "[Network]" >> $CONFIGFILE + if [ "$8" -a "$9" -a "${10}" ]; then + debug "setting up ipv6 networking $8/$9 via ${10}" + echo -e "Address=$8/$9" >> $CONFIGFILE + echo -e "Gateway=${10}" >> $CONFIGFILE + echo -e "" >> $CONFIGFILE + fi + + if [ "$3" -a "$4" -a "$5" -a "$6" -a "$7" ]; then + debug "setting up ipv4 networking $3/$5 via $6" + echo -e "Address=$3/$CIDR" >> $CONFIGFILE + echo -e "Gateway=$6" >> $CONFIGFILE + echo -e "" >> $CONFIGFILE + + echo -e "[Route]" >> $CONFIGFILE + echo -e "Destination=$7/$CIDR" >> $CONFIGFILE + echo -e "Gateway=$6" >> $CONFIGFILE + fi + + execute_chroot_command "systemctl enable systemd-networkd.service" + + return 0 + fi +} + +# generate_mdadmconf "NIL" +generate_config_mdadm() { + if [ "$1" ]; then + MDADMCONF="/etc/mdadm.conf" + echo "DEVICES /dev/[hs]d*" > $FOLD/hdd$MDADMCONF + echo "MAILADDR root" >> $FOLD/hdd$MDADMCONF + execute_chroot_command "mdadm --examine --scan >> $MDADMCONF"; EXITCODE=$? + return $EXITCODE + fi +} + + +# generate_new_ramdisk "NIL" +generate_new_ramdisk() { + if [ "$1" ]; then + local blacklist_conf="$FOLD/hdd/etc/modprobe.d/blacklist-hetzner.conf" + echo -e "### Hetzner Online AG - installimage" > $blacklist_conf + echo -e "### silence any onboard speaker" >> $blacklist_conf + echo -e "blacklist pcspkr" >> $blacklist_conf + echo -e "blacklist snd_pcsp" >> $blacklist_conf + echo -e "### i915 driver blacklisted due to various bugs" >> $blacklist_conf + echo -e "### especially in combination with nomodeset" >> $blacklist_conf + echo -e "blacklist i915" >> $blacklist_conf + echo -e "### mei driver blacklisted due to serious bugs" >> $blacklist_conf + echo -e "blacklist mei" >> $blacklist_conf + echo -e "blacklist mei-me" >> $blacklist_conf + + execute_chroot_command 'sed -i /etc/mkinitcpio.conf -e "s/^HOOKS=.*/HOOKS=\"base udev autodetect modconf block mdadm lvm2 filesystems keyboard fsck\"/"' + execute_chroot_command "mkinitcpio -p linux"; EXITCODE=$? + + return $EXITCODE + fi +} + +setup_cpufreq() { + if [ "$1" ]; then + if ! isVServer; then + CPUFREQCONF="$FOLD/hdd/etc/default/cpupower" + sed -i -e "s/#governor=.*/governor'$1'/" $CPUFREQCONF + execute_chroot_command "systemctl enable cpupower" + fi + + return 0 + fi +} + +# +# generate_config_grub +# +# Generate the GRUB bootloader configuration. +# +generate_config_grub() { + EXITCODE=0 + execute_chroot_command "rm -rf /boot/grub; mkdir -p /boot/grub/ >> /dev/null 2>&1" + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"nomodeset\"/"' + execute_chroot_command 'sed -i /etc/default/grub -e "s/^#GRUB_TERMINAL_OUTPUT=.*/GRUB_TERMINAL_OUTPUT=console/"' + + execute_chroot_command "grub-mkconfig -o /boot/grub/grub.cfg 2>&1" + + execute_chroot_command "grub-install --no-floppy --recheck $DRIVE1 2>&1"; EXITCODE=$? + + # only install grub2 in mbr of all other drives if we use swraid + if [ "$SWRAID" = "1" ] ; then + local i=2 + while [ `eval echo \\$DRIVE${i}` ]; do + local TARGETDRIVE=`eval echo \\$DRIVE${i}` + execute_chroot_command "grub-install --no-floppy --recheck $TARGETDRIVE 2>&1" + let i=i+1 + done + fi + uuid_bugfix + + return $EXITCODE +} + + +# +# os specific functions +# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP +# +run_os_specific_functions() { + + execute_chroot_command "pacman-key --init" + execute_chroot_command "pacman-key --populate archlinux" + execute_chroot_command "systemctl enable sshd" + execute_chroot_command "systemctl enable haveged" + execute_chroot_command "systemctl enable cronie" + + return 0 +} + +# validate image with detached signature +validate_image() { + # no detached sign found + return 2 +} + +# extract image file to hdd +extract_image() { + LANG=C pacstrap -m -a $FOLD/hdd base btrfs-progs cpupower cronie findutils gptfdisk grub haveged ntp openssh vim wget 2>&1 | debugoutput + + if [ "$EXITCODE" -eq "0" ]; then + cp -r "$FOLD/fstab" "$FOLD/hdd/etc/fstab" 2>&1 | debugoutput + + #timezone - we are in Germany + execute_chroot_command "ln -s /usr/share/timezone/Europe/Berlin /etc/localtime" + echo en_US.UTF-8 UTF-8 > $FOLD/hdd/etc/locale.gen + echo de_DE.UTF-8 UTF-8 >> $FOLD/hdd/etc/locale.gen + execute_chroot_command "locale-gen" + + echo > $FOLD/hdd/etc/locale.conf + echo "LANG=de_DE.UTF-8" >> $FOLD/hdd/etc/locale.conf + echo "LC_MESSAGES=C" >> $FOLD/hdd/etc/locale.conf + + echo > $FOLD/hdd/etc/vconsole.conf + echo "KEYMAP=de" >> $FOLD/hdd/etc/vconsole.conf + echo "FONT=LatArCyrHeb-16" >> $FOLD/hdd/etc/vconsole.conf + + + return 0 + else + return 1 + fi +} diff --git a/autosetup.sh b/autosetup.sh new file mode 100644 index 0000000..acb205f --- /dev/null +++ b/autosetup.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# +# skip menu - use "autosetup" file +# +# originally written by Florian Wicke and David Mayr +# (c) 2008-2015, Hetzner Online AG +# + + +# read global variables and functions +. /tmp/install.vars + + +# check if the script is temporary disabled due some maintenance or something +debug "# checking if the script is disabled" +if [ -f $DISABLEDFILE ]; then + debug "=> script is DISABLED" + echo_red "Due to maintenance the installimage-script is temporarily unavailable.\nWe are sorry for the inconvenience." + exit 1 +fi + + +# display information about autosetup +echo -e "\n\033[01;32mFound AUTOSETUP file '$AUTOSETUPCONFIG'\033[00m" +echo -e "\033[01;33mRunning unattended installimage installation ...\033[00m\n" +cat $FOLD/install.conf | grep -v "^#" | grep -v "^$" +echo -e "\n" + + +# validate config +VALIDATED="false" +CANCELLED="false" +while [ "$VALIDATED" = "false" ]; do + debug "# validating config ..." + validate_vars "$FOLD/install.conf"; EXITCODE=$? + if [ "$CANCELLED" = "true" ]; then + echo "Cancelled." + exit 1 + fi + if [ $EXITCODE = 0 ]; then + VALIDATED="true" + else + debug "=> FAILED" + mcedit $FOLD/install.conf + fi +done + + +# if we are using the config file option "-c" and not using the automatic mode, +# ask for confirmation before continuing ... +if [ "$OPT_CONFIGFILE" -a -z "$OPT_AUTOMODE" ] ; then + echo -en "\n${RED}ALL DATA ON THE GIVEN DISKS WILL BE DESTROYED!\n" + echo -en "${YELLOW}DO YOU REALLY WANT TO CONTINUE?${NOCOL} [y|N] " + read -n1 aw + case "$aw" in + y|Y|j|J) echo -e "\n\n" ;; + *) echo -e "\n\n${GREEN}ABORT${NOCOL}\n" ; exit 0 ;; + esac +fi + + +# execute installfile +echo -e "\033[01;31mWARNING:" +echo -e "\033[01;33m Starting installation in 20 seconds ..." +echo -e "\033[01;33m Press X to continue immediately ...\033[00m" +echo -e "\033[01;31m Installation will DELETE ALL DATA ON DISK(s)!" +echo -e "\033[01;33m Press CTRL-C to abort now!\033[00m" +echo -n " => " +for i in $(seq 1 20) ; do + echo -n "." + read -t1 -n1 anykey + if [ "$anykey" = "x" -o "$anykey" = "X" ] ; then break ; fi +done +echo +# +debug "# executing installfile ..." +if [ -f $INSTALLFILE -a "$VALIDATED" = "true" ] ; then + . $INSTALLFILE ; EXITCODE=$? +else + debug "=> FAILED" + echo -e "\n\033[01;31mERROR: Cant find files\033[00m" +fi + + +# abort on error +if [ "$EXITCODE" = "1" ]; then + exit 1 +fi + diff --git a/centos.sh b/centos.sh new file mode 100644 index 0000000..52b6eeb --- /dev/null +++ b/centos.sh @@ -0,0 +1,405 @@ +#!/bin/bash +# +# CentOS specific functions +# +# originally written by Florian Wicke and David Mayr +# (c) 2008-2015, Hetzner Online AG + + + +# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" +setup_network_config() { + if [ "$1" -a "$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 -e "### Hetzner Online AG - installimage" > $UDEVFILE + echo -e "# device: $1" >> $UDEVFILE + echo -e "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$2\", KERNEL==\"eth*\", NAME=\"$1\"" >> $UDEVFILE + + local upper_mac="$(echo "$2" | awk '{ print toupper($0) }')" + + NETWORKFILE="$FOLD/hdd/etc/sysconfig/network" + echo -e "### Hetzner Online AG - installimage" > $NETWORKFILE 2>>$DEBUGFILE + echo -e "# general networking" >> $NETWORKFILE 2>>$DEBUGFILE + echo -e "NETWORKING=yes" >> $NETWORKFILE 2>>$DEBUGFILE + + CONFIGFILE="$FOLD/hdd/etc/sysconfig/network-scripts/ifcfg-$1" + ROUTEFILE="$FOLD/hdd/etc/sysconfig/network-scripts/route-$1" + + echo -e "### Hetzner Online AG - installimage" > $CONFIGFILE 2>>$DEBUGFILE + echo -e "#" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "# Note for customers who want to create bridged networking for virtualisation:" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "# Gateway is set in separate file" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "# Do not forget to change interface in file route-$1 and rename this file" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "#" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "# device: $1" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "DEVICE=$1" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "BOOTPROTO=none" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "ONBOOT=yes" >> $CONFIGFILE 2>>$DEBUGFILE + + if [ "$3" -a "$4" -a "$5" -a "$6" -a "$7" ]; then + echo -e "HWADDR=$upper_mac" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "IPADDR=$3" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "NETMASK=255.255.255.255" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "SCOPE=\"peer $6\"" >> $CONFIGFILE 2>>$DEBUGFILE + + echo -e "### Hetzner Online AG - installimage" > $ROUTEFILE 2>>$DEBUGFILE + echo -e "# routing for eth0" >> $ROUTEFILE 2>>$DEBUGFILE + echo -e "ADDRESS0=0.0.0.0" >> $ROUTEFILE 2>>$DEBUGFILE + echo -e "NETMASK0=0.0.0.0" >> $ROUTEFILE 2>>$DEBUGFILE + echo -e "GATEWAY0=$6" >> $ROUTEFILE 2>>$DEBUGFILE + fi + + if [ "$8" -a "$9" -a "${10}" ]; then + debug "setting up ipv6 networking $8/$9 via ${10}" + echo -e "NETWORKING_IPV6=yes" >> $NETWORKFILE 2>>$DEBUGFILE + echo -e "IPV6INIT=yes" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "IPV6ADDR=$8/$9" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "IPV6_DEFAULTGW=${10}" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "IPV6_DEFAULTDEV=$1" >> $CONFIGFILE 2>>$DEBUGFILE + fi + + # set duplex/speed + if ! isNegotiated && ! isVServer; then + echo -e "ETHTOOL_OPTS=\"speed 100 duplex full autoneg off\"" >> $CONFIGFILE 2>>$DEBUGFILE + fi + + # remove all hardware info from image (CentOS 5) + if [ -f $FOLD/hdd/etc/sysconfig/hwconf ]; then + echo -e "" > $FOLD/hdd/etc/sysconfig/hwconf + fi + + return 0 + fi +} + +# generate_mdadmconf "NIL" +generate_config_mdadm() { + if [ "$1" ]; then + MDADMCONF="/etc/mdadm.conf" + echo "DEVICES /dev/[hs]d*" > $FOLD/hdd$MDADMCONF + echo "MAILADDR root" >> $FOLD/hdd$MDADMCONF + execute_chroot_command "mdadm --examine --scan >> $MDADMCONF"; EXITCODE=$? + return $EXITCODE + fi +} + +# generate_new_ramdisk "NIL" +generate_new_ramdisk() { + if [ "$1" ]; then + + # pick the latest kernel + VERSION="$(ls -r -1 $FOLD/hdd/boot/vmlinuz-* | head -n1 |cut -d '-' -f 2-)" + + if [ $IMG_VERSION -lt 60 ] ; then + 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 -e "### Hetzner Online AG - installimage" > $MODULESFILE 2>>$DEBUGFILE + echo -e "# load all modules" >> $MODULESFILE 2>>$DEBUGFILE + echo -e "" >> $MODULESFILE 2>>$DEBUGFILE + + echo -e "# hdds" >> $MODULESFILE 2>>$DEBUGFILE + HDDDEV="" + for hddmodule in $MODULES; do + if [ "$hddmodule" != "powernow-k8" -a "$hddmodule" != "via82cxxx" -a "$hddmodule" != "atiixp" ]; then + echo -e "alias scsi_hostadapter$HDDDEV $hddmodule" >> $MODULESFILE 2>>$DEBUGFILE + [ -z "$HDDDEV" ] && HDDDEV="1" || HDDDEV="$(echo $[$HDDDEV+1])" + fi + done + echo -e "" >> $MODULESFILE 2>>$DEBUGFILE + 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-hetzner.conf" + echo -e "### Hetzner Online AG - installimage" > $blacklist_conf + echo -e "### silence any onboard speaker" >> $blacklist_conf + echo -e "blacklist pcspkr" >> $blacklist_conf + echo -e "### i915 driver blacklisted due to various bugs" >> $blacklist_conf + echo -e "### especially in combination with nomodeset" >> $blacklist_conf + echo -e "blacklist i915" >> $blacklist_conf + fi + + if [ $IMG_VERSION -ge 70 ] ; then + DRACUTFILE="$FOLD/hdd/etc/dracut.conf.d/hetzner.conf" + echo "add_dracutmodules+=\"mdraid lvm\"" >> $DRACUTFILE + echo "add_drivers+=\"raid1 raid10 raid0 raid456\"" >> $DRACUTFILE + echo "mdadmconf=\"yes\"" >> $DRACUTFILE + echo "lvmconf=\"yes\"" >> $DRACUTFILE + echo "hostonly=\"no\"" >> $DRACUTFILE + echo "early_microcode=\"no\"" >> $DRACUTFILE + fi + + if [ $IMG_VERSION -ge 70 ] ; then + execute_chroot_command "/sbin/dracut -f --kver $VERSION"; EXITCODE=$? + else + if [ $IMG_VERSION -ge 60 ] ; then + execute_chroot_command "/sbin/new-kernel-pkg --mkinitrd --dracut --depmod --install $VERSION"; EXITCODE=$? + else + execute_chroot_command "/sbin/new-kernel-pkg --package kernel --mkinitrd --depmod --install $VERSION"; EXITCODE=$? + fi + fi + return $? + fi +} + + +setup_cpufreq() { + if [ "$1" ]; then + if isVServer; then + return 0 + fi + #https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/sec-Persistent_Module_Loading.html + CPUFREQCONF="$FOLD/hdd/etc/sysconfig/modules/cpufreq.modules" + echo -e "" > $CPUFREQCONF 2>>$DEBUGFILE + echo -e "#!/bin/sh" > $CPUFREQCONF 2>>$DEBUGFILE + echo -e "### Hetzner Online AG - installimage" >> $CPUFREQCONF 2>>$DEBUGFILE + echo -e "# cpu frequency scaling" >> $CPUFREQCONF 2>>$DEBUGFILE + echo -e "# this gets started by /etc/rc.sysinit" >> $CPUFREQCONF 2>>$DEBUGFILE + if [ "$(check_cpu)" = "intel" ]; then + debug "# Setting: cpufreq modprobe to intel" + echo -e "modprobe acpi-cpufreq >> /dev/null 2>&1" >> $CPUFREQCONF 2>>$DEBUGFILE + else + debug "# Setting: cpufreq modprobe to amd" + echo -e "modprobe powernow-k8 >> /dev/null 2>&1" >> $CPUFREQCONF 2>>$DEBUGFILE + fi + echo -e "cpufreq-set -g $1 -r >> /dev/null 2>&1" >> $CPUFREQCONF 2>>$DEBUGFILE + chmod a+x $CPUFREQCONF >>$DEBUGFILE + + return 0 + fi +} + +# +# generate_config_grub +# +# Generate the GRUB bootloader configuration. +# +generate_config_grub() { + [ "$1" ] || return + # we should not need to do anything, as grubby (new-kernel-pkg) should have + # already generated a grub.conf + if [ $IMG_VERSION -lt 70 ] ; 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 + [ -f $DMAPFILE ] && rm $DMAPFILE + + local i=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + local j="$[$i-1]" + local disk="$(eval echo "\$DRIVE"$i)" + echo "(hd$j) $disk" >> $DMAPFILE + done + cat $DMAPFILE >> $DEBUGFILE + + local elevator='' + if isVServer; then + elevator='elevator=noop' + fi + + if [ $IMG_VERSION -lt 70 ] ; then + 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=$? + + BFILE="$FOLD/hdd/boot/grub/grub.conf" + + rm -rf "$FOLD/hdd/boot/grub/*" >> /dev/null 2>&1 + + echo "#" > $BFILE 2>> $DEBUGFILE + echo "# Hetzner Online AG - installimage" >> $BFILE 2>> $DEBUGFILE + echo "# GRUB bootloader configuration file" >> $BFILE 2>> $DEBUGFILE + echo "#" >> $BFILE 2>> $DEBUGFILE + echo >> $BFILE 2>> $DEBUGFILE + + PARTNUM=`echo "$SYSTEMBOOTDEVICE" | rev | cut -c1` + + if [ "$SWRAID" = "0" ]; then + PARTNUM="$[$PARTNUM - 1]" + fi + + echo "timeout 5" >> $BFILE 2>> $DEBUGFILE + echo "default 0" >> $BFILE 2>> $DEBUGFILE + echo >> $BFILE 2>> $DEBUGFILE + echo "title CentOS ($1)" >> $BFILE 2>> $DEBUGFILE + echo "root (hd0,$PARTNUM)" >> $BFILE 2>> $DEBUGFILE + # 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 '8086:10d3')" ] && ASPM='pcie_aspm=off' || ASPM='' + + if [ $IMG_VERSION -ge 60 ]; then + echo "kernel /boot/vmlinuz-$1 ro root=$SYSTEMROOTDEVICE rd_NO_LUKS rd_NO_DM nomodeset $elevator $ASPM" >> $BFILE 2>> $DEBUGFILE + else + echo "kernel /boot/vmlinuz-$1 ro root=$SYSTEMROOTDEVICE nomodeset" >> $BFILE 2>> $DEBUGFILE + 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 [ $INITRD ]; then + echo "initrd /boot/$INITRD-$1.img" >> $BFILE 2>> $DEBUGFILE + fi + + echo >> $BFILE 2>> $DEBUGFILE + + uuid_bugfix + # TODO: let grubby add its own stuff (SYSFONT, LANG, KEYTABLE) +# if [ $IMG_VERSION -lt 60 ] ; then +# execute_chroot_command "/sbin/new-kernel-pkg --package kernel --install $VERSION"; EXITCODE=$? +# else +# execute_chroot_command "/sbin/new-kernel-pkg --install $VERSION"; EXITCODE=$? +# fi + else + if isVServer; then + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"nomodeset rd.auto=1 crashkernel=auto elevator=noop\"/"' + else + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\"nomodeset rd.auto=1 crashkernel=auto\"/"' + fi + + [ -e $FOLD/hdd/boot/grub2/grub.cfg ] && rm "$FOLD/hdd/boot/grub2/grub.cfg" + execute_chroot_command "grub2-mkconfig -o /boot/grub2/grub.cfg 2>&1"; EXITCODE=$? + + fi + return $EXITCODE +} + +write_grub() { + if [ $IMG_VERSION -ge 70 ] ; then + # only install grub2 in mbr of all other drives if we use swraid + local i=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + if [ $SWRAID -eq 1 -o $i -eq 1 ] ; then + local disk="$(eval echo "\$DRIVE"$i)" + execute_chroot_command "grub2-install --no-floppy --recheck $disk 2>&1" EXITCODE=$? + fi + done + else + local i=0 + + for i in $(seq 1 $COUNT_DRIVES) ; do + if [ $SWRAID -eq 1 -o $i -eq 1 ] ; then + local 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" + fi + done + fi + + return $? +} + +disabled_set_hostname() { + local SETHOSTNAME="$1" + + hostname $SETHOSTNAME + execute_chroot_command "hostname $SETHOSTNAME" + + if [ -z "$SETHOSTNAME" ]; then + SETHOSTNAME="$IMAGENAME" + fi + if [ "$IMG_VERSION" -ge 70 ] ; then + HOSTNAMEFILE="$FOLD/hdd/etc/hostname" + echo "$SETHOSTNAME" > $HOSTNAMEFILE + debug "# set new hostname '$SETHOSTNAME' in $HOSTNAMEFILE" + # remove machine-id from install (will be regen upon first boot) + echo > $FOLD/hdd/etc/machine-id + else + NETWORKFILE="$FOLD/hdd/etc/sysconfig/network" + echo -e "HOSTNAME=$SETHOSTNAME" >> $NETWORKFILE 2>>$DEBUGFILE + fi + +} + +# +# os specific functions +# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP +# +run_os_specific_functions() { + + execute_chroot_command "chkconfig iptables off" + + # + # setup env in cpanel image + # + debug "# Testing and setup of cpanel image" + if [ -f "$FOLD/hdd/etc/wwwacct.conf" ] && [ -f "$FOLD/hdd/etc/cpupdate.conf" ] ; then + echo $IMAGENAME | grep -q -i cpanel && ( setup_cpanel || return 1 ) + fi + + # selinux autorelabel if enabled + if [ "$(egrep "SELINUX=enforcing" $FOLD/hdd/etc/sysconfig/selinux)" ] ; then + touch $FOLD/hdd/.autorelabel + fi + + return 0 + +} + +setup_cpanel() { + randomize_cpanel_mysql_passwords + change_mainIP + modify_wwwacct +} + +# +# randomize mysql passwords in cpanel image +# +randomize_cpanel_mysql_passwords() { + CPHULKDCONF="$FOLD/hdd/var/cpanel/hulkd/password" + CPHULKDPASS=$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c16) + ROOTPASS=$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c8) + MYSQLCOMMAND="UPDATE mysql.user SET password=PASSWORD(\""$CPHULKDPASS"\") WHERE user='cphulkd'; \ + UPDATE mysql.user SET password=PASSWORD(\""$ROOTPASS"\") WHERE user='root';\nFLUSH PRIVILEGES;" + echo -e "$MYSQLCOMMAND" > "$FOLD/hdd/tmp/pwchange.sql" + debug "changing mysql passwords" + execute_chroot_command "service mysql start --skip-grant-tables --skip-networking >/dev/null 2>&1"; EXITCODE=$? + execute_chroot_command "mysql < /tmp/pwchange.sql >/dev/null 2>&1"; EXITCODE=$? + execute_chroot_command "service mysql stop >/dev/null 2>&1" + cp "$CPHULKDCONF" "$CPHULKDCONF.old" + sed s/pass.*/"pass=\"$CPHULKDPASS\""/g "$CPHULKDCONF.old" > "$CPHULKDCONF" + rm "$FOLD/hdd/tmp/pwchange.sql" + rm "$CPHULKDCONF.old" + + # write password file + echo -e "[client]\nuser=root\npass=$ROOTPASS" > $FOLD/hdd/root/.my.cnf + + return $EXITCODE +} + +# +# set the content of /var/cpanel/mainip correct +# +change_mainIP() { + MAINIPFILE="/var/cpanel/mainip" + debug "changing content of ${MAINIPFILE}" + execute_chroot_command "echo -n ${IPADDR} > $MAINIPFILE" +} + +# +# set the correct hostname, IP and nameserver in /etc/wwwacct.conf +# +modify_wwwacct() { + WWWACCT="/etc/wwwacct.conf" + NS="ns1.first-ns.de" + NS2="robotns2.second-ns.de" + NS3="robotns3.second-ns.com" + + debug "setting hostname in ${WWWACCT}" + execute_chroot_command "echo \"HOST ${SETHOSTNAME}\" >> $WWWACCT" + debug "setting IP in ${WWWACCT}" + execute_chroot_command "echo \"ADDR ${IPADDR}\" >> $WWWACCT" + debug "setting NS in ${WWWACCT}" + execute_chroot_command "echo \"NS ${NS}\" >> $WWWACCT" + execute_chroot_command "echo \"NS2 ${NS2}\" >> $WWWACCT" + execute_chroot_command "echo \"NS3 ${NS3}\" >> $WWWACCT" +} diff --git a/config.sh b/config.sh new file mode 100755 index 0000000..51cf774 --- /dev/null +++ b/config.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# +# set all necessary vars and functions +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + +DEBUGFILE=/root/debug.txt + + +# set up standard env +SCRIPTPATH=`dirname $0` +DISABLEDFILE=$SCRIPTPATH"/disabled" +SETUPFILE=$SCRIPTPATH"/setup.sh" +AUTOSETUPFILE=$SCRIPTPATH"/autosetup.sh" +AUTOSETUPCONFIG="/autosetup" +INSTALLFILE=$SCRIPTPATH"/install.sh" +FUNCTIONSFILE=$SCRIPTPATH"/functions.sh" +GETOPTIONSFILE=$SCRIPTPATH"/get_options.sh" +STANDARDCONFIG=$SCRIPTPATH"/standard.conf" +CONFIGSPATH=$SCRIPTPATH"/configs" +POSTINSTALLPATH=$SCRIPTPATH"/post-install" +IMAGESPATH=$SCRIPTPATH"/../images/" +OLDIMAGESPATH=$SCRIPTPATH"/../images.old/" +IMAGESPATHTYPE="local" +IMAGESEXT="tar.gz" +IMAGEFILETYPE="tgz" +HETZNER_PUBKEY=$SCRIPTPATH"/gpg/public-key.asc" + +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" +STATSSERVER="rz-admin.hetzner.de" +#STATSSERVER="192.168.100.1" +CURL_OPTIONS="-q -s -S --ftp-create-dirs" +HDDMINSIZE="70000000" + +NAMESERVER=("213.133.98.98" "213.133.99.99" "213.133.100.100") +DNSRESOLVER_V6=("2a01:4f8:0:a111::add:9898" "2a01:4f8:0:a102::add:9999" "2a01:4f8:0:a0a1::add:1010") + +DEFAULTPARTS="PART swap swap SWAPSIZE##G\nPART /boot ext3 512M\nPART / ext4 all" +DEFAULTPARTS_BIG="PART swap swap SWAPSIZE##G\nPART /boot ext3 512M\nPART / ext4 1024G\nPART /home ext4 all" +DEFAULTPARTS_LARGE="PART swap swap SWAPSIZE##G\nPART /boot ext3 512M\nPART / ext4 2015G\nPART /home ext4 all" +DEFAULTPARTS_VSERVER="PART / ext3 all" +DEFAULTSWRAID="1" +DEFAULTTWODRIVESWRAIDLEVEL="1" +DEFAULTTHREEDRIVESWRAIDLEVEL="5" +DEFAULTFOURDRIVESWRAIDLEVEL="6" +DEFAULTLVM="0" +DEFAULTLOADER="grub" +DEFAULTGOVERNOR="ondemand" + +V6ONLY="0" + +# dialog settings +DIATITLE='Hetzner Online AG' +OSMENULIST='Debian (official) ' +OSMENULIST=$OSMENULIST'Ubuntu (official) ' +OSMENULIST=$OSMENULIST'CentOS (official) ' +OSMENULIST=$OSMENULIST'openSUSE (official) ' +OSMENULIST=$OSMENULIST'Archlinux (!!NO_SUPPORT!!) ' +OSMENULIST=$OSMENULIST'Virtualization (!!NO_SUPPORT!!) ' +OSMENULIST=$OSMENULIST'old_images (!!NO_SUPPORT!!) ' +OSMENULIST=$OSMENULIST'custom_image (blanco_config_for_user_images) ' + +PROXMOX3_BASE_IMAGE="Debian-78-wheezy-64-minimal" + +RED="\033[1;31m" +GREEN="\033[1;32m" +YELLOW="\033[1;33m" +BLUE="\033[0;34m" +MANGENTA="\033[0;35m" +CYAN="\033[1;36m" +GREY="\033[0;37m" +WHITE="\033[1;39m" +NOCOL="\033[00m" + +# write log entries in debugfile - single line as second argument +debug() { + line="$@" + echo -e "[$(date '+%H:%M:%S')] $line" >> $DEBUGFILE; +} + + +# write log entries in debugfile - multiple lines at once +debugoutput() { + while read line ; do + echo -e "[$(date '+%H:%M:%S')] : $line" >> $DEBUGFILE; + done +} + +. $FUNCTIONSFILE + diff --git a/configs/hsa-baculadir b/configs/hsa-baculadir new file mode 100644 index 0000000..6db4a90 --- /dev/null +++ b/configs/hsa-baculadir @@ -0,0 +1,37 @@ +# set the HOSTNAME like this: +# HOSTNAME wwwXXX.cpt1.host-h.net +HOSTNAME + +### SA IMAGE: +### IMAGE ftp://managedbuilds:PASSWD@bootserver/masterbuild64wheezy.jnb1.host-h.net.tar.gz + +### DE IMAGE: +### IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild64.flk1.host-h.net.tar.gz +IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild64wheezy.jnb1.host-h.net.tar.gz + + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb +DRIVE3 /dev/sdc +DRIVE4 /dev/sdd +DRIVE5 /dev/sde +DRIVE6 /dev/sdf + +FORMAT_DRIVE2 1 +FORMAT_DRIVE3 1 +FORMAT_DRIVE4 1 +FORMAT_DRIVE5 1 +FORMAT_DRIVE6 1 + +SWRAID 1 +SWRAIDLEVEL 5 + +BOOTLOADER grub + +PART /boot ext3 256 +PART lvm vg all + +LV vg root / ext4 20G +LV vg swap swap swap 4G +LV vg postgres /var/lib/postgresql ext4 650G +LV vg cache /var/glusterfs_local ext4 229G diff --git a/configs/hsa-managed b/configs/hsa-managed new file mode 100644 index 0000000..4bd5913 --- /dev/null +++ b/configs/hsa-managed @@ -0,0 +1,41 @@ + +# set the HOSTNAME like this: +# HOSTNAME wwwXXX.flk1.host-h.net +#HOSTNAME + +### SA IMAGE: +#### IMAGE ftp://managedbuilds:PASSWD@bootserver/masterbuild.jnb2.host-h.net.tar.gz + +### DE IMAGE: +IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild.nur4.host-h.net.tar.gz + + + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb + +FORMAT_DRIVE2 0 + +SWRAID 1 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +# special param to avoid partition alignment +# disabled since 2012.10.26 +#NO_PART_ALIGN 1 + +# special param to force using grub2 even in debian <= 5.0 +### FORCE_GRUB2_IN_DEBIAN 1 + +PART /boot ext3 256 +PART lvm vg all + +LV vg root / ext4 5G +LV vg swap swap swap 4G +LV vg tmp /tmp ext4 5G +LV vg usr /usr ext4 100G +LV vg usrhome /usr/home ext4 100G +LV vg var /var ext4 10G +LV vg vartmp /var/tmp ext4 6G + diff --git a/configs/hsa-minimal64 b/configs/hsa-minimal64 new file mode 100644 index 0000000..c4972c9 --- /dev/null +++ b/configs/hsa-minimal64 @@ -0,0 +1,26 @@ +# set the HOSTNAME like this: +# HOSTNAME wwwXXX.cpt1.host-h.net +HOSTNAME + +### SA IMAGE: +### IMAGE ftp://managedbuilds:PASSWD@bootserver/masterbuild64wheezy.jnb1.host-h.net.tar.gz + +### DE IMAGE: +### IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild64.flk1.host-h.net.tar.gz +IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild64wheezy.jnb1.host-h.net.tar.gz + + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb + + +SWRAID 1 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +PART /boot ext3 256 +PART lvm vg all + +LV vg root / ext4 15G +LV vg swap swap swap 4G diff --git a/configs/hsa-sql b/configs/hsa-sql new file mode 100644 index 0000000..dc74268 --- /dev/null +++ b/configs/hsa-sql @@ -0,0 +1,30 @@ +# set the HOSTNAME like this: +# HOSTNAME wwwXXX.cpt1.host-h.net +HOSTNAME + +### SA IMAGE: +#IMAGE ftp://managedbuilds:PASSWD@bootserver/masterbuild64wheezy.jnb1.host-h.net.tar.gz + +### DE IMAGE: +### IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild64.flk1.host-h.net.tar.gz +IMAGE ftp://demaster:PASSWD@imagemaster.nur4.host-h.net/masterbuild64wheezy.jnb1.host-h.net.tar.gz + + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb + +SWRAID 1 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +PART /boot ext3 256 +PART lvm vg all + +LV vg root / ext4 15G +LV vg swap swap swap 4G +LV vg tmp /tmp ext4 5G +LV vg usr /usr ext4 60G +LV vg var /var ext4 60G +LV vg vartmp /var/tmp ext4 6G + diff --git a/configs/proxmox b/configs/proxmox new file mode 100644 index 0000000..d30f53c --- /dev/null +++ b/configs/proxmox @@ -0,0 +1,22 @@ + +## =================================================== +## Hetzner Online AG - installimage - Proxmox-VE +## =================================================== + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb + +SWRAID 1 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +HOSTNAME Proxmox-VE.localdomain + +PART /boot ext3 512M +PART lvm vg0 all +LV vg0 root / ext3 15G +LV vg0 swap swap swap 6G + +IMAGE /root/images/Debian-78-wheezy-64-minimal.tar.gz + diff --git a/configs/simple-debian64-noraid b/configs/simple-debian64-noraid new file mode 100644 index 0000000..32f4b95 --- /dev/null +++ b/configs/simple-debian64-noraid @@ -0,0 +1,18 @@ + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb +FORMATDRIVE2 0 + +SWRAID 0 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +HOSTNAME Debian-78-wheezy-64-minimal + +PART swap swap 8G +PART /boot ext3 512M +PART / ext4 all + +IMAGE /root/images/Debian-78-wheezy-64-minimal.tar.gz + diff --git a/configs/simple-debian64-raid b/configs/simple-debian64-raid new file mode 100644 index 0000000..246fa03 --- /dev/null +++ b/configs/simple-debian64-raid @@ -0,0 +1,16 @@ + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb + +SWRAID 1 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +HOSTNAME Debian-78-wheezy-64-minimal + +PART swap swap 2G +PART / ext4 all + +IMAGE /root/images/Debian-78-wheezy-64-minimal.tar.gz + diff --git a/configs/simple-debian64-raid-lvm b/configs/simple-debian64-raid-lvm new file mode 100644 index 0000000..7172443 --- /dev/null +++ b/configs/simple-debian64-raid-lvm @@ -0,0 +1,19 @@ + +DRIVE1 /dev/sda +DRIVE2 /dev/sdb + +SWRAID 1 +SWRAIDLEVEL 1 + +BOOTLOADER grub + +HOSTNAME Debian-78-wheezy-64-minimal + +PART /boot ext2 512M +PART lvm vg0 all + +LV vg0 root / ext4 20G +LV vg0 swap swap swap 4G + +IMAGE /root/images/Debian-78-wheezy-64-minimal.tar.gz + diff --git a/configs/standard b/configs/standard new file mode 120000 index 0000000..fb3d5cd --- /dev/null +++ b/configs/standard @@ -0,0 +1 @@ +simple-debian64-raid \ No newline at end of file diff --git a/coreos.sh b/coreos.sh new file mode 100755 index 0000000..4b96917 --- /dev/null +++ b/coreos.sh @@ -0,0 +1,356 @@ +#!/bin/bash + +# +# CoreOS specific functions +# +# originally written by Markus Schade +# (c) 2014-2015, Hetzner Online AG +# + +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 [ "$1" -a "$2" ]; then + case "$2" in + bin) + COMPRESSION="" + ;; + bgz) + COMPRESSION="gzip" + ;; + bbz) + COMPRESSION="bzip2" + ;; + bxz) + COMPRESSION="xz" + ;; + *)return 1;; + esac + + # extract image with given compression + $COMPRESSION -d --stdout $EXTRACTFROM > ${DRIVE1}; EXITCODE=$? + + if [ "$EXITCODE" -eq "0" ]; then + echo "sucess " | debugoutput + # 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_mdadmconf "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 -e "write_files:" >>$CLOUDINIT + echo -e " - path: /etc/ntp.conf\n content: |" >>$CLOUDINIT + echo -e " # hetzner ntp servers \n server ntp1.hetzner.de iburst\n server ntp2.hetzner.com iburst\n server ntp3.hetzner.net iburst" >>$CLOUDINIT | debugoutput + echo -e " # - Allow only time queries, at a limited rate.\n # - Allow all local queries (IPv4, IPv6)\n restrict default nomodify nopeer noquery limited kod\n restrict 127.0.0.1\n restrict [::1]" >>$CLOUDINIT + return 0 + else + return 1 + fi +} + +set_hostname() { + if [ -f "$CLOUDINIT" ]; then + echo -e "hostname: $1\n" >>$CLOUDINIT + return 0 + else + return 1 + fi +} + +setup_cpufreq() { + return 0 +} + +generate_resolvconf() { + echo -e "write_files:" >> $CLOUDINIT + echo -e " - path: /etc/resolv.conf\n permissions: 0644\n owner: root\n content: |" >> $CLOUDINIT + + # 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]}" >> $CLOUDINIT + 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]}" >> $CLOUDINIT + done + fi + return 0 +} + +generate_hosts() { + return 0 +} + +generate_sysctlconf() { + return 0 +} + +set_rootpassword() { + if [ "$1" -a "$2" ]; then + if [ "$2" != '*' ]; then + echo -e "users:" >> $CLOUDINIT + echo -e " - name: core" >> $CLOUDINIT + echo -e " passwd: $2" >> $CLOUDINIT + echo -e " - name: root" >> $CLOUDINIT + echo -e " passwd: $2" >> $CLOUDINIT + fi + return 0 + else + return 1 + fi +} + +# set sshd PermitRootLogin +set_ssh_rootlogin() { + if [ "$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() { + if [ "$1" ]; then + local key_url="$1" + echo -e "ssh_authorized_keys:" >> $CLOUDINIT + case $key_url in + https:*|http:*|ftp:*) + wget $key_url -O "$FOLD/authorized_keys" + while read line; do + echo -e " - $line" >> $CLOUDINIT + done < "$FOLD/authorized_keys" + ;; + *) + while read line; do + echo -e " - $line" >> $CLOUDINIT + done < $key_url + ;; + esac + else + return 1 + fi +} + + +# generate_config_grub +generate_config_grub() { + return 0 +} + +write_grub() { + return 0 +} + +add_coreos_oem_scripts() { + if [ "$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 [ "$1" ]; then + local mntpath=$1 + local cloudconfig="$mntpath/cloud-config.yml" + echo -e "#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=$(blkid -t "LABEL=ROOT" -o device "${DRIVE1}"*) + local OEM_DEV=$(blkid -t "LABEL=OEM" -o device "${DRIVE1}"*) + local 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" + cat $CLOUDINIT | debugoutput + cp "${CLOUDINIT}" "$FOLD/hdd/var/lib/coreos-install/user_data" + + return 0 +} + diff --git a/debian.sh b/debian.sh new file mode 100755 index 0000000..341696c --- /dev/null +++ b/debian.sh @@ -0,0 +1,266 @@ +#!/bin/bash + +# +# Debian specific functions +# +# originally written by Florian Wicke and David Mayr +# (c) 2008-2015, Hetzner Online AG +# + + +# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" +setup_network_config() { + if [ "$1" -a "$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 -e "### Hetzner Online AG - installimage" > $UDEVFILE + echo -e "# device: $1" >> $UDEVFILE + echo -e "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$2\", ATTR{dev_id}==\"0x0\", ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"$1\"" >> $UDEVFILE + + echo -e "### Hetzner Online AG - installimage" > $CONFIGFILE + echo -e "# Loopback device:" >> $CONFIGFILE + echo -e "auto lo" >> $CONFIGFILE + echo -e "iface lo inet loopback" >> $CONFIGFILE + echo -e "" >> $CONFIGFILE + + if [ "$3" -a "$4" -a "$5" -a "$6" -a "$7" ]; then + echo -e "# device: $1" >> $CONFIGFILE + echo -e "auto $1" >> $CONFIGFILE + echo -e "iface $1 inet static" >> $CONFIGFILE + echo -e " address $3" >> $CONFIGFILE + echo -e " broadcast $4" >> $CONFIGFILE + echo -e " netmask $5" >> $CONFIGFILE + echo -e " gateway $6" >> $CONFIGFILE + echo -e " # default route to access subnet" >> $CONFIGFILE + echo -e " up route add -net $7 netmask $5 gw $6 $1" >> $CONFIGFILE + fi + + if [ "$8" -a "$9" -a "${10}" ]; then + debug "setting up ipv6 networking $8/$9 via ${10}" + echo -e "" >> $CONFIGFILE + echo -e "iface $1 inet6 static" >> $CONFIGFILE + echo -e " address $8" >> $CONFIGFILE + echo -e " netmask $9" >> $CONFIGFILE + echo -e " gateway ${10}" >> $CONFIGFILE + fi + + # set duplex speed + if ! isNegotiated && ! isVServer; then + echo -e " # force full-duplex for ports without auto-neg" >> $CONFIGFILE + echo -e " post-up mii-tool -F 100baseTx-FD $1" >> $CONFIGFILE + fi + + return 0 + fi +} + +# generate_mdadmconf "NIL" +generate_config_mdadm() { + if [ "$1" ]; then + MDADMCONF="/etc/mdadm/mdadm.conf" +# echo "DEVICES /dev/[hs]d*" > $FOLD/hdd$MDADMCONF +# execute_chroot_command "mdadm --detail --scan | sed -e 's/metadata=00.90/metadata=0.90/g' >> $MDADMCONF"; EXITCODE=$? + execute_chroot_command "/usr/share/mdadm/mkconf > $MDADMCONF"; EXITCODE=$? + # Enable mdadm + sed -i "s/AUTOCHECK=false/AUTOCHECK=true # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + sed -i "s/AUTOSTART=false/AUTOSTART=true # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + sed -i "s/START_DAEMON=false/START_DAEMON=true # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + sed -i -e "s/^INITRDSTART=.*/INITRDSTART='all' # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + + return $EXITCODE + fi +} + + +# generate_new_ramdisk "NIL" +generate_new_ramdisk() { + if [ "$1" ]; then + OUTFILE=`ls -1r $FOLD/hdd/boot/initrd.img-* | grep -v ".bak$\|.gz$" | awk -F "/" '{print $NF}' | grep -m1 "initrd"` + VERSION=`echo $OUTFILE |cut -d "-" -f2-` + echo "Kernel Version found: $VERSION" | debugoutput + + if [ "$IMG_VERSION" -ge 60 ]; then + # blacklist i915 driver due to many bugs and stability issues + local blacklist_conf="$FOLD/hdd/etc/modprobe.d/blacklist-hetzner.conf" + echo -e "### Hetzner Online AG - installimage" > $blacklist_conf + echo -e "### silence any onboard speaker" >> $blacklist_conf + echo -e "blacklist pcspkr" >> $blacklist_conf + echo -e "blacklist snd_pcsp" >> $blacklist_conf + echo -e "### i915 driver blacklisted due to various bugs" >> $blacklist_conf + echo -e "### especially in combination with nomodeset" >> $blacklist_conf + echo -e "blacklist i915" >> $blacklist_conf + echo -e "### mei driver blacklisted due to serious bugs" >> $blacklist_conf + echo -e "blacklist mei" >> $blacklist_conf + echo -e "blacklist mei-me" >> $blacklist_conf + fi + + # just make sure that we do not accidentally try to install a bootloader + # when we haven't configured grub yet + # Debian won't install a boot loader anyway, but display an error message, + # that needs to be confirmed + sed -i "s/do_bootloader = yes/do_bootloader = no/" $FOLD/hdd/etc/kernel-img.conf + execute_chroot_command "update-initramfs -u -k $VERSION"; EXITCODE=$? + + return $EXITCODE + fi +} + +setup_cpufreq() { + if [ "$1" ]; then + LOADCPUFREQCONF="$FOLD/hdd/etc/default/loadcpufreq" + CPUFREQCONF="$FOLD/hdd/etc/default/cpufrequtils" + echo -e "### Hetzner Online AG - installimage" > $CPUFREQCONF + echo -e "# cpu frequency scaling" >> $CPUFREQCONF + if isVServer; then + echo -e "ENABLE=\"false\"" > $LOADCPUFREQCONF + echo -e "ENABLE=\"false\"" >> $CPUFREQCONF + else + echo -e "ENABLE=\"true\"" >> $CPUFREQCONF + echo -e "GOVERNOR=\"$1\"" >> $CPUFREQCONF + echo -e "MAX_SPEED=\"0\"" >> $CPUFREQCONF + echo -e "MIN_SPEED=\"0\"" >> $CPUFREQCONF + fi + + return 0 + fi +} + +# +# generate_config_grub +# +# Generate the GRUB bootloader configuration. +# +generate_config_grub() { + EXITCODE=0 + [ "$1" ] || return + + execute_chroot_command "mkdir -p /boot/grub/; cp -r /usr/lib/grub/* /boot/grub >> /dev/null 2>&1" + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_HIDDEN_TIMEOUT=.*/GRUB_HIDDEN_TIMEOUT=5/" -e "s/^GRUB_HIDDEN_TIMEOUT_QUIET=.*/GRUB_HIDDEN_TIMEOUT_QUIET=false/"' + if isVServer; then + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"nomodeset elevator=noop\"/"' + else + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"nomodeset\"/"' + fi + # only install grub2 in mbr of all other drives if we use swraid + local i=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + if [ $SWRAID -eq 1 -o $i -eq 1 ] ; then + local disk="$(eval echo "\$DRIVE"$i)" + execute_chroot_command "grub-install --no-floppy --recheck $disk 2>&1" + fi + done + [ -e $FOLD/hdd/boot/grub/grub.cfg ] && rm "$FOLD/hdd/boot/grub/grub.cfg" + + execute_chroot_command "grub-mkconfig -o /boot/grub/grub.cfg 2>&1" + + uuid_bugfix + + PARTNUM=`echo "$SYSTEMBOOTDEVICE" | rev | cut -c1` + + if [ "$SWRAID" = "0" ]; then + PARTNUM="$[$PARTNUM - 1]" + fi + + delete_grub_device_map + + return $EXITCODE +} + +delete_grub_device_map() { + [ -f $FOLD/hdd/boot/grub/device.map ] && rm $FOLD/hdd/boot/grub/device.map +} + +# +# os specific functions +# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP +# +run_os_specific_functions() { + randomize_mdadm_checkarray_cronjob_time + + # + # randomize mysql password for debian-sys-maint in LAMP image + # + debug "# Testing if mysql is installed and if this is a LAMP image and setting new debian-sys-maint password" + if [ -f "$FOLD/hdd/etc/mysql/debian.cnf" ] ; then + echo $IMAGENAME | grep -q -i lamp && ( randomize_maint_mysql_pass || return 1 ) + fi + + return 0 +} + +randomize_mdadm_checkarray_cronjob_time() { + if [ -e "$FOLD/hdd/etc/cron.d/mdadm" -a "$(grep checkarray "$FOLD/hdd/etc/cron.d/mdadm")" ]; then + hour=$((($RANDOM % 4) + 1)) + minute=$((($RANDOM % 59) + 1)) + day=$((($RANDOM % 28) + 1)) + debug "# Randomizing cronjob run time for mdadm checkarray: day $day @ $hour:$minute" + + sed -i \ + -e "s/^57 0 \* \* 0 /$minute $hour $day \* \* /" \ + -e 's/ && \[ \$(date +\\%d) -le 7 \]//' \ + "$FOLD/hdd/etc/cron.d/mdadm" + else + debug "# No /etc/cron.d/mdadm found to randomize cronjob run time" + fi +} + +# +# randomize mysql password for debian-sys-maint in LAMP image +# +randomize_maint_mysql_pass() { + SQLCONFIG="$FOLD/hdd/etc/mysql/debian.cnf" + MYCNF="$FOLD/hdd/root/.my.cnf" + # generate PW for user debian-sys-maint and root + NEWPASS=$(cat /dev/urandom | strings | head -c 512 | md5sum | cut -b -16) + ROOTPASS=$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c8) + MYSQLCOMMAND="USE mysql;\nUPDATE user SET password=PASSWORD(\""$NEWPASS"\") WHERE user='debian-sys-maint'; \ + UPDATE user SET password=PASSWORD(\""$ROOTPASS"\") WHERE user='root';\nFLUSH PRIVILEGES;" + echo -e "$MYSQLCOMMAND" > "$FOLD/hdd/etc/mysql/pwchange.sql" + execute_chroot_command "/etc/init.d/mysql start >>/dev/null 2>&1" + execute_chroot_command "mysql --defaults-file=/etc/mysql/debian.cnf < /etc/mysql/pwchange.sql >>/dev/null 2>&1"; EXITCODE=$? + execute_chroot_command "/etc/init.d/mysql stop >>/dev/null 2>&1" + cp "$SQLCONFIG" "$SQLCONFIG.old" + sed s/password.*/"password = $NEWPASS"/g "$SQLCONFIG.old" > "$SQLCONFIG" + rm "$FOLD/hdd/etc/mysql/pwchange.sql" + rm "$SQLCONFIG.old" + + # generate correct ~/.my.cnf + echo "[client]" > $MYCNF + echo "user=root" >> $MYCNF + echo "pass=$ROOTPASS" >> $MYCNF + + # write password file and erase script + cp $SCRIPTPATH/password.txt $FOLD/hdd/ + sed -i -e "s##$ROOTPASS#" $FOLD/hdd/password.txt + chmod 600 $FOLD/hdd/password.txt + echo -e "\nNote: Your MySQL password is in /password.txt (delete this with \"erase_password_note\")\n" >> $FOLD/hdd/etc/motd.tail + cp $SCRIPTPATH/erase_password_note $FOLD/hdd/usr/local/bin/ + chmod +x $FOLD/hdd/usr/local/bin/erase_password_note + + return $EXITCODE +} + + +debian_grub_fix() { + MAPPER="$FOLD/hdd/dev/mapper" + TEMPFILE="$FOLD/hdd/tmp" + + ls -l $MAPPER > $TEMPFILE/tmp.tmp + cat $TEMPFILE/tmp.tmp | grep -v "total" | grep -v "crw" | while read line; do + VOLGROUP=$(echo $line | cut -d " " -f9) + DMDEVICE=$(echo $line | cut -d "/" -f2) + + rm $MAPPER/$VOLGROUP + cp -R $FOLD/hdd/dev/$DMDEVICE $MAPPER/$VOLGROUP + done +} + diff --git a/erase_password_note b/erase_password_note new file mode 100644 index 0000000..d8099d1 --- /dev/null +++ b/erase_password_note @@ -0,0 +1,9 @@ +#!/bin/bash + +FILE=$(cat /etc/motd.tail | grep -v "Note: Your MySQL password is in /etc/password.txt (delete this with \"erase_password_note\")" | head -n -2) + +echo -e "$FILE" > /etc/motd.tail +rm /password.txt + +echo -e "File /password.txt is removed.\n" +echo -e "The note is removed from /etc/motd after a reboot.\n" diff --git a/functions.sh b/functions.sh new file mode 100755 index 0000000..61bc556 --- /dev/null +++ b/functions.sh @@ -0,0 +1,3796 @@ +#!/bin/bash + +# +# functions +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + +# nil settings parsed out of the config +PART_COUNT="" +PART_MOUNT="" +PART_FS="" +PART_SIZE="" +PARTS_SUM_SIZE="" +MOUNT_POINT_SIZE="" +HASROOT="" +SWRAID="" +SWRAIDLEVEL="" +LVM="" +LVM_VG_CHECK="" +IMAGE_PATH="" +IMAGE_PATH_TYPE="" +IMAGE_FILE="" +IMAGE_FILE_TYPE="" +IMAGE_SIGN="" +IMAGE_PUBKEY="" +IMAGE_PUBKEY_IMPORTED="" +IAM="" +IMG_VERSION=0 +BOOTLOADER="" +GOVERNOR="" +SFDISKPARTS="" +COUNT_DRIVES="0" +LAST_PART_START="" +LAST_PART_END="" +DISK_SIZE_SECTORS="" + +SYSTEMROOTDEVICE="" +SYSTEMBOOTDEVICE="" +SYSTEMREALBOOTDEVICE="" +EXTRACTFROM="" + +ETHDEV="" +HWADDR="" +IPADDR="" +BROADCAST="" +SUBNETMASK="" +GATEWAY="" +NETWORK="" +IP6ADDR="" +IP6PREFLEN="" +IP6GATEWAY="" + +ROOTHASH="" +LILOEXTRABOOT="" + +ERROREXIT="0" +FINALIMAGEPATH="" + +PLESK_STD_VERSION="PLESK_12_0_18" + +SYSMFC=$(dmidecode -s system-manufacturer 2>/dev/null | head -n1) +SYSTYPE=$(dmidecode -s system-product-name 2>/dev/null | head -n1) +MBTYPE=$(dmidecode -s baseboard-product-name 2>/dev/null | head -n1) + +# functions +# show text in a different color +echo_red() { + echo -e "\033[01;31m$*\033[00m" +} +echo_green() { + echo -e "\033[01;32m$*\033[00m" +} +echo_bold() { + echo -e "\033[0;1m$*\033[00m" +} + + +# generate submenus to choose which image to install +# generate_menu "SUBMENU" +generate_menu() { + # security check - just execute the function WITH parameters + if [ "$1" ]; then + # empty the menu + MENULIST="" + PROXMOX=false + # find image-files and generate raw list + FINALIMAGEPATH="$IMAGESPATH" + if [ "$1" = "openSUSE" ]; then + RAWLIST=`ls -1 $IMAGESPATH | grep -i -e "^$1\|^old_$1\|^suse\|^old_suse"` + elif [ "$1" = "Virtualization" ]; then + RAWLIST="" + RAWLIST=`ls -1 $IMAGESPATH | grep -i -e "^CoreOS"` + RAWLIST="$RAWLIST Proxmox-Virtualization-Environment-on-Debian-Squeeze" + RAWLIST="$RAWLIST Proxmox-Virtualization-Environment-on-Debian-Wheezy" + elif [ "$1" = "old_images" ]; then + RAWLIST=`ls -1 $OLDIMAGESPATH` + FINALIMAGEPATH="$OLDIMAGESPATH" + else + RAWLIST=`ls -1 $IMAGESPATH | grep -i -e "^$1\|^old_$1"` + fi + # Remove CPANEL image and signature files from list + RAWLIST="`echo $RAWLIST |tr ' ' '\n' |egrep -i -v "cpanel|.sig$"`" + # check if 32-bit rescue is activated and disable 64-bit images then + ARCH="`uname -m`" + if [ "$ARCH" != "x86_64" ]; then + RAWLIST="`echo $RAWLIST |tr ' ' '\n' |grep -v "\-64\-[a-zA-Z]"`" + fi + # generate formatted list for usage with "dialog" + for i in $RAWLIST; do + TEMPVAR="$i" + TEMPVAR=`basename $TEMPVAR .bin` + TEMPVAR=`basename $TEMPVAR .bin.bz2` + TEMPVAR=`basename $TEMPVAR .txz` + TEMPVAR=`basename $TEMPVAR .tar.xz` + TEMPVAR=`basename $TEMPVAR .tgz` + TEMPVAR=`basename $TEMPVAR .tar.gz` + TEMPVAR=`basename $TEMPVAR .tbz` + TEMPVAR=`basename $TEMPVAR .tar.bz` + TEMPVAR=`basename $TEMPVAR .tar.bz2` + TEMPVAR=`basename $TEMPVAR .tar` + MENULIST=$MENULIST"$TEMPVAR . " + done + # add "back to mainmenu" entry + MENULIST=$MENULIST'back . ' + + # show menu and get result + dialog --backtitle "$DIATITLE" --title "$1 images" --no-cancel --menu "choose image" 0 0 0 $MENULIST 2>$FOLD/submenu.chosen + IMAGENAME=`cat $FOLD/submenu.chosen` + + # create proxmox post-install file if needed + case $IMAGENAME in + Proxmox-Virtualization-Environment*) + case "$IMAGENAME" in + Proxmox-Virtualization-Environment-on-Debian-Squeeze) export PROXMOX_VERSION="2" ;; + Proxmox-Virtualization-Environment-on-Debian-Wheezy) export PROXMOX_VERSION="3" ;; + esac + cp $SCRIPTPATH/post-install/proxmox$PROXMOX_VERSION /post-install + chmod 0755 /post-install + PROXMOX=true + IMAGENAME=`eval echo \\$PROXMOX${PROXMOX_VERSION}_BASE_IMAGE` + DEFAULTPARTS="" + DEFAULTPARTS="$DEFAULTPARTS\nPART /boot ext3 512M" + DEFAULTPARTS="$DEFAULTPARTS\nPART lvm vg0 all\n" + DEFAULTPARTS="$DEFAULTPARTS\nLV vg0 root / ext3 15G" + DEFAULTPARTS="$DEFAULTPARTS\nLV vg0 swap swap swap 6G" + ;; + CoreOS*) + PROXMOX=false + ;; + *) + : # no proxmox installation + ;; + esac + + whoami "$IMAGENAME" + fi +} + +# create new config file from standardconfig and misc options +# create_config "IMAGENAME" +create_config() { + if [ "$1" ]; then + CNF="$FOLD/install.conf" + getdrives; EXITCODE=$? + + if [ $COUNT_DRIVES -eq 0 ] ; then + graph_notice "There are no drives in your server!\nIf there is a raid controller in your server, please configure it!\n\nThe setup will quit now!" + return 1 + fi + + echo -e "## ===================================================" > $CNF + echo -e "## Hetzner Online AG - installimage - standardconfig " >> $CNF + echo -e "## ===================================================" >> $CNF + echo -e "" >> $CNF + + # first drive + echo -e "\n" >> $CNF + echo -e "## ====================" >> $CNF + echo -e "## HARD DISK DRIVE(S):" >> $CNF + echo -e "## ====================\n" >> $CNF + [ $COUNT_DRIVES -gt 2 ] && echo -e "## PLEASE READ THE NOTES BELOW!" >> $CNF + echo -e "" >> $CNF + + local found_optdrive=0 + local optdrive_count=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + DISK="$(eval echo \$DRIVE${i})" + OPTDISK="$(eval echo \$OPT_DRIVE${i})" + if [ -n "$OPTDISK" ] ; then + optdrive_count=$[$optdrive_count+1] + found_optdrive=1 + hdinfo /dev/$OPTDISK >>$CNF + echo "DRIVE$i /dev/$OPTDISK" >>$CNF + else + hdinfo $DISK >>$CNF + # comment drive out when not given via commandline + [ $found_optdrive -eq 1 ] && echo -n "# " >>$CNF + echo "DRIVE$i $DISK" >>$CNF + fi + done + + # reset drive count to number of drives explicitly passed via command line + [ $optdrive_count -gt 0 ] && COUNT_DRIVES=$optdrive_count + + echo -e "" >> $CNF + if [ $COUNT_DRIVES -gt 2 ] ; then + if [ $COUNT_DRIVES -lt 4 ] ; then + echo "## if you dont want raid over your three drives then comment out the following line and set SWRAIDLEVEL not to 5" >>$CNF + echo "## please make sure the DRIVE[nr] variable is strict ascending with the used harddisks, when you comment out one or more harddisks" >>$CNF + else + echo "## if you dont want raid over all of your drives then comment out the following line and set SWRAIDLEVEL not to 5 or 6 or 10" >>$CNF + echo "## please make sure the DRIVE[nr] variable is strict ascending with the used harddisks, when you comment out one or more harddisks" >>$CNF + fi + fi + echo -e "" >> $CNF + + # software-raid + if [ $COUNT_DRIVES -gt 1 ]; then + echo -e "\n" >> $CNF + + echo -e "## ===============" >> $CNF + echo -e "## SOFTWARE RAID:" >> $CNF + echo -e "## ===============\n" >> $CNF + echo -e "## activate software RAID? < 0 | 1 >\n" >> $CNF + + case "$OPT_SWRAID" in + 0) echo -e "SWRAID 0" >> $CNF ;; + 1) echo -e "SWRAID 1" >> $CNF ;; + *) echo -e "SWRAID $DEFAULTSWRAID" >> $CNF ;; + esac + + echo >> $CNF + + # available raidlevels + local raid_levels="0 1 5 6 10" + # set default raidlevel + local default_level=$DEFAULTTWODRIVESWRAIDLEVEL + if [ $COUNT_DRIVES -eq 3 ] ; then + default_level=$DEFAULTTHREEDRIVESWRAIDLEVEL + elif [ $COUNT_DRIVES -gt 3 ] ; then + default_level=$DEFAULTFOURDRIVESWRAIDLEVEL + fi + + local set_level="" + local avail_level="0" + # check for possible raidlevels + for level in $raid_levels ; do + # set raidlevel to given opt raidlevel + if [ -n "$OPT_SWRAIDLEVEL" ] ; then + [ $OPT_SWRAIDLEVEL -eq $level ] && set_level="$level" + fi + + # create list of all possible raidlevels + [ $level -ne 0 ] && avail_level="$avail_level | $level" + + # no raidlevel 5 if just two hdds + [ $level -eq 1 -a $COUNT_DRIVES -eq 2 ] && break + # no raidlevel 6 or 10 if just three hdds + [ $level -eq 5 -a $COUNT_DRIVES -eq 3 ] && break + done + [ -z "$set_level" ] && set_level="$default_level" + + echo -e "## Choose the level for the software RAID < $avail_level >\n" >> $CNF + echo -e "SWRAIDLEVEL $set_level" >> $CNF + fi + + + # bootloader + # we no longer support lilo, so don't show this option if it isn't in the image + if [ "$IAM" = "arch" ] || + [ "$IAM" = "coreos" ] || + [ "$IAM" = "centos" ] || + [ "$IAM" = "ubuntu" -a "$IMG_VERSION" -ge 1204 ] || + [ "$IAM" = "debian" -a "$IMG_VERSION" -ge 70 ] || + [ "$IAM" = "suse" -a "$IMG_VERSION" -ge 122 ]; then + NOLILO="true" + else + NOLILO='' + fi + + echo -e "\n" >> $CNF + echo -e "## ============" >> $CNF + echo -e "## BOOTLOADER:" >> $CNF + echo -e "## ============\n" >> $CNF + if [ "$NOLILO" ]; then + echo -e "\n## Do not change. This image does not include or support lilo (grub only)!:\n" >> $CNF + echo "BOOTLOADER grub" >> $CNF + else + echo -e "\n## which bootloader should be used? < lilo | grub >\n" >> $CNF + case "$OPT_BOOTLOADER" in + lilo) echo "BOOTLOADER lilo" >> $CNF ;; + grub) echo "BOOTLOADER grub" >> $CNF ;; + *) echo "BOOTLOADER $DEFAULTLOADER" >> $CNF ;; + esac + echo -e "" >> $CNF + fi + + # hostname + get_active_eth_dev + gather_network_information + echo -e "\n" >> $CNF + echo -e "## ==========" >> $CNF + echo -e "## HOSTNAME:" >> $CNF + echo -e "## ==========\n" >> $CNF + echo -e "## which hostname should be set?\n## \n" >> $CNF + # set default hostname to image name + DEFAULT_HOSTNAME="$1" + # or to proxmox if chosen + if [ "$PROXMOX" = "true" ]; then + echo -e "## This must be a FQDN otherwise installation will fail\n## \n" >> $CNF + DEFAULT_HOSTNAME="Proxmox-VE.localdomain" + fi + # or to the hostname passed through options + [ "$OPT_HOSTNAME" ] && DEFAULT_HOSTNAME="$OPT_HOSTNAME" + echo -e "HOSTNAME $DEFAULT_HOSTNAME" >> $CNF + echo -e "" >> $CNF + + + ## Calculate how much hardisk space at raid level 0,1,5,6,10 + RAID0=0 + local small_hdd="$(smallest_hd)" + local small_hdd_size="$[$(blockdev --getsize64 $small_hdd)/1024/1024/1024]" + RAID0=$[$small_hdd_size*$COUNT_DRIVES] + RAID1=$small_hdd_size + if [ $COUNT_DRIVES -ge 3 ] ; then + RAID5=$[$RAID0-$small_hdd_size] + fi + if [ $COUNT_DRIVES -ge 4 ] ; then + RAID6=$[$RAID0-2*$small_hdd_size] + RAID10=$[$RAID0/2] + fi + + # partitions + echo -e "\n" >> $CNF + echo -e "## ==========================" >> $CNF + echo -e "## PARTITIONS / FILESYSTEMS:" >> $CNF + echo -e "## ==========================\n" >> $CNF + echo -e "## define your partitions and filesystems like this:" >> $CNF + echo -e "##" >> $CNF + echo -e "## PART " >> $CNF + echo -e "##" >> $CNF + echo -e "## * mountpoint for this filesystem *OR* keyword 'lvm'" >> $CNF + echo -e "## to use this PART as volume group (VG) for LVM" >> $CNF + echo -e "## * can be ext2, ext3, reiserfs, xfs, swap *OR* name" >> $CNF + echo -e "## of the LVM volume group (VG), if this PART is a VG" >> $CNF + echo -e "## * you can use the keyword 'all' to assign all the" >> $CNF + echo -e "## remaining space of the drive to the *last* partition." >> $CNF + echo -e "## you can use M/G/T for unit specification in MIB/GIB/TIB" >> $CNF + echo -e "##" >> $CNF + echo -e "## notes:" >> $CNF + echo -e "## - extended partitions are created automatically" >> $CNF + echo -e "## - '/boot' cannot be on a xfs filesystem!" >> $CNF + echo -e "## - '/boot' cannot be on LVM!" >> $CNF + echo -e "## - when using software RAID 0, you need a '/boot' partition" >> $CNF + echo -e "##" >> $CNF + echo -e "## example without LVM (default):" >> $CNF + echo -e "## -> 4GB swapspace" >> $CNF + echo -e "## -> 512MB /boot" >> $CNF + echo -e "## -> 10GB /" >> $CNF + echo -e "## -> 5GB /tmp" >> $CNF + echo -e "## -> all the rest to /home" >> $CNF + echo -e "#PART swap swap 4096" >> $CNF + echo -e "#PART /boot ext2 512" >> $CNF + echo -e "#PART / reiserfs 10240" >> $CNF + echo -e "#PART /tmp xfs 5120" >> $CNF + echo -e "#PART /home ext3 all" >> $CNF + echo -e "#" >> $CNF + echo -e "##" >> $CNF + echo -e "## to activate LVM, you have to define volume groups and logical volumes" >> $CNF + echo -e "##" >> $CNF + echo -e "## example with LVM:" >> $CNF + echo -e "#" >> $CNF + echo -e "## normal filesystems and volume group definitions:" >> $CNF + echo -e "## -> 512MB boot (not on lvm)" >> $CNF + echo -e "## -> all the rest for LVM VG 'vg0'" >> $CNF + echo -e "#PART /boot ext3 512M" >> $CNF + echo -e "#PART lvm vg0 all" >> $CNF + + echo -e "#" >> $CNF + echo -e "## logical volume definitions:" >> $CNF + echo -e "#LV " >> $CNF + echo -e "#" >> $CNF + echo -e "#LV vg0 root / ext4 10G" >> $CNF + echo -e "#LV vg0 swap swap swap 4G" >> $CNF + echo -e "#LV vg0 tmp /tmp reiserfs 5G" >> $CNF + echo -e "#LV vg0 home /home xfs 20G" >> $CNF + echo -e "#" >> $CNF + + if [ -x "/usr/local/bin/hwdata" ]; then + echo -e "#" >> $CNF + echo -e "## your system has the following devices:" >> $CNF + echo -e "#" >> $CNF + echo -e "$(/usr/local/bin/hwdata | grep "Disk /" | sed "s/^ /#/")" >> $CNF + fi + + if [ "$RAID1" -a "$RAID0" ] ; then + echo -e "#" >> $CNF + echo -e "## Based on your disks and which RAID level you will choose you have" >> $CNF + echo -e "## the following free space to allocate (in GiB):" >> $CNF + echo -e "# RAID 0: ~$RAID0" >> $CNF + echo -e "# RAID 1: ~$RAID1" >> $CNF + [ "$RAID5" ] && echo -e "# RAID 5: ~$RAID5" >> $CNF + if [ "$RAID6" ]; then + echo -e "# RAID 6: ~$RAID6" >> $CNF + echo -e "# RAID 10: ~$RAID10" >> $CNF + fi + fi + + echo -e "#" >> $CNF + echo -e "" >> $CNF + + # check if there are 3TB disks inside and use other default scheme + local LIMIT=2096128 + local THREE_TB=2861588 + local DRIVE_SIZE="$(sfdisk -s `smallest_hd` 2>/dev/null)" + DRIVE_SIZE="$(echo $DRIVE_SIZE / 1024 | bc)" + + # adjust swap dynamically according to RAM + # RAM < 2 GB : SWAP=2 * RAM + # RAM > 2GB - 8GB : SWAP=RAM + # RAM > 8GB - 64GB : SWAP = 0.5 RAM + # RAM > 64GB: SWAP = 4GB + # http://docs.fedoraproject.org/en-US/Fedora/18/html/Installation_Guide/s2-diskpartrecommend-x86.html + # https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Installation_Guide/s2-diskpartrecommend-x86.html + RAM=$(free -m | grep Mem: | tr -s ' ' | cut -d' ' -f2) + SWAPSIZE=4 + if [ "$RAM" -lt 2048 ]; then + SWAPSIZE=$(($RAM * 2 / 1024 + 1)) + elif [ "$RAM" -lt 8192 ]; then + SWAPSIZE=$(($RAM / 1024 + 1)) + elif [ "$RAM" -lt 65535 ]; then + SWAPSIZE=$(($RAM / 2 / 1024 + 1)) + fi + + DEFAULTPARTS=${DEFAULTPARTS/SWAPSIZE##/$SWAPSIZE} + DEFAULTPARTS_BIG=${DEFAULTPARTS_BIG/SWAPSIZE##/$SWAPSIZE} + DEFAULTPARTS_LARGE=${DEFAULTPARTS_LARGE/SWAPSIZE##/$SWAPSIZE} + + # use ext3 for vservers, because ext4 is too trigger happy of device timeouts + if isVServer; then +# DEFAULTPARTS=${DEFAULTPARTS//ext4/ext3} + DEFAULTPARTS=$DEFAULTPARTS_VSERVER + fi + + # use /var instead of /home for all partition when installing plesk + if [ "$OPT_INSTALL" ]; then + if [ $(echo $OPT_INSTALL | grep -i "PLESK") ]; then + DEFAULTPARTS_BIG="${DEFAULTPARTS_BIG//home/var}" + fi + fi + + if [ "$IAM" = "coreos" ]; then + echo -e "## NOTICE: This image does not support custom partition sizes." >>$CNF + echo -e "## 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 + else + [ "$OPT_PARTS" ] && echo -e "$OPT_PARTS" >>$CNF || echo -e "$DEFAULTPARTS_BIG" >>$CNF + fi + else + [ "$OPT_PARTS" ] && echo -e "$OPT_PARTS" >>$CNF || echo -e "$DEFAULTPARTS" >>$CNF + fi + + [ "$OPT_LVS" ] && echo -e "$OPT_LVS" >>$CNF + echo -e "" >> $CNF + + # image + echo -e "\n" >> $CNF + echo -e "## ========================" >> $CNF + echo -e "## OPERATING SYSTEM IMAGE:" >> $CNF + echo -e "## ========================\n" >> $CNF + echo -e "## full path to the operating system image" >> $CNF + echo -e "## supported image sources: local dir, ftp, http, nfs" >> $CNF + echo -e "## supported image types: tar, tar.gz, tar.bz, tar.bz2, tar.xz, tgz, tbz, txz" >> $CNF + echo -e "## examples:" >> $CNF + echo -e "#" >> $CNF + echo -e "# local: /path/to/image/filename.tar.gz" >> $CNF + echo -e "# ftp: ftp://:@hostname/path/to/image/filename.tar.bz2" >> $CNF + echo -e "# http: http://:@hostname/path/to/image/filename.tbz" >> $CNF + echo -e "# https: https://:@hostname/path/to/image/filename.tbz" >> $CNF + echo -e "# nfs: hostname:/path/to/image/filename.tgz" >> $CNF + echo -e "#" >> $CNF + echo -e "# for validation of the image, place the detached gpg-signature" >> $CNF + echo -e "# and your public key in the same directory as your image file." >> $CNF + echo -e "# naming examples:" >> $CNF + echo -e "# signature: filename.tar.bz2.sig" >> $CNF + echo -e "# public key: public-key.asc" >> $CNF + echo -e "" >> $CNF + if [ "$1" = "custom" ]; then + echo -e "IMAGE " >> $CNF + else + if [ "$OPT_IMAGE" ] ; then + if [ -f "$FINALIMAGEPATH/$OPT_IMAGE" ] ; then + echo -e "IMAGE $FINALIMAGEPATH/$OPT_IMAGE" >> $CNF + else + echo -e "IMAGE $OPT_IMAGE" >> $CNF + fi + else + [ -n "$IMG_EXT" ] && IMAGESEXT="$IMG_EXT" + echo -e "IMAGE $FINALIMAGEPATH$1.$IMAGESEXT" >> $CNF + fi + fi + echo -e "" >> $CNF + + fi +return 0 +} + +getdrives() { + local DRIVES="$(sfdisk -s 2>/dev/null | sort -u | grep -e "/dev/[hsv]d" | cut -d: -f1)" + local i=1 + + #cast drives into an array + DRIVES=( $DRIVES ) + + for drive in ${DRIVES[*]} ; do + # if we have just one drive, add it. Otherwise check that multiple drives are at least HDDMINSIZE + if [ ${#DRIVES[@]} -eq 1 ] || [ ! $(fdisk -s $drive 2>/dev/null || echo 0) -lt $HDDMINSIZE ] ; then + eval DRIVE$i="$drive" + let i=i+1 + fi + done + [ -z "$DRIVE1" ] && DRIVE1="no valid drive found" + + COUNT_DRIVES=$[$i - 1] + + return 0 +} + +# read all variables from config file +# read_vars "CONFIGFILE" +read_vars(){ +if [ "$1" ]; then + # count disks again, for setting COUNT_DRIVES correct after restarting installimage + getdrives + + # special hidden configure option: create RAID1 and 10 with assume clean to + # avoid initial resync + RAID_ASSUME_CLEAN="`grep -m1 -e ^RAID_ASSUME_CLEAN $1 |awk '{print \$2}'`" + + # special hidden configure option: GPT usage + # if set to 1, use GPT even on disks smaller than 2TiB + # if set to 2, always use GPT, even if the OS does not support it + FORCE_GPT="`grep -m1 -e ^FORCE_GPT $1 |awk '{print \$2}'`" + + # another special hidden configure option: force image validation + # if set to 1: force validation + FORCE_SIGN="`grep -m1 -e ^FORCE_SIGN $1 |awk '{print \$2}'`" + + # hidden configure option: + # if set to 1: force setting root password even if ssh keys are + # provided + FORCE_PASSWORD="`grep -m1 -e ^FORCE_PASSWORD $1 |awk '{print \$2}'`" + + # get all disks from configfile + local used_disks=1 + for i in $(seq 1 $COUNT_DRIVES) ; do + disk="$(grep -m1 -e ^DRIVE$i $1 | awk '{print $2}')" + if [ -n "$disk" ] ; then + export DRIVE$i + eval DRIVE$i="$disk" + let used_disks=used_disks+1 + else + unset DRIVE$i + fi + format_disk="$(grep -m1 -e ^FORMATDRIVE$i $1 | awk '{print $2}')" + export FORMAT_DRIVE$i + eval FORMAT_DRIVE$i="0" + if [ -n "$format_disk" ] ; then + eval FORMAT_DRIVE$i="1" + fi + done + + # get count of drives + COUNT_DRIVES="$((used_disks-1))" + + # is RAID activated? + SWRAID="`grep -m1 -e ^SWRAID $1 |awk '{print \$2}'`" + [ "$SWRAID" = "" ] && SWRAID="0" + + # Software RAID Level + SWRAIDLEVEL="$(grep -m1 -e ^SWRAIDLEVEL $1 | awk '{ print $2 }')" + [ "$SWRAIDLEVEL" = "" ] && SWRAIDLEVEL="1" + + PARTS_SUM_SIZE="0" + PART_COUNT="$(grep -c -e '^PART' $1)" + PART_LINES="$(grep -e '^PART ' $1)" + echo "$PART_LINES" > /tmp/part_lines.tmp + i=0 + while read PART_LINE ; do + i=$[$i+1] + PART_MOUNT[$i]="`echo $PART_LINE | awk '{print \$2}'`" + PART_FS[$i]="`echo $PART_LINE | awk '{print \$3}'`" + PART_SIZE[$i]="$(translate_unit "$(echo "$PART_LINE" | awk '{ print $4 }')")" + MOUNT_POINT_SIZE[$i]=${PART_SIZE[$i]} + #calculate new partition size if software raid is enabled and it is not /boot or swap + if [ "$SWRAID" = "1" ]; then + if [ "${PART_MOUNT[$i]}" != "/boot" -a "${PART_SIZE[$i]}" != "all" -a "${PART_MOUNT[$i]}" != "swap" ]; then + if [ "$SWRAIDLEVEL" = "0" ]; then + PART_SIZE[$i]=$((${PART_SIZE[$i]}/$COUNT_DRIVES)) + elif [ "$SWRAIDLEVEL" = "5" ]; then + PART_SIZE[$i]=$((${PART_SIZE[$i]}/($COUNT_DRIVES-1))) + elif [ "$SWRAIDLEVEL" = "6" ]; then + PART_SIZE[$i]=$((${PART_SIZE[$i]}/($COUNT_DRIVES-2))) + elif [ "$SWRAIDLEVEL" = "10" ]; then + PART_SIZE[$i]=$((${PART_SIZE[$i]}/($COUNT_DRIVES/2))) + fi + fi + fi + echo "${PART_MOUNT[$i]} : ${PART_SIZE[$i]}" | debugoutput + if [ "${PART_SIZE[$i]}" != "all" ]; then + PARTS_SUM_SIZE="$(echo ${PART_SIZE[$i]} + $PARTS_SUM_SIZE | bc)" + fi + if [ "${PART_MOUNT[$i]}" = "/" ]; then + HASROOT="true" + fi + done < /tmp/part_lines.tmp + + # get LVM volume group config + LVM_VG_COUNT="$(egrep -c '^PART *lvm ' $1)" + LVM_VG_ALL="$(egrep '^PART *lvm ' $1)" + + # void the check var + LVM_VG_CHECK="" + for i in `seq 1 $LVM_VG_COUNT`; do + LVM_VG_LINE="`echo "$LVM_VG_ALL" | head -n$i | tail -n1`" + #LVM_VG_PART[$i]=$i #"`echo $LVM_VG_LINE | awk '{print \$2}'`" + LVM_VG_PART[$i]=$(echo "$PART_LINES" | egrep -n '^PART *lvm ' | head -n$i | tail -n1 | cut -d: -f1) + LVM_VG_NAME[$i]="`echo $LVM_VG_LINE | awk '{print \$3}'`" + LVM_VG_SIZE[$i]="$(translate_unit "$(echo $LVM_VG_LINE | awk '{print $4}')")" + + if [ "${LVM_VG_SIZE[$i]}" != "all" ] ; then + LVM_VG_CHECK="$i $LVM_VG_CHECK" + fi + done + + # get LVM logical volume config + LVM_LV_COUNT="`grep -c -e "^LV " $1`" + LVM_LV_ALL="`grep -e "^LV " $1`" + for i in `seq 1 $LVM_LV_COUNT`; do + LVM_LV_LINE="`echo "$LVM_LV_ALL" | head -n$i | tail -n1`" + LVM_LV_VG[$i]="`echo $LVM_LV_LINE | awk '{print \$2}'`" + LVM_LV_VG_SIZE[$i]="$(echo "$LVM_VG_ALL" | grep "${LVM_LV_VG[$i]}" | awk '{print $4}')" + LVM_LV_NAME[$i]="`echo $LVM_LV_LINE | awk '{print \$3}'`" + LVM_LV_MOUNT[$i]="`echo $LVM_LV_LINE | awk '{print \$4}'`" + LVM_LV_FS[$i]="`echo $LVM_LV_LINE | awk '{print \$5}'`" + LVM_LV_SIZE[$i]="$(translate_unit "$(echo "$LVM_LV_LINE" | awk '{ print $6 }')")" + # we only add LV sizes to PART_SUM_SIZE if the appropiate volume group has + # "all" as size (otherwise we would count twice: SIZE of VG + SIZE of LVs of VG) + if [ "${LVM_LV_SIZE[$i]}" != "all" ] && [ "${LVM_LV_VG_SIZE[$i]}" == "all" ]; then + PARTS_SUM_SIZE="$(echo ${LVM_LV_SIZE[$i]} + $PARTS_SUM_SIZE | bc)" + fi + if [ "${LVM_LV_MOUNT[$i]}" = "/" ]; then + HASROOT="true" + fi + done + + + + # is LVM activated? + [ "$LVM_VG_COUNT" != "0" -a "$LVM_LV_COUNT" != "0" ] && LVM="1" || LVM="0" + + + IMAGE="`grep -m1 -e ^IMAGE $1 | awk '{print \$2}'`" + [ -e "$wd/$IMAGE" ] && IMAGE="$wd/$IMAGE" + IMAGE_PATH="$(dirname $IMAGE)/" + IMAGE_FILE="$(basename $IMAGE)" + case $IMAGE_PATH in + https:*|http:*|ftp:*) IMAGE_PATH_TYPE="http" ;; + /*) IMAGE_PATH_TYPE="local" ;; + *) IMAGE_PATH_TYPE="nfs" ;; + esac + case $IMAGE_FILE in + *.tar) IMAGE_FILE_TYPE="tar" ;; + *.tar.gz|*.tgz) IMAGE_FILE_TYPE="tgz" ;; + *.tar.bz|*.tbz|*.tbz2|*.tar.bz2) IMAGE_FILE_TYPE="tbz" ;; + *.tar.xz|*.txz) IMAGE_FILE_TYPE="txz" ;; + *.bin) IMAGE_FILE_TYPE="bin" ;; + *.bin.bz2|*.bin.bz) IMAGE_FILE_TYPE="bbz" ;; + esac + + BOOTLOADER="`grep -m1 -e ^BOOTLOADER $1 |awk '{print \$2}'`" + if [ "$BOOTLOADER" = "" ]; then + BOOTLOADER=$(echo "$DEFAULTLOADER" | awk '{ print $2 }') + fi + BOOTLOADER=$(echo $BOOTLOADER | tr [:upper:] [:lower:]) + + NEWHOSTNAME=$(grep -m1 -e ^HOSTNAME $1 | awk '{print $2}') + + GOVERNOR="`grep -m1 -e ^GOVERNOR $1 |awk '{print \$2}'`" + if [ "$GOVERNOR" = "" ]; then GOVERNOR="ondemand"; fi + + SYSTEMDEVICE="$DRIVE1" + SYSTEMREALDEVICE="$DRIVE1" + +fi +} + + +# validate all variables for correct values +# validate_vars "CONFIGFILE" +validate_vars() { + if [ "$1" ]; then + + read_vars "$1" + + # test if IMAGEPATH is given + if [ -z "$IMAGE_PATH" ]; then + graph_error "ERROR: No valid IMAGEPATH" + return 1 + fi + + # 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 + fi + + # test if IMAGEFILE is given + if [ -z "$IMAGE_FILE" ]; then + graph_error "ERROR: No valid IMAGEFILE" + return 1 + fi + + # 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 + fi + + whoami "$IMAGE_FILE" + + # test if $DRIVE1 is a valid block device and is able to create partitions + CHECK="`test -b "$DRIVE1" && sfdisk -l "$DRIVE1" 2>>/dev/null`" + if [ -z "$CHECK" ]; then + graph_error "ERROR: Value for DRIVE1 is not correct: $DRIVE1 " + return 1 + fi + + # test if $DRIVE1 is not busy + CHECK="$(hdparm -z $DRIVE1 2>&1 | grep 'BLKRRPART failed: Device or resource busy')" + if [ "$CHECK" ]; then + graph_error "ERROR: DRIVE1 is busy - cannot access device $DRIVE1 " + return 1 + fi + + # test if $SWRAID has not 0 or 1 as parameter + if [ "$SWRAID" != "0" -a "$SWRAID" != "1" ]; then + graph_error "ERROR: Value for SWRAID is not correct" + return 1 + fi + + # test if $SWRAIDLEVEL is either 0 or 1 + if [ "$SWRAID" = "1" -a "$SWRAIDLEVEL" != "0" -a "$SWRAIDLEVEL" != "1" -a "$SWRAIDLEVEL" != "5" -a "$SWRAIDLEVEL" != "6" -a "$SWRAIDLEVEL" != "10" ]; then + graph_error "ERROR: Value for SWRAIDLEVEL is not correct" + return 1 + fi + + # check for valid drives + local drive_array=( $DRIVE1 ) + for i in $(seq 1 $COUNT_DRIVES) ; do + local format="$(eval echo \$FORMAT_DRIVE$i)" + local drive="$(eval echo \$DRIVE$i)" + if [ $i -gt 1 ] ; then + for j in $(seq 0 $((${#drive_array[@]} - 1))); do + if [ ${drive_array[$j]} = $drive ]; then + graph_error "Duplicate DRIVE definition. $drive used for DRIVE$[$j+1] and DRIVE$i" + fi + done + drive_array=( "${drive_array[@]}" "$drive" ) + if [ "$format" != "0" -a "$format" != "1" ]; then + graph_error "ERROR: Value for FORMATDRIVE$i is not correct" + return 1 + fi + if [ "$format" = 1 -a "$SWRAID" = 1 ] ; then + graph_error "ERROR: FORMATDRIVE$i _AND_ SWRAID are active - use one or none of these options, not both" + return 1 + fi + fi + if [ "$SWRAID" = "1" -o "$format" = "1" -o $i -eq 1 ] ; then + # test if drive is a valid block device and is able to create partitions + CHECK="`test -b "$drive" && sfdisk -l "$drive" 2>>/dev/null`" + if [ -z "$CHECK" ]; then + graph_error "ERROR: Value for DRIVE$i is not correct: $drive" + return 1 + fi + + # test if drive is not busy + CHECK="$(hdparm -z $drive 2>&1 | grep 'BLKRRPART failed: Device or resource busy')" + if [ "$CHECK" ]; then + graph_error "ERROR: DRIVE$i is busy - cannot access device $drive" + return 1 + fi + fi + done + + # test if there is more than 1 hdd if swraid enabled + if [ "$SWRAID" = "1" -a $COUNT_DRIVES -le 1 ] ; then + graph_error "ERROR: You need to select at least 2 disks for creating software raid!" + return 1 + fi + + # test if enough disks for the choosen raid level + if [ "$SWRAID" = "1" ]; then + if [ "$SWRAIDLEVEL" = "5" -a "$COUNT_DRIVES" -lt "3" ]; then + graph_error "ERROR: Not enough disks for RAID level 5" + return 1 + elif [ "$SWRAIDLEVEL" = "6" -a "$COUNT_DRIVES" -lt "4" ]; then + graph_error "ERROR: Not enough disks for RAID level 6" + return 1 + elif [ "$SWRAIDLEVEL" = "10" -a "$COUNT_DRIVES" -lt "4" ]; then + graph_error "ERROR: Not enough disks for RAID level 10" + return 1 + fi + fi + + # test if a /boot partition is defined when using software RAID 0 + if [ "$SWRAID" = "1" ]; then + if [ "$SWRAIDLEVEL" = "0" -o "$SWRAIDLEVEL" = "5" -o "$SWRAIDLEVEL" = "6" -o "$SWRAIDLEVEL" = "10" ]; then + TMPCHECK=0 + + for i in $(seq 1 $PART_COUNT); do + if [ "${PART_MOUNT[$i]}" = "/boot" ]; then + TMPCHECK=1 + fi + done + + if [ $TMPCHECK -eq 0 ]; then + graph_error "ERROR: You need a /boot partition when using software RAID level 0, 5, 6 or 10" + return 1 + fi + fi + fi + + # calculate drive_sum_size + if [ "$SWRAID" = "0" ] ; then + # just the first hdd is used so we need the size of DRIVE1 + DRIVE_SUM_SIZE=$(blockdev --getsize64 $DRIVE1) + echo "Size of the first hdd is: $DRIVE_SUM_SIZE" | debugoutput + else + local smallest_hdd=$(smallest_hd) + DRIVE_SUM_SIZE="$(blockdev --getsize64 $smallest_hdd)" + # this variable is used later when determining what disk to use as reference + # when drives of different sizes are in a system + SMALLEST_HDD_SIZE=$DRIVE_SUM_SIZE + SMALLEST_HDD_SIZE=$[$SMALLEST_HDD_SIZE / 1024 / 1024] + echo "Size of smallest drive is $DRIVE_SUM_SIZE" | debugoutput + if [ "$SWRAIDLEVEL" = "0" ]; then + DRIVE_SUM_SIZE=$[$DRIVE_SUM_SIZE * $COUNT_DRIVES] + elif [ "$SWRAIDLEVEL" = "5" ]; then + DRIVE_SUM_SIZE=$[$DRIVE_SUM_SIZE * ($COUNT_DRIVES - 1)] + elif [ "$SWRAIDLEVEL" = "6" ]; then + DRIVE_SUM_SIZE=$[$DRIVE_SUM_SIZE * ($COUNT_DRIVES - 2)] + elif [ "$SWRAIDLEVEL" = "10" ]; then + DRIVE_SUM_SIZE=$[$DRIVE_SUM_SIZE * ($COUNT_DRIVES / 2)] + fi + echo "Calculated size of array is: $DRIVE_SUM_SIZE" | debugoutput + fi + + DRIVE_SUM_SIZE=$[$DRIVE_SUM_SIZE / 1024 / 1024] + for i in `seq 1 $PART_COUNT`; do + if [ "${PART_SIZE[$i]}" = "all" ]; then + # make sure that the all partition has at least 1G available + DRIVE_SUM_SIZE=$[$DRIVE_SUM_SIZE - 1024] + fi + done + + + # test if /boot or / is mounted outside the LVM + if [ "$LVM" = "1" ]; then + TMPCHECK=0 + for i in $(seq 1 $PART_COUNT); do + if [ "${PART_MOUNT[$i]}" = "/boot" ]; then + TMPCHECK=1 + fi + done + + if [ "$TMPCHECK" = "0" ]; then + for i in $(seq 1 $PART_COUNT); do + if [ "${PART_MOUNT[$i]}" = "/" ]; then + TMPCHECK=1 + fi + done + fi + + if [ "$TMPCHECK" = "0" ]; then + graph_error "ERROR: /boot or / may not be a Logical Volume" + return 1 + fi + fi + + # Check if /boot or / is mounted on one of the first three partitions. + if [ $PART_COUNT -gt 3 ]; then + tmp=0 + + for i in $(seq 1 $PART_COUNT); do + if [ "${PART_MOUNT[$i]}" = "/boot" ]; then + tmp=$i + break + fi + done + + if [ $tmp -gt 3 ]; then + graph_error "ERROR: /boot must be mounted on a primary partition" + return 1 + fi + + if [ $tmp -eq 0 ]; then + for i in $(seq 4 $PART_COUNT); do + if [ "${PART_MOUNT[$i]}" = "/" ]; then + graph_error "ERROR: / must be mounted on a primary partition" + return 1 + fi + done + fi + fi + + + # test if there are partitions in the configfile + if [ "$PART_COUNT" -gt "0" ]; then + WARNBTRFS=0 + # test each partition line + for i in `seq 1 $PART_COUNT`; do + + # test if the mountpoint is valid (start with / or swap or lvm) + CHECK="`echo ${PART_MOUNT[$i]} | grep -e "^none\|^/\|^swap$\|^lvm$"`" + if [ -z "$CHECK" ]; then + graph_error "ERROR: Mountpoint for partition $i is not correct" + return 1 + fi + + # test if the filesystem is one of our supportet types (btrfs/ext2/ext3/ext4/reiserfs/xfs/swap) + CHECK="`echo ${PART_FS[$i]} |grep -e "^bios_grub\|^btrfs$\|^ext2$\|^ext3$\|^ext4$\|^reiserfs$\|^xfs$\|^swap$\|^lvm$"`" + if [ -z "$CHECK" -a "${PART_MOUNT[$i]}" != "lvm" ]; then + graph_error "ERROR: Filesystem for partition $i is not correct" + return 1 + fi + + if [ "${PART_FS[$i]}" = "reiserfs" -a "$IAM" = "centos" ]; then + graph_error "ERROR: centos doesn't support reiserfs" + return 1 + fi + + # warn if using btrfs + if [ "${PART_FS[$i]}" = "btrfs" ]; then + WARNBTRFS=1 + fi + + # we can't use bsdtar on non ext2/3/4 partitions + CHECK=$(echo ${PART_FS[$i]} |grep -e "^ext2$\|^ext3$\|^ext4$\|^swap$") + if [ -z "$CHECK" -a "${PART_MOUNT[$i]}" != "lvm" ]; then + export TAR="tar" + echo "setting TAR to GNUtar" | debugoutput + fi + + if [ "${PART_FS[$i]}" = "btrfs" -a "$IAM" = "centos" -a "$IMG_VERSION" -lt 62 ]; then + graph_error "ERROR: CentOS older than 6.2 doesn't support btrfs" + return 1 + fi + + # test if "all" is at the last partition entry + ### TODO: correct this for LVM + if [ "${PART_SIZE[$i]}" = "all" -a "$i" -lt "$PART_COUNT" ]; then + graph_error "ERROR: Partition size \"all\" has to be on the last partition" + return 1 + fi + + # Check if the partition size is a valid number + if [ "${PART_SIZE[$i]}" != "all" -a "$(echo "${PART_SIZE[$i]}" | sed "s/[0-9]//g")" != "" -o "${PART_SIZE[$i]}" = "0" ]; then + graph_error "ERROR: The size of the partiton PART ${PART_MOUNT[$i]} is not a valid number" + return 1 + fi + + + # check if /boot partition has at least 200M + if [ "${PART_MOUNT[$i]}" = "/boot" -a "${PART_SIZE[$i]}" != "all" ]; then + if [ "${MOUNT_POINT_SIZE[$i]}" -lt "200" ]; then + graph_error "ERROR: Your /boot partition has to be at least 200M (current size: ${MOUNT_POINT_SIZE[$i]})" + return 1 + fi + fi + + # check if / partition has at least 1500M + if [ "${PART_MOUNT[$i]}" = "/" -a "${PART_SIZE[$i]}" != "all" ]; then + if [ "${MOUNT_POINT_SIZE[$i]}" -lt "1500" ]; then + graph_error "ERROR: Your / partition has to be at least 1500M (current size: ${MOUNT_POINT_SIZE[$i]})" + return 1 + fi + fi + + if [ "$BOOTLOADER" = "grub" ]; then + if [ "${PART_MOUNT[$i]}" = "/boot" -a "${PART_FS[$i]}" = "xfs" ]; then + graph_error "ERROR: /boot partiton 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 in `seq 1 $PART_COUNT`; do + if [ "${PART_MOUNT[$j]}" = "/boot" ]; then + TMPCHECK="1" + fi + done + if [ "$TMPCHECK" = "0" ]; then + graph_error "ERROR: / partiton will not work properly with xfs with no /boot partition" + return 1 + fi + fi + fi + + done + if [ "$WARNBTRFS" = "1" ]; then + graph_notice "WARNING: the btrfs filesystem is still under development. Data loss may occur!" + fi + else + graph_error "ERROR: The config has no partitions" + return 1 + fi + + + # test if there are lvs in the configfile + if [ "$LVM_VG_COUNT" -gt "0" ]; then + names= + + for i in `seq 1 $LVM_VG_COUNT`; do + names="$names\n${LVM_VG_NAME[$i]}" + done + + if [ $(echo -e "$names" | egrep -v "^$" | sort | uniq -d | wc -l) -gt 1 -a $BOOTLOADER = "lilo" ] ; then + graph_error "ERROR: you cannot use more than one VG with lilo - use grub as bootloader" + return 1 + fi + + fi + + CHECK="`echo $BOOTLOADER |grep -i -e "^grub$\|^lilo$"`" + if [ -z "$CHECK" ]; then + graph_error "ERROR: No valid BOOTLOADER" + return 1 + fi + + if [ "$BOOTLOADER" = "lilo" ]; then + if [ "$IAM" = "arch" ] || + [ "$IAM" = "coreos" ] || + [ "$IAM" = "centos" ] || + [ "$IAM" = "ubuntu" -a "$IMG_VERSION" -ge 1204 ] || + [ "$IAM" = "debian" -a "$IMG_VERSION" -ge 70 ] || + [ "$IAM" = "suse" -a "$IMG_VERSION" -ge 122 ]; then + graph_error "ERROR: Image doesn't support lilo" + return 1 + fi + fi + + + CHECK="`echo $GOVERNOR |grep -i -e "^performance$\|^ondemand$"`" + if [ -z "$CHECK" ]; then + graph_error "ERROR: No valid GOVERNOR" + return 1 + fi + + + # LVM checks + if [ "$LVM" = "0" -a "$LVM_VG_COUNT" != "0" ] ; then + graph_error "ERROR: There are volume groups defined, but no logical volumes are defined" + return 1 + fi + + if [ "$LVM" = "0" -a "$LVM_LV_COUNT" != "0" ] ; then + graph_error "ERROR: There are logical volumes defined, but no volume groups are defined" + return 1 + fi + + for lv_id in $(seq 1 $LVM_LV_COUNT) ; do + lv_size="${LVM_LV_SIZE[$lv_id]}" + lv_mountp="${LVM_LV_MOUNT[$lv_id]}" + lv_fs="${LVM_LV_FS[$lv_id]}" + lv_vg="${LVM_LV_VG[$lv_id]}" + + + # test if the mountpoint is valid (start with / or swap) + CHECK="`echo $lv_mountp | grep -e "^/\|^swap$"`" + 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$"`" + if [ -z "$CHECK" ]; then + graph_error "ERROR: Filesystem for LV '${LVM_LV_NAME[$lv_id]}' is not correct" + return 1 + fi + + # test if one of the filesystem is not using ext + CHECK=$(echo $lv_fs |grep -e "^ext2$\|^ext3$\|^ext4$\|^swap$") + if [ -z "$CHECK" ]; then + export TAR="tar" + echo "setting TAR to GNUtar" | debugoutput + fi + + if [ "$lv_fs" = "reiserfs" -a "$IAM" = "centos" ]; then + graph_error "ERROR: centos doesn't support reiserfs" + return 1 + fi + +# this seems to be a very old problem. Not a problem for 6.x and later +# if [ "$lv_fs" = "xfs" -a "$lv_mountp" = "/" -a "$IAM" = "centos" ]; then +# graph_error "ERROR: centos doesn't support xfs on partition /" +# return 1 +# fi + + if [ "$lv_size" != "all" -a "$(echo "$lv_size" | sed "s/[0-9]//g")" != "" -o "$lv_size" = "0" ]; then + graph_error "ERROR: size of LV '${LVM_LV_NAME[$lv_id]}' is not a valid number" + return 1 + fi + + if [ "$lv_mountp" = "/" -a "$lv_size" != "all" ]; then + if [ "$lv_size" -lt "1500" ]; then + graph_error "ERROR: Your / partition has to be at least 1500M" + return 1 + fi + fi + + # problem with multiple vgs and all as lv size + # get last lv in vg + for i_lv in $(seq 1 $LVM_LV_COUNT) ; do + if [ "${LVM_LV_VG[$i_lv]}" = "$lv_vg" ] ; then + vg_last_lv=$i_lv + fi + done + if [ "$lv_size" = "all" -a $vg_last_lv -ne $lv_id ] ; then + graph_error "ERROR: LV size \"all\" has to be on the last LV in VG $lv_vg." + return 1 + fi + done + + for lv_id in $(seq 1 $LVM_LV_COUNT) ; do + found_vg="false" + lv_vg=${LVM_LV_VG[$lv_id]} + for vg_id in $(seq 1 $LVM_VG_COUNT) ; do + [ "$lv_vg" = "${LVM_VG_NAME[$vg_id]}" ] && found_vg="true" + done + if [ "$found_vg" = "false" ] ; then + graph_error "ERROR: LVM volume group '$lv_vg' not defined" + return 1 + fi + done + + # check for lvm size + for vg_id in $LVM_VG_CHECK ; do + vg_name="${LVM_VG_NAME[$vg_id]}" + vg_size="${LVM_VG_SIZE[$vg_id]}" + sum_size="0" + + # calculate size correct if more vg with same name + # (e.g. for 2TB limit in CentOS workaround) + for i in $(seq 1 $LVM_VG_COUNT) ; do + # check if vg has same name and is not the same vg + if [ "${LVM_VG_NAME[$i]}" = "$vg_name" -a $i -ne $vg_id ] ; then + vg_add_size=0 + if [ "${LVM_VG_SIZE[$i]}" = "all" ] ; then + vg_add_size=$[$DRIVE_SUM_SIZE - $PARTS_SUM_SIZE] + else + vg_add_size=${LVM_VG_SIZE[$i]} + fi + vg_size=$[$vg_size + $vg_add_size] + fi + done + + for lv_id in $(seq 1 $LVM_LV_COUNT) ; do + if [ "${LVM_LV_VG[$lv_id]}" = "$vg_name" -a "${LVM_LV_SIZE[$lv_id]}" = "all" ] ; then + sum_size=$[$sum_size + ${LVM_LV_SIZE[$lv_id]}] + fi + done + + if [ $vg_size -lt $sum_size ] ; then + graph_error "ERROR: You are going to use more space than your VG $vg_name has available." + return 1 + fi + + done + + #check for identical mountpoints listed in "PART" and "LV" + + local mounts_as_string="" + + # list all mountpoints without the 'lvm' and 'swap' keyword + for i in `seq 1 $PART_COUNT`; do + if [ ${PART_MOUNT[$i]} != "lvm" -a ${PART_MOUNT[$i]} != "swap" ]; then + mounts_as_string="$mounts_as_string${PART_MOUNT[$i]}\n" + fi + done + # append all logical volume mountpoints to $mounts_as_string + for i in `seq 1 $LVM_LV_COUNT`; do + mounts_as_string="$mounts_as_string${LVM_LV_MOUNT[$i]}\n" + done + + # check if there are identical mountpoints + local identical_mount_points="$(echo -e "$mounts_as_string" | sort | uniq -d)" + if [ "$identical_mount_points" ]; then + graph_error "ERROR: There are identical mountpoints in the config ($(echo $identical_mount_points | tr " " ", "))" + return 1 + fi + + # check size of partitions + if [ -n "$(getUSBFlashDrives)" ]; then + graph_notice "\nYou are going to install on an USB flash drive ($(getUSBFlashDrives)). Do you really want this?" + fi + + if [ "$SWRAID" -eq 1 ]; then + if [ "$(getHDDsNotInToleranceRange)" ]; then + graph_notice " + \nNOTICE: You are going to use hard disks with different disk space. + \nWe set the maximum of your allocable disc space based on the smallest hard disk at $SMALLEST_HDD_SIZE MB + \nYou can change this by customizing the drive settings. + " + fi + fi + + if [ "$DRIVE_SUM_SIZE" -lt "$PARTS_SUM_SIZE" ]; then + local diff=$[DRIVE_SUM_SIZE - $PARTS_SUM_SIZE] + graph_error "ERROR: You are going to use more space than your drives have available. + \nUsage: $PARTS_SUM_SIZE MiB of $DRIVE_SUM_SIZE MiB + \nDiff: $diff MiB" + return 1 + fi + + if [ "$HASROOT" != "true" ]; then + graph_error "ERROR: You dont have a partition for /" + return 1 + fi + + if [ "$OPT_INSTALL" ]; then + if [ $(echo $OPT_INSTALL | grep -i "PLESK") ]; then + if [ "$IAM" != "centos" -a "$IAM" != "debian" ]; then + graph_error "ERROR: PLESK is not available for this image" + return 1 + fi + fi + fi + + if [ "$BOOTLOADER" == "grub" ]; then + # check dos partition sizes for centos + local result="$(check_dos_partitions)" + + if [ -n "$result" ]; then + if [ "$result" == "PART_OVERSIZED" ]; then + graph_error "One of your partitions is using more than 2TiB. CentOS only supports booting from hard disks with MS-DOS partition tables which allows only partition sizes up to 2TiB." + return 1 + elif [ "$result" == "PART_BEGIN_OVER_LIMIT" ]; then + graph_error "One of your partitions is starting above 2TiB. CentOS only supports booting from hard disks with MS-DOS partition tables which requires partitions to start below 2TiB." + return 1 + elif [ "$result" == "PART_ALL_BEGIN_OVER_LIMIT" ]; then + graph_error "The \"all\" partition would be starting above 2TiB. CentOS only supports booting from hard disks with MS-DOS partition tables which requires partitions to start below 2TiB." + return 1 + elif [ "$result" == "PART_CHANGED_ALL" ]; then + if [ "$OPT_AUTOMODE" = 1 ] || [ -e /autosetup ]; then + echo -e 'CentOS only supports MS-DOS partition tables when using grub. We changed the space of your \"all\" partition to match the 2TiB limit.' | debugoutput + else + graph_notice "CentOS only supports MS-DOS partition tables when using grub. We changed the space of your \"all\" partition to match the 2TiB limit." + fi + fi + fi + fi + + if [ "$BOOTLOADER" == "lilo" ]; then + graph_notice "WARNING: Lilo is deprecated and no longer supported. Please consider using grub" + fi + + if [ -z "$NEWHOSTNAME" ]; then + graph_error "ERROR: HOSTNAME may not be empty" + return 1 + fi + + fi + return 0 +} + +# +# graph_error [text] +# +# Show graphical error when a validation error occurs. +# +graph_error() { + if [ $# -gt 0 ]; then + dialog --backtitle "$DIATITLE" --title "ERROR" --yes-label "OK" \ + --no-label "Cancel" --yesno \ + "$@\n\nYou will be dropped back to the editor to fix the problem." 0 0 + EXITCODE=$? + else + dialog --backtitle "$DIATITLE" --title "ERROR" --yes-label "OK" \ + --no-label "Cancel" --yesno "An unknown error occured..." 0 0 + EXITCODE=$? + fi + + # set var if user hit "Cancel" + if [ "$EXITCODE" -eq "1" ]; then + CANCELLED="true" + fi +} + +# +# graph_notice [text] +# +# Show graphical notice to user. +# +graph_notice() { + if [ $# -gt 0 ]; then + dialog --backtitle "$DIATITLE" --title "NOTICE" --msgbox \ + "$@\n\n" 0 0 + fi +} + +# which operating system will be installed +# whoami "IMAGENAME" +whoami() { + IAM="debian" + if [ "$1" ]; then + case "$1" in + *SuSE*|*suse*|*Suse*|*SUSE*)IAM="suse";; + *CentOS*|*centos*|*Centos*)IAM="centos";; + *Ubuntu*|*ubuntu*)IAM="ubuntu";; + Arch*)IAM="arch";; + CoreOS*|coreos*) + IAM="coreos" + CLOUDINIT="$FOLD/cloud-config" + echo -e "#cloud-config\n" > $CLOUDINIT + ;; + esac + fi + + IMG_VERSION="$(echo "$1" | cut -d "-" -f 2)" + [ -z "$IMG_VERSION" -o "$IMG_VERSION" = "" -o "$IMG_VERSION" = "h.net.tar.gz" ] && IMG_VERSION="0" + IMG_ARCH="$(echo "$1" | sed 's/.*-\(32\|64\)-.*/\1/')" + + IMG_FULLNAME="$(ls -1 $IMAGESPATH | grep "$1" | grep -v ".sig")" + IMG_EXT="${IMG_FULLNAME#*.}" + + export IAM + export IMG_VERSION + export IMG_ARCH + export IMG_EXT + + return 0 +} + +# +# unmount_all +# +# Unmount all partitions and display an error message if +# unmounting a partition failed. +# +unmount_all() { + unmount_errors=0 + + while read line ; do + device="$(echo "$line" | grep -v "^/dev/loop" | grep -v "^/dev/root" | grep "^/" | awk '{ print $1 }')" + if [ "$device" ] ; then + unmount_output="$unmount_output\n$(umount $device 2>&1)"; EXITCODE=$? + unmount_errors=$[$unmount_errors + $EXITCODE] + fi + done < /proc/mounts + + return $unmount_errors +} + +# +# stop_lvm_raid +# +# Stop the Logical Volume Manager and all software RAID arrays. +# +stop_lvm_raid() { + test -x /etc/init.d/lvm && /etc/init.d/lvm stop &>/dev/null + test -x /etc/init.d/lvm2 && /etc/init.d/lvm2 stop &>/dev/null + + dmsetup remove_all + + test -x "$(which mdadm)" && for i in $(cat /proc/mdstat | grep md | cut -d ' ' -f1); do + [ -e /dev/$i ] && mdadm -S /dev/$i >> /dev/null 2>&1 + done +} + + +# delete partitiontable +# delete_partitions "DRIVE" +delete_partitions() { + if [ "$1" ]; then + # clean RAID information for every partition not only for the blockdevice + for raidmember in $(sfdisk -l "$1" 1>/dev/null 2>/dev/null | grep -o "$1[0-9]"); do + mdadm --zero-superblock $raidmember 2> /dev/null + done + # clean RAID information in superblock of blockdevice + mdadm --zero-superblock $1 2> /dev/null + + #delete GPT and MBR + sgdisk -Z $1 1>/dev/null 2>/dev/null + + # clean mbr boot code + dd if=/dev/zero of=$1 bs=512 count=1 >/dev/null 2>&1 ; EXITCODE=$? + + # re-read partition table + partprobe 2>/dev/null + + return $EXITCODE + fi +} + + +# function which gets the end of the extended partition +# get_end_of_extended "DRIVE" +function get_end_of_extended() { + local DEV="$1" + local DRIVE_SIZE=$(blockdev --getsize64 $DEV) + local SECTORSIZE=$(blockdev --getss $DEV ) + + local end=0 + local sum=0 + local LIMIT=2199023255040 + # get sector limit + local SECTORLIMIT=$[($LIMIT / $SECTORSIZE) - 1] + local STARTSEC=$(sgdisk --first-aligned-in-largest $1 | tail -n1) + + for i in $(seq 1 3); do + sum=$(echo "$sum + ${PART_SIZE[$i]}" | bc) + done + rest=$(echo "$DRIVE_SIZE - ($sum * 1024 * 1024)" | bc) + + end=$(blockdev --getsz $DEV) + + if [ $DRIVE_SIZE -lt $LIMIT ]; then + echo "$[$end-1]" + else + if [ $rest -gt $LIMIT ]; then + # if the remaining space is more than 2 TiB, the end of the extended + # partition is the current sector plus 2^32-1 sectors (2TiB-512 Byte) + echo "$(echo "$STARTSEC+$SECTORLIMIT" | bc)" + else + # otherwise the end is the number of sectors - 1 + echo "$[$end-1]" + fi + fi +} + +# function which calculates the end of the partition +# get_end_of_partition "PARTITION" +function get_end_of_partition { + local DEV=$1 + local START=$2 + local NR=$3 + local LIMIT=2199023255040 + local SECTORSIZE=$(blockdev --getss $DEV) + local SECTORLIMIT=$[($LIMIT / $SECTORSIZE) - 1] + local END_EXTENDED="$(parted -s $DEV unit s print | grep extended | awk '{print $3}' | sed -e 's/s//')" + local DEVSIZE=$(blockdev --getsize64 $DEV) + + # use the smallest hdd as reference when using swraid + # to determine the end of a partition + local smallest_hdd=$(smallest_hd) + local smallest_hdd_space="$(blockdev --getsize64 $smallest_hdd)" + if [ "$SWRAID" -eq "1" ] && [ $DEVSIZE -gt $smallest_hdd_space ]; then + DEV=$smallest_hdd + fi + + local LAST=$(blockdev --getsz $DEV) + + # make the partition at least 1 MiB if all else fails + local END=[$START+2048] + + if [ "`echo ${PART_SIZE[$NR]} |tr [:upper:] [:lower:]`" = "all" ]; then + # leave 1MiB space at the end (may be needed for mdadm or for later conversion to GPT) + END=$[$LAST-2048] + else + END="$(echo "$START+(${PART_SIZE[$NR]}* 1024 * 1024 / $SECTORSIZE)" | bc)" + # trough alignment the calculated end could be a little bit over drive size + # or too close to the end. Always leave 1MiB space + # (may be needed for mdadm or for later conversion to GPT) + if [ $END -ge $LAST ] || [ $[$LAST - $END] -lt 2048 ]; then + END=$[$LAST-2048] + fi + fi + # check if end of logical partition is over the end extended partition + if [ $PCOUNT -gt 4 ] && [ $END -gt $END_EXTENDED ]; then + # leave 1MiB space at the end (may be needed for mdadm or for later conversion to GPT) + END=$[$END_EXTENDED-2048] + fi + + echo $END +} + + +# create partitons on the given drive +# create_partitions "DRIVE" +create_partitions() { + if [ "$1" ]; then + # write standard entries to fstab + echo "proc /proc proc defaults 0 0" > $FOLD/fstab + # 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 + echo "devpts /dev/pts devpts gid=5,mode=620 0 0" >> $FOLD/fstab + echo "tmpfs /dev/shm tmpfs defaults 0 0" >> $FOLD/fstab + echo "sysfs /sys sysfs defaults 0 0" >> $FOLD/fstab + fi + #copy defaults to tempfstab for softwareraid + ### cp $FOLD/fstab $FOLD/fstab.md >>/dev/null 2>&1 + + echo "deactivate all dm-devices with dmraid and dmsetup" | debugoutput + dmsetup remove_all 2>&1 | debugoutput + dmraid -a no 2>&1 | debugoutput + + dd if=/dev/zero of=$1 bs=1M count=10 1>/dev/null 2>&1 + hdparm -z $1 >/dev/null 2>&1 + + #create GPT + if [ $GPT -eq '1' ]; then + #create GPT and randomize disk id (GUID) + sgdisk -o $1 1>/dev/null 2>/dev/null + sgdisk -G $1 1>/dev/null 2>/dev/null + + # set dummy partition active/bootable in protective MBR to give some too + # smart BIOS the clue that this disk can be booted in legacy mode + sfdisk -A $1 1 --force 1>/dev/null 2>/dev/null + else + parted -s $1 mklabel msdos 1>/dev/null 2>/tmp/$$.tmp + cat /tmp/$$.tmp | debugoutput + fi + + # start loop to create all partitions + for i in `seq 1 $PART_COUNT`; do + + SFDISKTYPE="83" + if [ "${PART_FS[$i]}" = "swap" ]; then + SFDISKTYPE="82" + fi + if [ "${PART_MOUNT[$i]}" = "lvm" ]; then + SFDISKTYPE="8e" + fi + if [ "$SWRAID" -eq "1" ]; then + SFDISKTYPE="fd" + fi + + if [ "`echo ${PART_SIZE[$i]} |tr [:upper:] [:lower:]`" = "all" ]; then + SFDISKSIZE="" + else + SFDISKSIZE="${PART_SIZE[$i]}" + fi + + + #create GPT partitions + if [ $GPT -eq 1 ]; then + + # start at 2MiB so we have 1 MiB left for BIOS Boot Partition + START=4096 + if [ $i -gt 1 ]; then + START=$(sgdisk --first-aligned-in-largest $1 | tail -n1) + fi + END=$(sgdisk --end-of-largest $1 | tail -n 1) + local gpt_part_size='' + + if [ -n "$SFDISKSIZE" ]; then + gpt_part_size="+${SFDISKSIZE}M" + fi + + local gpt_part_type="${SFDISKTYPE}00" + + if [ $i -eq $PART_COUNT ]; then + echo "Creating BIOS_GRUB partition" | debugoutput + sgdisk --new $i:2048:+1M -t $i:EF02 $1 | debugoutput + else + if [ -z $SFDISKSIZE ] && [ $i -gt 1 ]; then + sgdisk --largest-new $i -t $i:$gpt_part_type $1 | debugoutput + else + sgdisk --new $i:$START:$gpt_part_size -t $i:$gpt_part_type $1 | debugoutput + fi + fi + + make_fstab_entry "$1" "$i" "${PART_MOUNT[$i]}" "${PART_FS[$i]}" + + else + # part without GPT + START=2048 + TYPE="primary" + PCOUNT="$i" + + if [ "$i" -gt "1" ]; then + START=$(sgdisk --first-aligned-in-largest $1 | tail -n1) + fi + + # determine the end sector of the partition + END=$(get_end_of_partition $1 $START $i) + + if [ "$i" -eq "4" ]; then + TYPE="extended" + END="$(get_end_of_extended $1)" + + # create the extended partition + echo "create partition: parted -s $1 mkpart $TYPE ${START}s ${END}s" | debugoutput + OUTPUT="$(parted -s $1 mkpart $TYPE ${START}s ${END}s)" + if [ -n "$OUTPUT" ]; then + echo "$OUTPUT" | debugoutput + fi + + PCOUNT=$[$PCOUNT+1] + + TYPE="logical" + START=$[$START + 2048] + + END=$(get_end_of_partition $1 $START $i) + fi + + if [ "$i" -gt "4" ]; then + TYPE="logical" + fi + + # create partitions as ext3 which results in type 83 + local FSTYPE="ext3" + if [ "${PART_FS[$i]}" = "swap" ]; then + FSTYPE="linux-swap" + fi + + echo "create partition: parted -s $1 mkpart $TYPE $FSTYPE ${START}s ${END}s" | debugoutput + OUTPUT="$(parted -s $1 mkpart $TYPE $FSTYPE ${START}s ${END}s)" + + if [ -n "$OUTPUT" ]; then + echo "$OUTPUT" | debugoutput + fi + + if [ "${PART_MOUNT[$i]}" = "lvm" ]; then + parted -s $1 set $PCOUNT lvm on + fi + + + if [ "$SWRAID" = "1" ]; then + parted -s $1 set $PCOUNT raid on + fi + + + if [ "$PART_COUNT" -ge "4" -a "$i" -ge "4" ]; then + make_fstab_entry "$1" "$[$i+1]" "${PART_MOUNT[$i]}" "${PART_FS[$i]}" + else + make_fstab_entry "$1" "$i" "${PART_MOUNT[$i]}" "${PART_FS[$i]}" + fi + fi + + done + + # we make sure in get_end_of_partition that the all msdos partitions end at + # 1MiB before the end of the disk, so the following is not needed anymore + +# if [ "$GPT" != "1" ]; then +# # resize last partition so that we have 128 kb free +# echo "resize last partition for mdadm" | debugoutput +# LAST_PART_START="$(parted -s $1 unit s print | tail -n 2 | head -n 1 | awk '{print$2}' | rev | cut -c 2- | rev)" +# LAST_PART_END="$(parted -s $1 unit s print | tail -n 2 | head -n 1 | awk '{print$3}' |rev | cut -c 2- | rev)" +# DISK_SIZE_SECTORS="$(parted -s $1 unit s print | grep Disk | awk '{print$3}' | rev | cut -c 2- | rev)" + +# SECTOR_DIFF=$((DISK_SIZE_SECTORS-LAST_PART_END)) + +# if [ "$SWRAID" = "1" ]; then +# if [ "$SECTOR_DIFF" -lt "250" ]; then +# part_end_diff=$((250-SECTOR_DIFF)) +# NEW_LAST_PART_END=$((LAST_PART_END-part_end_diff)) + +# parted -s $1 mkfs $PART_COUNT linux-swap >/dev/null 2>/tmp/$$.tmp +# parted -s $1 unit s resize ${PART_COUNT} ${LAST_PART_START} ${NEW_LAST_PART_END} >/dev/null 2>/tmp/$$.tmp +# fi +# cat /tmp/$$.tmp | debugoutput +# fi +# fi + + #reread partition table after some break + echo "reread partition table after 5 seconds" | debugoutput + sleep 5 + hdparm -z $1 >/dev/null 2>&1 + + echo "deactivate all dm-devices with dmraid and dmsetup" | debugoutput + dmraid -a no 2>&1 | debugoutput + dmsetup remove_all 2>&1 | debugoutput + + return $EXITCODE + fi +} + +# create fstab entries +# make_fstab_entry "DRIVE" "NUMBER" "MOUNTPOINT" "FILESYSTEM" +make_fstab_entry() { + if [ "$1" -a "$2" -a "$3" -a "$4" ]; then + ENTRY="" + + if [ "$4" = "swap" ] ; then + ENTRY="$1$2 none swap sw 0 0" + elif [ "$3" = "lvm" ] ; then + ENTRY="# $1$2 belongs to LVM volume group '$4'" + else + ENTRY="$1$2 $3 $4 defaults 0 0" + fi + + echo $ENTRY >>$FOLD/fstab + + if [ "$3" = "/" ]; then + SYSTEMREALROOTDEVICE="$1$2" + if [ -z "$SYSTEMREALBOOTDEVICE" ]; then + SYSTEMREALBOOTDEVICE="$1$2" + fi + fi + if [ "$3" = "/boot" ]; then + SYSTEMREALBOOTDEVICE="$1$2" + fi + + fi +} + + +next_partnum() { + num="$1" + if [ "$GPT" != "1" ]; then + if [ $num -lt 3 ] ; then + echo $[$num+1] ; return + else + echo $[$num+2] + fi + else + echo $[$num+1] + fi +} + + +make_swraid() { + if [ "$1" ] ; then + fstab=$1 + + dmsetup remove_all + + count=0 + PARTNUM=0 + LASTDRIVE="$(eval echo \$DRIVE${COUNT_DRIVES})" + SEDHDD="$(echo $LASTDRIVE | sed 's/\//\\\//g')" + + LILOEXTRABOOT="raid-extra-boot=" + for i in $(seq 1 $COUNT_DRIVES) ; do + TARGETDISK="$(eval echo \$DRIVE${i})" + LILOEXTRABOOT="$LILOEXTRABOOT,$TARGETDISK" + done + + mv $fstab $fstab.tmp + + debug "# create software raid array(s)" + METADATA="--metadata=1.2" + + #centos 6.x metadata + if [ "$IAM" = "centos" ]; then + if [ "$IMG_VERSION" -ge 60 ]; then + METADATA="--metadata=1.0" + else + METADATA="--metadata=0.90" + fi + fi + + local metadata_boot=$METADATA + [ "$IAM" == "ubuntu" -a "$IMG_VERSION" -lt 1204 ] && metadata_boot="--metadata=0.90" + + while read line ; do + PARTNUM="$(next_partnum $count)" + + echo "Line is: \"$line\"" | debugoutput + # we always use /dev/mdX in Ubuntu 10.04. In all other distributions we use it when we have Metadata format 0.90 + # in Ubuntu 11.04 we have to use /boot with metadata format 0.90 + if [ -n "$(echo "$line" | grep "/boot")" -a "$metadata_boot" == "--metadata=0.90" ] || [ "$METADATA" == "--metadata=0.90" ] || [ "$IAM" == "ubuntu" -a "$IMG_VERSION" == "1004" ] || [ "$IAM" == "suse" ] || [ "$IAM" == "centos" ]; then + # update fstab - replace /dev/sdaX with /dev/mdY + echo $line | sed "s/$SEDHDD[[:digit:]]\{1,2\}/\/dev\/md$count/g" >> $fstab + else + # update fstab - replace /dev/sdaX with /dev/md/Y + echo $line | sed "s/$SEDHDD[[:digit:]]\{1,2\}/\/dev\/md\/$count/g" >> $fstab + fi + + # create raid array + if echo $line | grep $LASTDRIVE >/dev/null ; then + + local raid_device="/dev/md/$count" + local components="" + local n=0 + for n in $(seq 1 $COUNT_DRIVES) ; do + TARGETDISK="$(eval echo \$DRIVE${n})" + components="$components $TARGETDISK$PARTNUM" + done + + local array_metadata=$METADATA + local array_raidlevel=$SWRAIDLEVEL + local can_assume_clean='' + + # lilo and GRUB can't boot from a RAID0/5/6 or 10 partition, so make /boot always RAID1 + if [ "$(echo "$line" | grep "/boot")" ]; then + array_raidlevel="1" + array_metadata=$metadata_boot + # make swap partiton RAID1 for all levels except RAID0 + elif [ "$(echo "$line" | grep "swap")" ] && [ "$SWRAIDLEVEL" != "0" ]; then + array_raidlevel="1" + fi + + if [ "$RAID_ASSUME_CLEAN" = "1" ]; then + if [ "$SWRAIDLEVEL" = "1" ] || [ "$SWRAIDLEVEL" = "10" ] || [ "$SWRAIDLEVEL" = "6" ]; then + can_assume_clean='--assume-clean' + fi + fi + echo "Array RAID Level is: \"$array_raidlevel\" - $can_assume_clean" | debugoutput + echo "Array metadata is: \"$array_metadata\"" | debugoutput + + yes | mdadm -q -C $raid_device -l$array_raidlevel -n$n $array_metadata $can_assume_clean $components 2>&1 >/dev/null | debugoutput ; EXITCODE=$? + + count="$[$count+1]" + fi + + done < $fstab.tmp + + fi + return 0 +} + + +make_lvm() { + if [ "$1" -a "$2" ] ; then + fstab=$1 + disk1=$2 + + # get device names for PVs depending if we use swraid or not + inc_dev=1 + if [ $SWRAID -eq 1 ]; then + for md in $(ls -1 /dev/md/[0-9]*) ; do + dev[$inc_dev]="$md" + let inc_dev=inc_dev+1 + done + else + for inc_dev in $(seq 1 $(ls -1 ${DRIVE1}[0-9]* | wc -l)) ; do + dev[$inc_dev]="$disk1$(next_partnum $[$inc_dev-1])" + done + fi + + # remove all Logical Volumes and Volume Groups + debug "# Removing all Logical Volumes and Volume Groups" + vgs --noheadings 2> /dev/null | while read vg pvs; do + lvremove -f $vg 2>&1 | debugoutput + vgremove -f $vg 2>&1 | debugoutput + done + + # remove all Physical Volumes + debug "# Removing all Physical Volumes" + pvs --noheadings 2>/dev/null | while read pv vg; do + pvremove -ff $pv 2>&1 | debugoutput + done + + # create PVs + for i in $(seq 1 $LVM_VG_COUNT) ; do + pv=${dev[${LVM_VG_PART[${i}]}]} + debug "# Creating PV $pv" + pvcreate -ff $pv 2>&1 | debugoutput + done + + # create VGs + for i in $(seq 1 $LVM_VG_COUNT) ; do + vg=${LVM_VG_NAME[$i]} + pv=${dev[${LVM_VG_PART[${i}]}]} + + # extend the VG if a VG with the same name already exists + if [ "$(vgs --noheadings 2>/dev/null | grep "$vg")" ]; then + debug "# Extending VG $vg with PV $pv" + vgextend $vg $pv 2>&1 | debugoutput + else + debug "# Creating VG $vg with PV $pv" + [ "$vg" ] && rm -rf "/dev/$vg" 2>&1 | debugoutput + vgcreate $vg $pv 2>&1 | debugoutput + fi + done + + # create LVs + for i in $(seq 1 $LVM_LV_COUNT) ; do + lv=${LVM_LV_NAME[$i]} + vg=${LVM_LV_VG[$i]} + size=${LVM_LV_SIZE[$i]} + vg_last_lv='' + free='' + + # get last lv of vg + for i_lv in $(seq 1 $LVM_LV_COUNT) ; do + if [ "${LVM_LV_VG[$i_lv]}" = "$vg" ] ; then + vg_last_lv=$i_lv + fi + done + + # calculate free space of vg + free="$(vgs --units m $vg | tail -n1 | awk '{ print $7 }' | rev | cut -b 5- | rev)" + + # calculate size of all lv + # or resize last lv if not enough space in vg + # (has to be recalculated because of lvm metadata) + if [ "$size" = "all" ] ; then + size="$(translate_unit $free)" + else + if [ $i -eq $vg_last_lv -a $free -lt $size ] ; then + size="$(translate_unit $free)" + debug "# Resize LV $lv in VG $vg to $size MiB because of not enough free space" + fi + fi + + debug "# Creating LV $vg/$lv ($size MiB)" + lvcreate --name $lv --size $size $vg 2>&1 | debugoutput + test $? -eq 0 || return 1 + done + + # 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 + done + + else + debug "parameters incorrect for make_lvm()" + echo "params incorrect for make_lvm" ; return 1 + fi + return 0 +} + + +format_partitions() { + if [ "$1" -a "$2" ]; then + DEV="$1" + FS="$2" + EXITCODE=0 + + # reread partition table after some break + sleep 4 + hdparm -z $1 >/dev/null 2>/dev/null + + if [ -b $DEV ] ; then + debug "# formatting $DEV with $FS" + if [ "$FS" = "swap" ]; then + # format swap partition with dd first because mkswap + # doesnt overwrite sw-raid information! + mkfs -t xfs -f $DEV 2>&1 | debugoutput + dd if=/dev/zero of=$DEV bs=256 count=8 2>&1 | debugoutput + # then write swap information + mkswap $DEV 2>&1 | debugoutput ; EXITCODE=$? + elif [ "$FS" = "ext2" -o "$FS" = "ext3" -o "$FS" = "ext4" ]; then + mkfs -t $FS -q $DEV 2>&1 | debugoutput ; EXITCODE=$? + elif [ "$FS" = "btrfs" ]; then + wipefs $DEV | debugoutput + mkfs -t $FS $DEV 2>&1 | debugoutput ; EXITCODE=$? + else + mkfs -t $FS -q -f $DEV 2>&1 >/dev/null | debugoutput ; EXITCODE=$? + fi + else + debug "! this is no valid block device: $DEV" + debug "content from ls /dev/[hmsv]d*: $(ls /dev/[hmsv]d*)" + fi + return $EXITCODE + fi +} + +mount_partitions() { + if [ "$1" -a "$2" ]; then + fstab="$1" + basedir="$2" + + ROOTDEVICE="`cat $fstab | grep " / " | cut -d " " -f 1`" + SYSTEMROOTDEVICE="$ROOTDEVICE" + SYSTEMBOOTDEVICE="$SYSTEMROOTDEVICE" + + mount "$ROOTDEVICE" "$basedir" 2>&1 | debugoutput ; EXITCODE=$? + [ "$EXITCODE" -ne "0" ] && return 1 + + mkdir -p $basedir/proc 2>&1 | debugoutput + mount -o bind /proc $basedir/proc 2>&1 | debugoutput ; EXITCODE=$? + [ "$EXITCODE" -ne "0" ] && return 1 + + mkdir -p $basedir/dev 2>&1 | debugoutput + mount -o bind /dev $basedir/dev 2>&1 | debugoutput ; EXITCODE=$? + [ "$EXITCODE" -ne "0" ] && return 1 + + mkdir -p $basedir/dev/pts 2>&1 | debugoutput + mount -o bind /dev/pts $basedir/dev/pts 2>&1 | debugoutput ; EXITCODE=$? + [ "$EXITCODE" -ne "0" ] && return 1 + + # bind /dev/shm too + # wheezy rescue: /dev/shm links to /run/shm + if [ -L $basedir/dev/shm ] ; then + shmlink="$(readlink $basedir/dev/shm)" + mkdir -p ${basedir}${shmlink} 2>&1 | debugoutput + if [ -e $shmlink ] ; then + mount -o bind $shmlink ${basedir}${shmlink} 2>&1 | debugoutput ; EXITCODE=$? + else + mount -o bind /dev/shm ${basedir}${shmlink} 2>&1 | debugoutput ; EXITCODE=$? + fi + [ "$EXITCODE" -ne "0" ] && return 1 + else + mkdir -p $basedir/dev/shm 2>&1 | debugoutput + mount -o bind /dev/shm $basedir/dev/shm 2>&1 | debugoutput ; EXITCODE=$? + [ "$EXITCODE" -ne "0" ] && return 1 + fi + + mkdir -p $basedir/sys 2>&1 | debugoutput + mount -o bind /sys $basedir/sys 2>&1 | debugoutput ; EXITCODE=$? + [ "$EXITCODE" -ne "0" ] && return 1 + + cat $fstab | grep -v " / \|swap" | grep "^/dev/" > $fstab.tmp + + while read line ; do + DEVICE="`echo $line | cut -d " " -f 1`" + MOUNTPOINT="`echo $line | cut -d " " -f 2`" + mkdir -p "$basedir$MOUNTPOINT" 2>&1 | debugoutput + + # create lock and run dir for ubuntu if /var has its own filesystem + # otherwise network does not come up - see ticket 2008012610009793 + if [ "$MOUNTPOINT" = "/var" -a "$IAM" = "ubuntu" ]; then + mkdir -p -m 1777 "$basedir/var/lock" 2>&1 | debugoutput + mkdir -p -m 1777 "$basedir/var/run" 2>&1 | debugoutput + fi + + # mount it + mount "$DEVICE" "$basedir$MOUNTPOINT" 2>&1 | debugoutput + if [ $? -ne 0 ]; then + return 1 + fi + if [ "$MOUNTPOINT" = "/boot" ]; then + SYSTEMBOOTDEVICE="$DEVICE" + fi + done < $fstab.tmp + + if [ "$SWRAID" -eq "1" ]; then + SYSTEMDEVICE="$SYSTEMBOOTDEVICE" + fi + mkdir -p $basedir/sys + return 0 + fi +} + +# set EXTRACTFROM for next functions +# params: IMAGE_PATH, IMAGE_PATH_TYPE, IMAGE_FILE +get_image_info() { + if [ "$1" -a "$2" -a "$3" ]; then + case $2 in + nfs) + mount -t "nfs" "$1" "$FOLD/nfs" 2>&1 | debugoutput ; EXITCODE=$? + if [ "$EXITCODE" -ne "0" -o ! -e "$FOLD/nfs/$3" ]; then + return 1 + else + EXTRACTFROM="$FOLD/nfs/$3" + if [ -e "${EXTRACTFROM}.sig" ] ; then + IMAGE_SIGN="${EXTRACTFROM}.sig" + fi + if [ -e "${1}public-key.asc" ] ; then + IMAGE_PUBKEY="${1}public-key.asc" + fi + fi + ;; + http) + mkdir $FOLD/keys/ 2>&1 + cd $FOLD/keys/ + # no exitcode, because if not found hetzner-pubkey will be used + wget -q --no-check-certificate "${1}public-key.asc" 2>&1 | debugoutput ; >/dev/null + if [ "$EXITCODE" -eq "0" ]; then + IMAGE_PUBKEY="$FOLD/keys/public-key.asc" + fi + cd - >/dev/null + # download image with get_image_url later after mounting hdd + EXITCODE=0; + ;; + local) + if [ -e "$1$3" ]; then + EXTRACTFROM="$1$3" + if [ -e "${EXTRACTFROM}.sig" ] ; then + IMAGE_SIGN="${EXTRACTFROM}.sig" + elif [ -e "${1}sig/${3}.sig" ] ; then + IMAGE_SIGN="${1}sig/${3}.sig" + fi + if [ -e "${1}public-key.asc" ] ; then + IMAGE_PUBKEY="${1}public-key.asc" + fi + else + return 1 + fi + ;; + *)return 1;; + esac + + if [ "$EXITCODE" -eq "0" ]; then + return 0 + else + return 1 + fi + fi +} + +# download image via http/ftp +get_image_url() { + # load image to mounted hdd + cd $FOLD/hdd/ ; wget -q --no-check-certificate "$1$2" 2>&1 | debugoutput ; EXITCODE=$?; cd - >/dev/null + if [ "$EXITCODE" -eq "0" ]; then + EXTRACTFROM="$FOLD/hdd/$2" + # search for sign file and download + cd $FOLD/keys/ ; wget -q --no-check-certificate "$1$2.sig" 2>&1 | debugoutput ; EXITCODE=$?; cd - >/dev/null + if [ "$EXITCODE" -eq "0" ]; then + IMAGE_SIGN="$FOLD/keys/$2.sig" + fi + return 0 + else + return 1 + fi +} + +# import the gpg public key for imagevalidation +import_imagekey() { + local PUBKEY="" + # check if pubkey is given by the customer + if [ -n "$IMAGE_PUBKEY" -a -e "$IMAGE_PUBKEY" ] ; then + PUBKEY=$IMAGE_PUBKEY + elif [ -e "$HETZNER_PUBKEY" ] ; then + # if no special pubkey given, use the hetzner key + echo "Using hetzner standard pubkey: $HETZNER_PUBKEY" | debugoutput + PUBKEY=$HETZNER_PUBKEY + fi + if [ -n "$PUBKEY" ] ; then + # import public key + gpg --batch --import $PUBKEY 2>&1 | debugoutput ; EXITCODE=$? + + if [ "$EXITCODE" -eq "0" ]; then + IMAGE_PUBKEY_IMPORTED="yes" + return 0 + else + return 1 + fi + fi + echo "No public key found" | debugoutput + return 2 +} + +# validate image with detached signature +validate_image() { + if [ "$IMAGE_PUBKEY_IMPORTED" = "yes" ] ; then + if [ -n "$IMAGE_SIGN" ] ; then + # verify image with given pubkey and signature + gpg --batch --verify $IMAGE_SIGN $EXTRACTFROM 2>&1 | debugoutput ; EXITCODE=$? + if [ "$EXITCODE" -eq "0" ]; then + # image file valid + return 0 + else + # image file not valid + return 1 + fi + else + # no detached sign found + return 2 + fi + else + # no public key found + return 3 + fi +} + +# extract image file to hdd +extract_image() { + local COMPRESSION="" + if [ "$1" -a "$2" ]; then + case "$2" in + tar) + COMPRESSION="" + ;; + tgz) + COMPRESSION="-z" + ;; + tbz) + COMPRESSION="-j" + ;; + txz) + COMPRESSION="-J" + ;; + *)return 1;; + esac + + # extract image with given compression + if [ "$TAR" = "tar" ] || [ ! -x /usr/bin/bsdtar ]; then + tar --anchored --numeric-owner --exclude "sys" --exclude "proc" --exclude "dev" $COMPRESSION -x -f "$EXTRACTFROM" -C "$FOLD/hdd/" 2>&1 | debugoutput ; EXITCODE=$? + else + bsdtar --numeric-owner --exclude '^sys' --exclude '^proc' --exclude '^dev' $COMPRESSION -x -f "$EXTRACTFROM" -C "$FOLD/hdd/" 2>&1 | debugoutput ; EXITCODE=$? + fi + # remove image after extraction if we got it via wget (http(s)/ftp) + [ "$1" = "http" ] && rm -f $EXTRACTFROM + + if [ "$EXITCODE" -eq "0" ]; then + cp -r "$FOLD/fstab" "$FOLD/hdd/etc/fstab" 2>&1 | debugoutput + return 0 + else + return 1 + fi + + 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 our global ipv6 + DOIPV6=$(ip -6 addr show dev $ETHDEV | grep 'inet6 2a01:4f8:') + if [ -n "$DOIPV6" ]; then + local INET6ADDR=$(ip -6 addr show dev $ETHDEV | grep 'inet6 2a01:4f8:' | 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 | grep "default\ via" | 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" -a "$2" -a "$3" -a "$4" -a "$5" -a "$6" -a "$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. +# +generate_resolvconf() { + if [ "$IAM" = "suse" ] && [ "$IMG_VERSION" -ge 122 ]; then + # disable netconfig of DNS servers in YaST config file + sed -i -e \ + "s/^NETCONFIG_DNS_POLICY=\".*\"/NETCONFIG_DNS_POLICY=\"\"/" \ + $FOLD/hdd/etc/sysconfig/network/config + +# 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" + fi +# else + NAMESERVERFILE="$FOLD/hdd/etc/resolv.conf" + echo -e "### Hetzner Online AG 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 + + # 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 + + return 0 +} + +# set_hostname "HOSTNAME" +set_hostname() { + if [ "$1" -a "$2" ]; then + local sethostname="$1" + + local mailname="$sethostname" + local hostnamefile="$FOLD/hdd/etc/hostname" + local mailnamefile="$FOLD/hdd/etc/mailname" + local machinefile="$FOLD/hdd/etc/machine-id" + local networkfile="$FOLD/hdd/etc/sysconfig/network" + local hostsfile="$FOLD/hdd/etc/hosts" + + [ -f $FOLD/hdd/etc/HOSTNAME ] && hostnamefile="$FOLD/hdd/etc/HOSTNAME" + + hostname $sethostname + execute_chroot_command "hostname $sethostname" + + check_fqdn "$sethostname" + [ $? -eq 1 ] && shortname="$sethostname" || shortname="$(hostname -s )" + + if [ -f $hostnamefile ]; then + echo "$shortname" > $hostnamefile + debug "# set new hostname '$shortname' in $hostnamefile" + fi + + check_fqdn "$mailname" + [ $? -eq 1 ] && mailname="$(create_hostname $IPADDR)" + if [ -f $mailnamefile ]; then + echo "$mailname" > $mailnamefile + debug "# set new mailname '$mailname' in $mailnamefile" + fi + + if [ -f $machinefile ]; then + # clear machine-id from install (will be regen upon first boot) + echo > $machinefile + fi + + if [ -f $networkfile ]; then + debug "# set new hostname '$shortname' in $networkfile" + echo -e "HOSTNAME=$shortname" >> $networkfile 2>>$DEBUGFILE + fi + + local fqdn_name="$sethostname" + [ "$sethostname" = "$shortname" ] && fqdn_name='' + + echo "### Hetzner Online AG 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 + 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 + if [ "$PROXMOX" = 'true' ] && [ "$PROXMOX_VERSION" = '3' ]; then + debug "not adding ipv6 fqdn to hosts for Proxmox3" + else + echo "$3 $fqdn_name $shortname" >> $hostsfile + fi + fi + + return 0 + else + return 1 + fi +} + +# generate_hosts "IP" +generate_hosts() { + if [ "$1" ]; then + HOSTSFILE="$FOLD/hdd/etc/hosts" + [ -f $FOLD/hdd/etc/hostname ] && HOSTNAMEFILE="$FOLD/hdd/etc/hostname" + [ -f $FOLD/hdd/etc/HOSTNAME ] && HOSTNAMEFILE="$FOLD/hdd/etc/HOSTNAME" + if [ "$HOSTNAMEFILE" = "" ]; then + if [ "$NEWHOSTNAME" ]; then + HOSTNAME="$NEWHOSTNAME"; + else + HOSTNAME="$IMAGENAME"; + fi + else + FULLHOSTNAME="`cat $HOSTNAMEFILE`" + HOSTNAME="`cat $HOSTNAMEFILE | cut -d. -f1`"; + [ "$FULLHOSTNAME" = "$HOSTNAME" ] && FULLHOSTNAME="" + fi + echo "### Hetzner Online AG installimage" > $HOSTSFILE + echo "# nameserver config" >> $HOSTSFILE + echo "# IPv4" >> $HOSTSFILE + echo "127.0.0.1 localhost.localdomain localhost" >> $HOSTSFILE + echo "$1 $FULLHOSTNAME $HOSTNAME" >> $HOSTSFILE + echo "#" >> $HOSTSFILE + echo "# IPv6" >> $HOSTSFILE + 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 [ "$2" ]; then + if [ "$PROXMOX" = 'true' ] && [ "$PROXMOX_VERSION" = '3' ]; then + debug "not adding ipv6 fqdn to hosts for Proxmox3" + else + echo "$2 $FULLHOSTNAME $HOSTNAME" >> $HOSTSFILE + fi + fi + fi + return 0 +} + +# execute_chroot_command "COMMMAND" +execute_chroot_command() { + if [ "$1" ]; then + debug "# chroot_command: $1" + chroot $FOLD/hdd/ /bin/bash -c "$1" 2>&1 | debugoutput ; EXITCODE=$? + return $EXITCODE + fi +} + +# execute chroot command but without debugoutput +execute_chroot_command_wo_debug() { + if [ "$1" ]; then + chroot $FOLD/hdd/ /bin/bash -c "$1" 2>&1; EXITCODE=$? + return $EXITCODE + fi +} + +# copy_mtab "NIL" +copy_mtab() { + if [ "$1" ]; then + if [ -L "$FOLD/hdd/etc/mtab" ]; then + debug "mtab is already a symlink" + return 0 + else + execute_chroot_command "grep -v swap /etc/fstab > /etc/mtab" ; EXITCODE=$? + return $EXITCODE + fi + fi +} + + +generate_new_sshkeys() { + if [ "$1" ]; then +# rm -rf $FOLD/hdd/etc/ssh/ssh_host_* 2>&1 | debugoutput + + if [ -f "$FOLD/hdd/etc/ssh/ssh_host_key" ]; then + rm -f $FOLD/hdd/etc/ssh/ssh_host_k* 2>&1 | debugoutput + execute_chroot_command "ssh-keygen -t rsa1 -b 1024 -f /etc/ssh/ssh_host_key -N '' >/dev/null"; EXITCODE=$? + if [ "$EXITCODE" -ne "0" ]; then + return $EXITCODE + fi + else + debug "skipping rsa1 key gen" + fi + + if [ -f "$FOLD/hdd/etc/ssh/ssh_host_dsa_key" ]; then + rm -f $FOLD/hdd/etc/ssh/ssh_host_dsa_* 2>&1 | debugoutput + execute_chroot_command "ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' >/dev/null"; EXITCODE=$? + if [ "$EXITCODE" -ne "0" ]; then + return $EXITCODE + fi + else + debug "skipping dsa key gen" + fi + + if [ -f "$FOLD/hdd/etc/ssh/ssh_host_rsa_key" ]; then + rm -f $FOLD/hdd/etc/ssh/ssh_host_rsa_* 2>&1 | debugoutput + execute_chroot_command "ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' >/dev/null"; EXITCODE=$? + if [ "$EXITCODE" -ne "0" ]; then + return $EXITCODE + fi + else + debug "skipping rsa key gen" + fi + + # create ecdsa keys for Ubuntu 11.04, Opensuse 12.1, Debian 7.0, CentOS 7.0 and any version above +# if [ "$IAM" = "arch" ] || +# [ "$IAM" = "ubuntu" -a "$IMG_VERSION" -ge 1104 ] || +# [ "$IAM" = "suse" -a "$IMG_VERSION" -ge 121 ] || +# [ "$IAM" = "debian" -a "$IMG_VERSION" -ge 70 ] || +# [ "$IAM" = "centos" -a "$IMG_VERSION" -ge 70 ]; then + if [ -f "$FOLD/hdd/etc/ssh/ssh_host_ecdsa_key" ]; then + rm -f $FOLD/hdd/etc/ssh/ssh_host_ecdsa_* 2>&1 | debugoutput + execute_chroot_command "ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N '' >/dev/null"; EXITCODE=$? + if [ "$EXITCODE" -ne "0" ]; then + return $EXITCODE + fi + else + debug "skipping ecdsa key gen" + fi + +# if [ "$IAM" = "arch" ] || +# [ "$IAM" = "debian" -a "$IMG_VERSION" -ge 80 ] || +# [ "$IAM" = "ubuntu" -a "$IMG_VERSION" -ge 1404 ] || +# [ "$IAM" = "suse" -a "$IMG_VERSION" -ge 132 ]; then + if [ -f "$FOLD/hdd/etc/ssh/ssh_host_ed25515_key" ]; then + rm -f $FOLD/hdd/etc/ssh/ssh_host_ed25519_* 2>&1 | debugoutput + execute_chroot_command "ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N '' >/dev/null"; EXITCODE=$? + if [ "$EXITCODE" -ne "0" ]; then + return $EXITCODE + fi + else + debug "skipping ed25519 key gen" + fi + + ### create json of host ssh fingerprints for robot + local keys_json="" + + for key_type in rsa dsa ecdsa ed25519 ; do + file="/etc/ssh/ssh_host_${key_type}_key.pub" + key_json="\"key_type\": \"${key_type}\"" + if [ -f "$FOLD/hdd/$file" ]; then + execute_chroot_command "ssh-keygen -l -f ${file} > /tmp/${key_type}" + while read bits fingerprint name type ; do + key_json="${key_json}, \"key_bits\": \"${bits}\", \"key_fingerprint\": \"${fingerprint}\", \"key_name\": \"${name}\"" + done <<< $(cat $FOLD/hdd/tmp/${key_type}) + [ -z "${keys_json}" ] && keys_json="{${key_json}}" || keys_json="${keys_json}, {${key_json}}" + rm "$FOLD/hdd/tmp/${key_type}" + fi + done + keys_json="{\"keys\": [ ${keys_json} ] }" + + echo "${keys_json}" > $FOLD/ssh_fingerprints + + return 0 + fi +} + +set_ntp_time() { + local ntp_pid + local count=0 + local running=1 + service ntp status 1>/dev/null 2>&1 && running=0 + + # stop ntp daemon first + [ $running -eq 0 ] && service ntp stop 2>&1 | debugoutput + + # manual time resync via ntp + # start ntp in background task + (ntpd -gq -4 2>&1 | debugoutput) & + ntp_pid=$! + # disconnect process from bash to hide kill message + disown $ntp_pid + + # wait 15 seconds and check if ntp still running + while [ $count -lt 15 ] ; do + kill -0 $ntp_pid 2>/dev/null + # if not running - stop waiting + [ $? -ne 0 ] && break + let count=count+1 + sleep 1 + done + + # if process is still running + if [ $count -eq 15 ] ; then + debug "ntp still running - kill it" + kill -9 $ntp_pid 2>&1 1>/dev/null + fi + + # write time to hwclock + hwclock -w 2>&1 | debugoutput + + # start ntp daemon again + [ $running -eq 0 ] && service ntp start 2>&1 | debugoutput + + return 0 +} + +# +# Checks if a post mount script exists. +# +has_postmount_script() { + local scripts="/root/post-mount /post-mount" + for i in $scripts ; do test -e "$i" && return 0 ; done + return 1 +} + +# +# If a post-mount script is found, it is executed +# +execute_postmount_script() { + local script= + [ -e "/root/post-mount" ] && script="/root/post-mount" + [ -e "/post-mount" ] && script="/post-mount" + + if [ "$script" ]; then + if [ ! -x "$script" ] ; then + debug "# Found post-mount script $script, but it isn't executable" + return 1 + fi + + debug "# Found post-mount script $script; executing it..." + $script ; EXITCODE=$? + + if [ $EXITCODE -ne 0 ]; then + debug "# Post-mount script didn't exit successfully (exit code = $EXITCODE)" + fi + + return $EXITCODE + fi +} + + +# +# Checks if a post installation script exists. +# +has_postinstall_script() { + local scripts="/root/post-install /post-install $FOLD/hdd/root/post-install $FOLD/hdd/root/post-install.sh" + for i in $scripts ; do test -e "$i" && return 0 ; done + return 1 +} + +# +# If a post-installation script is found, it is executed inside +# the chroot environment. +# +execute_postinstall_script() { + local script= + + if [ -e "/root/post-install" ]; then + cp "/root/post-install" "$FOLD/hdd/post-install" + script="/post-install" + elif [ -e "/post-install" ]; then + cp "/post-install" "$FOLD/hdd/post-install" + script="/post-install" + elif [ -e "$FOLD/hdd/root/post-install" ]; then + script="/root/post-install" + elif [ -e "$FOLD/hdd/root/post-install.sh" ]; then + script="/root/post-install.sh" + fi + + if [ "$script" ]; then + if [ ! -x "$FOLD/hdd$script" ]; then + debug "# Found post-installation script $script, but it isn't executable" + return 1 + fi + + debug "# Found post-installation script $script; executing it..." + # don't use the execute_chroot_command function and logging here - we need output on stdout! + + chroot $FOLD/hdd/ /bin/bash -c "$script" ; EXITCODE=$? + + if [ $EXITCODE -ne 0 ]; then + debug "# Post-installation script didn't exit successfully (exit code = $EXITCODE)" + fi + + return $EXITCODE + fi +} + + +generate_config_mdadm() { + if [ "$1" ]; then + return 1 + fi +} + + +generate_new_ramdisk() { + if [ "$1" ]; then + return 1 + fi +} + +setup_cpufreq() { + if [ "$1" ]; then + return 1 + fi +} + +# clear_logs "NIL" +clear_logs() { + if [ "$1" ]; then + find $FOLD/hdd/var/log -type f > /tmp/filelist.tmp + while read a; do + if [ "`echo $a |grep ".gz$\|.[[:digit:]]\{1,3\}$"`" ]; then + rm -rf "$a" >> /dev/null 2>&1 + else + echo -n > $a + fi + done < /tmp/filelist.tmp + fi + return 0 +} + +# activate ip_forward for new netsetup +generate_sysctlconf() { + local sysctl_conf="$FOLD/hdd/etc/sysctl.conf" + if [ -d $FOLD/hdd/etc/sysctl.d ]; then + sysctl_conf="$FOLD/hdd/etc/sysctl.d/99-hetzner.conf" + fi + cat << EOF > $sysctl_conf +### Hetzner Online AG installimage +# sysctl config +#net.ipv4.ip_forward=1 +net.ipv4.conf.all.rp_filter=1 +net.ipv4.icmp_echo_ignore_broadcasts=1 +# ipv6 settings (no autoconfiguration) +net.ipv6.conf.default.autoconf=0 +net.ipv6.conf.default.accept_dad=0 +net.ipv6.conf.default.accept_ra=0 +net.ipv6.conf.default.accept_ra_defrtr=0 +net.ipv6.conf.default.accept_ra_rtr_pref=0 +net.ipv6.conf.default.accept_ra_pinfo=0 +net.ipv6.conf.default.accept_source_route=0 +net.ipv6.conf.default.accept_redirects=0 +net.ipv6.conf.default.forwarding=0 +net.ipv6.conf.all.autoconf=0 +net.ipv6.conf.all.accept_dad=0 +net.ipv6.conf.all.accept_ra=0 +net.ipv6.conf.all.accept_ra_defrtr=0 +net.ipv6.conf.all.accept_ra_rtr_pref=0 +net.ipv6.conf.all.accept_ra_pinfo=0 +net.ipv6.conf.all.accept_source_route=0 +net.ipv6.conf.all.accept_redirects=0 +net.ipv6.conf.all.forwarding=0 +EOF + + # only swap to avoid a OOM condition on vps + if isVServer; then + echo "vm.swappiness=0" >>$sysctl_conf + fi + + return 0 +} + +# get_rootpassword "/etc/shadow" +get_rootpassword() { + if [ "$1" ]; then + ROOTHASH="`cat "$1" |grep "^root" | cut -d ":" -f2`" + if [ "$ROOTHASH" ]; then + return 0 + else + return 1 + fi + fi +} + +# set_rootpassword "$FOLD/hdd/etc/shadow" "ROOTHASH" +set_rootpassword() { + if [ "$1" -a "$2" ]; then + LINE="`cat "$1" |grep "^root"`" + cat "$1" | grep -v "^root" > /tmp/shadow.tmp + GECOS="`echo $LINE |cut -d ":" -f3-`" + echo "root:$2:$GECOS" > $1 + cat /tmp/shadow.tmp >> $1 + return 0 + else + return 1 + fi +} + +# fetch_ssh_keys "$OPT_SSHKEYS_URL" +fetch_ssh_keys() { + if [ "$1" ]; then + local key_url="$1" + case $key_url in + https:*|http:*|ftp:*) + curl -s -m 10 $key_url > "$FOLD/authorized_keys" 2>&1 | debugoutput + ;; + *) + cat "$key_url" > "$FOLD/authorized_keys" + ;; + esac + if [ ! -s "$FOLD/authorized_keys" ]; then + debug "authorized keys file is empty. not disabling password" + OPT_USE_SSHKEYS=0 + fi + return 0 + else + return 1 + fi +} + +# copy_ssh_keys "$user" +copy_ssh_keys() { + local targetuser='root' + + if [ "$1" ]; then + targetuser="home/$1" + fi + + mkdir -p "$FOLD/hdd/$targetuser/.ssh" + if [ $targetuser != 'root' ]; then + execute_chroot_command "chown $targetuser: /$targetuser/.ssh" + fi + + cat "$FOLD/authorized_keys" >> "$FOLD/hdd/$targetuser/.ssh/authorized_keys" + + return $? +} + +# set sshd PermitRootLogin +set_ssh_rootlogin() { + if [ "$1" ]; then + local permit="$1" + case $permit in + yes|no|without-password|forced-commands-only) + sed -i "$FOLD/hdd/etc/ssh/sshd_config" -e "s/^PermitRootLogin.*/PermitRootLogin $1/" + ;; + *) + debug "invalid option for PermitRootLogin" + return 1 + ;; + esac + else + return 1 + fi +} + +generate_config_grub() { + if [ "$1" ]; then + return 1 + fi +} + +# +# write_grub +# +# Write the GRUB bootloader into the MBR +# +write_grub() { + if [ "$1" ]; then + return 0 + fi + +#TODO: this needs to be fixed in general, as all distros now install the +# bootloader in generate_grub_config instead + +# # Delete existing lilo.conf +# execute_chroot_command "rm -rf /etc/lilo.conf" +# +# execute_chroot_command "echo -e \"device (hd0) $DRIVE1\nroot (hd0,$PARTNUM)\nsetup (hd0)\nquit\" | grub --batch >> /dev/null 2>&1" +# [ $? -ne 0 ] && return $? +# +# # Install GRUB also on the second HDD when software RAID is enabled. +# if [ "$SWRAID" -eq "1" ]; then +# execute_chroot_command "echo -e \"device (hd0) $DRIVE2\nroot (hd0,$PARTNUM)\nsetup (hd0)\nquit\" | grub --batch >> /dev/null 2>&1" +# fi + +# return $? +} + +generate_config_lilo() { + if [ "$1" ]; then + BFILE="$FOLD/hdd/etc/lilo.conf" + rm -rf "$FOLD/hdd/boot/grub/menu.lst" >>/dev/null 2>&1 + echo -e "### Hetzner Online AG installimage" > $BFILE + echo -e "# bootloader config" >> $BFILE + if [ "$LILOEXTRABOOT" ]; then + echo -e "$LILOEXTRABOOT" >> $BFILE + fi + echo -e "boot=$SYSTEMDEVICE" >> $BFILE + echo -e "root=`cat $FOLD/hdd/etc/fstab |grep " / " |cut -d " " -f 1`" >> $BFILE + echo -e "vga=0x317" >> $BFILE + echo -e "timeout=40" >> $BFILE + echo -e "prompt" >> $BFILE + echo -e "default=Linux" >> $BFILE + echo -e "large-memory" >> $BFILE + echo -e "" >> $BFILE + if [ -e "$FOLD/hdd/boot/vmlinuz-$VERSION" ]; then + echo -e "image=/boot/vmlinuz-$VERSION" >> $BFILE + else + return 1 + fi + echo -e " label=Linux" >> $BFILE +# echo -e " read-only" >> $BFILE + if [ -e "$FOLD/hdd/boot/initrd.img-$VERSION" ]; then + echo -e " initrd=/boot/initrd.img-$VERSION" >> $BFILE + elif [ -e "$FOLD/hdd/boot/initrd-$VERSION" ]; then + echo -e " initrd=/boot/initrd-$VERSION" >> $BFILE + fi + echo -e "" >> $BFILE + + + return 0 + fi +} + +write_lilo() { + if [ "$1" ]; then + execute_chroot_command "yes |/sbin/lilo -F" | debugoutput + EXITCODE=$? + return $EXITCODE + fi +} + +generate_ntp_config() { + CFGNTP="/etc/ntp.conf" + CFGCHRONY="/etc/chrony/chrony.conf" + + # find out versions + local debian_version=0 + local ubuntu_version=0 + local suse_version=0 + [ "$IAM" == debian ] && debian_version=$(cut -c 1 $FOLD/hdd/etc/debian_version) + [ "$IAM" = 'ubuntu' ] && ubuntu_version="$IMG_VERSION" + [ "$IAM" = 'suse' ] && suse_version="$IMG_VERSION" + + if [ -f "$FOLD/hdd/$CFGNTP" -o -f "$FOLD/hdd/$CFGCHRONY" ] ; then + if [ -f "$FOLD/hdd/$CFGNTP" ]; then + CFG="$CFGNTP" + echo "using ntp.conf" | debugoutput + execute_chroot_command 'sed -e "s/^server \(.*\)$/## server \1 ## see end of file/" -i '"$CFG" | debugoutput + execute_chroot_command 'echo -e "\n\n# hetzner ntp servers \nserver ntp1.hetzner.de iburst\nserver ntp2.hetzner.com iburst\nserver ntp3.hetzner.net iburst\n" >> '"$CFG" | debugoutput + [ "$IAM" = "suse" ] && execute_chroot_command 'echo -e "\n# local clock\nserver 127.127.1.0" >> '"$CFG" | debugoutput + else + CFG="$CFGCHRONY" + echo "using chrony" | debugoutput + execute_chroot_command 'echo -e "\n\n# hetzner ntp servers \nserver ntp1.hetzner.de offline minpoll 8\nserver ntp2.hetzner.com offline minpoll 8\nserver ntp3.hetzner.net offline minpoll 8\n" >> '"$CFG" | debugoutput + fi + else + msg="ntp config '$CFG' not found, ignoring" + echo $msg | debugoutput + fi + return 0 +} + +# check_fqdn $DOMAIN - return 0 when the domain is ok +check_fqdn() { + + CHECKFQDN="" + CHECKFQDN="$(echo $1 | grep -e "^\([[:alnum:]][[:alnum:]-]*[[:alnum:]]\.\)\{2,\}")" + + if [ -z "$CHECKFQDN" ]; then + return 1 + else + return 0 + fi +} + +# +# create_hostname - creates a generic hostname from ip +# +create_hostname() { + + FIRST="$(echo $1 | cut -d '.' -f 1)" + SECOND="$(echo $1 | cut -d '.' -f 2)" + THIRD="$(echo $1 | cut -d '.' -f 3)" + FOURTH="$(echo $1 | cut -d '.' -f 4)" + + if [ -z "$FIRST" -o -z "$SECOND" -o -z "$THIRD" -o -z "$FOURTH" ]; then + return 1 + fi + if [ "$FIRST" -eq "78" -o "$FIRST" -eq "188" -o "$FIRST" -eq "178" -o "$FIRST" -eq "46" -o "$FIRST" -eq "176" -o "$FIRST" -eq "5" -o "$FIRST" -eq "185" -o "$FIRST" -eq "136" -o "$FIRST" -eq "144" -o "$FIRST" -eq "148" -o "$FIRST" -eq "138" ]; then + GENERATEDHOSTNAME="static.$FOURTH.$THIRD.$SECOND.$FIRST.clients.your-server.de" + else + GENERATEDHOSTNAME="static.$FIRST-$SECOND-$THIRD-$FOURTH.clients.your-server.de" + fi + + echo $GENERATEDHOSTNAME + return 0 + +} + + +# check for latest subversion of Plesk +check_plesk_subversion() { + local main_version="$1" + local output="" + local latest_release="" + + # test if pleskinstaller is already downloaded + if [ ! -x "$FOLD/hdd/pleskinstaller" ] ; then + wget http://mirror.hetzner.de/tools/parallels/plesk/$IMAGENAME -O $FOLD/hdd/pleskinstaller 2>&1 | debugoutput + chmod a+x $FOLD/hdd/pleskinstaller >> /dev/null + fi + + output="$(execute_chroot_command_wo_debug "/pleskinstaller --select-product-id plesk --show-releases" 2>&1)" + latest_release="$(echo -e "$output" | grep "PLESK_${main_version}" | head -n1 | awk '{print $2}')" + + [ -n "$latest_release" ] && echo "$latest_release" + +} + +# +# determine image version and install plesk +# +install_plesk() { + # get Plesk version to install + local plesk_version=$1 + + # we need the installer first + wget http://mirror.hetzner.de/tools/parallels/plesk/$IMAGENAME -O $FOLD/hdd/pleskinstaller 2>&1 | debugoutput + chmod a+x $FOLD/hdd/pleskinstaller >> /dev/null + + # if there was no version specified, take our standard version + if [ "$plesk_version" == "plesk" ]; then + debug "install standard version" + plesk_version="$PLESK_STD_VERSION" + elif [ -n "$(echo "$plesk_version" | egrep "plesk_[0-9]+_[0-9]+_[0-9]+$")" ]; then + plesk_version="$(echo "$plesk_version" | tr '[:lower:]' '[:upper:]')" + else + # check if we want a main version and should detect the latest subversion + local main_version="${plesk_version#plesk_}" + local latest_sub="" + + [ -n "$main_version" ] && latest_sub="$(check_plesk_subversion "$main_version")" + if [ -z "$latest_sub" ]; then + echo "Could not determine latest subversion of Plesk $main_version" + return 1 + fi + plesk_version="$latest_sub" + fi + +# if [ "$IMAGENAME" == "CentOS-57-64-minimal" -o "$IMAGENAME" == "CentOS-58-64-minimal" -o "$IMAGENAME" == "CentOS-60-64-minimal" -o "$IMAGENAME" == "CentOS-62-64-minimal" -o "$IMAGENAME" == "CentOS-63-64-minimal" ]; then + if [ "$IAM" == 'centos' ]; then + execute_chroot_command "yum -y install mysql mysql-server" + # we should install rails here as well, but this is a bit tricky + # because there is no package and we would have to install via gem + # + # centos wants to have a fqdn for pleskinstallation + sed -i "s|$IMAGENAME|$IMAGENAME.yourdomain.localdomain $IMAGENAME|" $FOLD/hdd/etc/hosts + fi + + if [ "$IAM" == "debian" -a "$IMG_VERSION" -ge 70 ]; then + # create folder /run/lock since it doesn't exist after the installation of debian7 and needed for plesk installation + execute_chroot_command "mkdir -p /run/lock" + fi + +# old COMPONENTS="base psa-autoinstaller mod-bw mod_python qmail ruby mailman horde psa-firewall spamassassin pmm backup" + COMPONENTS="common psa-autoinstaller mod-bw mod_phyton postfix ruby mailman horde psa-firewall spamassassin pmm bind" + COMPONENTLIST="$(for component in $COMPONENTS; do echo -n "--install-component $component "; done)" + + execute_chroot_command "/pleskinstaller --select-product-id plesk --select-release-id $plesk_version $COMPONENTLIST"; EXITCODE=$? + rm -rf $FOLD/hdd/pleskinstaller >/dev/null 2>&1 + + return $EXITCODE + +} + +install_omsa() { +# maybe split into separate functions for debian/ubuntu and centos +# if [ "$1" ]; then +# return 1 +# fi + # need to stop dell_rbu driver before install, or the installation will look + # for the kernel modules of the rescue system inside the image + /etc/init.d/instsvcdrv stop >/dev/null + + if [ "$IAM" = "debian" ] || [ "$IAM" = "ubuntu" ]; then + REPOFILE="$FOLD/hdd/etc/apt/sources.list.d/dell-omsa.list" + local codename="precise" + if [ "$IAM" = "debian" ] && [ $IMG_VERSION -ge 70 ]; then + codename="wheezy" + fi + echo -e "\n# Community OMSA packages provided by linux.dell.com" >$REPOFILE + echo -e "deb http://linux.dell.com/repo/community/$IAM $codename openmanage\n" >>$REPOFILE + execute_chroot_command "gpg --keyserver pool.sks-keyservers.net --recv-key 1285491434D8786F" + execute_chroot_command "gpg -a --export 1285491434D8786F | apt-key add -" + execute_chroot_command "mkdir -p /run/lock" + execute_chroot_command "aptitude update >/dev/null" + execute_chroot_command "aptitude --without-recommends -y install srvadmin-base srvadmin-idracadm srvadmin-idrac7"; EXITCODE=$? + return $EXITCODE + elif [ "$IAM" = "centos" ]; then + execute_chroot_command "yum -y install perl" + execute_chroot_command "wget -q -O - http://linux.dell.com/repo/hardware/latest/bootstrap.cgi | bash" + execute_chroot_command "yum -y install srvadmin-base srvadmin-idrac7" + else + debug "no OMSA packages available for this OS" + return 0 + fi + /etc/init.d/instsvcdrv start >/dev/null + +} + +# +# translate_unit +# +translate_unit() { + if [ -z "$1" ]; then + echo "0" + return 1 + fi + for unit in M MiB G GiB T TiB; do + if echo "$1" | egrep -q "^[[:digit:]]+$unit$"; then + value=$(echo "$1" | sed "s/$unit//") + + case "$unit" in + M|MiB) + factor=1 + ;; + G|GiB) + factor=1024 + ;; + T|TiB) + factor=1048576 + ;; + esac + echo $(($value * $factor)) + return 0 + fi + done + + echo "$1" + return 0 +} + + +# +# install_robot_script +# +# Installs a script in the new system that is used for automatic +# installations by the Robot. The script removes itself afterwards. +# +install_robot_script() { + VERSION=$(echo $IMAGENAME | cut -d- -f2) + cp $SCRIPTPATH/robot.sh $FOLD/hdd/ + chmod +x $FOLD/hdd/robot.sh + sed -i -e "s#^URL=?#URL=\"$ROBOTURL\"#" $FOLD/hdd/robot.sh + case "$IAM" in + debian|ubuntu) + sed -e 's/^exit 0$//' -i $FOLD/hdd/etc/rc.local + echo -e "[ -x /robot.sh ] && /robot.sh\nexit 0" >> $FOLD/hdd/etc/rc.local + ;; + centos) + echo -e "[ -x /robot.sh ] && /robot.sh" >> $FOLD/hdd/etc/rc.local + chmod +x $FOLD/hdd/etc/rc.local 1>/dev/null 2>&1 + ;; + suse) + # needs suse 12.2 or higher + echo "bash /robot.sh" >> $FOLD/hdd/etc/init.d/boot.local + ;; + esac +} + +#report_statistic "SERVER" "IMAGENAME" "SWRAID" "LVM" +report_statistic() { + if [ "$1" -a "$2" -a "$3" -a "$4" -a "$5" ]; then + REPORTSRV="$1" + + STANDARDIMAGE="`ls -1 "$IMAGESPATH" |grep "$2"`" + + if [ ! "$STANDARDIMAGE" ]; then + REPORTIMG="Custom" + else + REPORTIMG="`echo $2 |sed 's/\./___/g'`" + fi + + REPORTSWR="$3" + REPORTLVM="$4" + if [ "$5" = "lilo" -o "$5" = "LILO" ]; then + BLCODE="0" + elif [ "$5" = "grub" -o "$5" = "GRUB" ]; then + BLCODE="1" + fi + ERROREXITCODE="$6" + wget --no-check-certificate --timeout=20 "https://$REPORTSRV/report/image/$REPORTIMG/$REPORTSWR/$REPORTLVM/$BLCODE/$ERROREXITCODE" -O /tmp/wget.tmp >> /dev/null 2>&1; EXITCODE=$? + return $EXITCODE + fi +} + +report_config() { + local config_file="$FOLD/install.conf" + # currently use new rz-admin to report the install.conf + # TODO: change that later to rz-admin + local report_ip="213.133.99.103" + local report_status="" + + report_status="$(curl -m 10 -s -k -X POST -T $config_file "https://${report_ip}/api/${HWADDR}/image/new")" + echo "report install.conf to rz-admin: ${report_status}" | debugoutput + + echo "${report_status}" +} + +report_debuglog() { + local log_id="$1" + if [ -z "$log_id" ] ; then + echo "report_debuglog: no log_id given" | debugoutput + return 1 + fi + # currently use new rz-admin to report the install.conf + # TODO: change that later to rz-admin + local report_ip="213.133.99.103" + local report_status="" + + report_status="$(curl -m 10 -s -k -X POST -T $DEBUGFILE "https://${report_ip}/api/${HWADDR}/image/${log_id}/log")" + echo "report debug.txt to rz-admin: ${report_status}" | debugoutput + + return 0 +} + +# +# cleanup +# +# Unmount filesystems and remove temporary directories. +# +cleanup() { + debug "# Cleaning up..." + + while read line ; do + mount="$(echo $line | grep $FOLD | cut -d' ' -f2)" + if [ -n "$mount" ] ; then + umount -l $mount >> /dev/null 2>&1 + fi + done < /proc/mounts + + rm -rf $FOLD >> /dev/null 2>&1 + rm -rf /tmp/install.vars 2>&1 + rm -rf /tmp/*.tmp 2>&1 +} + +exit_function() { + local report_id="" + ERROREXIT="1" + + test "$1" && echo_red "$1" + echo + echo -e "$RED An error occured while installing the new system!$NOCOL" + echo -e "$RED See the debug file $DEBUGFILE for details.$NOCOL" + echo + echo "Please check our wiki for a description of the error:" + echo + echo "http://wiki.hetzner.de/index.php/Betriebssystem_Images_installieren" + echo + echo "If your problem is not described there, try booting into a fresh" + echo "rescue system and restart the installation. If the installation" + echo "fails again, please contact our support via Hetzner Robot, providing" + echo "the IP address of the server and a copy of the debug file." + echo + echo " https://robot.your-server.de" + echo + + report_statistic "$STATSSERVER" "$IMAGE_FILE" "$SWRAID" "$LVM" "$BOOTLOADER" "$ERROREXIT" + report_id="$(report_config)" + report_debuglog $report_id + cleanup +} + +#function to check if it is a intel or amd cpu +function check_cpu () { + if [ "$(cat /proc/cpuinfo | grep GenuineIntel)" ]; then + MODEL="intel" + else + MODEL="amd" + fi + + echo $MODEL + + return 0 +} + +#get the smallest harddrive +function smallest_hd() { + local smallest_drive_space="$(blockdev --getsize64 $DRIVE1 2>/dev/null)" + local smallest_drive=$DRIVE1 + for i in $(seq 1 $COUNT_DRIVES); do + if [ "$smallest_drive_space" -gt "$(blockdev --getsize64 "$(eval echo "\$DRIVE"$i)")" ]; then + smallest_drive_space="$(blockdev --getsize64 "$(eval echo "\$DRIVE"$i)")" + smallest_drive="$(eval echo "\$DRIVE"$i)" + fi + done + + echo $smallest_drive + + return 0 +} + +function largest_hd() { + LARGEST_DRIVE_SPACE="$(blockdev --getsize64 $DRIVE1)" + LARGEST_DRIVE=$DRIVE1 + for i in $(seq 1 $COUNT_DRIVES); do + if [ "$LARGEST_DRIVE_SPACE" -lt "$(blockdev --getsize64 "$(eval echo "\$DRIVE"$i)")" ]; then + LARGEST_DRIVE_SPACE="$(blockdev --getsize64 "$(eval echo "\$DRIVE"$i)")" + LARGEST_DRIVE="$(eval echo "\$DRIVE"$i)" + fi + done + + echo $LARGEST_DRIVE + + return 0 +} + +# get the drives which are connected through an USB port +function getUSBFlashDrives() { + for i in $(seq 1 $COUNT_DRIVES); do + DEV=$(eval echo "\$DRIVE"$i) + # remove string '/dev/' + DEV=$(echo $DEV | sed -e 's/\/dev\///') + if [ -n "$(ls -l /sys/block/$DEV/ | grep usb)" ]; then + echo "/dev/${DEV}" + fi + done + + return 0 +} + +# get HDDs with size not in tolerance range +function getHDDsNotInToleranceRange() { + # RANGE in percent relative to smallest hdd + local RANGE=135 + local smallest_hdd="$(smallest_hd)" + local smallest_hdd_size="$(blockdev --getsize64 $smallest_hdd)" + local max_size=$[ $smallest_hdd_size * $RANGE / 100 ] + debug "checking if hdd sizes are within tolerance. min: $smallest_hdd_size / max: $max_size" + for i in $(seq 1 $COUNT_DRIVES); do + if [ "$(blockdev --getsize64 "$(eval echo "\$DRIVE"$i)")" -gt "$max_size" ]; then + echo $(eval echo "\$DRIVE"$i) + debug "DRIVE$i not in range" + else + debug "DRIVE$i in range" + echo "$(blockdev --getsize64 "$(eval echo "\$DRIVE"$i)")" | debugoutput + fi + done + + return 0 +} + +uuid_bugfix() { + debug "# change all device names to uuid (e.g. for ide/pata transition)" + TEMPFILE="$(mktemp)" + sed -n 's|^/dev/\([hsv]d[a-z][1-9][0-9]\?\).*|\1|p' < $FOLD/hdd/etc/fstab > "$TEMPFILE" + while read LINE; do + UUID="$(blkid -o value -s UUID /dev/$LINE)" + # not quite perfect. We need to match /dev/sda1 but not /dev/sda10. + # device name may not always be followed by whitespace + [ -e $FOLD/hdd/etc/fstab ] && sed -i "s|^/dev/${LINE} |# /dev/${LINE} during Installation (RescueSystem)\nUUID=${UUID} |" $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 + [ -e $FOLD/hdd/etc/lilo.conf ] && sed -i "s|append=\"root=/dev/${LINE}|append=\"root=UUID=${UUID}|" $FOLD/hdd/etc/lilo.conf + [ -e $FOLD/hdd/etc/lilo.conf ] && sed -i "s|/dev/${LINE}|\"UUID=${UUID}\"|" $FOLD/hdd/etc/lilo.conf + done < $TEMPFILE + rm "$TEMPFILE" + return 0 +} + +# param 1: /dev/sda (e.g) +function hdinfo() { + local withoutdev= vendor= name= logical_nr= + withoutdev=${1##*/} + vendor="$(cat /sys/block/$withoutdev/device/vendor | tr -d ' ')" + + case "$vendor" in + LSI) + logical_nr="$(ls /sys/block/$withoutdev/device/scsi_device/ | cut -d: -f3)" + name="$(megacli -ldinfo -L$logical_nr -aall | grep Name | cut -d: -f2)" + [ -z "$name" ] && name="no name" + echo "# LSI RAID (LD $logical_nr): $name" + ;; + Adaptec) + logical_nr="$(cat /sys/block/$withoutdev/device/model 2>&1 | awk '{print $2}')" + name="$(arcconf GETCONFIG 1 LD $logical_nr | grep "Logical device name" | sed 's/.*: \(.*\)/\1/g')" + [ -z "$name" ] && name="no name" + echo "# Adaptec RAID (LD $logical_nr): $name" + ;; + AMCC) + logical_nr="$(ls /sys/block/$withoutdev/device/scsi_device/ | cut -d: -f4)" + echo "# 3ware RAID (LD $logical_nr)" + ;; + ATA) + name="$(hdparm -i $1 | grep Model | sed 's/ Model=\(.*\), Fw.*/\1/g')" + echo "# Onboard: $name" + ;; + *) + echo "# unkown" + ;; + 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 [ -n "$(ip a show $i | grep "inet [1-9]")" ]; then + #check if we got autonegotiated + if [ -n "$(mii-tool 2>/dev/null | grep "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() { +# local model="$(cat /proc/cpuinfo | grep "^model name" | cut -d ":" -f2 | tr -d ' ')" +# if [ -n "$(echo "$model" | grep -i "QEMUVirtualCPU")" ] || [ -n "$(echo "$model" | grep -i "PentiumII(Klamath)")" ]; then + case "$SYSTYPE" in + vServer|Bochs|Xen|KVM|VirtualBox|'VMware,Inc.') + debug "# Systype: $SYSTYPE" + return 0;; + *) + debug "# Systype: $SYSTYPE" + case "$SYSMFC" in + QEMU) + debug "# Manufacturer: $SYSMFC" + return 0;; + *) + debug "# Manufacturer: $SYSMFC" + return 1;; + esac + return 1;; + esac +} + +# function to check if we have to use GPT or MS-DOS partition tables + +function part_test_size() { + #2TiB limit + local LIMIT=2096128 + + GPT=0 + + if [ "$FORCE_GPT" = "2" ]; then + debug "Forcing use of GPT as directed" + GPT=1 + PART_COUNT=$[$PART_COUNT+1] + return 0 + fi + + local dev=$(smallest_hd) + if [ "$SWRAID" -eq 0 ]; then + dev=$DRIVE1 + fi + local DRIVE_SIZE=$(blockdev --getsize64 $dev) + DRIVE_SIZE=$[ $DRIVE_SIZE / 1024 / 1024 ] + + if [ $DRIVE_SIZE -ge $LIMIT ] || [ "$FORCE_GPT" = "1" ]; then + # use only GPT if not CentOS or OpenSuSE newer than 12.2 + if [ "$IAM" != "centos" ] || [ "$IAM" == "centos" -a "$IMG_VERSION" -ge 70 ]; then + if [ "$IAM" = "suse" ] && [ "$IMG_VERSION" -lt 122 ]; then + echo "SuSE older than 12.2. cannot use GPT (but drive size is bigger then 2TB)" | debugoutput + else + echo "using GPT (drive size bigger then 2TB or requested)" | debugoutput + GPT=1 + PART_COUNT=$[$PART_COUNT+1] + fi + else + echo "cannot use GPT (but drive size is bigger then 2TB)" | debugoutput + fi + fi +} + +# function to check and correct sizes of normal DOS styled partitions +# if first param is "no_output" only correct size of "all" partition + +function check_dos_partitions() { + + echo "check_dos_partitions" | debugoutput + if [ "$FORCE_GPT" = "2" ] || [ "$IAM" != "centos" ] || [ "$IAM" == "centos" -a "$IMG_VERSION" -ge 70 ] || [ "$BOOTLOADER" == "lilo" ]; then + if [ "$IAM" = "suse" ] && [ "$IMG_VERSION" -lt 122 ]; then + echo "SuSE version older than 12.2, no grub2 support" | debugoutput + else + return 0 + fi + fi + + local LIMIT=2096128 + local PART_WO_ALL_SIZE_PRIM=0 + local PART_WO_ALL_SIZE=0 + local output="$1" + local PART_ALL_SIZE=0 + local temp_size=0 + local result='' + local found_all_part='' + local dev=$(smallest_hd) + if [ "$SWRAID" -eq 0 ]; then + dev=$DRIVE1 + fi + + local DRIVE_SIZE=$(blockdev --getsize64 $dev) + DRIVE_SIZE=$[ $DRIVE_SIZE / 1024 / 1024 ] + + if [ $DRIVE_SIZE -lt $LIMIT ]; then + return 0 + fi + + echo "DRIVE size is: $DRIVE_SIZE" | debugoutput + + # check if all primary partitions (without "all") are within the 2TB Limit + for i in $(seq 1 $PART_COUNT); do + #check only primary partitions + if [ "${PART_SIZE[$i]}" != "all" ]; then + if [ $i -lt 4 ]; then + PART_WO_ALL_SIZE_PRIM="$(echo ${PART_SIZE[$i]} + $PART_WO_ALL_SIZE_PRIM | bc)" + fi + # MS-DOS partitions may not start above 2TiB either + if [ $PART_WO_ALL_SIZE -gt $LIMIT ]; then + result="PART_BEGIN_OVER_LIMIT" + fi + PART_WO_ALL_SIZE="$(echo ${PART_SIZE[$i]} + $PART_WO_ALL_SIZE | bc)" + if [ ${PART_SIZE[$i]} -gt $LIMIT ]; then + [ -z $result ] && result="PART_OVERSIZED" + fi + else + found_all_part="yes" + fi + done + + echo "partitions without \"all\" sum up to $PART_WO_ALL_SIZE" | debugoutput + echo "primary partitions without \"all\" sum up to $PART_WO_ALL_SIZE_PRIM" | debugoutput + + # now check how big an "all" partition is + # MS-DOS partitions may not start above 2TiB either + if [ $PART_WO_ALL_SIZE -gt $LIMIT ]; then + if [ "$found_all_part" = "yes" ] ; then + [ -z $result ] && result="PART_ALL_BEGIN_OVER_LIMIT" + fi + fi + + # if we have an extended partition + if [ $PART_COUNT -gt 3 ]; then + for i in $(seq 4 $PART_COUNT); do + if [ "${PART_SIZE[$i]}" != "all" ]; then + temp_size="$(echo "$temp_size + ${PART_SIZE[$i]}" | bc)" + fi + done + + PART_ALL_SIZE=$(echo "$DRIVE_SIZE - $PART_WO_ALL_SIZE_PRIM - $temp_size" | bc) + echo "Part_all_size is: $PART_ALL_SIZE" | debugoutput + if [ $PART_ALL_SIZE -gt $LIMIT ]; then + PART_ALL_SIZE=$(echo "$LIMIT - $temp_size" | bc) + [ -z $result ] && result="PART_CHANGED_ALL" + fi + # if we have no more than 3 partitions + else + PART_ALL_SIZE=$(echo "$DRIVE_SIZE - $PART_WO_ALL_SIZE" | bc) + if [ $PART_ALL_SIZE -gt $LIMIT ]; then + PART_ALL_SIZE=$LIMIT + [ -z $result ] && result="PART_CHANGED_ALL" + fi + fi + + for i in $(seq 1 $PART_COUNT); do + if [ "${PART_SIZE[$i]}" == "all" ]; then + PART_SIZE[$i]=$PART_ALL_SIZE + echo "new size of \"all\" is now ${PART_SIZE[$i]}" | debugoutput + fi + done + [ "$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. + UDEVPFAD="/etc/udev/rules.d" + + ETHCOUNT="$(ifconfig -a | grep -c eth)" + if [ "$ETHCOUNT" -gt "1" ]; then + cp $UDEVPFAD/70-persistent-net.rules $FOLD/hdd$UDEVPFAD/ + #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$UDEVPFAD/70-persistent-net.rules + fi + for NIC in /sys/class/net/*; do + 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 !!! + if [ -n "$iptest" ] && [ "iptest" != "192.168" ] && [ "$INTERFACE" != "eth0" ] && [ "$INTERFACE" != "lo" ]; then + debug "# renaming active $INTERFACE to eth0 via udev in installed system" + sed -i "s/$INTERFACE/dummy/" $FOLD/hdd$UDEVPFAD/70-persistent-net.rules + sed -i "s/eth0/$INTERFACE/" $FOLD/hdd$UDEVPFAD/70-persistent-net.rules + sed -i "s/dummy/eth0/" $FOLD/hdd$UDEVPFAD/70-persistent-net.rules + fix_eth_naming "$INTERFACE" + fi + done + [ "$IAM" = 'suse' ] && suse_version="$IMG_VERSION" + [ "$suse_version" == "123" ] && suse_netdev_fix + fi +} + +# Rename eth device (ethX to eth0) +# +fix_eth_naming() { + if [ "$1" ]; then + debug "# fix eth naming" + + # for Debian and Debian derivatives + if [ "$IAM" = "debian" ] || [ "$IAM" = "ubuntu" ]; then + FILE="etc/network/interfaces" + if [ -f "$FOLD/hdd/$FILE" ]; then + debug "# fix_eth_naming replaces $1/eth0" + execute_chroot_command "sed -i 's/$1/eth0/g' $FILE" +# fi + fi + fi + + # CentOS + if [ "$IAM" = "centos" ]; then + FILE="/etc/sysconfig/network-scripts/ifcfg-$1" + NEWFILE="/etc/sysconfig/network-scripts/ifcfg-eth0" + ROUTE="/etc/sysconfig/network-scripts/route-$1" + NEWROUTE="/etc/sysconfig/network-scripts/route-eth0" + if [ -f "$FOLD/hdd/$FILE" ] && [ -f "$FOLD/hdd/$ROUTE" ]; then + debug "# fix_eth_naming replaces $1 with eth0" + execute_chroot_command "sed -i 's/$1/eth0/g' $FILE" + execute_chroot_command "mv $FILE $NEWFILE" + execute_chroot_command "mv $ROUTE $NEWROUTE" + fi + fi + + # SUSE + if [ "$IAM" = "suse" ]; then + FILE="/etc/sysconfig/network/ifcfg-$1" + NEWFILE="/etc/sysconfig/network/ifcfg-eth0" + if [ -f "$FOLD/hdd/$FILE" ]; then + debug "# fix_eth_naming mv $FILE to $NEWFILE" + execute_chroot_command "mv $FILE $NEWFILE" + fi + fi + fi + +} + + +suse_netdev_fix() { +# device naming in OpenSuSE 12.3 for multiple NICs is +# currently broken. (kernel and systemd disagree with each other) +# Workaround is to map the NICs to their own namespace (net0 instead of eth0) +# until the fix is released +# see https://bugzilla.novell.com/show_bug.cgi?id=809843 + + FILE_NET="/etc/sysconfig/network/ifcfg-eth0" + FILE_NET_NEW="/etc/sysconfig/network/ifcfg-net0" + execute_chroot_command "mv $FILE_NET $FILE_NET_NEW"; + execute_chroot_command "sed -i 's/eth0/net0/g' $FILE_NET_NEW"; + sed -i 's/eth\([0-9]\)/net\1/g' $FOLD/hdd$UDEVPFAD/70-persistent-net.rules +} + + diff --git a/get_options.sh b/get_options.sh new file mode 100755 index 0000000..59c62fa --- /dev/null +++ b/get_options.sh @@ -0,0 +1,268 @@ +#!/bin/bash + +# read config +#. /tmp/install.vars +# +# originally written by David Mayr +# (c) 2009-2015, Hetzner Online AG +# + + + +# check command line params / options +while getopts "han:b:r:l:i:p:v:d:f:c:R:s:z:x:gkK:" OPTION ; do + case $OPTION in + + # help + h) + echo + echo "usage: installimage [options]" + echo + echo " without any options, installimage starts in interactive mode." + echo " possible options are:" + echo + echo " -h display this help" + echo + echo " -a automatic mode / batch mode - use this in combination" + echo " with the options below to install without further" + echo " interaction. there will be no further confirmations" + echo " for deleting disks / all your data, so use with care!" + echo + echo " -c use the specified config file in" + echo " $CONFIGSPATH for autosetup. when using" + echo " this option, no other options except '-a' are accepted." + echo + echo " -x Use this file as post-install script, that will be executed after" + echo " installation inside the chroot." + echo + echo " -n set the specified hostNAME." + echo " -b use either lilo or grub as BOOTLOADER." + echo " -r activate software RAID or not." + echo " -l <0|1|5|6|10> set the specified raid LEVEL." + echo " -i use the specified IMAGE to install (full path to the OS image)" + echo " - supported image sources: local dir, ftp, http, nfs" + echo " - supported image types: tar,tar.gz,tar.bz,tar.bz2,tar.xz,tgz,tbz,txz" + echo " - supported binary image types: bin,bin.bz2 (CoreOS only)" + echo " examples:" + echo " - local: /path/to/image/filename.tar.gz" + echo " - ftp: ftp://:@hostname/path/to/image/filename.tar.bz2" + echo " - http: http://:@hostname/path/to/image/filename.tbz" + echo " - https: https://:@hostname/path/to/image/filename.tbz" + echo " - nfs: hostname:/path/to/image/filename.tgz" + echo " -g Use this to force validation of the image file with detached GPG signature." + echo " If the image is not valid, the installation will abort." + echo " -p define the PARTITIONS to create, example:" + echo " - regular partitions: swap:swap:4G,/:ext3:all" + echo " - lvm setup example: /boot:ext2:256M,lvm:vg0:all" + echo " -v define the logical VOLUMES you want to be created" + echo " - example: vg0:root:/:ext3:20G,vg0:swap:swap:swap:4G" + echo " -d list of hardDRIVES to use, e.g.: sda or sda,sdb" + echo " -f FORMAT the second drive (if not used for raid)?" + echo " -s Language to use for different things (e.g.PLESK)" + echo " -z PLESK_ Install optional software like PLESK with version " + echo " -K Install SSH-Keys from file/URL" + echo + exit 0 + ;; + + # config file (file.name) + c) + if [ -e $CONFIGSPATH/$OPTARG ] ; then + OPT_CONFIGFILE=$CONFIGSPATH/$OPTARG + elif [ -e $OPTARG ] ; then + OPT_CONFIGFILE=$OPTARG + else + msg="=> FAILED: config file $OPT_CONFIGFILE for autosetup not found" + debug $msg + echo -e "${RED}$msg${NOCOL}" + exit 1 + fi + debug "# use config file $OPT_CONFIGFILE for autosetup" + echo $OPT_CONFIGFILE | grep "^/" >/dev/null || OPT_CONFIGFILE="$(pwd)/$OPT_CONFIGFILE" + cp $OPT_CONFIGFILE /autosetup + if grep -q PASSWD /autosetup ; then + echo -e "\n\n${RED}Please enter the PASSWORD for $OPT_CONFIGFILE:${NOCOL}" + echo -e "${YELLOW}(or edit /autosetup manually and run installimage without params)${NOCOL}\n" + echo -en "PASSWORD: " + read -s imagepasswd + sed -i /autosetup -e "s/PASSWD/$imagepasswd/" + fi + ;; + + # post-install file (file.name) + x) + if [ -e $POSTINSTALLPATH/$OPTARG ] ; then + OPT_POSTINSTALLFILE=$POSTINSTALLPATH/$OPTARG + elif [ -e $OPTARG ] ; then + OPT_POSTINSTALLFILE=$OPTARG + else + msg="=> FAILED: post-install file $OPT_POSTINSTALLFILE not found or not executable" + debug $msg + echo -e "${RED}$msg${NOCOL}" + exit 1 + fi + debug "# use post-install file $OPT_POSTINSTALLFILE" + echo $OPT_POSTINSTALLFILE | grep "^/" >/dev/null || OPT_POSTINSTALLFILE="$(pwd)/$OPT_POSTINSTALLFILE" + ln -fs $OPT_POSTINSTALLFILE /post-install + ;; + + # automatic mode + a) OPT_AUTOMODE=1 ;; + + # hostname (host.domain.tld) + n) + OPT_HOSTNAME=$OPTARG + if [ -e /autosetup ]; then + sed -i /autosetup -e "s/HOSTNAME.*/HOSTNAME $OPT_HOSTNAME/" + fi + ;; + + # bootloader (lilo|grub) + b) OPT_BOOTLOADER=$OPTARG ;; + + # raid (on|off|true|false|yes|no|0|1) + r) + case $OPTARG in + off|false|no|0) OPT_SWRAID=0 ;; + on|true|yes|1) OPT_SWRAID=1 ;; + esac + ;; + + # raidlevel (0|1) + l) OPT_SWRAIDLEVEL=$OPTARG ;; + + # image + # e.g.: file.tar.gz | http://domain.tld/file.tar.gz + i) + [ -f "$IMAGESPATH/$OPTARG" ] && OPT_IMAGE="$IMAGESPATH/$OPTARG" || OPT_IMAGE="$OPTARG" + IMAGENAME=$(basename $OPT_IMAGE) + IMAGENAME=${IMAGENAME/.tar.gz/} + IMAGENAME=${IMAGENAME/.tar.bz/} + IMAGENAME=${IMAGENAME/.tar.bz2/} + IMAGENAME=${IMAGENAME/.tar.xz/} + IMAGENAME=${IMAGENAME/.tar/} + IMAGENAME=${IMAGENAME/.tgz/} + IMAGENAME=${IMAGENAME/.tbz/} + IMAGENAME=${IMAGENAME/.txz/} + IMAGENAME=${IMAGENAME/.bin.bz2/} + IMAGENAME=${IMAGENAME/.bin/} + ;; + + # partitions + # e.g.: swap:swap:4G,/boot:ext2:256M,/:ext3:all | /boot:ext2:256M,lvm:vg0:all + p) + OPT_PARTITIONS=$OPTARG + OPT_PARTS='' + OLD_IFS="$IFS" + IFS="," + for part in $OPT_PARTITIONS ; do + OPT_PARTS="$OPT_PARTS\nPART " + IFS=":" + for val in $part ; do + OPT_PARTS="$OPT_PARTS $val " + done + done + IFS="$OLD_IFS" + ;; + + # logical volumes + # e.g.: vg0:swap:swap:swap:4G,vg0:root:/:ext3:20G,vg0:tmp:/tmp:ext3:5G + v) + OPT_VOLUMES=$OPTARG + OPT_LVS='' + OLD_IFS="$IFS" + IFS="," + for lv in $OPT_VOLUMES ; do + OPT_LVS="$OPT_LVS\nLV " + IFS=":" + for val in $lv ; do + OPT_LVS="$OPT_LVS $val " + done + done + IFS="$OLD_IFS" + ;; + + # drives + # e.g.: sda,sdb | sda + d) + OPT_DRIVES=$OPTARG + sel_drives="$(echo $OPT_DRIVES | sed s/,/\\n/g)" + i=1 + for optdrive in $sel_drives ; do + eval OPT_DRIVE$i="$optdrive" + let i=i+1 + done + ;; + + # format second drive (on|off|true|false|yes|no|0|1) + f) + case $OPTARG in + off|false|no|0) export OPT_FORMATDRIVE2=0 ;; + on|true|yes|1) export OPT_FORMATDRIVE2=1 ;; + esac + ;; + + s) + export OPT_LANGUAGE="$OPTARG" + ;; + + z) + export OPT_INSTALL="$OPTARG" + ;; + + # URL to open after first boot of the new system. Used by the + # Robot for automatic installations. + R) + ROBOTURL=$OPTARG + ;; + + # force signature validating of the image file + g) + export OPT_FORCE_SIGN="1" + ;; + K) + if [ "$OPTARG" ]; then + export OPT_SSHKEYS_URL="$OPTARG" + export OPT_USE_SSHKEYS="1" + else + msg="=> FAILED: cannot install ssh-keys without a source" + debug $msg + echo -e "${RED}$msg${NOCOL}" + exit 1 + fi + ;; + esac +done + + +# VALIDATION +if [ "$OPT_AUTOMODE" -a -z "$OPT_IMAGE" -a -z "$OPT_CONFIGFILE" ] ; then + echo -e "\n${RED}ERROR: in automatic mode you need to specify an image and a config file!${NOCOL}\n" + debug "=> FAILED, no image given" + exit 1 +fi + +if [ "$OPT_USE_SSHKEYS" -a -z "$OPT_SSHKEYS_URL" ]; then + msg="=> FAILED: Should install SSH keys, but key URL not set." + debug $msg + echo -e "${RED}$msg${NOCOL}" + exit 1 +fi + +# DEBUG: +[ "$OPT_CONFIGFILE" ] && debug "# OPT_CONFIGFILE: $OPT_CONFIGFILE" +[ "$OPT_HOSTNAME" ] && debug "# OPT_HOSTNAME: $OPT_HOSTNAME" +[ "$OPT_BOOTLOADER" ] && debug "# OPT_BOOTLOADER: $OPT_BOOTLOADER" +[ "$OPT_SWRAID" ] && debug "# OPT_SWRAID: $OPT_SWRAID" +[ "$OPT_SWRAIDLEVEL" ] && debug "# OPT_SWRAIDLEVEL: $OPT_SWRAIDLEVEL" +[ "$OPT_IMAGE" ] && debug "# OPT_IMAGE: $OPT_IMAGE" +[ "$OPT_PARTITIONS" ] && debug "# OPT_PARTITIONS: $OPT_PARTITIONS" +[ "$OPT_VOLUMES" ] && debug "# OPT_VOLUMES: $OPT_VOLUMES" +[ "$OPT_DRIVES" ] && debug "# OPT_DRIVES: $OPT_DRIVES" +[ "$OPT_FORMATDRIVE2" ] && debug "# OPT_FORMATDRIVE2: $OPT_FORMATDRIVE2" +[ "$OPT_INSTALL" ] && debug "# OPT_INSTALL: $OPT_INSTALL" +[ "$OPT_FORCE_SIGN" ] && debug "# OPT_FORCE_SIGN: $OPT_FORCE_SIGN" +[ "$OPT_USE_SSHKEYS" ] && debug "# OPT_USE_SSHKEYS: $OPT_USE_SSHKEYS" +[ "$OPT_SSHKEYS_URL" ] && debug "# OPT_SSHKEYS_URL: $OPT_SSHKEYS_URL" + + diff --git a/gpg/coreos-pubkey.asc b/gpg/coreos-pubkey.asc new file mode 100644 index 0000000..1fdca80 --- /dev/null +++ b/gpg/coreos-pubkey.asc @@ -0,0 +1,109 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQINBFIqVhQBEADjC7oxg5N9Xqmqqrac70EHITgjEXZfGm7Q50fuQlqDoeNWY+sN +szpw//dWz8lxvPAqUlTSeR+dl7nwdpG2yJSBY6pXnXFF9sdHoFAUI0uy1Pp6VU9b +/9uMzZo+BBaIfojwHCa91JcX3FwLly5sPmNAjgiTeYoFmeb7vmV9ZMjoda1B8k4e +8E0oVPgdDqCguBEP80NuosAONTib3fZ8ERmRw4HIwc9xjFDzyPpvyc25liyPKr57 +UDoDbO/DwhrrKGZP11JZHUn4mIAO7pniZYj/IC47aXEEuZNn95zACGMYqfn8A9+K +mHIHwr4ifS+k8UmQ2ly+HX+NfKJLTIUBcQY+7w6C5CHrVBImVHzHTYLvKWGH3pmB +zn8cCTgwW7mJ8bzQezt1MozCB1CYKv/SelvxisIQqyxqYB9q41g9x3hkePDRlh1s +5ycvN0axEpSgxg10bLJdkhE+CfYkuANAyjQzAksFRa1ZlMQ5I+VVpXEECTVpLyLt +QQH87vtZS5xFaHUQnArXtZFu1WC0gZvMkNkJofv3GowNfanZb8iNtNFE8r1+GjL7 +a9NhaD8She0z2xQ4eZm8+Mtpz9ap/F7RLa9YgnJth5bDwLlAe30lg+7WIZHilR09 +UBHapoYlLB3B6RF51wWVneIlnTpMIJeP9vOGFBUqZ+W1j3O3uoLij1FUuwARAQAB +tDZDb3JlT1MgQnVpbGRib3QgKE9mZmljYWwgQnVpbGRzKSA8YnVpbGRib3RAY29y +ZW9zLmNvbT6JAjkEEwECACMFAlIqVhQCGwMHCwkIBwMCAQYVCAIJCgsEFgIDAQIe +AQIXgAAKCRBQ4IhVk9LctFkGD/46/I3S392oQQs81pUOMbPulCitA7/ehYPuVlgy +mv6+SEZOtafEJuI9uiTzlAVremZfalyL20RBtU10ANJfejp14rOpMadlRqz0DCvc +Wuuhhn9FEQE59Yk3LQ7DBLLbeJwUvEAtEEXq8xVXWh4OWgDiP5/3oALkJ4Lb3sFx +KwMy2JjkImr1XgMY7M2UVIomiSFD7v0H5Xjxaow/R6twttESyoO7TSI6eVyVgkWk +GjOSVK5MZOZlux7hW+uSbyUGPoYrfF6TKM9+UvBqxWzz9GBG44AjcViuOn9eH/kF +NoOAwzLcL0wjKs9lN1G4mhYALgzQx/2ZH5XO0IbfAx5Z0ZOgXk25gJajLTiqtOkM +E6u691Dx4c87kST2g7Cp3JMCC+cqG37xilbV4u03PD0izNBt/FLaTeddNpPJyttz +gYqeoSv2xCYC8AM9N73Yp1nT1G1rnCpe5Jct8Mwq7j8rQWIBArt3lt6mYFNjuNpg +om+rZstK8Ut1c8vOhSwz7Qza+3YaaNjLwaxe52RZ5svt6sCfIVO2sKHf3iO3aLzZ +5KrCLZ/8tJtVxlhxRh0TqJVqFvOneP7TxkZs9DkU5uq5lHc9FWObPfbW5lhrU36K +Pf5pn0XomaWqge+GCBCgF369ibWbUAyGPqYj5wr/jwmG6nedMiqcOwpeBljpDF1i +d9zMN4kCHAQQAQIABgUCUipXUQAKCRDAr7X91+bcxwvZD/0T4mVRyAp8+EhCta6f +Qnoiqc49oHhnKsoN7wDg45NRlQP84rH1knn4/nSpUzrB29bhY8OgAiXXMHVcS+Uk +hUsF0sHNlnunbY0GEuIziqnrjEisb1cdIGyfsWUPc/4+inzu31J1n3iQyxdOOkrA +ddd0iQxPtyEjwevAfptGUeAGvtFXP374XsEo2fbd+xHMdV1YkMImLGx0guOK8tgp ++ht7cyHkfsyymrCV/WGaTdGMwtoJOxNZyaS6l0ccneW4UhORda2wwD0mOHHk2EHG +dJuEN4SRSoXQ0zjXvFr/u3k7Qww11xU0V4c6ZPl0Rd/ziqbiDImlyODCx6KUlmJb +k4l77XhHezWD0l3ZwodCV0xSgkOKLkudtgHPOBgHnJSL0vy7Ts6UzM/QLX5GR7uj +do7P/v0FrhXB+bMKvB/fMVHsKQNqPepigfrJ4+dZki7qtpx0iXFOfazYUB4CeMHC +0gGIiBjQxKorzzcc5DVaVaGmmkYoBpxZeUsAD3YNFr6AVm3AGGZO4JahEOsul2FF +V6B0BiSwhg1SnZzBjkCcTCPURFm82aYsFuwWwqwizObZZNDC/DcFuuAuuEaarhO9 +BGzShpdbM3Phb4tjKKEJ9Sps6FBC2Cf/1pmPyOWZToMXex5ZKB0XHGCI0DFlB4Tn +in95D/b2+nYGUehmneuAmgde87kCDQRSKlZGARAAuMYYnu48l3AvE8ZpTN6uXSt2 +RrXnOr9oEah6hw1fn9KYKVJi0ZGJHzQOeAHHO/3BKYPFZNoUoNOU6VR/KAn7gon1 +wkUwk9Tn0AXVIQ7wMFJNLvcinoTkLBT5tqcAz5MvAoI9sivAM0Rm2BgeujdHjRS+ +UQKq/EZtpnodeQKE8+pwe3zdf6A9FZY2pnBs0PxKJ0NZ1rZeAW9w+2WdbyrkWxUv +jYWMSzTUkWK6533PVi7RcdRmWrDMNVR/X1PfqqAIzQkQ8oGcXtRpYjFL30Z/LhKe +c9Awfm57rkZk2EMduIB/Y5VYqnOsmKgUghXjOo6JOcanQZ4sHAyQrB2Yd6UgdAfz +qa7AWNIAljSGy6/CfJAoVIgl1revG7GCsRD5Dr/+BLyauwZ/YtTH9mGDtg6hy/So +zzDAM8+79Y8VMBUtj64GQBgg2+0MVZYNsZCN209X+EGpGUmAGEFQLGLHwFoNlwwL +1Uj+/5NTAhp2MQA/XRDTVx1nm8MZZXUOu6NTCUXtUmgTQuQEsKCosQzBuT/G+8Ia +R5jBVZ38/NJgLw+YcRPNVo2S2XSh7liw+Sl1sdjEW1nWQHotDAzd2MFG++KVbxwb +cXbDgJOB0+N0c362WQ7bzxpJZoaYGhNOVjVjNY8YkcOiDl0DqkCk45obz4hG2T08 +x0OoXN7Oby0FclbUkVsAEQEAAYkERAQYAQIADwUCUipWRgIbAgUJAeEzgAIpCRBQ +4IhVk9LctMFdIAQZAQIABgUCUipWRgAKCRClQeyydOfjYdY6D/4+PmhaiyasTHqh +iui2DwDVdhwxdikQEl+KQQHtk7aqgbUAxgU1D4rbLxzXyhTbmql7D30nl+oZg0Be +yl67Xo6X/wHsP44651aTbwxVT9nzhOp6OEW5z/qxJaX1B9EBsYtjGO87N854xC6a +QEaGZPbNauRpcYEadkppSumBo5ujmRWc4S+H1VjQW4vGSCm9m4X7a7L7/063HJza +SYaHybbu/udWW8ymzuUf/UARH4141bGnZOtIa9vIGtFl2oWJ/ViyJew9vwdMqiI6 +Y86ISQcGV/lL/iThNJBn+pots0CqdsoLvEZQGF3ZozWJVCKnnn/kC8NNyd7Wst9C ++p7ZzN3BTz+74Te5Vde3prQPFG4ClSzwJZ/U15boIMBPtNd7pRYum2padTK9oHp1 +l5dI/cELluj5JXT58hs5RAn4xD5XRNb4ahtnc/wdqtle0Kr5O0qNGQ0+U6ALdy/f +IVpSXihfsiy45+nPgGpfnRVmjQvIWQelI25+cvqxX1dr827ksUj4h6af/Bm9JvPG +KKRhORXPe+OQM6y/ubJOpYPEq9fZxdClekjA9IXhojNA8C6QKy2Kan873XDE0H4K +Y2OMTqQ1/n1A6g3qWCWph/sPdEMCsfnybDPcdPZp3psTQ8uX/vGLz0AAORapVCbp +iFHbF3TduuvnKaBWXKjrr5tNY/njrU4zEADTzhgbtGW75HSGgN3wtsiieMdfbH/P +f7wcC2FlbaQmevXjWI5tyx2m3ejG9gqnjRSyN5DWPq0m5AfKCY+4Glfjf01l7wR2 +5oOvwL9lTtyrFE68t3pylUtIdzDz3EG0LalVYpEDyTIygzrriRsdXC+Na1KXdr5E +GC0BZeG4QNS6XAsNS0/4SgT9ceA5DkgBCln58HRXabc25Tyfm2RiLQ70apWdEuoQ +TBoiWoMDeDmGLlquA5J2rBZh2XNThmpKU7PJ+2g3NQQubDeUjGEa6hvDwZ3vni6V +vVqsviCYJLcMHoHgJGtTTUoRO5Q6terCpRADMhQ014HYugZVBRdbbVGPo3YetrzU +/BuhvvROvb5dhWVi7zBUw2hUgQ0g0OpJB2TaJizXA+jIQ/x2HiO4QSUihp4JZJrL +5G4P8dv7c7/BOqdj19VXV974RAnqDNSpuAsnmObVDO3Oy0eKj1J1eSIp5ZOA9Q3d +bHinx13rh5nMVbn3FxIemTYEbUFUbqa0eB3GRFoDz4iBGR4NqwIboP317S27NLDY +J8L6KmXTyNh8/Cm2l7wKlkwi3ItBGoAT+j3cOG988+3slgM9vXMaQRRQv9O1aTs1 +ZAai+Jq7AGjGh4ZkuG0cDZ2DuBy22XsUNboxQeHbQTsAPzQfvi+fQByUi6TzxiW0 +BeiJ6tEeDHDzdLkCDQRUDREaARAA+Wuzp1ANTtPGooSq4W4fVUz+mlEpDV4fzK6n +HQ35qGVJgXEJVKxXy206jNHx3lro7BGcJtIXeRb+Wp1eGUghrG1+V/mKFxE4wulN +tFXoTOJ//AOYkPq9FG12VGeLZDckAR4zMhDwdcwsJ208hZzBSslJOWAuZTPoWple ++xie4B8jZiUcjf10XaWvBnlx4EPohhvtv5VEczZWNvGa/0VDe/FfI4qGknJM3+d0 +kvXK/7yaFpdGwnY3nE/V4xbwx2tggqQRXoFmYbjogGHpTcdXkWbGEz5F7mLNwzZ/ +voyTiZeukZP5I45CCLgiB+g2WTl8cm3gcxrnt/aZAJCAl/eclFeYQ/Xiq8sK1+U2 +nDEYLWRygoZACULmLPbUEVmQBOw/HAufE98sb36MHcFss634h2ijIp9/wvnX9GOE +LgX4hgqkgM85QaMeaS3d2+jlMu8BdsMYxPkTumsEUShcFtAYgtrNrPSayHtV6I9I +41ISg8EIr9qEhH1xLGvSA+dfUvXqwa0cIBxhI3bXOa25vPHbT+SLtfQlvUvKySIb +c6fobw2Wf1ZtM8lgFL3f/dHbT6fsvK6Jd/8iVMAZkAYFbJcivjS9/ugXbMznz5Wv +g9O7hbQtXUvRjvh8+AzlASYidqSd6neW6o+i2xduUBlrbCfW6R0bPLX+7w9iqMaT +0wEQs3MAEQEAAYkERAQYAQIADwUCVA0RGgIbAgUJAeEzgAIpCRBQ4IhVk9LctMFd +IAQZAQIABgUCVA0RGgAKCRClqWY15Wdu/JYcD/95hNCztDFlwzYi2p9vfaMbnWcR +qzqavj21muB9vE/ybb9CQrcXd84y7oNq2zU7jOSAbT3aGloQDP9+N0YFkQoYGMRs +CPiTdnF7/mJCgAnXei6SO+H6PIw9qgC4wDV0UhCiNh+CrsICFFbK+O+Jbgj+CEN8 +XtVhZz3UXbH/YWg/AV/XGWL1BT4bFilUdF6b2nJAtORYQFIUKwOtCAlI/ytBo34n +M6lrMdMhHv4MoBHP91+Y9+t4D/80ytOgH6lq0+fznY8Tty+ODh4WNkfXwXq+0TfZ +fJiZLvkoXGD+l/I+HE3gXn4MBwahQQZl8gzI9daEGqPF8KYX0xyyKGo+8yJG5/WG +lfdGeKmz8rGP/Ugyo6tt8DTSSqJv6otAF/AWV1Wu/DCniehtfHYrp2EHZUlpvGRl +7Ea9D9tv9BKYm6S4+2yD5KkPu4qp3r6glVbePPCLeZ4NLQCEIpKakIERfxk66JqZ +Tb5XI9HKKbnhKunOoGiL5SMXVsS67Sxt//Ta/3vSaLC3wnVwN5OeXNaa04Yx7jg/ +wtMJ9Jz0EYFtVv2NLizEeGCI8iPJOyMWOy+twCIk5zmvwsLu5MKmg1tLI2mtCTYz +qo8uVIqETlojxIqAhRYtmeiYKf2fZs5um3+Sjv28v4nw3VfQgibTKc2uBjeqxxOe +XGw0ysKnS2VO72SK879+EADd3HoF9U80odCgN5T6aljhaNaruqmG4CvBdRyzp3EQ +9RP7jPOEhcM00etw572orviK9AqCk+zwvfzEFbt/uC7zOpO0BJ8fnMAZ0Zn/fF8s +88zR4zq6BBq9WD4RCmazw2G6IyGXHvVAWi8UxoNjNoJJosLyLauFdPPUeoye5PxE +g+fQew3behcCaebjZwUA+xZMj7dfwcNXlDa4VkCDHzTfU43znawBo9avB8hNwMeW +CZYINmym+LSKyQnz3sirTpYcjorxtov1fyml8413tDJoOvkotSX9o3QQgbBPsyQ7 +nwLTscYc5eklGRH7iytXOPI+29EPpfRHX2DAnVyTeVSFPEr79tIsijy02ZBZTiKY +lBlJy/Cj2C5cGhVeQ6v4jnj1Nt3sjHkZlVfmipSYVfcBoID1/4r2zHl4OFlLCjvk +XUhbqhm9xWV8NdmItO3BBSlIEksFunykzz1HM6shvzw77sM5+TEtSsxoOxxys+9N +ItCl8L6yf84A5333pLaUWh5HON1J+jGGbKnUzXKBsDxGSvgDcFlyVloBRQShUkv3 +FMem+FWqt7aA3/YFCPgyLp7818VhfM70bqIxLi0/BJHp6ltGN5EH+q7Ewz210VAB +ju5IO7bjgCqTFeR3YYUN87l8ofdARx3shApXS6TkVcwaTv5eqzdFO9fZeRqHj4L9 +Pg== +=LY4G +-----END PGP PUBLIC KEY BLOCK----- diff --git a/gpg/public-key.asc b/gpg/public-key.asc new file mode 100644 index 0000000..9a27c57 --- /dev/null +++ b/gpg/public-key.asc @@ -0,0 +1,20 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.11 (GNU/Linux) + +mQENBFIcd10BCADA+oOX1XhUsCDxV4Q7Y1xxgNmDy3zwjwAKo2kwq4T7zD9PWO59 +XFVImZE5qD3us5OhB7c8yQKNj+uR83r9ORQ246a0iM4khcLrtvJwzdeIOviSxeHR +YKcyrXPZV2EFN7ydjQvnCr5CIg4M190ePQXxX7WEufELP9EF75ddRGLa3Q4zFLbX +cJadegY5TUpj95R+8/bZHmnSuPi1MdUjzJa72XL4Y8tHtc1wAoVjj+lkaaJJVC0o +DN+uMwjlTD9rM8x3xN5djMtunvveWGLy6t0njXoYj9FBh0mp/pdRbaX7HsnswtRK +EnoLbU3aCqsz1E7nha24avPYgE3OfYmHZpvdABEBAAG0TkhldHpuZXIgT25saW5l +IEFHLCBSWi1Tb2Z0d2FyZWVudHdpY2tsdW5nIChTaWduaW5nIEtleSAyMDEzKSA8 +aW5mb0BoZXR6bmVyLmRlPokBPgQTAQIAKAUCUhx3XQIbAwUJCWYBgAYLCQgHAwIG +FQgCCQoLBBYCAwECHgECF4AACgkQngPivrjw9GPDcwf/WQjD1/J9i4xjmLZ9QqYY +oDe3y4eGj0ZK1eP/x9hzvVnMSwEB6qgJT1rFKTTxjCqZ9/AA/W9Ij60gi3mKabXd +0YN7dk6cvVuZP/nWmEFbqGBb1E5xCbYkmckCZTge5Ux/wOpf/iug7ciC7u8WqBDE +9ZaRlvVF0Pjhtmr9vHaYtqRpbMyIQxr1kVvT5vFumnuZonBw+1ogWbpS7M/IpUyM +eJYXRt6Kf2LVef3kddMFGbcFHCnTU8x86MjtCAYcA1/3XUOftdNJZR6aqbEdP0Ok +xaK2VslZQVDOheu7lz3qjZEaPuK05Cez0C5y4SkDQ0f4Jsrv2JdosawfMn3d5GJz +fg== +=4M7W +-----END PGP PUBLIC KEY BLOCK----- diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..d5768ec --- /dev/null +++ b/install.sh @@ -0,0 +1,527 @@ +#!/bin/bash + +# +# install - installation commands +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + +STATUS_POSITION="\033[60G" + +TOTALSTEPS=15 +CURSTEP=0 + +# read global variables and functions +clear +. /tmp/install.vars + + +inc_step() { + CURSTEP=$(($CURSTEP + 1)) +} + +status_busy() { + local step="$CURSTEP" + test $CURSTEP -lt 10 && step=" $CURSTEP" + echo -ne " $step/$TOTALSTEPS : $@ $STATUS_POSITION${CYAN} busy $NOCOL" + debug "# $@" +} + +status_busy_nostep() { + echo -ne " : $@ $STATUS_POSITION${CYAN} busy $NOCOL" +} + +status_none() { + local step="$CURSTEP" + test $CURSTEP -lt 10 && step=" $CURSTEP" + echo -e " $step/$TOTALSTEPS : $@" +} + +status_none_nostep() { + echo -e " : $@" +} + +status_done() { + echo -e "$STATUS_POSITION${GREEN} done $NOCOL" +} + +status_failed() { + echo -e "$STATUS_POSITION${RED}failed$NOCOL" + [ $# -gt 0 ] && echo -e "${RED} : $@${NOCOL}" + debug "=> FAILED" + exit_function + exit 1 +} + +status_warn() { + echo -e "$STATUS_POSITION${YELLOW} warn" + echo -e " : $@${NOCOL}" +} + +status_donefailed() { + if [ "$1" -a $1 -eq 0 ]; then + status_done + else + status_failed + fi +} + +echo +echo_bold " Hetzner Online AG - 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 +# +status_busy_nostep "Reading configuration" +read_vars $FOLD/install.conf +status_donefailed $? + +# +# Load image variables +# +status_busy_nostep "Loading image file variables" +get_image_info "$IMAGE_PATH" "$IMAGE_PATH_TYPE" "$IMAGE_FILE" +status_donefailed $? + + +# change sizes of DOS partitions +check_dos_partitions "no_output" + +whoami $IMAGE_FILE +status_busy_nostep "Loading $IAM specific functions " +debug "# load $IAM specific functions..." +if [ -e "$SCRIPTPATH/$IAM.sh" ]; then + . $SCRIPTPATH/$IAM.sh 2>&1 > /dev/null + status_done +else + status_failed +fi + +test "$SWRAID" = "1" && TOTALSTEPS=$(($TOTALSTEPS + 1)) +test "$LVM" = "1" && TOTALSTEPS=$(($TOTALSTEPS + 1)) +test "$OPT_INSTALL" && TOTALSTEPS=$(($TOTALSTEPS + 1)) +test "$IMAGE_PATH_TYPE" = "http" && TOTALSTEPS=$(($TOTALSTEPS + 1)) + +# +# Remove partitions +# +inc_step +status_busy "Deleting partitions" + +unmount_all +stop_lvm_raid + +for part_inc in $(seq 1 $COUNT_DRIVES) ; do + if [ "$(eval echo \$FORMAT_DRIVE${part_inc})" = "1" -o "$SWRAID" = "1" -o $part_inc -eq 1 ] ; then + TARGETDISK="$(eval echo \$DRIVE${part_inc})" + debug "# Deleting partitions on $TARGETDISK" + delete_partitions "$TARGETDISK" || status_failed + fi +done + +status_done + +# +# Test partition size +# +inc_step +status_busy "Test partition size" +part_test_size +check_dos_partitions "no_output" +status_done + + +# +# Create partitions +# +inc_step +status_busy "Creating partitions and /etc/fstab" + +for part_inc in $(seq 1 $COUNT_DRIVES) ; do + if [ "$SWRAID" = "1" -o $part_inc -eq 1 ] ; then + TARGETDISK="$(eval echo \$DRIVE${part_inc})" + debug "# Creating partitions on $TARGETDISK" + create_partitions $TARGETDISK || status_failed + fi +done + +status_done + + +# +# Software RAID +# +if [ "$SWRAID" = "1" ]; then + inc_step + status_busy "Creating software RAID level $SWRAIDLEVEL" + make_swraid "$FOLD/fstab" + status_donefailed $? +fi + + +# +# LVM +# +if [ "$LVM" = "1" ]; then + inc_step + status_busy "Creating LVM volumes" + make_lvm "$FOLD/fstab" "$DRIVE1" "$DRIVE2" + LVM_EXIT=$? + if [ $LVM_EXIT -eq 2 ] ; then + status_failed "LVM thin-pool detected! Can't remove automatically!" + else + status_donefailed $LVM_EXIT + fi +fi + + +# +# Format partitions +# +inc_step +status_none "Formatting partitions" +cat $FOLD/fstab | grep "^/dev/" > /tmp/fstab.tmp +while read line ; do + DEV="$(echo $line |cut -d " " -f 1)" + FS="$(echo $line |cut -d " " -f 3)" + status_busy_nostep " formatting $DEV with $FS" + format_partitions "$DEV" "$FS" + status_donefailed $? +done < /tmp/fstab.tmp + + +# +# Mount filesystems +# +inc_step +status_busy "Mounting partitions" +mount_partitions "$FOLD/fstab" "$FOLD/hdd" || status_failed +status_donefailed $? + + +# +# Look for a post-mount script and call it if existing +# +# this can be used e.g. for asking the user if +# he wants to restore from an ebackup-server +# +if has_postmount_script ; then + status_none_nostep "Executing post mount script" + execute_postmount_script || exit 0 +fi + +# +# ntp resync +# +inc_step +status_busy "Sync time via ntp" +set_ntp_time +status_donefailed $? + +# +# Download image +# +if [ "$IMAGE_PATH_TYPE" = "http" ] ; then + inc_step + status_busy "Downloading image ($IMAGE_PATH_TYPE)" + get_image_url "$IMAGE_PATH" "$IMAGE_FILE" + status_donefailed $? +fi + +# +# Import public key for image validation +# +status_busy_nostep "Importing public key for image validation" +import_imagekey +IMPORT_EXIT=$? +if [ $IMPORT_EXIT -eq 2 ] ; then + status_warn "No public key found!" +else + status_donefailed $IMPORT_EXIT +fi + +# +# Validate image +# +inc_step +status_busy "Validating image before starting extraction" +validate_image +VALIDATE_EXIT=$? +if [ -n "$FORCE_SIGN" -o -n "$OPT_FORCE_SIGN" ] && [ $VALIDATE_EXIT -gt 0 ] ; then + debug "FORCE_SIGN set, but validation failed!" + status_failed +fi +if [ $VALIDATE_EXIT -eq 3 ] ; then + status_warn "No imported public key found!" +elif [ $VALIDATE_EXIT -eq 2 ] ; then + status_warn "No detached signature file found!" +else + status_donefailed $VALIDATE_EXIT +fi + +# +# Extract image +# +inc_step +status_busy "Extracting image ($IMAGE_PATH_TYPE)" +extract_image "$IMAGE_PATH_TYPE" "$IMAGE_FILE_TYPE" +status_donefailed $? + +# +# Setup network +# +inc_step +status_busy "Setting up network for $ETHDEV" +setup_network_config "$ETHDEV" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" +status_donefailed $? + +# +# Set udev rules +# +set_udev_rules + +# +# chroot commands +# +inc_step +status_none "Executing additional commands" + +copy_mtab "NIL" + +status_busy_nostep " Setting hostname" +debug "# Setting hostname" +#set_hostname "$NEWHOSTNAME" || status_failed +set_hostname "$NEWHOSTNAME" "$IPADDR" "$IP6ADDR" || status_failed +status_done + +status_busy_nostep " Generating new SSH keys" +debug "# Generating new SSH keys" +generate_new_sshkeys "NIL" || status_failed +status_done + +if [ "$SWRAID" = "1" ]; then + status_busy_nostep " Generating mdadm config" + debug "# Generating mdadm configuration" + generate_config_mdadm "NIL" || status_failed + status_done +fi + +status_busy_nostep " Generating ramdisk" +debug "# Generating ramdisk" +generate_new_ramdisk "NIL" || status_failed +status_done + +status_busy_nostep " Generating ntp config" +debug "# Generating ntp config" +generate_ntp_config "NIL" || status_failed +status_done + + + +# +# Cool'n'Quiet +# +#inc_step +#status_busy "Setting CPU frequency scaling to $GOVERNOR" +setup_cpufreq "$GOVERNOR" || { + debug "=> FAILED" +# exit 1 +} +#status_donefailed $? + + + +# +# Set up misc files +# +inc_step +status_busy "Setting up miscellaneous files" +generate_resolvconf || status_failed +# already done in set_hostname +#generate_hosts "$IPADDR" "$IP6ADDR" || status_failed +generate_sysctlconf || status_failed +status_done + + +# +# Set root password and/or install ssh keys +# +inc_step +status_none "Configuring authentication" + +if [ -n "$OPT_SSHKEYS_URL" ] ; then + status_busy_nostep " Fetching SSH keys" + debug "# Fetch public SSH keys" + fetch_ssh_keys "$OPT_SSHKEYS_URL" + status_donefailed $? +fi + +if [ "$OPT_USE_SSHKEYS" = "1" -a -z "$FORCE_PASSWORD" ]; then + status_busy_nostep " Disabling root password" + set_rootpassword "$FOLD/hdd/etc/shadow" "*" + status_donefailed $? + status_busy_nostep " Disabling SSH root login without password" + set_ssh_rootlogin "without-password" + status_donefailed $? +else + status_busy_nostep " Setting root password" + get_rootpassword "/etc/shadow" || status_failed + set_rootpassword "$FOLD/hdd/etc/shadow" "$ROOTHASH" + status_donefailed $? + status_busy_nostep " Enabling SSH root login with password" + set_ssh_rootlogin "yes" + status_donefailed $? +fi + +if [ "$OPT_USE_SSHKEYS" = "1" ] ; then + status_busy_nostep " Copying SSH keys" + debug "# Adding public SSH keys" + copy_ssh_keys + status_donefailed $? +fi + +# +# Write Bootloader +# +inc_step +status_busy "Installing bootloader $BOOTLOADER" + +debug "# Generating config for $BOOTLOADER" +if [ "$BOOTLOADER" = "grub" -o "$BOOTLOADER" = "GRUB" ]; then + generate_config_grub "$VERSION" || status_failed +else + generate_config_lilo "$VERSION" || status_failed +fi + +debug "# Writing bootloader $BOOTLOADER into MBR" +if [ "$BOOTLOADER" = "grub" -o "$BOOTLOADER" = "GRUB" ]; then + write_grub "NIL" || status_failed +else + write_lilo "NIL" || status_failed +fi + +status_done + +# +# installing optional software (e.g. Plesk) +# + +if [ "$OPT_INSTALL" ]; then + inc_step + status_none "Installing additional software" + opt_install_items="$(echo $OPT_INSTALL | sed s/,/\\n/g)" + for opt_item in $opt_install_items; do + opt_item=$(echo $opt_item | tr [:upper:] [:lower:]) + case "$opt_item" in + plesk*) + status_busy_nostep " Installing PLESK Control Panel" + debug "# installing PLESK" + install_plesk "$opt_item" + status_donefailed $? + ;; + omsa) + status_busy_nostep " Installing Open Manage" + debug "# installing OMSA" + install_omsa + status_donefailed $? + ;; + esac + done +fi + +# +# os specific functions +# details in debian.sh / suse.sh / ubuntu.sh +# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP +# +inc_step +status_busy "Running some $IAM specific functions" +run_os_specific_functions || status_failed +status_done + +# +# Clear log files +# +inc_step +status_busy "Clearing log files" +clear_logs "NIL" +status_donefailed $? + +# +# Execute post installation script +# +if has_postinstall_script; then + status_none_nostep "Executing post installation script" + execute_postinstall_script +fi + +# +# Install robot script for automatic installations +# +if [ "$ROBOTURL" ]; then + debug "# Installing Robot script..." + install_robot_script 2>&1 | debugoutput +fi + +# +### report SSH fingerprints to URL where we got the pubkeys from (or not) +if [ -n "$OPT_SSHKEYS_URL" ] ; then + case $OPT_SSHKEYS_URL in + https:*|http:*) + debug "# Reporting SSH fingerprints..." + curl -s -m 10 -X POST -H "Content-Type: application/json" -d @"$FOLD/ssh_fingerprints" $OPT_SSHKEYS_URL -o /dev/null + ;; + *) + debug "# cannot POST SSH fingerprints to non-HTTP URLs" + esac +fi + +# +# +# Report statistic +# +report_statistic "$STATSSERVER" "$IMAGE_FILE" "$SWRAID" "$LVM" "$BOOTLOADER" "$ERROREXIT" + +# +# Report install.conf to rz_admin +# Report debug.txt to rz_admin +# +report_id="$(report_config)" +report_debuglog $report_id + +# +# Save installimage configuration and debug file on the new system +# +( + echo "#" + echo "# Hetzner Online AG - installimage" + echo "#" + echo "# This file contains the configuration used to install this" + echo "# system via installimage script. Comments have been removed." + echo "#" + echo "# More information about the installimage script and" + echo "# automatic installations can be found in our wiki:" + echo "#" + echo "# http://wiki.hetzner.de/index.php/Betriebssystem_Images_installieren" + echo "#" + echo + cat $FOLD/install.conf | grep -v "^#" | grep -v "^$" +) > $FOLD/hdd/installimage.conf +cat /root/debug.txt > $FOLD/hdd/installimage.debug +chmod 640 $FOLD/hdd/installimage.conf +chmod 640 $FOLD/hdd/installimage.debug + +echo +echo_bold " INSTALLATION COMPLETE" +echo_bold " You can now reboot and log in to your new system with" +echo_bold " the same password as you logged in to the rescue system.\n" diff --git a/installimage b/installimage new file mode 100755 index 0000000..ca792aa --- /dev/null +++ b/installimage @@ -0,0 +1,133 @@ +#!/bin/bash + +# +# installimage main start script +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + +# simple params - restart with other params +case $1 in + proxmox) exec $0 -c proxmox -x proxmox ;; + hsa-baculadir) exec $0 -c hsa-baculadir -x hsa-baculadir ;; + hsa-minimal64) exec $0 -c hsa-minimal64 -x hsa-minimal64 ;; + hsa-managed) exec $0 -c hsa-managed -x hsa-managed ;; + hsa-sql) exec $0 -c hsa-sql -x hsa-sql ;; +esac + + +clear +wd=$(pwd) + +# important: set pipefile bash option, see bash manual +set -o pipefail + +export LANG="en_US.UTF-8" +export LC_ALL="en_US.UTF-8" +export EXITCODE=0 + +# invalidate all caches, so we get the latest version from nfs +echo 3 >/proc/sys/vm/drop_caches + + +# realconfig +SCRIPTPATH="`dirname $0`" +REALCONFIG="$SCRIPTPATH/config.sh" + +# copy our config file and read global variables and functions +cp -a "$REALCONFIG" /tmp/install.vars +. /tmp/install.vars +FOLD="$(mktemp -d /installimage.XXXXX)" + +# clear debugfile +echo > $DEBUGFILE + + +# get command line options +if [ $# -lt 1 -a ! -e "$AUTOSETUPCONFIG" ] ; then + echo -e "\n${YELLOW}run 'installimage -h' to get help for command line arguments." + echo -e "${GREEN}starting interactive mode ...${NOCOL}\n" + # press any key or sleep 1 sec ... + read -n1 -t1 +fi +. $GETOPTIONSFILE + + +# deleting possible existing files and create dirs +umount -l "$FOLD/*" >> /dev/null 2>&1 +rm -rf "$FOLD" >> /dev/null 2>&1 +mkdir -p "$FOLD/nfs" >> /dev/null 2>&1 +mkdir -p "$FOLD/hdd" >> /dev/null 2>&1 +cd "$FOLD" +myip=$(ifconfig eth0 | grep "inet addr" | cut -d: -f2 | cut -d ' ' -f1) +debug "# starting installimage on [ $myip ]" + + +# log hardware data +debug "-------------------------------------" +hwdata="/usr/local/bin/hwdata" +[ -f $hwdata ] && $hwdata | grep -v "^$" | debugoutput +debug "-------------------------------------" + + +# generate new config file with our parameters and the template config from the nfs-server +debug "# make clean config" +if [ -f /tmp/install.vars ]; then + . /tmp/install.vars +else + debug "=> FAILED" +fi + +# Unmount all partitions and print an error message if it fails +unmount_all ; EXITCODE=$? +if [ $EXITCODE -ne 0 ] ; then + echo -e "$RED""\nERROR unmounting device(s):$NOCOL\n$unmount_output\n" + echo -e "$RED""Cannot continue, device(s) seem to be in use.$NOCOL" + echo -e "Please unmount used devices manually or reboot the rescuesystem and retry.\n" + exit 1 +fi +stop_lvm_raid ; EXITCODE=$? +if [ $EXITCODE -ne 0 ] ; then + echo -e "$RED""\nERROR stopping LVM and/or RAID device(s):$NOCOL\n$unmount_output\n" + echo -e "$RED""Cannot continue, device(s) seem to be in use.$NOCOL" + echo -e "Please stop used lvm/raid manually or reboot the rescuesystem and retry.\n" + exit 1 +fi + + +# check if we have a autosetup-file, else we start the menu +if [ -e $AUTOSETUPCONFIG ] ; then + + # start autosetup + AUTOSETUP="true" + cp $AUTOSETUPCONFIG $FOLD/install.conf + [ "$OPT_CONFIGFILE" ] && mv $AUTOSETUPCONFIG $AUTOSETUPCONFIG.bak-$(date +%Y%m%d-%H%M%S) + debug "# executing autosetup ..." + if [ -f $AUTOSETUPFILE ] ; then + . $AUTOSETUPFILE ; EXITCODE=$? + else + echo -e "${RED}\nERROR: $AUTOSETUPFILE does not exist${NOCOL}" + debug "=> FAILED, $AUTOSETUPFILE does not exist" + fi + +else + + # start the menu + debug "# executing setupfile" + if [ -f $SETUPFILE ] ; then + . $SETUPFILE ; EXITCODE=$? + else + debug "=> FAILED, $SETUPFILE does not exist" + echo -e "${RED}\nERROR: Cant find files${NOCOL}" + fi +fi + +# clean mounts and close debugfile +cleanup + +if [ "$EXITCODE" = "1" ]; then + exit 1 +fi + diff --git a/installimage.in_screen b/installimage.in_screen new file mode 100755 index 0000000..051cdc1 --- /dev/null +++ b/installimage.in_screen @@ -0,0 +1,65 @@ +#!/bin/bash + +# +# starts installimage in a new screen session +# and reboots the system on success +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + + +TIMEOUT=20 +INSTALLIMAGE="/root/.oldroot/nfs/install/installimage" +export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +export LANG="en_US.UTF-8" +export LC_ALL="en_US.UTF-8" + +case $1 in + + start) + # start installimage script and reboot if successful + # + shift + until false ; do + + $INSTALLIMAGE $@ ; EXITCODE=$? + + if [ $EXITCODE -eq 0 ] ; then + echo -e "\n\n\n===> Erfolgreich beendet.\n" + echo -e "Der Computer wird in $TIMEOUT Sekunden neu gestartet !" + echo -en "Druecken sie jetzt eine beliebige Taste, um den Neustart zu verhindern: " + for i in $(seq 1 $TIMEOUT) ; do + echo -n "." + read -n1 -t1 key + if [ "$key" ] ; then + echo -e "\n\nEs wird nicht neu gestartet.\n\n" + exec /bin/bash + exit 0 + fi + done + echo -e "\n\nDer Computer wird jetzt neu gestartet ...\n" + reboot + sleep 60 + else + echo -e "\n\n\n===> Es sind Fehler aufgetreten.\n" + echo -e "Es wird eine Sub-Shell gestartet ..." + echo -e "Nach beenden der Sub-Shell wird installimage erneut ausgefuehrt.\n" + /bin/bash + fi + + done + ;; + + *) + # if we were called without the parameter 'start', restart ourself in a new screen + # + echo -e "\n\nHINWEIS:\n-------" >>/etc/motd + echo -e "installimage wurde nach dem booten in einer screen-session gestartet." >>/etc/motd + echo -e "Um sich mit der screen-session zu verbinden, 'screen -x' eingeben ...\n" >>/etc/motd + screen -AS installimage $0 start $@ + ;; + +esac + diff --git a/password.txt b/password.txt new file mode 100644 index 0000000..35f1edb --- /dev/null +++ b/password.txt @@ -0,0 +1,10 @@ +The MySQL root password is: + +Webmin: + +http://:10000 + +phpmyadmin: + +http:///phpmyadmin + diff --git a/post-install/hsa-baculadir b/post-install/hsa-baculadir new file mode 100755 index 0000000..bdf8ffa --- /dev/null +++ b/post-install/hsa-baculadir @@ -0,0 +1,121 @@ +#!/bin/bash + + +NEW_HNAME="$(hostname -f)" +NEW_ADDRESS=`/sbin/ifconfig eth0 | grep "inet addr:" | head -1 | awk '{print $2}'| cut -d: -f2` +NEW_DC="$(hostname -f | cut -d. -f2)" + +if echo $NEW_DC | grep -Eq 'cpt[1234]|jnb[12]'; then + OLD_ADDRESS="41.203.16.241" + OLD_HNAME="masterbuild64.jnb2.host-h.net" + OLD_DOMAIN="jnb2.host-h.net" + OLD_SHNAME="masterbuild64" +elif echo $NEW_DC | grep -Eq 'nur4|flk1'; then + OLD_ADDRESS="196.22.132.40" + OLD_HNAME="masterbuild64wheezy.jnb1.host-h.net" + OLD_DOMAIN="jnb1.host-h.net" + OLD_SHNAME="masterbuild64wheezy" +fi + + + +echo -e "\n===============================================================\n" +echo -e "Press any key to edit the new IP and hostname:\n" +echo -e " Hostname: ... old=$OLD_HNAME \t=>\t new=$NEW_HNAME" +echo -e " IP: ......... old=$OLD_ADDRESS \t\t=>\t new=$NEW_ADDRESS\n " + +X="" +for i in $(seq 1 10) ; do + echo -n "." + read -n1 -t1 X + [ "$X" ] && break +done +echo +if [ "$X" ] ; then + echo -n "Enter hostname: " ; read NEW_HNAME + echo -n "Enter IP address: " ; read NEW_ADDRESS +fi +echo + +NEW_SHNAME="$(echo $NEW_HNAME | cut -d. -f1)" + + + +echo "...Updating /etc/hosts" +sed -i -e "s/$OLD_ADDRESS/$NEW_ADDRESS/g" /etc/hosts + +echo "...Activating new hostname" +hostname $NEW_HNAME + +echo "...Updating /etc/hostname" +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/hostname + +#Kerberos +echo "...Installing kerberos host keytab" +#Need to create a new tempuser with key auth to run script on master kdc host +#/usr/sbin/useradd -m -d /home/kdcadd -s /bin/bash -e '' kdcadd +#ssh-keygen -t dsa -P "" -f .ssh/id_dsa +#ssh-copy-id -i .ssh/id_dsa.pub kdcadd@kdc1.cpt1.host-h.net +echo "============== Kerberos key gen ================" +touch /etc/krb5.keytab +chmod 600 /etc/krb5.keytab +su kdcadd -l -c "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no mkservtab@kdc2.cpt2.host-h.net mkservtab $NEW_HNAME" > /etc/krb5.keytab +echo "================================================" +userdel kdcadd +rm -rf /home/kdcadd +#cd /usr/local/hetzner/_inst/kerberos +#sh install + +echo "...Updating /etc/fstab" +rm /etc/fstab + +linktarget=`basename "$(readlink /initrd.img)" | sed s,initrd.img-,,` + +mdadm --examine --scan > /etc/mdadm/mdadm.conf 2>/dev/null +mdadm --examine --scan > /etc/mdadm/generated.conf 2>/dev/null + +update-initramfs -d -k $linktarget +update-initramfs -c -k $linktarget + +boot_device=$(mount | awk '$3 == "/boot" {print $1}') +cat << EOF > /etc/fstab +proc /proc proc defaults 0 0 +/dev/mapper/vg-root / ext4 defaults,usrquota,errors=remount-ro 0 1 +${boot_device} /boot ext3 defaults 0 2 +/dev/mapper/vg-postgres /var/lib/postgresql ext4 defaults,usrquota,errors=remount-ro 0 1 +/dev/mapper/vg-cache /var/glusterfs_local ext4 defaults,usrquota,errors=remount-ro 0 1 +EOF + +echo -e "\n" +rm -f /etc/udev/rules.d/*-net.rules + +if echo $NEW_HNAME | grep -Eq '\.(cpt[1234]|jnb[12]|nur4|flk1)\.'; then + geo_domain=$(echo $NEW_HNAME | awk -F \. '{print $2}').host-h.net +elif echo $NEW_HNAME | grep -Eq '\.(dur1\.|hetzner\.africa)'; then + geo_domain=cpt1.host-h.net +else + geo_domain="" +fi + +echo "=> Upgrading APT packages ..." +/usr/local/bin/aptitude_upgrade + +#Update the puppet config file for location from local puppetmaster1 +if [ -n "$geo_domain" ]; then + sed -i -e "s,$OLD_DOMAIN,$geo_domain,g" /etc/puppet/puppet.conf + sed -i "s,splay=true,splay=false,g" /etc/puppet/puppet.conf +fi + +echo "Cleaning up puppet" +rm -rf /var/lib/puppet/clientbucket/ +find /var/lib/puppet/ssl -type f -name 'master*' -delete + +echo "Generating host certificate for puppet via Certmeister" +/usr/local/bin/certmeister-client create /var/lib/puppet/ssl/private_keys/"$NEW_HNAME".pem /var/lib/puppet/ssl/certs/"$NEW_HNAME".pem + +echo "Removing uptrack uuid file" +rm -f /var/lib/uptrack/uuid + +echo -e "...done\n" +echo "===============================================================" + diff --git a/post-install/hsa-managed b/post-install/hsa-managed new file mode 100755 index 0000000..a98e8ba --- /dev/null +++ b/post-install/hsa-managed @@ -0,0 +1,208 @@ +#!/bin/bash + + +NEW_HNAME="$(hostname -f)" +NEW_ADDRESS=`/sbin/ifconfig eth0 | grep "inet addr:" | head -1 | awk '{print $2}'| cut -d: -f2` +NEW_DC="$(hostname -f | cut -d. -f2)" + +if echo $NEW_DC | grep -Eq 'cpt[1234]|jnb[12]'; then + OLD_ADDRESS="41.203.16.240" + OLD_HNAME="masterbuild.jnb2.host-h.net" + OLD_DOMAIN="jnb2.host-h.net" + OLD_SHNAME="masterbuild" +elif echo $NEW_DC | grep -Eq 'nur4|flk1'; then + OLD_ADDRESS="78.46.4.57" + OLD_HNAME="masterbuild.nur4.host-h.net" + OLD_DOMAIN="nur4.host-h.net" + OLD_SHNAME="masterbuild" +fi + + + +echo -e "\n===============================================================\n" +echo -e "Press any key to edit the new IP and hostname:\n" +echo -e " Hostname: ... old=$OLD_HNAME \t=>\t new=$NEW_HNAME" +echo -e " IP: ......... old=$OLD_ADDRESS \t\t=>\t new=$NEW_ADDRESS\n " + +X="" +for i in $(seq 1 10) ; do + echo -n "." + read -n1 -t1 X + [ "$X" ] && break +done +echo +if [ "$X" ] ; then + echo -n "Enter hostname: " ; read NEW_HNAME + echo -n "Enter IP address: " ; read NEW_ADDRESS +fi +echo + +NEW_SHNAME="$(echo $NEW_HNAME | cut -d. -f1)" + + + +echo "...Updating /etc/hosts" +cp /etc/hosts /etc/hosts.bak +sed -i -e "s/$OLD_ADDRESS/$NEW_ADDRESS/g" /etc/hosts + +echo "...Updating httpd.conf" +cp /etc/apache/httpd.conf /etc/apache/httpd.conf.bak +sed -i -e "s/$OLD_ADDRESS/$NEW_ADDRESS/g" /etc/apache/httpd.conf + +echo "...Updating httpd.conf.template" +cp /etc/apache/httpd.conf.template /etc/apache/httpd.conf.template.bak +sed -i -e "s:$OLD_ADDRESS:$NEW_ADDRESS:" /etc/apache/httpd.conf.template + +echo "...Updating /etc/resolv.conf" +cp /etc/resolv.conf /etc/resolv.conf.bak +sed -i -e "s:$OLD_ADDRESS:$NEW_ADDRESS:" /etc/resolv.conf + +if echo "$NEW_ADDRESS" | grep '^192\.168\.'; then + echo "...Adding private network rules to hos_iptables.post" + cat << EOF > /etc/hos_iptables.post +iptables -I bad-ip -s 192.168.0.0/23 -j RETURN # Durbanville office +iptables -I bad-ip -s 192.168.2.0/24 -j RETURN # Newlands office +iptables -I bad-ip -s 192.168.4.0/24 -j RETURN # JNB office +EOF + chmod +x /etc/hos_iptables.post + sed -i -e 's,^exit 0,/usr/local/hetzner/bin/rc.iptables\n\nexit 0,' /etc/hos_iptables.post +fi + +echo "...Updating httpd.conf" +cp /etc/apache/httpd.conf /etc/apache/httpd.conf.bak +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/apache/httpd.conf + +echo "...Activating new hostname" +/etc/init.d/hostname.sh + +echo "...Updating exim4.conf.local" +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/exim4/exim4.conf.local +echo "--------------" + +echo "...Updating /etc/hostname" +cp /etc/hostname /etc/hostname.bak +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/hostname + +echo "...Updating /etc/hosts" +cp /etc/hosts /etc/hosts.bak +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/hosts + +echo "...Updating /etc/mailname" +cp /etc/mailname /etc/mailname.bak +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/mailname + +echo "...Removing /etc/host_type" +rm -rf /etc/host_type + +#echo "...Tripwire config" +#echo -e "Please enter Tripwire Site passphrase: " +#read twpass +#/usr/sbin/twadmin -m G -S /etc/tripwire/site.key -Q $twpass +#echo "... Reconfiguring new passphrase" +#/usr/sbin/dpkg-reconfigure tripwire + +#Kerberos +echo "...Installing kerberos host keytab" +#Need to create a new tempuser with key auth to run script on master kdc host +#/usr/sbin/useradd -m -d /home/kdcadd -s /bin/bash -e '' kdcadd +#ssh-keygen -t dsa -P "" -f .ssh/id_dsa +#ssh-copy-id -i .ssh/id_dsa.pub kdcadd@kdc1.cpt1.host-h.net +echo "============== Kerberos key gen ================" +touch /etc/krb5.keytab +chmod 600 /etc/krb5.keytab +su kdcadd -l -c "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no mkservtab@kdc2.cpt2.host-h.net mkservtab $NEW_HNAME" > /etc/krb5.keytab +echo "================================================" +userdel kdcadd +rm -rf /home/kdcadd +#cd /usr/local/hetzner/_inst/kerberos +#sh install + +echo "...Updating /etc/fstab" +rm /etc/fstab + +linktarget=`basename "$(readlink /initrd.img)" | sed s,initrd.img-,,` + +mdadm --examine --scan > /etc/mdadm/mdadm.conf 2>/dev/null +mdadm --examine --scan > /etc/mdadm/generated.conf 2>/dev/null + +update-initramfs -d -k $linktarget +update-initramfs -c -k $linktarget + +boot_device=$(mount | awk '$3 == "/boot" {print $1}') +cat << EOF > /etc/fstab +proc /proc proc defaults 0 0 +/dev/mapper/vg-root / ext4 defaults,usrquota,errors=remount-ro 0 1 +${boot_device} /boot ext3 defaults 0 2 +/dev/mapper/vg-tmp /tmp ext4 defaults 0 0 +/dev/mapper/vg-usr /usr ext4 defaults,usrquota 0 0 +/dev/mapper/vg-usrhome /usr/home ext4 defaults,usrquota 0 0 +/dev/mapper/vg-var /var ext4 defaults 0 0 +/dev/mapper/vg-vartmp /var/tmp ext4 defaults 0 0 +/dev/mapper/vg-swap none swap sw 0 0 +EOF + +echo "...Disabling count- and interval-based fsck" +for fsname in root tmp usr usrhome var vartmp; do + /sbin/tune2fs -c 0 -i 0 /dev/mapper/vg-$fsname >/dev/null +done + +#echo -e "\n" +#WK/SB/WB - Removing this because we now install the rescue system udev rules +#rm -f /etc/udev/rules.d/*-net.rules + +### GRUB setup is already done by installimage + +#for component_device in ${boot_device} $(mdadm --query --detail /dev/md0 2>/dev/null | awk '$7 ~ /\/dev\/[sdv]d[a-z][0-9]/ {gsub(/[0-9]*$/, "", $7); print $7}'); do +# /usr/sbin/grub --batch --no-floppy < Upgrading APT packages ..." +/usr/local/bin/aptitude_upgrade + +echo "Cleaning up local puppet install" +find /var/lib/puppet/clientbucket -type f -delete +find /var/lib/puppet/ssl -type f -name 'master*' -delete + +echo "Generating host certificate for puppet via Certmeister" +/usr/local/bin/certmeister-client create /var/lib/puppet/ssl/private_keys/"$NEW_HNAME".pem /var/lib/puppet/ssl/certs/"$NEW_HNAME".pem + +echo "Removing uptrack uuid file" +rm -f /var/lib/uptrack/uuid + +if echo $NEW_HNAME | grep -q backup; then + echo "Installing needed entries for ftpbackupserver.. (y/n)" + read ans + if [ "$ans" == "y" ];then + echo "creating ftpbackupserver now" + mkdir -p /ftpbackup + echo "/dev/mapper/vg-bak /ftpbackup ext4 defaults,usrquota 0 0" >> /etc/fstab + + echo "add to konsoleh_genie database" + PASSWD=`grep -A 3 livedb.konsoleh.co.za /usr/local/hetzner/bin/config/connections.yml | grep password| awk {'print $2'}` + MSQLT=$(/usr/bin/mysql -uhetzner -hlivedb.konsoleh.co.za -p`echo $PASSWD` konsoleh_genie -s -N -e "SELECT ftpb_server, (total_space - used_space) / quota FROM ftp_backup_servers;" | cut -f1 | grep $NEW_HNAME) + + if [ "`echo $MSQLT| grep -c $NEW_HNAME`" -eq 0 ] ;then + /usr/bin/mysql -uhetzner -hlivedb.konsoleh.co.za -p`echo $PASSWD` konsoleh_genie -e "INSERT INTO ftp_backup_servers (datacentre ,ftpb_server ,total_space ,used_space ,quota) values ('$NEW_DC' ,'$NEW_HNAME' ,'3000' ,'0' ,'50');" + fi + + fi +fi + +echo -e "...done\n" +echo "===============================================================" + diff --git a/post-install/hsa-minimal64 b/post-install/hsa-minimal64 new file mode 100755 index 0000000..7412c86 --- /dev/null +++ b/post-install/hsa-minimal64 @@ -0,0 +1,143 @@ +#!/bin/bash + + +NEW_HNAME="$(hostname -f)" +NEW_ADDRESS=`/sbin/ifconfig eth0 | grep "inet addr:" | head -1 | awk '{print $2}'| cut -d: -f2` +NEW_DC="$(hostname -f | cut -d. -f2)" + +if echo $NEW_DC | grep -Eq 'cpt[1234]|jnb[12]'; then + OLD_ADDRESS="41.203.16.241" + OLD_HNAME="masterbuild64.jnb2.host-h.net" + OLD_DOMAIN="jnb2.host-h.net" + OLD_SHNAME="masterbuild64" +elif echo $NEW_DC | grep -Eq 'nur4|flk1'; then + OLD_ADDRESS="196.22.132.40" + OLD_HNAME="masterbuild64wheezy.jnb1.host-h.net" + OLD_DOMAIN="jnb1.host-h.net" + OLD_SHNAME="masterbuild64wheezy" +fi + + + +echo -e "\n===============================================================\n" +echo -e "Press any key to edit the new IP and hostname:\n" +echo -e " Hostname: ... old=$OLD_HNAME \t=>\t new=$NEW_HNAME" +echo -e " IP: ......... old=$OLD_ADDRESS \t\t=>\t new=$NEW_ADDRESS\n " + +X="" +for i in $(seq 1 10) ; do + echo -n "." + read -n1 -t1 X + [ "$X" ] && break +done +echo +if [ "$X" ] ; then + echo -n "Enter hostname: " ; read NEW_HNAME + echo -n "Enter IP address: " ; read NEW_ADDRESS +fi +echo + +NEW_SHNAME="$(echo $NEW_HNAME | cut -d. -f1)" + + + +echo "...Updating /etc/hosts" +sed -i -e "s/$OLD_ADDRESS/$NEW_ADDRESS/g" /etc/hosts + +echo "...Activating new hostname" +hostname $NEW_HNAME + +echo "...Updating /etc/hostname" +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/hostname + +#Kerberos +echo "...Installing kerberos host keytab" +#Need to create a new tempuser with key auth to run script on master kdc host +#/usr/sbin/useradd -m -d /home/kdcadd -s /bin/bash -e '' kdcadd +#ssh-keygen -t dsa -P "" -f .ssh/id_dsa +#ssh-copy-id -i .ssh/id_dsa.pub kdcadd@kdc1.cpt1.host-h.net +echo "============== Kerberos key gen ================" +touch /etc/krb5.keytab +chmod 600 /etc/krb5.keytab +su kdcadd -l -c "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no mkservtab@kdc2.cpt2.host-h.net mkservtab $NEW_HNAME" > /etc/krb5.keytab +echo "================================================" +userdel kdcadd +rm -rf /home/kdcadd +#cd /usr/local/hetzner/_inst/kerberos +#sh install + +echo "...Updating /etc/fstab" +rm /etc/fstab + +linktarget=`basename "$(readlink /initrd.img)" | sed s,initrd.img-,,` + +mdadm --examine --scan > /etc/mdadm/mdadm.conf 2>/dev/null +mdadm --examine --scan > /etc/mdadm/generated.conf 2>/dev/null + +update-initramfs -d -k $linktarget +update-initramfs -c -k $linktarget + +boot_device=$(mount | awk '$3 == "/boot" {print $1}') +cat << EOF > /etc/fstab +proc /proc proc defaults 0 0 +/dev/mapper/vg-root / ext4 defaults,usrquota,errors=remount-ro 0 1 +${boot_device} /boot ext3 defaults 0 2 +EOF + +echo "...Disabling count- and interval-based fsck" +for fsname in root tmp usr usrhome var vartmp; do + /sbin/tune2fs -c 0 -i 0 /dev/mapper/vg-$fsname >/dev/null +done + +echo -e "\n" +rm -f /etc/udev/rules.d/*-net.rules + +if echo $NEW_HNAME | grep -Eq '\.(cpt[1234]|jnb[12]|nur4|flk1)\.'; then + geo_domain=$(echo $NEW_HNAME | awk -F \. '{print $2}').host-h.net +elif echo $NEW_HNAME | grep -Eq '\.(dur1\.|hetzner\.africa)'; then + geo_domain=cpt1.host-h.net +else + geo_domain="" +fi + +echo "=> Upgrading APT packages ..." +/usr/local/bin/aptitude_upgrade + +#Update the puppet config file for location from local puppetmaster1 +if [ -n "$geo_domain" ]; then + sed -i -e "s,$OLD_DOMAIN,$geo_domain,g" /etc/puppet/puppet.conf + sed -i "s,splay=true,splay=false,g" /etc/puppet/puppet.conf +fi + +echo "Cleaning up puppet" +rm -rf /var/lib/puppet/clientbucket/ +find /var/lib/puppet/ssl -type f -name 'master*' -delete + +echo "Generating host certificate for puppet via Certmeister" +/usr/local/bin/certmeister-client create /var/lib/puppet/ssl/private_keys/"$NEW_HNAME".pem /var/lib/puppet/ssl/certs/"$NEW_HNAME".pem + +echo "Removing uptrack uuid file" +rm -f /var/lib/uptrack/uuid + +if echo $NEW_HNAME | grep -q ftpbackup; then +# echo "Installing needed entries for ftpbackupserver.. (y/n)" +# read ans +# if [ "$ans" == "y" ];then + echo "creating ftpbackupserver now" + mkdir -p /ftpbackup + echo "/dev/mapper/vg--bak-bak /ftpbackup ext4 defaults,usrquota 0 0" >> /etc/fstab + + echo "add to konsoleh_genie database" + PASSWD=`grep -A 3 livedb.konsoleh.co.za /usr/local/hetzner/bin/config/connections.yml | grep password| awk {'print $2'}` + MSQLT=$(/usr/bin/mysql -uhetzner -hlivedb.konsoleh.co.za -p`echo $PASSWD` konsoleh_genie -s -N -e "SELECT ftpb_server, (total_space - used_space) / quota FROM ftp_backup_servers;" | cut -f1 | grep $NEW_HNAME) + + if [ "`echo $MSQLT| grep -c $NEW_HNAME`" -eq 0 ] ;then + /usr/bin/mysql -uhetzner -hlivedb.konsoleh.co.za -p`echo $PASSWD` konsoleh_genie -e "INSERT INTO ftp_backup_servers (datacentre ,ftpb_server ,total_space ,used_space ,quota) values ('$NEW_DC' ,'$NEW_HNAME' ,'3000' ,'0' ,'50');" + fi + +# fi +fi + +echo -e "...done\n" +echo "===============================================================" + diff --git a/post-install/hsa-sql b/post-install/hsa-sql new file mode 100755 index 0000000..b37f18b --- /dev/null +++ b/post-install/hsa-sql @@ -0,0 +1,129 @@ +#!/bin/bash + + +NEW_HNAME="$(hostname -f)" +NEW_ADDRESS=`/sbin/ifconfig eth0 | grep "inet addr:" | head -1 | awk '{print $2}'| cut -d: -f2` +NEW_DC="$(hostname -f | cut -d. -f2)" + +if echo $NEW_DC | grep -Eq 'cpt[1234]|jnb[12]'; then + OLD_ADDRESS="41.203.16.241" + OLD_HNAME="masterbuild64.jnb2.host-h.net" + OLD_DOMAIN="jnb2.host-h.net" + OLD_SHNAME="masterbuild64" +elif echo $NEW_DC | grep -Eq 'nur4|flk1'; then + OLD_ADDRESS="196.22.132.40" + OLD_HNAME="masterbuild64wheezy.jnb1.host-h.net" + OLD_DOMAIN="jnb1.host-h.net" + OLD_SHNAME="masterbuild64wheezy" +fi + + + +echo -e "\n===============================================================\n" +echo -e "Press any key to edit the new IP and hostname:\n" +echo -e " Hostname: ... old=$OLD_HNAME \t=>\t new=$NEW_HNAME" +echo -e " IP: ......... old=$OLD_ADDRESS \t\t=>\t new=$NEW_ADDRESS\n " + +X="" +for i in $(seq 1 10) ; do + echo -n "." + read -n1 -t1 X + [ "$X" ] && break +done +echo +if [ "$X" ] ; then + echo -n "Enter hostname: " ; read NEW_HNAME + echo -n "Enter IP address: " ; read NEW_ADDRESS +fi +echo + +NEW_SHNAME="$(echo $NEW_HNAME | cut -d. -f1)" + + + +echo "...Updating /etc/hosts" +sed -i -e "s/$OLD_ADDRESS/$NEW_ADDRESS/g" /etc/hosts + +echo "...Activating new hostname" +hostname $NEW_HNAME + +echo "...Updating /etc/hostname" +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/hostname + +#Kerberos +echo "...Installing kerberos host keytab" +#Need to create a new tempuser with key auth to run script on master kdc host +#/usr/sbin/useradd -m -d /home/kdcadd -s /bin/bash -e '' kdcadd +#ssh-keygen -t dsa -P "" -f .ssh/id_dsa +#ssh-copy-id -i .ssh/id_dsa.pub kdcadd@kdc1.cpt1.host-h.net +echo "============== Kerberos key gen ================" +touch /etc/krb5.keytab +chmod 600 /etc/krb5.keytab +su kdcadd -l -c "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no mkservtab@kdc2.cpt2.host-h.net mkservtab $NEW_HNAME" > /etc/krb5.keytab +echo "================================================" +userdel kdcadd +rm -rf /home/kdcadd +#cd /usr/local/hetzner/_inst/kerberos +#sh install + +echo "...Updating /etc/fstab" +rm /etc/fstab + +linktarget=`basename "$(readlink /initrd.img)" | sed s,initrd.img-,,` + +mdadm --examine --scan > /etc/mdadm/mdadm.conf 2>/dev/null +mdadm --examine --scan > /etc/mdadm/generated.conf 2>/dev/null + +update-initramfs -d -k $linktarget +update-initramfs -c -k $linktarget + +boot_device=$(mount | awk '$3 == "/boot" {print $1}') +cat << EOF > /etc/fstab +proc /proc proc defaults 0 0 +/dev/mapper/vg-root / ext4 defaults,usrquota,errors=remount-ro 0 1 +${boot_device} /boot ext3 defaults 0 2 +/dev/mapper/vg-tmp /tmp ext4 defaults 0 0 +/dev/mapper/vg-usr /usr ext4 defaults,usrquota 0 0 +/dev/mapper/vg-var /var ext4 defaults 0 0 +/dev/mapper/vg-vartmp /var/tmp ext4 defaults 0 0 +/dev/mapper/vg-swap none swap sw 0 0 +EOF + +echo "...Disabling count- and interval-based fsck" +for fsname in root tmp usr usrhome var vartmp; do + /sbin/tune2fs -c 0 -i 0 /dev/mapper/vg-$fsname >/dev/null +done + +echo -e "\n" +rm -f /etc/udev/rules.d/*-net.rules + +if echo $NEW_HNAME | grep -Eq '\.(cpt[1234]|jnb[12]|nur4|flk1)\.'; then + geo_domain=$(echo $NEW_HNAME | awk -F \. '{print $2}').host-h.net +elif echo $NEW_HNAME | grep -Eq '\.(dur1\.|hetzner\.africa)'; then + geo_domain=cpt1.host-h.net +else + geo_domain="" +fi + +echo "=> Upgrading APT packages ..." +/usr/local/bin/aptitude_upgrade + +#Update the puppet config file for location from local puppetmaster1 +if [ -n "$geo_domain" ]; then + sed -i -e "s,$OLD_DOMAIN,$geo_domain,g" /etc/puppet/puppet.conf + sed -i "s,splay=true,splay=false,g" /etc/puppet/puppet.conf +fi + +echo "Cleaning up puppet" +rm -rf /var/lib/puppet/clientbucket/ +find /var/lib/puppet/ssl -type f -name 'master*' -delete + +echo "Generating host certificate for puppet via Certmeister" +/usr/local/bin/certmeister-client create /var/lib/puppet/ssl/private_keys/"$NEW_HNAME".pem /var/lib/puppet/ssl/certs/"$NEW_HNAME".pem + +echo "Removing uptrack uuid file" +rm -f /var/lib/uptrack/uuid + +echo -e "...done\n" +echo "===============================================================" + diff --git a/post-install/minimal64squeeze b/post-install/minimal64squeeze new file mode 100755 index 0000000..5b45e7a --- /dev/null +++ b/post-install/minimal64squeeze @@ -0,0 +1,163 @@ +#!/bin/sh + + +NEW_HNAME="$(cat /etc/hostname)" +NEW_ADDRESS=`/sbin/ifconfig eth0 | grep "inet addr:" | head -1 | awk '{print $2}'| cut -d: -f2` +NEW_DC="$(cat /etc/hostname | cut -d. -f2)" + +if echo $NEW_DC | grep -Eq 'cpt[123]|jnb[12]'; then + OLD_ADDRESS="41.203.18.225" + OLD_HNAME="masterbuild64.jnb2.host-h.net" + OLD_DOMAIN="jnb2.host-h.net" + OLD_SHNAME="masterbuild64" +elif echo $NEW_DC | grep -Eq 'nur4|flk1'; then + OLD_ADDRESS="188.40.248.69" + OLD_HNAME="masterbuild64.flk1.host-h.net" + OLD_DOMAIN="flk1.host-h.net" + OLD_SHNAME="masterbuild64" +fi + + + +echo -e "\n===============================================================\n" +echo -e "Press any key to edit the new IP and hostname:\n" +echo -e " Hostname: ... old=$OLD_HNAME \t=>\t new=$NEW_HNAME" +echo -e " IP: ......... old=$OLD_ADDRESS \t\t=>\t new=$NEW_ADDRESS\n " + +X="" +for i in $(seq 1 10) ; do + echo -n "." + read -n1 -t1 X + [ "$X" ] && break +done +echo +if [ "$X" ] ; then + echo -n "Enter hostname: " ; read NEW_HNAME + echo -n "Enter IP address: " ; read NEW_ADDRESS +fi +echo + +NEW_SHNAME="$(echo $NEW_HNAME | cut -d. -f1)" + + + +echo "...Updating /etc/hosts" +sed -i -e "s/$OLD_ADDRESS/$NEW_ADDRESS/g" /etc/hosts + +echo "...Activating new hostname" +hostname $NEW_HNAME + +echo "...Updating /etc/hostname" +sed -i -e "s:$OLD_HNAME:$NEW_HNAME:" /etc/hostname + +#Kerberos +echo "...Installing kerberos host keytab" +#Need to create a new tempuser with key auth to run script on master kdc host +#/usr/sbin/useradd -m -d /home/kdcadd -s /bin/bash -e '' kdcadd +#ssh-keygen -t dsa -P "" -f .ssh/id_dsa +#ssh-copy-id -i .ssh/id_dsa.pub kdcadd@kdc1.cpt1.host-h.net +echo "============== Kerberos key gen ================" +touch /etc/krb5.keytab +chmod 600 /etc/krb5.keytab +su kdcadd -l -c "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no mkservtab@kdc2.cpt2.host-h.net mkservtab $NEW_HNAME" > /etc/krb5.keytab +echo "================================================" +userdel kdcadd +rm -rf /home/kdcadd +#cd /usr/local/hetzner/_inst/kerberos +#sh install + +echo "...Updating /etc/fstab" +rm /etc/fstab + +linktarget=`basename "$(readlink /initrd.img)" | sed s,initrd.img-,,` + +mdadm --examine --scan > /etc/mdadm/mdadm.conf 2>/dev/null +mdadm --examine --scan > /etc/mdadm/generated.conf 2>/dev/null + +update-initramfs -u -k all + +boot_device=$(mount | awk '$3 == "/boot" {print $1}') +cat << EOF > /etc/fstab +proc /proc proc defaults 0 0 +/dev/mapper/vg-root / ext3 defaults,usrquota,errors=remount-ro 0 1 +${boot_device} /boot ext3 defaults 0 2 +/dev/mapper/vg-tmp /tmp ext3 defaults 0 0 +/dev/mapper/vg-usr /usr ext3 defaults,usrquota 0 0 +/dev/mapper/vg-var /var ext3 defaults 0 0 +/dev/mapper/vg-vartmp /var/tmp ext3 defaults 0 0 +/dev/mapper/vg-swap none swap sw 0 0 +EOF + +echo "...Disabling count- and interval-based fsck" +for fsname in root tmp usr usrhome var vartmp; do + /sbin/tune2fs -c 0 -i 0 /dev/mapper/vg-$fsname >/dev/null +done + +echo -e "\n" +rm -f /etc/udev/rules.d/*-net.rules + +if echo $NEW_HNAME | grep -Eq '\.(cpt[123]|jnb[12]|nur4|flk1)\.'; then + geo_domain=$(echo $NEW_HNAME | awk -F \. '{print $2}').host-h.net +elif echo $NEW_HNAME | grep -Eq '\.(dur1\.|hetzner\.africa)'; then + geo_domain=cpt1.host-h.net +else + geo_domain="" +fi + +#Update the puppet config file for location and fetch_hos_server from local puppetmaster1 +if [ -n "$geo_domain" ]; then + sed -i -e "s,$OLD_DOMAIN,$geo_domain,g" /etc/puppet/puppet.conf + sed -i "s,splay=true,splay=false,g" /etc/puppet/puppet.conf +fi + +echo "Cleaning up puppet" +rm -rf /var/lib/puppet/clientbucket/ +find /var/lib/puppet -type f -delete + +echo "Cleaning up ebackup" +rm -rf /etc/ebackup.conf + +echo "Removing uptrack uuid file" +rm -f /var/lib/uptrack/uuid + +if echo $NEW_HNAME | grep -q ftpbackup; then +# echo "Installing needed entries for ftpbackupserver.. (y/n)" +# read ans +# if [ "$ans" == "y" ];then + echo "creating ftpbackupserver now" + mkdir -p /ftpbackup + echo "/dev/mapper/vg-bak /ftpbackup ext3 defaults,usrquota 0 0" >> /etc/fstab + + echo "add to konsoleh_genie database" + PASSWD=`grep -A 3 livedb.konsoleh.co.za /usr/local/hetzner/bin/config/connections.yml | grep password| awk {'print $2'}` + MSQLT=$(/usr/bin/mysql -uhetzner -hlivedb.konsoleh.co.za -p`echo $PASSWD` konsoleh_genie -s -N -e "SELECT ftpb_server, (total_space - used_space) / quota FROM ftp_backup_servers;" | cut -f1 | grep $NEW_HNAME) + + if [ "`echo $MSQLT| grep -c $NEW_HNAME`" -eq 0 ] ;then + /usr/bin/mysql -uhetzner -hlivedb.konsoleh.co.za -p`echo $PASSWD` konsoleh_genie -e "INSERT INTO ftp_backup_servers (datacentre ,ftpb_server ,total_space ,used_space ,quota) values ('$NEW_DC' ,'$NEW_HNAME' ,'3000' ,'0' ,'50');" + fi + +# fi +fi + +echo "Updating UID's for staff" +cd /home +for i in `dir -A`; do chown -R $i:staff $i; done + +echo "Fix zabbix ownership" +chown -R zabbix:zabbix /var/run/zabbix-agent +chown -R zabbix:zabbix /usr/lib/zabbix +chown -R zabbix:zabbix /var/lib/statcache + +echo "Fix puppet ownership" +chown -R puppet:puppet /var/lib/puppet + +echo "Fix uuid ownership" +chown -R libuuid:libuuid /var/lib/libuuid +chown -R libuuid:libuuid /usr/sbin/uuidd + +echo "Fix ntp ownership" +chown -R ntp:ntp /var/lib/ntp + +echo -e "...done\n" +echo "===============================================================" + diff --git a/post-install/proxmox2 b/post-install/proxmox2 new file mode 100755 index 0000000..0180bdc --- /dev/null +++ b/post-install/proxmox2 @@ -0,0 +1,71 @@ +#!/bin/bash + +# +# Proxmox Virtualization Environment installer script +# based on Debian Squeeze +# + + +PROXMOX_KERNEL_VERSION="2.6.32" + + +echo -e "\n----- Add Proxmox Repo to APT sources -----\n" + +echo -e "\n\n# PVE packages provided by proxmox.com" >>/etc/apt/sources.list +echo -e "deb http://mirror.hetzner.de/debian/pve squeeze pve\n" >>/etc/apt/sources.list +echo -e "deb http://download.proxmox.com/debian squeeze pve\n" >>/etc/apt/sources.list +wget -q -O- "http://download.proxmox.com/debian/key.asc" | apt-key add - + + +#echo -e "\n----- Remove default kernel -----\n" +#aptitude -y remove $(dpkg -l | grep "^ii linux-image" | tr -s " " | cut -d " " -f2) + + +echo -e "\n----- Update and upgrade system, please wait ... -----\n" + +export LANG="en_US.UTF-8" +export LC_ALL="C" + + +aptitude update >/dev/null +aptitude -y safe-upgrade + +echo -e "\n----------------- Deinstallieren des Linux-Firmware-Realtek-Paketes ------------------\n" + +firmware="$(dpkg -l | grep -i 'firmware')" + +if [ -n "$firmware" ]; then + aptitude -q -y purge firmware-realtek firmware-linux firmware-linux-free firmware-linux-nonfree +else + echo "kein firmware Paket vorhanden" +fi + +echo -e "\n----- Install Proxmox packages -----\n" + +cat <>/etc/apt/sources.list.d/proxmox.list +echo -e "deb http://mirror.hetzner.de/debian/pve wheezy pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list +echo -e "deb http://download.proxmox.com/debian wheezy pve-no-subscription\n" >>/etc/apt/sources.list.d/proxmox.list +wget -q -O- "http://download.proxmox.com/debian/key.asc" | apt-key add - + + +#echo -e "\n----- Remove default kernel -----\n" +#aptitude -y remove $(dpkg -l | grep "^ii linux-image" | tr -s " " | cut -d " " -f2) + + +echo -e "\n----- Update and upgrade system, please wait ... -----\n" + +export LANG="en_US.UTF-8" +export LC_ALL="C" + +#create lock dir for aptitude +mkdir /run/lock +chmod a+rwxt /run/lock + +aptitude update >/dev/null +aptitude -y safe-upgrade + +echo -e "\n----------------- Deinstallieren des Linux-Firmware-Realtek-Paketes ------------------\n" + +firmware="$(dpkg -l | grep -i 'firmware')" + +if [ -n "$firmware" ]; then + aptitude -q -y purge firmware-realtek firmware-linux firmware-linux-free firmware-linux-nonfree +else + echo "kein firmware Paket vorhanden" +fi + +echo -e "\n----------------- Deinstallieren des Standard-Linux-Kernel-Paketes ------------------\n" +aptitude -q -y purge linux-image-amd64 linux-image-3.2.0-4-amd64 + + +echo -e "\n----- Install Proxmox packages -----\n" + +cat </dev/null + test $? -eq 0 && break + let n++ + sleep 5 +done + +# need to change this soon, b/c SuSE-release is deprecated +# and CentOS has also os-release +#if [ -f /etc/os-release ]; then +if [ -f /etc/SuSE-release ]; then + # openSuSE + sed -i -e "s#^bash /robot.*##" /etc/init.d/after.local + sed -i -e "s#^bash /robot.*##" /etc/init.d/boot.local +else + sed -e 's/^\[ -x \/robot\.sh \] && \/robot\.sh$//' -i /etc/rc.local +fi + +rm -f /robot.sh diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..45431a0 --- /dev/null +++ b/setup.sh @@ -0,0 +1,203 @@ +#!/bin/bash + +# +# mainmenu - choose which image should be installed +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + +# read global variables and functions +. /tmp/install.vars + +# check if the script is temporary disabled due some maintenance or something +debug "# checking if the script is disabled" +if [ -f $DISABLEDFILE ]; then + debug "=> script is DISABLED" + echo_red "Due to maintenance the installimage-script is temporarily unavailable.\nWe are sorry for the inconvenience." + exit 1 +fi + + +if [ "$OPT_AUTOMODE" ] ; then + + ### automatic mode ------------------------------------------------ + + debug "# AUTOMATIC MODE: start" + + # create config + debug "# AUTOMATIC MODE: create config" + create_config $IMAGENAME ; EXITCODE=$? + if [ $EXITCODE != 0 ] ; then + debug "=> FAILED" + cleanup + exit 1 + fi + + + # validate config + VALIDATED="false" + CANCELLED="false" + while [ "$VALIDATED" = "false" ]; do + debug "# validating config ..." + validate_vars "$FOLD/install.conf"; EXITCODE=$? + if [ "$CANCELLED" = "true" ]; then + echo "Cancelled." + exit 1 + fi + if [ $EXITCODE = 0 ]; then + VALIDATED="true" + else + debug "=> FAILED" + mcedit $FOLD/install.conf + fi + done + + # display information about automatic mode + echo -e "\n\033[01;32mStarting AUTOMATIC MODE\033[00m" + echo -e "\033[01;33mRunning unattended installimage installation ...\033[00m\n" + cat $FOLD/install.conf | grep -v "^#" | grep -v "^$" + echo -e "\n" + + # print warning + echo -e "\033[01;31mWARNING:" + echo -e "\033[01;33m Starting installation in 20 seconds ..." + echo -e "\033[01;33m Press X to continue immediately ...\033[00m" + echo -e "\033[01;31m Installation will DELETE ALL DATA ON DISK(s)!" + echo -e "\033[01;33m Press CTRL-C to abort now!\033[00m" + echo -n " => " + for i in $(seq 1 20) ; do + echo -n "." + read -t1 -n1 anykey + if [ "$anykey" = "x" -o "$anykey" = "X" ] ; then break ; fi + done + echo + + # start install + debug "# AUTOMATIC MODE: start installation" + . $INSTALLFILE ; EXITCODE=$? + [ $EXITCODE != 0 ] && debug "=> FAILED" + +else + + ### interactive mode ---------------------------------------------- + + # start the mainmenu and loop while not chosen "exit" or a config and finished configuration + ACCEPTED="" + while [ -z "$ACCEPTED" ]; do + + if [ "$OPT_IMAGE" ] ; then + # use image from option, do not display image menu + NOIMAGEMENU=true + else + # display the image menu + IMAGENAME="" + debug "# starting menu..." + while [ -z "$IMAGENAME" -o "$IMAGENAME" = "back" ]; do + dialog --backtitle "$DIATITLE" --title "o/s list" --no-cancel --menu "choose o/s" 0 0 0 $OSMENULIST "exit" "" 2>$FOLD/mainmenu.chosen + MAINMENUCHOSEN=`cat $FOLD/mainmenu.chosen` + case $MAINMENUCHOSEN in + "exit") + debug "=> user exited from menu" + cleanup + exit 1 + ;; + "custom_image") + IMAGENAME="custom" + ;; + *) + generate_menu $MAINMENUCHOSEN + ;; + esac + done + fi + + debug "# chosen image: [ $IMAGENAME ]" + + debug "# copy & create config..." + create_config $IMAGENAME; EXITCODE=$? + if [ $EXITCODE != 0 ] ; then + debug "=> FAILED" + cleanup + exit 1 + fi + + if [ "$PROXMOX" = "true" ]; then + graph_notice "\nPlease note: This image isn't supported by us."; + fi + + text='\n An editor will now show you the config for the image.\n + You can edit the parameters for your needs.\n + To accept all changes and continue the installation\n + just save and exit the editor with F10.' + + [ $COUNT_DRIVES -gt 1 ] && text=$text'\n\n\Z1 Please note!: by default all disks are used for software raid\n + change this to (SWRAID 0) if you want to leave your other harddisk(s)\n untouched!\Zn' + + dialog --backtitle "$DIATITLE" --title " NOTICE " --colors --msgbox "$text" 14 75 + VALIDATED="false" + CANCELLED="false" + while [ "$VALIDATED" = "false" ]; do + debug "# starting mcedit..." + whoami $IMAGENAME + mcedit $FOLD/install.conf; EXITCODE=$? + [ $EXITCODE != 0 ] && debug "=> FAILED" + debug "# validating vars..." + validate_vars "$FOLD/install.conf"; EXITCODE=$? + if [ $EXITCODE = 0 ]; then + VALIDATED="true" + else + if [ "$CANCELLED" = "true" ]; then + debug "=> CANCELLED" + VALIDATED="true" + else + debug "=> FAILED" + fi + fi + done + + if [ "$LVM" = "1" ]; then + graph_notice "Please note that ALL existing LVs and VGs will be removed during the installation!" + fi + + + + + if [ "$CANCELLED" = "false" ]; then + debug "# asking for confirmation..." + for i in $(seq 1 $COUNT_DRIVES) ; do + ask_format="$(eval echo \$FORMAT_DRIVE$i)" + ask_drive="$(eval echo \$DRIVE$i)" + if [ "$SWRAID" = "1" -o "$ask_format" = "1" -o $i -eq 1 ]; then + dialog --backtitle "$DIATITLE" --title "Confirmation" --colors --yesno "\n\Z1WARNING!: DATA ON THE FOLLOWING DRIVE WILL BE DELETED:\n\n $ask_drive\n\nDo you want to continue?\Zn\n" 0 0 + if [ $? -ne 0 ]; then + debug "# Confirmation for drive $ask_drive NOT accepted" + ACCEPTED="" + [ "$NOIMAGEMENU" ] && exit || break + else + debug "# Confirmation for drive $ask_drive accepted" + ACCEPTED="true" + fi + fi + done + fi + done + + + debug "# executing installfile..." + if [ -f $INSTALLFILE -a "$ACCEPTED" = "true" -a "$VALIDATED" = "true" -a "$IMAGENAME" ] ; then + . $INSTALLFILE ; EXITCODE=$? + else + debug "=> FAILED" + echo -e "\n\033[01;31mERROR: Cant find files\033[00m" + fi + +fi + + +if [ "$EXITCODE" = "1" ]; then + cleanup + exit 1 +fi + diff --git a/suse.sh b/suse.sh new file mode 100755 index 0000000..4c7eb00 --- /dev/null +++ b/suse.sh @@ -0,0 +1,302 @@ +#!/bin/bash + +# +# OpenSUSE specific functions +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + +# setup_network_config "$device" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" "$IP6ADDR" "$IP6PREFLEN" "$IP6GATEWAY" +setup_network_config() { + if [ "$1" -a "$2" ]; then + # good we have a device and a MAC + + SUSEVERSION="$(grep VERSION $FOLD/hdd/etc/SuSE-release | cut -d ' ' -f3 | sed -e 's/\.//')" + debug "# Version: ${SUSEVERSION}" + + 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 -e "### Hetzner Online AG - installimage" > $UDEVFILE + echo -e "# device: $1" >> $UDEVFILE + echo -e "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$2\", KERNEL==\"eth*\", NAME=\"$1\"" >> $UDEVFILE + + # remove any other existing config files + for i in `find "$FOLD/hdd/etc/sysconfig/network/" -name "*-eth*"`; do rm -rf "$i" >>/dev/null 2>&1; done + + CONFIGFILE="$FOLD/hdd/etc/sysconfig/network/ifcfg-$1" + + echo -e "### Hetzner Online AG - installimage" > $CONFIGFILE 2>>$DEBUGFILE + echo -e "# device: $1" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "BOOTPROTO='static'" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "MTU=''" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "STARTMODE='auto'" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "UNIQUE=''" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "USERCONTROL='no'" >> $CONFIGFILE 2>>$DEBUGFILE + + if [ "$1" -a "$2" -a "$3" -a "$4" -a "$5" -a "$6" -a "$7" ]; then + echo -e "REMOTE_IPADDR=''" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "BROADCAST='$4'" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "IPADDR='$3'" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "NETMASK='$5'" >> $CONFIGFILE 2>>$DEBUGFILE + echo -e "NETWORK='$7'" >> $CONFIGFILE 2>>$DEBUGFILE + + echo -e "$7 $6 $5 $1" > $ROUTEFILE 2>>$DEBUGFILE + echo -e "$6 - 255.255.255.255 $1" >> $ROUTEFILE 2>>$DEBUGFILE + echo -e "default $6 - -" >> $ROUTEFILE 2>>$DEBUGFILE + fi + + if [ "$8" -a "$9" -a "${10}" ]; then + debug "setting up ipv6 networking $8/$9 via ${10}" + if [ "$3" ]; then + # add v6 addr as an alias, if we have a v4 addr + echo -e "IPADDR_0='$8/$9'" >> $CONFIGFILE 2>>$DEBUGFILE + else + echo -e "IPADDR='$8/$9'" >> $CONFIGFILE 2>>$DEBUGFILE + fi + echo -e "default ${10} - $1" >> $ROUTEFILE 2>>$DEBUGFILE + fi + + if ! isNegotiated && ! isVServer; then + echo -e "ETHTOOL_OPTIONS=\"speed 100 duplex full autoneg off\"" >> $CONFIGFILE 2>>$DEBUGFILE + fi + + return 0 + fi +} + +# generate_mdadmconf "NIL" +generate_config_mdadm() { + if [ "$1" ]; then + MDADMCONF="/etc/mdadm.conf" + echo "DEVICES /dev/[hs]d*" > $FOLD/hdd$MDADMCONF + echo "MAILADDR root" >> $FOLD/hdd$MDADMCONF + if [ "$SUSEVERSION" -ge 132 ] ; then + echo > $FOLD/hdd$MDADMCONF + fi +# if [ "$SUSEVERSION" = "11.0" -o "$SUSEVERSION" = "11.2" -o "$SUSEVERSION" = "11.3" -o "$SUSEVERSION" = "11.4" -o "$SUSEVERSION" = "12.1" -o "$SUSEVERSION" = "12.2" ]; then + if [ "$SUSEVERSION" -ge 110 ]; then + # Suse 11.2 argues about failing opening of /dev/md/, so do a --examine instead of --details + execute_chroot_command "mdadm --examine --scan >> $MDADMCONF"; EXITCODE=$? + else + execute_chroot_command "mdadm --detail --scan >> $MDADMCONF"; EXITCODE=$? + fi + return $EXITCODE + fi +} + +# generate_new_ramdisk "NIL" +generate_new_ramdisk() { + if [ "$1" ]; then + OUTFILE=`ls -1r $FOLD/hdd/boot/initrd-* |grep -v ".bak$\|.gz$" |awk -F "/" '{print $NF}' |grep -m1 "initrd"` + VERSION=`echo $OUTFILE |cut -d "-" -f2-` + + # opensuse 13.2 uses dracut for generating initrd + if [ "$SUSEVERSION" -ge 132 ] ; then + DRACUTFILE="$FOLD/hdd/etc/dracut.conf.d/03-hetzner.conf" + echo "add_dracutmodules+=\"mdraid lvm\"" >> $DRACUTFILE + echo "add_drivers+=\"raid1 raid10 raid0 raid456\"" >> $DRACUTFILE + echo "mdadmconf=\"yes\"" >> $DRACUTFILE + echo "lvmconf=\"yes\"" >> $DRACUTFILE + echo "hostonly=\"no\"" >> $DRACUTFILE + echo "early_microcode=\"no\"" >> $DRACUTFILE + + # dracut fix for auto-assembling raid + local mdraid_rule="$FOLD/hdd/usr/lib/udev/rules.d/64-md-raid-assembly.rules" + local dracut_rulesd="$FOLD/hdd/usr/lib/dracut/rules.d" + mkdir -p $dracut_rulesd + cp $mdraid_rule $dracut_rulesd + else + KERNELCONF="$FOLD/hdd/etc/sysconfig/kernel" + + sed -i "$KERNELCONF" -e 's/INITRD_MODULES=.*/INITRD_MODULES=""/' + + #do not load kms and nouveau modules during boot + if [ "$SUSEVERSION" -ge 113 ]; then + sed -i "$KERNELCONF" -e 's/^NO_KMS_IN_INITRD=.*/NO_KMS_IN_INIRD="yes"/' + fi + fi + + local blacklist_conf="$FOLD/hdd/etc/modprobe.d/99-local.conf" + echo -e "### Hetzner Online AG - installimage" > $blacklist_conf + echo -e "### i915 driver blacklisted due to various bugs" >> $blacklist_conf + echo -e "### especially in combination with nomodeset" >> $blacklist_conf + echo -e "blacklist i915" >> $blacklist_conf + + # change the if contruct to test + if [ "$SUSEVERSION" -ge 112 ]; then + # mkinitrd doesn't have the switch -t anymore as of 11.2 and uses /dev/shm if it is writeable + if [ "$SUSEVERSION" -ge 121 ]; then + # run without updating bootloader as this would fail because of missing + # or at this point still wrong device.map. + # A device.map is temp. generated by grub2-install in 12.2 + execute_chroot_command "mkinitrd -B"; EXITCODE=$? + else + execute_chroot_command "mkinitrd"; EXITCODE=$? + fi + else + execute_chroot_command "mkinitrd -t /tmp"; EXITCODE=$? + fi + return $? + fi +} + + +setup_cpufreq() { + if [ "$1" ]; then + # openSuSE defaults to the ondemand governor, so we don't need to set this at all + # http://doc.opensuse.org/documentation/html/openSUSE/opensuse-tuning/cha.tuning.power.html + # check release notes of furture releases carefully, if this has changed! + +# CPUFREQCONF="$FOLD/hdd/etc/init.d/boot.local" +# echo -e "### Hetzner Online AG - installimage" > $CPUFREQCONF 2>>$DEBUGFILE +# echo -e "# cpu frequency scaling" >> $CPUFREQCONF 2>>$DEBUGFILE +# echo -e "cpufreq-set -g $1 -r >> /dev/null 2>&1" >> $CPUFREQCONF 2>>$DEBUGFILE + + return 0 + fi +} + +# +# generate_config_grub +# +# Generate the GRUB bootloader configuration. +# +generate_config_grub() { + [ "$1" ] || return + + EXITCODE=0 + + if [ "$SUSEVERSION" -lt 122 ]; then + DMAPFILE="$FOLD/hdd/boot/grub/device.map" + else + # even though grub2-mkconfig will generate a device.map on the fly, the + # yast perl bootloader script, will use the fscking device.map, as well as + # mkinitrd (which also uses the perl bootloader script) if the -B option is + # not passed + DMAPFILE="$FOLD/hdd/boot/grub2/device.map" + fi + [ -f $DMAPFILE ] && rm $DMAPFILE + + local i=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + local j="$[$i-1]" + local disk="$(eval echo "\$DRIVE"$i)" + echo "(hd$j) $disk" >> $DMAPFILE + done + cat $DMAPFILE >> $DEBUGFILE + + if [ "$SUSEVERSION" -lt 122 ]; then + BFILE="$FOLD/hdd/boot/grub/menu.lst" + + echo "#" > $BFILE 2>> $DEBUGFILE + echo "# Hetzner Online AG - installimage" >> $BFILE 2>> $DEBUGFILE + echo "# GRUB bootloader configuration file" >> $BFILE 2>> $DEBUGFILE + echo "#" >> $BFILE 2>> $DEBUGFILE + echo >> $BFILE 2>> $DEBUGFILE + + PARTNUM=`echo "$SYSTEMBOOTDEVICE" | rev | cut -c1` + + if [ "$SWRAID" = "0" ]; then + PARTNUM="$[$PARTNUM - 1]" + fi + + echo "timeout 5" >> $BFILE 2>> $DEBUGFILE + echo "default 0" >> $BFILE 2>> $DEBUGFILE + echo >> $BFILE 2>> $DEBUGFILE + echo "title Linux (openSUSE)" >> $BFILE 2>> $DEBUGFILE + echo "root (hd0,$PARTNUM)" >> $BFILE 2>> $DEBUGFILE + echo "kernel /boot/vmlinuz-$1 root=$SYSTEMROOTDEVICE vga=0x317" >> $BFILE 2>> $DEBUGFILE + + if [ -f "$FOLD/hdd/boot/initrd-$1" ]; then + echo "initrd /boot/initrd-$1" >> $BFILE 2>> $DEBUGFILE + fi + echo >> $BFILE 2>> $DEBUGFILE + + else + local grub_linux_default="nomodeset" + # set net.ifnames=0 to avoid predictable interface names for opensuse 13.2 + if [ "$SUSEVERSION" -ge 132 ] ; then + grub_linux_default="${grub_linux_default} net.ifnames=0 quiet systemd.show_status=1" + fi + # set elevator to noop for vserver + if isVServer; then + grub_linux_default="${grub_linux_default} elevater=noop" + fi + # H8SGL need workaround for iommu + if [ -n "$(dmidecode -s baseboard-product-name | grep -i h8sgl)" -a $IMG_VERSION -ge 131 ] ; then + grub_linux_default="${grub_linux_default} iommu=noaperture" + fi + + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_HIDDEN_TIMEOUT=.*/#GRUB_HIDDEN_TIMEOUT=5/" -e "s/^GRUB_HIDDEN_TIMEOUT_QUIET=.*/#GRUB_HIDDEN_TIMEOUT_QUIET=false/"' + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"'"${grub_linux_default}"'\"/"' + + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_TERMINAL=.*/GRUB_TERMINAL=console/"' + + [ -e $FOLD/hdd/boot/grub2/grub.cfg ] && rm "$FOLD/hdd/boot/grub2/grub.cfg" + execute_chroot_command "grub2-mkconfig -o /boot/grub2/grub.cfg 2>&1" + + # the opensuse mkinitrd uses this file to determine where to write the bootloader... + GRUBINSTALLDEV_FILE="$FOLD/hdd/etc/default/grub_installdevice" + [ -f $GRUBINSTALLDEV_FILE ] && rm $GRUBINSTALLDEV_FILE + for i in $(seq 1 $COUNT_DRIVES) ; do + local disk="$(eval echo "\$DRIVE"$i)" + echo "$disk" >> $GRUBINSTALLDEV_FILE + done + echo "generic_mbr" >> $GRUBINSTALLDEV_FILE + fi + + return $EXITCODE +} + +# +# write_grub +# +# Write the GRUB bootloader into the MBR +# +write_grub() { + # grub1 for all before OpenSuSE 12.2 + if [ "$SUSEVERSION" -lt 122 ]; then + execute_chroot_command "rm -rf /etc/lilo.conf" + + local i=0 + + for i in $(seq 1 $COUNT_DRIVES) ; do + if [ $SWRAID -eq 1 -o $i -eq 1 ] ; then + local 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" + fi + done + else + # only install grub2 in mbr of all other drives if we use swraid + local i=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + if [ $SWRAID -eq 1 -o $i -eq 1 ] ; then + local disk="$(eval echo "\$DRIVE"$i)" + execute_chroot_command "grub2-install --no-floppy --recheck $disk 2>&1" EXITCODE=$? + fi + done + fi + uuid_bugfix + + return $? + +} +# +# os specific functions +# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP +# +run_os_specific_functions() { + return 0 +} + + + diff --git a/ubuntu.sh b/ubuntu.sh new file mode 100755 index 0000000..c4a4076 --- /dev/null +++ b/ubuntu.sh @@ -0,0 +1,242 @@ +#!/bin/bash + +# +# Ubuntu specific functions +# +# originally written by Florian Wicke and David Mayr +# (c) 2007-2015, Hetzner Online AG +# + + +# setup_network_config "$ETH" "$HWADDR" "$IPADDR" "$BROADCAST" "$SUBNETMASK" "$GATEWAY" "$NETWORK" +setup_network_config() { + if [ "$1" -a "$2" ]; then + 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 -e "### Hetzner Online AG - installimage" > $UDEVFILE + echo -e "# device: $1" >> $UDEVFILE + echo -e "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$2\", ATTR{dev_id}==\"0x0\", ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"$1\"" >> $UDEVFILE + + echo -e "### Hetzner Online AG - installimage" > $CONFIGFILE + echo -e "# Loopback device:" >> $CONFIGFILE + echo -e "auto lo" >> $CONFIGFILE + echo -e "iface lo inet loopback" >> $CONFIGFILE + echo -e "" >> $CONFIGFILE + if [ "$3" -a "$4" -a "$5" -a "$6" -a "$7" ]; then + echo -e "# device: $1" >> $CONFIGFILE + echo -e "auto $1" >> $CONFIGFILE + echo -e "iface $1 inet static" >> $CONFIGFILE + echo -e " address $3" >> $CONFIGFILE + echo -e " broadcast $4" >> $CONFIGFILE + echo -e " netmask $5" >> $CONFIGFILE + echo -e " gateway $6" >> $CONFIGFILE + echo -e " # default route to access subnet" >> $CONFIGFILE + echo -e " up route add -net $7 netmask $5 gw $6 $1" >> $CONFIGFILE + fi + + if [ "$8" -a "$9" -a "${10}" ]; then + debug "setting up ipv6 networking $8/$9 via ${10}" + echo -e "" >> $CONFIGFILE + echo -e "iface $1 inet6 static" >> $CONFIGFILE + echo -e " address $8" >> $CONFIGFILE + echo -e " netmask $9" >> $CONFIGFILE + echo -e " gateway ${10}" >> $CONFIGFILE + fi + + # set duplex speed + if ! isNegotiated && ! isVServer; then + echo -e " # force full-duplex for ports without auto-neg" >> $CONFIGFILE + echo -e " post-up mii-tool -F 100baseTx-FD $1" >> $CONFIGFILE + fi + + return 0 + fi +} + +# generate_mdadmconf "NIL" +generate_config_mdadm() { + if [ "$1" ]; then + MDADMCONF="/etc/mdadm/mdadm.conf" +# echo "DEVICES /dev/[hs]d*" > $FOLD/hdd$MDADMCONF +# execute_chroot_command "mdadm --examine --scan | sed -e 's/metadata=00.90/metadata=0.90/g' >> $MDADMCONF"; EXITCODE=$? + execute_chroot_command "/usr/share/mdadm/mkconf > $MDADMCONF"; EXITCODE=$? + # Enable mdadm + sed -i "s/AUTOCHECK=false/AUTOCHECK=true # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + sed -i "s/AUTOSTART=false/AUTOSTART=true # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + sed -i "s/START_DAEMON=false/START_DAEMON=true # modified by installimage/" \ + $FOLD/hdd/etc/default/mdadm + if [ -f $FOLD/hdd/etc/initramfs-tools/conf.d/mdadm ]; then + sed -i "s/BOOT_DEGRADED=false/BOOT_DEGRADED=true # modified by installimage/" \ + $FOLD/hdd/etc/initramfs-tools/conf.d/mdadm + fi + + return $EXITCODE + fi +} + + +# generate_new_ramdisk "NIL" +generate_new_ramdisk() { + if [ "$1" ]; then + OUTFILE=`ls -1r $FOLD/hdd/boot/initrd.img-* | grep -v ".bak$\|.gz$" | awk -F "/" '{print $NF}' | grep -m1 "initrd"` + VERSION=`echo $OUTFILE | cut -d "-" -f2-` + echo "Kernel Version found: $VERSION" | debugoutput + + if [ "$IMG_VERSION" -ge 1204 ]; then + # blacklist i915 driver due to many bugs and stability issues + # required for Ubuntu 12.10 because of a kernel bug + local blacklist_conf="$FOLD/hdd/etc/modprobe.d/blacklist-hetzner.conf" + echo -e "### Hetzner Online AG - installimage" > $blacklist_conf + echo -e "### silence any onboard speaker" >> $blacklist_conf + echo -e "blacklist pcspkr" >> $blacklist_conf + echo -e "### i915 driver blacklisted due to various bugs" >> $blacklist_conf + echo -e "### especially in combination with nomodeset" >> $blacklist_conf + echo -e "blacklist i915" >> $blacklist_conf + echo -e "blacklist i915_bdw" >> $blacklist_conf + echo -e "install i915 /bin/true" >> $blacklist_conf + echo -e "### mei driver blacklisted due to serious bugs" >> $blacklist_conf + echo -e "blacklist mei" >> $blacklist_conf + echo -e "blacklist mei_me" >> $blacklist_conf + fi + + sed -i "s/do_bootloader = yes/do_bootloader = no/" $FOLD/hdd/etc/kernel-img.conf + execute_chroot_command "update-initramfs -u -k $VERSION"; EXITCODE=$? + sed -i "s/do_bootloader = no/do_bootloader = yes/" $FOLD/hdd/etc/kernel-img.conf + + return $EXITCODE + fi +} + +setup_cpufreq() { + if [ "$1" ]; then + LOADCPUFREQCONF="$FOLD/hdd/etc/default/loadcpufreq" + CPUFREQCONF="$FOLD/hdd/etc/default/cpufrequtils" + echo -e "### Hetzner Online AG - installimage" > $CPUFREQCONF + echo -e "# cpu frequency scaling" >> $CPUFREQCONF + if isVServer; then + echo -e "ENABLE=\"false\"" > $LOADCPUFREQCONF + echo -e "ENABLE=\"false\"" >> $CPUFREQCONF + else + echo -e "ENABLE=\"true\"" >> $CPUFREQCONF + echo -e "GOVERNOR=\"$1\"" >> $CPUFREQCONF + echo -e "MAX_SPEED=\"0\"" >> $CPUFREQCONF + echo -e "MIN_SPEED=\"0\"" >> $CPUFREQCONF + fi + + return 0 + fi +} + +# this is just to generate an error and should never be reached +# because we dropped support for lilo on ubuntu since 12.04 +generate_config_lilo() { + if [ "$1" ]; then + return 1 + fi +} + +# this is just to generate an error and should never be reached +# because we dropped support for lilo on ubuntu since 12.04 +write_lilo() { + if [ "$1" ]; then + return 1 + fi +} + +# +# generate_config_grub +# +# Generate the GRUB bootloader configuration. +# +generate_config_grub() { + + ubuntu_grub_fix + execute_chroot_command "cd /boot; [ -e boot ] && rm -rf boot; ln -s . boot >> /dev/null 2>&1" + + # set linux_default in grub + local grub_linux_default="nomodeset" + if isVServer; then + grub_linux_default="${grub_linux_default} elevator=noop" + else + if [ $IMG_VERSION -eq 1404 ]; then + grub_linux_default="${grub_linux_default} intel_pstate=enable" + fi + fi + + # H8SGL need workaround for iommu + if [ -n "$(dmidecode -s baseboard-product-name | grep -i h8sgl)" -a $IMG_VERSION -ge 1404 ] ; then + grub_linux_default="${grub_linux_default} iommu=noaperture" + fi + + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_HIDDEN_TIMEOUT=.*/GRUB_HIDDEN_TIMEOUT=5/" -e "s/^GRUB_HIDDEN_TIMEOUT_QUIET=.*/GRUB_HIDDEN_TIMEOUT_QUIET=false/"' + execute_chroot_command 'sed -i /etc/default/grub -e "s/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"'"${grub_linux_default}"'\"/"' + execute_chroot_command 'echo -e "\n# only use text mode - other modes may scramble screen\nGRUB_GFXPAYLOAD_LINUX=\"text\"\n" >>/etc/default/grub' + + # create /run/lock if it didn't exist because it is needed by grub-mkconfig + execute_chroot_command "mkdir -p /run/lock" + + execute_chroot_command "grub-mkconfig -o /boot/grub/grub.cfg 2>&1" + + # only install grub2 in mbr of all other drives if we use swraid + local i=0 + for i in $(seq 1 $COUNT_DRIVES) ; do + if [ $SWRAID -eq 1 -o $i -eq 1 ] ; then + local disk="$(eval echo "\$DRIVE"$i)" + execute_chroot_command "grub-install --no-floppy --recheck $disk 2>&1" + fi + done + + uuid_bugfix + + PARTNUM=`echo "$SYSTEMBOOTDEVICE" | rev | cut -c1` + if [ "$SWRAID" = "0" ]; then + PARTNUM="$[$PARTNUM - 1]" + fi + return $EXITCODE +} + +# +# os specific functions +# for purpose of e.g. debian-sys-maint mysql user password in debian/ubuntu LAMP +# +run_os_specific_functions() { + randomize_mdadm_checkarray_cronjob_time + return 0 +} + +randomize_mdadm_checkarray_cronjob_time() { + if [ -e "$FOLD/hdd/etc/cron.d/mdadm" -a "$(grep checkarray "$FOLD/hdd/etc/cron.d/mdadm")" ]; then + hour=$((($RANDOM % 4) + 1)) + minute=$((($RANDOM % 59) + 1)) + day=$((($RANDOM % 28) + 1)) + debug "# Randomizing cronjob run time for mdadm checkarray: day $day @ $hour:$minute" + + sed -i \ + -e "s/^57 0 \* \* 0 /$minute $hour $day \* \* /" \ + -e 's/ && \[ \$(date +\\%d) -le 7 \]//' \ + "$FOLD/hdd/etc/cron.d/mdadm" + else + debug "# No /etc/cron.d/mdadm found to randomize cronjob run time" + fi +} + +ubuntu_grub_fix() { + local mapper="$FOLD/hdd/dev/mapper" + local tempfile="$FOLD/hdd/tmp/mapper.tmp" + + ls -l $mapper > $tempfile + cat $tempfile | grep -v "total" | grep -v "crw" | while read line; do + local volgroup=$(echo $line | cut -d " " -f9) + local dmdevice=$(echo $line | cut -d "/" -f2) + + rm $mapper/$volgroup + cp -R $FOLD/hdd/dev/$dmdevice $mapper/$volgroup + done + rm $tempfile +}