From 44423c370010af0c273bb0038ed04cc53fcda8cf Mon Sep 17 00:00:00 2001 From: Juan RP Date: Sun, 19 May 2013 09:39:56 +0200 Subject: Start integration of void-installer and start conversion to non-busybox utils. --- installer.sh.in | 1311 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1311 insertions(+) create mode 100644 installer.sh.in (limited to 'installer.sh.in') diff --git a/installer.sh.in b/installer.sh.in new file mode 100644 index 0000000..6b0756f --- /dev/null +++ b/installer.sh.in @@ -0,0 +1,1311 @@ +#!/bin/sh +#- +# Copyright (c) 2012 Juan Romero Pardines . +# 2012 Dave Elusive . +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#- + +# Make sure we don't inherit these from env. +SOURCE_DONE= +HOSTNAME_DONE= +KEYBOARD_DONE= +LOCALE_DONE= +TIMEZONE_DONE= +ROOTPASSWORD_DONE= +BOOTLOADER_DONE= +PARTITIONS_DONE= +NETWORK_DONE= +FILESYSTEMS_DONE= + +TARGETDIR=/mnt/target +LOG=/dev/tty7 +CONF_FILE=/tmp/.void-installer.conf +if [ ! -f $CONF_FILE ]; then + touch -f $CONF_FILE +fi +ANSWER=$(mktemp -t vinstall-XXXXXXXX || exit 1) +TARGET_FSTAB=$(mktemp -t vinstall-fstab-XXXXXXXX || exit 1) + +trap "DIE" INT TERM QUIT + +# disable printk +if [ -w /proc/sys/kernel/printk ]; then + echo 0 >/proc/sys/kernel/printk +fi + +# Detect if this is an EFI system. +if [ -e /sys/firmware/efi/systab ]; then + EFI_SYSTEM=1 +fi + +# dialog colors +BLACK="\Z0" +RED="\Z1" +GREEN="\Z2" +YELLOW="\Z3" +BLUE="\Z4" +MAGENTA="\Z5" +CYAN="\Z6" +WHITE="\Z7" +BOLD="\Zb" +REVERSE="\Zr" +UNDERLINE="\Zu" +RESET="\Zn" + +# Properties shared per widget. +MENULABEL="${BOLD}Use UP and DOWN keys to navigate \ +menus. Use TAB to switch between buttons and ENTER to select.${RESET}" +MENUSIZE="14 60 0" +INPUTSIZE="8 60" +MSGBOXSIZE="8 70" +YESNOSIZE="$INPUTSIZE" +WIDGET_SIZE="10 70" + +# Hardcoded list of timezones; to not depend on tzdata. +TIMEZONES=" +Africa/Abidjan +Africa/Accra +Africa/Addis_Ababa +Africa/Algiers +Africa/Asmara +Africa/Bamako +Africa/Bangui +Africa/Banjul +Africa/Bissau +Africa/Blantyre +Africa/Brazzaville +Africa/Bujumbura +Africa/Cairo +Africa/Casablanca +Africa/Ceuta +Africa/Conakry +Africa/Dakar +Africa/Dar_es_Salaam +Africa/Djibouti +Africa/Douala +Africa/El_Aaiun +Africa/Freetown +Africa/Gaborone +Africa/Harare +Africa/Johannesburg +Africa/Juba +Africa/Kampala +Africa/Khartoum +Africa/Kigali +Africa/Kinshasa +Africa/Lagos +Africa/Libreville +Africa/Lome +Africa/Luanda +Africa/Lubumbashi +Africa/Lusaka +Africa/Malabo +Africa/Maputo +Africa/Maseru +Africa/Mbabane +Africa/Mogadishu +Africa/Monrovia +Africa/Nairobi +Africa/Ndjamena +Africa/Niamey +Africa/Nouakchott +Africa/Ouagadougou +Africa/Porto-Novo +Africa/Sao_Tome +Africa/Tripoli +Africa/Tunis +Africa/Windhoek +America/Adak +America/Anchorage +America/Anguilla +America/Antigua +America/Araguaina +America/Argentina/Buenos_Aires +America/Argentina/Catamarca +America/Argentina/Cordoba +America/Argentina/Jujuy +America/Argentina/La_Rioja +America/Argentina/Mendoza +America/Argentina/Rio_Gallegos +America/Argentina/Salta +America/Argentina/San_Juan +America/Argentina/San_Luis +America/Argentina/Tucuman +America/Argentina/Ushuaia +America/Aruba +America/Asuncion +America/Atikokan +America/Bahia +America/Bahia_Banderas +America/Barbados +America/Belem +America/Belize +America/Blanc-Sablon +America/Boa_Vista +America/Bogota +America/Boise +America/Cambridge_Bay +America/Campo_Grande +America/Cancun +America/Caracas +America/Cayenne +America/Cayman +America/Chicago +America/Chihuahua +America/Costa_Rica +America/Creston +America/Cuiaba +America/Curacao +America/Danmarkshavn +America/Dawson +America/Dawson_Creek +America/Denver +America/Detroit +America/Dominica +America/Edmonton +America/Eirunepe +America/El_Salvador +America/Fortaleza +America/Glace_Bay +America/Godthab +America/Goose_Bay +America/Grand_Turk +America/Grenada +America/Guadeloupe +America/Guatemala +America/Guayaquil +America/Guyana +America/Halifax +America/Havana +America/Hermosillo +America/Indiana/Indianapolis +America/Indiana/Knox +America/Indiana/Marengo +America/Indiana/Petersburg +America/Indiana/Tell_City +America/Indiana/Vevay +America/Indiana/Vincennes +America/Indiana/Winamac +America/Inuvik +America/Iqaluit +America/Jamaica +America/Juneau +America/Kentucky/Louisville +America/Kentucky/Monticello +America/Kralendijk +America/La_Paz +America/Lima +America/Los_Angeles +America/Lower_Princes +America/Maceio +America/Managua +America/Manaus +America/Marigot +America/Martinique +America/Matamoros +America/Mazatlan +America/Menominee +America/Merida +America/Metlakatla +America/Mexico_City +America/Miquelon +America/Moncton +America/Monterrey +America/Montevideo +America/Montreal +America/Montserrat +America/Nassau +America/New_York +America/Nipigon +America/Nome +America/Noronha +America/North_Dakota/Beulah +America/North_Dakota/Center +America/North_Dakota/New_Salem +America/Ojinaga +America/Panama +America/Pangnirtung +America/Paramaribo +America/Phoenix +America/Port-au-Prince +America/Port_of_Spain +America/Porto_Velho +America/Puerto_Rico +America/Rainy_River +America/Rankin_Inlet +America/Recife +America/Regina +America/Resolute +America/Rio_Branco +America/Santa_Isabel +America/Santarem +America/Santiago +America/Santo_Domingo +America/Sao_Paulo +America/Scoresbysund +America/Shiprock +America/Sitka +America/St_Barthelemy +America/St_Johns +America/St_Kitts +America/St_Lucia +America/St_Thomas +America/St_Vincent +America/Swift_Current +America/Tegucigalpa +America/Thule +America/Thunder_Bay +America/Tijuana +America/Toronto +America/Tortola +America/Vancouver +America/Whitehorse +America/Winnipeg +America/Yakutat +America/Yellowknife +Antarctica/Casey +Antarctica/Davis +Antarctica/DumontDUrville +Antarctica/Macquarie +Antarctica/Mawson +Antarctica/McMurdo +Antarctica/Palmer +Antarctica/Rothera +Antarctica/South_Pole +Antarctica/Syowa +Antarctica/Vostok +Arctic/Longyearbyen +Asia/Aden +Asia/Almaty +Asia/Amman +Asia/Anadyr +Asia/Aqtau +Asia/Aqtobe +Asia/Ashgabat +Asia/Baghdad +Asia/Bahrain +Asia/Baku +Asia/Bangkok +Asia/Beirut +Asia/Bishkek +Asia/Brunei +Asia/Choibalsan +Asia/Chongqing +Asia/Colombo +Asia/Damascus +Asia/Dhaka +Asia/Dili +Asia/Dubai +Asia/Dushanbe +Asia/Gaza +Asia/Harbin +Asia/Hebron +Asia/Ho_Chi_Minh +Asia/Hong_Kong +Asia/Hovd +Asia/Irkutsk +Asia/Jakarta +Asia/Jayapura +Asia/Jerusalem +Asia/Kabul +Asia/Kamchatka +Asia/Karachi +Asia/Kashgar +Asia/Kathmandu +Asia/Kolkata +Asia/Krasnoyarsk +Asia/Kuala_Lumpur +Asia/Kuching +Asia/Kuwait +Asia/Macau +Asia/Magadan +Asia/Makassar +Asia/Manila +Asia/Muscat +Asia/Nicosia +Asia/Novokuznetsk +Asia/Novosibirsk +Asia/Omsk +Asia/Oral +Asia/Phnom_Penh +Asia/Pontianak +Asia/Pyongyang +Asia/Qatar +Asia/Qyzylorda +Asia/Rangoon +Asia/Riyadh +Asia/Sakhalin +Asia/Samarkand +Asia/Seoul +Asia/Shanghai +Asia/Singapore +Asia/Taipei +Asia/Tashkent +Asia/Tbilisi +Asia/Tehran +Asia/Thimphu +Asia/Tokyo +Asia/Ulaanbaatar +Asia/Urumqi +Asia/Vientiane +Asia/Vladivostok +Asia/Yakutsk +Asia/Yekaterinburg +Asia/Yerevan +Atlantic/Azores +Atlantic/Bermuda +Atlantic/Canary +Atlantic/Cape_Verde +Atlantic/Faroe +Atlantic/Madeira +Atlantic/Reykjavik +Atlantic/South_Georgia +Atlantic/St_Helena +Atlantic/Stanley +Australia/Adelaide +Australia/Brisbane +Australia/Broken_Hill +Australia/Currie +Australia/Darwin +Australia/Eucla +Australia/Hobart +Australia/Lindeman +Australia/Lord_Howe +Australia/Melbourne +Australia/Perth +Australia/Sydney +Europe/Amsterdam +Europe/Andorra +Europe/Athens +Europe/Belgrade +Europe/Berlin +Europe/Bratislava +Europe/Brussels +Europe/Bucharest +Europe/Budapest +Europe/Chisinau +Europe/Copenhagen +Europe/Dublin +Europe/Gibraltar +Europe/Guernsey +Europe/Helsinki +Europe/Isle_of_Man +Europe/Istanbul +Europe/Jersey +Europe/Kaliningrad +Europe/Kiev +Europe/Lisbon +Europe/Ljubljana +Europe/London +Europe/Luxembourg +Europe/Madrid +Europe/Malta +Europe/Mariehamn +Europe/Minsk +Europe/Monaco +Europe/Moscow +Europe/Oslo +Europe/Paris +Europe/Podgorica +Europe/Prague +Europe/Riga +Europe/Rome +Europe/Samara +Europe/San_Marino +Europe/Sarajevo +Europe/Simferopol +Europe/Skopje +Europe/Sofia +Europe/Stockholm +Europe/Tallinn +Europe/Tirane +Europe/Uzhgorod +Europe/Vaduz +Europe/Vatican +Europe/Vienna +Europe/Vilnius +Europe/Volgograd +Europe/Warsaw +Europe/Zagreb +Europe/Zaporozhye +Europe/Zurich +Indian/Antananarivo +Indian/Chagos +Indian/Christmas +Indian/Cocos +Indian/Comoro +Indian/Kerguelen +Indian/Mahe +Indian/Maldives +Indian/Mauritius +Indian/Mayotte +Indian/Reunion +Pacific/Apia +Pacific/Auckland +Pacific/Chatham +Pacific/Chuuk +Pacific/Easter +Pacific/Efate +Pacific/Enderbury +Pacific/Fakaofo +Pacific/Fiji +Pacific/Funafuti +Pacific/Galapagos +Pacific/Gambier +Pacific/Guadalcanal +Pacific/Guam +Pacific/Honolulu +Pacific/Johnston +Pacific/Kiritimati +Pacific/Kosrae +Pacific/Kwajalein +Pacific/Majuro +Pacific/Marquesas +Pacific/Midway +Pacific/Nauru +Pacific/Niue +Pacific/Norfolk +Pacific/Noumea +Pacific/Pago_Pago +Pacific/Palau +Pacific/Pitcairn +Pacific/Pohnpei +Pacific/Port_Moresby +Pacific/Rarotonga +Pacific/Saipan +Pacific/Tahiti +Pacific/Tarawa +Pacific/Tongatapu +Pacific/Wake +Pacific/Wallis" + +DIALOG() { + rm -f $ANSWER + dialog --colors --keep-tite --no-shadow --no-mouse \ + --backtitle "${BOLD}${WHITE}Void Linux installation -- http://www.voidlinux.eu/${RESET}" \ + --cancel-label "Back" --aspect 20 "$@" 2>$ANSWER + return $? +} + +DIE() { + rval=$1 + [ -z "$rval" ] && rval=0 + clear + rm -f $ANSWER $TARGET_FSTAB + # reenable printk + if [ -w /proc/sys/kernel/printk ]; then + echo 4 >/proc/sys/kernel/printk + fi + umount_filesystems + exit $rval +} + +set_option() { + if grep -Eq "^${1}.*" $CONF_FILE; then + sed -i -e "/^${1}.*/d" $CONF_FILE + fi + echo "${1} ${2}" >>$CONF_FILE +} + +get_option() { + echo $(grep -E "^${1}.*" $CONF_FILE|sed -e "s|${1}||") +} + +show_disks() { + local dev size sectorsize gbytes + + # IDE + for dev in $(ls /sys/block|grep -E '^hd'); do + if [ "$(cat /sys/block/$dev/device/media)" = "disk" ]; then + # Find out nr sectors and bytes per sector; + echo "/dev/$dev" + size=$(cat /sys/block/$dev/size) + sectorsize=$(cat /sys/block/$dev/queue/hw_sector_size) + gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))" + echo "size:${gbytes}GB;sector_size:$sectorsize" + fi + done + # SATA/SCSI and Virtual disks (virtio) + for dev in $(ls /sys/block|grep -E '^[sv]d'); do + if [ "$(cat /sys/block/$dev/device/type)" != "5" ]; then + echo "/dev/$dev" + size=$(cat /sys/block/$dev/size) + sectorsize=$(cat /sys/block/$dev/queue/hw_sector_size) + gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))" + echo "size:${gbytes}GB;sector_size:$sectorsize" + fi + done +} + +show_partitions() { + local dev fstype fssize p part + + set -- $(show_disks) + while [ $# -ne 0 ]; do + disk=$(basename $1) + shift 2 + # ATA/SCSI/SATA + for p in /sys/block/$disk/$disk*; do + if [ -d $p ]; then + part=$(basename $p) + fstype=$(blkid /dev/$part|awk '{print $3}'|sed -e 's/TYPE=\"\(.*\)\"/\1/g') + [ "$fstype" = "iso9660" ] && continue + fssize=$(lsblk -r /dev/$part|awk '{print $4}'|grep -v SIZE) + echo "/dev/$part" + echo "size:${fssize:-unknown};fstype:${fstype:-none}" + fi + done + # LVM + for p in $(ls /dev/mapper 2>/dev/null|grep -v control); do + [ "$p" = "live-rw" ] && continue + fstype=$(blkid /dev/$part|awk '{print $3}'|sed -e 's/TYPE=\"\(.*\)\"/\1/g') + fssize=$(lsblk -r /dev/mapper/$p|awk '{print $4}'|grep -v SIZE) + echo "/dev/mapper/$p" + echo "size:${fssize:-unknown};fstype:${fstype:-none}" + done + # Software raid (md) + for p in $(ls -d /dev/md* 2>/dev/null|grep '[0-9]'); do + if cat /proc/mdstat|grep -qw $(echo $p|sed -e 's|/dev/||g'); then + fstype=$(blkid /dev/$part|awk '{print $3}'|sed -e 's/TYPE=\"\(.*\)\"/\1/g') + fssize=$(lsblk -r /dev/$p|awk '{print $4}'|grep -v SIZE) + echo "$p" + echo "size:${fssize:-unknown};fstype:${fstype:-none}" + fi + done + done +} + +menu_filesystems() { + local dev fstype fssize mntpoint reformat + + while true; do + DIALOG --title " Select the partition to edit " --menu "$MENULABEL" \ + ${MENUSIZE} $(show_partitions) + [ $? -ne 0 ] && return + + dev=$(cat $ANSWER) + DIALOG --title " Select the filesystem type for $dev " \ + --menu "$MENULABEL" ${MENUSIZE} \ + "vfat" "FAT32" \ + "btrfs" "Oracle's Btrfs" \ + "ext2" "Linux ext2 (no journaling)" \ + "ext3" "Linux ext3 (journal)" \ + "ext4" "Linux ext4 (journal)" \ + "swap" "Linux swap" \ + "xfs" "SGI's XFS" + if [ $? -eq 0 ]; then + fstype=$(cat $ANSWER) + else + continue + fi + if [ "$fstype" != "swap" ]; then + DIALOG --inputbox "Please specify the mount point for $dev:" ${INPUTSIZE} + if [ $? -eq 0 ]; then + mntpoint=$(cat $ANSWER) + elif [ $? -eq 1 ]; then + continue + fi + else + mntpoint=swap + fi + DIALOG --yesno "Do you want to create a new filesystem on $dev?" ${YESNOSIZE} + if [ $? -eq 0 ]; then + reformat=1 + elif [ $? -eq 1 ]; then + reformat=0 + else + continue + fi + fssize=$(lsblk -r $dev|awk '{print $4}'|grep -v SIZE) + set -- "$fstype" "$fssize" "$mntpoint" "$reformat" + if [ -n "$1" -a -n "$2" -a -n "$3" -a -n "$4" ]; then + local bdev=$(basename $dev) + if grep -Eq "^MOUNTPOINT \/dev\/${bdev}.*" $CONF_FILE; then + sed -i -e "/^MOUNTPOINT \/dev\/${bdev}.*/d" $CONF_FILE + fi + echo "MOUNTPOINT $dev $1 $2 $3 $4" >>$CONF_FILE + fi + done +} + +menu_partitions() { + DIALOG --title " Select the disk to partition " \ + --menu "$MENULABEL" ${MENUSIZE} $(show_disks) + if [ $? -eq 0 ]; then + local device=$(cat $ANSWER) + + DIALOG --title "Modify Partition Table on $device" --msgbox "\n +${BOLD}GNU parted will be executed in disk $device.${RESET}\n\n +For BIOS systems, MBR or GPT partition tables are supported.\n +To use GPT on PC BIOS systems an empty partition of 1MB must be added\n +at the first 2GB of the disk with the TOGGLE \`bios_grub' enabled.\n +${BOLD}NOTE: you don't need this on EFI systems.${RESET}\n\n +For EFI systems GPT is mandatory and a FAT32 partition with at least\n +100MB must be created with the TOGGLE \`boot', this will be used as\n +EFI System Partition. This partition must have mountpoint as \`/boot/efi'.\n\n +At least 2 partitions are required: swap and rootfs (/).\n +For swap, RAM*2 must be really enough. For / 600MB are required.\n\n +${BOLD}WARNING: /usr is not supported as a separate partition.${RESET}\n +${BOLD}WARNING: changes made by parted are destructive, you've been warned. +${RESET}\n" 18 80 + if [ $? -eq 0 ]; then + while true; do + clear; parted $device; PARTITIONS_DONE=1; partprobe $device + break + done + else + return + fi + fi +} + +menu_keymap() { + local KEYMAPS="de German fr French it Italian en English es Spanish ru Russia us American" + + while true; do + DIALOG --title " Select your keymap " --menu "$MENULABEL" 14 70 14 ${KEYMAPS} + if [ $? -eq 0 ]; then + set_option KEYMAP "$(cat $ANSWER)" + loadkeys "$(cat $ANSWER)" + KEYBOARD_DONE=1 + break + else + return + fi + done +} + +set_keymap() { + local KEYMAP=$(get_option KEYMAP) + sed -i -e "s|KEYMAP=.*|KEYMAP=$KEYMAP|g" $TARGETDIR/etc/vconsole.conf +} + +menu_locale() { + local _locales="$(localectl --no-pager list-locales)" + local _LOCALES= + + for f in ${_locales}; do + _LOCALES="${_LOCALES} ${f} -" + done + while true; do + DIALOG --title " Select your locale " --menu "$MENULABEL" 14 70 14 ${_LOCALES} + if [ $? -eq 0 ]; then + set_option LANG "$(cat $ANSWER)" + LOCALE_DONE=1 + break + else + return + fi + done +} + +set_locale() { + local LOCALE=$(get_option LOCALE) + sed -i -e "s|LANG=.*|LANG=$KEYMAP|g" $TARGETDIR/etc/locale.conf +} + +menu_timezone() { + local _tzones= + + for f in ${TIMEZONES}; do + _tzones="${_tzones} ${f} -" + done + while true; do + DIALOG --title " Select your timezone " --menu "$MENULABEL" 14 70 14 ${_tzones} + if [ $? -eq 0 ]; then + set_option TIMEZONE "$(cat $ANSWER)" + TIMEZONE_DONE=1 + break + else + return + fi + done +} + +set_timezone() { + local TIMEZONE="$(get_option TIMEZONE)" + ln -sf /usr/share/zoneinfo/${TIMEZONE} $TARGETDIR/etc/localtime +} + +menu_hostname() { + while true; do + DIALOG --inputbox "Set the machine hostname:" ${INPUTSIZE} + if [ $? -eq 0 ]; then + set_option HOSTNAME "$(cat $ANSWER)" + HOSTNAME_DONE=1 + break + else + return + fi + done +} + +set_hostname() { + echo $(get_option HOSTNAME) > $TARGETDIR/etc/hostname +} + +menu_rootpassword() { + local _firstpass= _secondpass= _desc= + + while true; do + if [ -n "${_firstpass}" ]; then + _desc="Enter the root password again (password won't be displayed)" + else + _desc="Enter the root password (password won't be displayed)" + fi + DIALOG --passwordbox "${_desc}" ${MSGBOXSIZE} + if [ $? -eq 0 ]; then + if [ -z "${_firstpass}" ]; then + _firstpass="$(cat $ANSWER)" + else + _secondpass="$(cat $ANSWER)" + fi + if [ -n "${_firstpass}" -a -n "${_secondpass}" ]; then + if [ "${_firstpass}" != "${_secondpass}" ]; then + DIALOG --infobox "Passwords do not match! please reenter it again" 6 80 + unset _firstpass _secondpass + sleep 2 && continue + fi + set_option ROOTPASSWORD "${_firstpass}" + ROOTPASSWORD_DONE=1 + break + fi + else + return + fi + done +} + +set_rootpassword() { + echo "root:$(get_option ROOTPASSWORD)" | chpasswd -R $TARGETDIR -c SHA512 +} + +menu_bootloader() { + while true; do + DIALOG --title " Select the disk to install the bootloader" \ + --menu "$MENULABEL" ${MENUSIZE} $(show_disks) + if [ $? -eq 0 ]; then + set_option BOOTLOADER "$(cat $ANSWER)" + BOOTLOADER_DONE=1 + break + else + return + fi + done +} + +set_bootloader() { + local dev=$(get_option BOOTLOADER) grub_args= + + # Check if it's an EFI system via efivars module. + if [ -n "$EFI_SYSTEM" ]; then + grub_args="--target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=void_grub --recheck" + fi + echo "Running grub-install $grub_args $dev..." >$LOG + chroot $TARGETDIR grub-install $grub_args $dev >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ + failed to install GRUB to $dev!\nCheck $LOG for errors." ${MSGBOXSIZE} + DIE 1 + fi + echo "Running grub-mkconfig on $TARGETDIR..." >$LOG + chroot $TARGETDIR grub-mkconfig -o /boot/grub/grub.cfg >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR${RESET}: \ + failed to run grub-mkconfig!\nCheck $LOG for errors." ${MSGBOXSIZE} + DIE 1 + fi +} + +test_network() { + rm -f xtraeme.asc && \ + wget http://xbps.nopcode.org/live/xtraeme.asc >$LOG 2>&1 + if [ $? -eq 0 ]; then + DIALOG --msgbox "Network is working properly!" ${MSGBOXSIZE} + NETWORK_DONE=1 + return 1 + fi + DIALOG --msgbox "Network is unaccessible, please setup it properly." ${MSGBOXSIZE} +} + +configure_wifi() { + local dev="$1" + + DIALOG --form "Wireless configuration for $dev:" 0 0 0 \ + "SSID:" 1 1 "add your AP name here" 1 21 20 0 \ + "Encryption:" 2 1 "Only supported: WEP or WPA-PSK" 2 21 20 0 \ + "Passphrase:" 3 1 "Enter the AP passphrase here" 3 21 20 0 || return 1 +} + +configure_eth() { + local dev="$1" + + DIALOG --yesno "Do you want to use DHCP for $dev?" ${YESNOSIZE} + if [ $? -eq 0 ]; then + configure_net_dhcp $dev + elif [ $? -eq 1 ]; then + configure_net_static $dev + fi +} + +iface_setup() { + ifconfig $1|grep -q 'inet addr:' + return $? +} + +configure_net_dhcp() { + local dev="$1" + + iface_setup $dev + if [ $? -eq 1 ]; then + udhcpc -q -t 10 -n -i $dev 2>&1 | tee $LOG | \ + DIALOG --progressbox "Initializing $dev via DHCP..." ${WIDGET_SIZE} + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} failed to run udhcpc. See $LOG for details." ${MSGBOXSIZE} + return 1 + fi + iface_setup $dev + if [ $? -eq 1 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} DHCP request failed for $dev. Check $LOG for errors." ${MSGBOXSIZE} + return 1 + fi + fi + test_network + if [ $? -eq 1 ]; then + set_option NETWORK "${dev} dhcp" + fi +} + +configure_net_static() { + local ip gw dns1 dns2 dev=$1 + + DIALOG --form "Static IP configuration for $dev:" 0 0 0 \ + "IP address:" 1 1 "192.168.0.2" 1 21 20 0 \ + "Gateway:" 2 1 "192.168.0.1" 2 21 20 0 \ + "DNS Primary" 3 1 "8.8.8.8" 3 21 20 0 \ + "DNS Secondary" 4 1 "8.8.4.4" 4 21 20 0 || return 1 + + set -- $(cat $ANSWER) + ip=$1; gw=$2; dns1=$3; dns2=$4 + echo "running: ifconfig $dev $IPADDR up" >$LOG + ifconfig $dev $ip up >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} Failed to setup $dev interface." ${MSGBOXSIZE} + return 1 + fi + route add default gw $gw >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} failed to setup your gateway." ${MSGBOXSIZE} + return 1 + fi + echo "nameserver $dns1" >/etc/resolv.conf + echo "nameserver $dns2" >>/etc/resolv.conf + test_network + if [ $? -eq 1 ]; then + set_option NETWORK "${dev} static $ip $gw $dns1 $dns2" + fi +} + +menu_network() { + local dev addr f DEVICES + + for f in $(ls /sys/class/net); do + [ "$f" = "lo" ] && continue + addr=$(cat /sys/class/net/$f/address) + DEVICES="$DEVICES $f $addr" + done + DIALOG --title " Select the network interface to configure " \ + --menu "$MENULABEL" ${MENUSIZE} ${DEVICES} + if [ $? -eq 0 ]; then + dev=$(cat $ANSWER) + if $(echo $dev|grep -q "wlan[0-9]" 2>/dev/null); then + configure_wifi $dev + else + configure_eth $dev + fi + fi +} + +validate_filesystems() { + local mnts dev size fstype mntpt mkfs rootfound swapfound fmt + local usrfound efi_system_partition + + unset TARGETFS + mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE) + set -- ${mnts} + while [ $# -ne 0 ]; do + dev=$2; fstype=$3; size=$4; mntpt="$5"; mkfs=$6 + shift 6 + + if [ "$mntpt" = "/" ]; then + rootfound=1 + elif [ "$mntpt" = "/usr" ]; then + usrfound=1 + elif [ "$fstype" = "vfat" -a "$mntpt" = "/boot/efi" ]; then + efi_system_partition=1 + fi + if [ "$mkfs" -eq 1 ]; then + fmt="NEW FILESYSTEM: " + fi + if [ -z "$TARGETFS" ]; then + TARGETFS="${fmt}$dev ($size) mounted on $mntpt as ${fstype}\n" + else + TARGETFS="${TARGETFS}${fmt}${dev} ($size) mounted on $mntpt as ${fstype}\n" + fi + done + if [ -z "$rootfound" ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +the mount point for the root filesystem (/) has not yet been configured." ${MSGBOXSIZE} + return 1 + elif [ -n "$usrfound" ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +/usr mount point has been configured but is not supported, please remove it to continue." ${MSGBOXSIZE} + return 1 + elif [ -n "$EFI_SYSTEM" -a -z "$efi_system_partition" ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +The EFI System Partition has not yet been configured, please create it\n +as FAT32, mountpoint /boot/efi and at least with 100MB of size." ${MSGBOXSIZE} + fi + FILESYSTEMS_DONE=1 +} + +create_filesystems() { + local mnts dev mntpt fstype mkfs size rv uuid + + mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE) + set -- ${mnts} + while [ $# -ne 0 ]; do + dev=$2; fstype=$3; mntpt="$5"; mkfs=$6 + shift 6 + + # swap partitions + if [ "$fstype" = "swap" ]; then + swapoff $dev >/dev/null 2>&1 + if [ "$mkfs" -eq 1 ]; then + mkswap $dev >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +failed to create swap on ${dev}!\ncheck $LOG for errors." ${MSGBOXSIZE} + DIE 1 + fi + fi + swapon $dev >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +failed to activate swap on $dev!\ncheck $LOG for errors." ${MSGBOXSIZE} + DIE 1 + fi + # Add entry for target fstab + uuid=$(blkid $dev|awk '{print $2}'|sed -e 's/UUID=\"\(.*\)\"/\1/g') + echo "UUID=$uuid none swap sw 0 0" >>$TARGET_FSTAB + continue + fi + + if [ "$mkfs" -eq 1 ]; then + case "$fstype" in + vfat) MKFS="mkfs.vfat -F32"; modprobe vfat >$LOG 2>&1;; + xfs) MKFS="mkfs.xfs -f"; modprobe xfs >$LOG 2>&1;; + ext2) MKFS="mke2fs"; modprobe ext2 >$LOG 2>&1;; + ext3) MKFS="mke2fs -j"; modprobe ext3 >$LOG 2>&1;; + ext4) MKFS="mke2fs -t ext4"; modprobe ext4 >$LOG 2>&1;; + btrfs) MKFS="mkfs.btrfs"; modprobe btrfs >$LOG 2>&1;; + esac + DIALOG --infobox "Creating filesystem $fstype on $dev for $mntpt ..." 8 60 + echo "Running $MKFS $dev..." >$LOG + $MKFS $dev >$LOG 2>&1; rv=$? + if [ $rv -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +failed to create filesystem $fstype on $dev!\ncheck $LOG for errors." ${MSGBOXSIZE} + DIE 1 + fi + fi + # Mount rootfs the first one. + [ "$mntpt" != "/" ] && continue + mkdir -p $TARGETDIR + echo "Mounting $dev on $mntpt ($fstype)..." >$LOG + mount -t $fstype $dev $TARGETDIR >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +failed to mount $dev on ${mntpt}! check $LOG for errors." ${MSGBOXSIZE} + DIE 1 + fi + # Add entry to target fstab + uuid=$(blkid $dev|awk '{print $2}'|sed -e 's/UUID=\"\(.*\)\"/\1/g') + echo "UUID=$uuid $mntpt $fstype defaults 0 1" >>$TARGET_FSTAB + done + + # mount all filesystems in target rootfs + mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE) + set -- ${mnts} + while [ $# -ne 0 ]; do + dev=$2; fstype=$3; mntpt="$5" + shift 6 + [ "$mntpt" = "/" -o "$fstype" = "swap" ] && continue + mkdir -p ${TARGETDIR}${mntpt} + echo "Mounting $dev on $mntpt ($fstype)..." >$LOG + mount -t $fstype $dev ${TARGETDIR}${mntpt} >$LOG 2>&1 + if [ $? -ne 0 ]; then + DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \ +failed to mount $dev on $mntpt! check $LOG for errors." ${MSGBOXSIZE} + DIE + fi + # Add entry to target fstab + uuid=$(blkid $dev|awk '{print $2}'|sed -e 's/UUID=\"\(.*\)\"/\1/g') + echo "UUID=$uuid $mntpt $fstype defaults 0 1" >>$TARGET_FSTAB + done +} + +mount_filesystems() { + for f in sys proc dev; do + [ ! -d $TARGETDIR/$f ] && mkdir $TARGETDIR/$f + echo "Mounting $TARGETDIR/$f..." >$LOG + mount --bind /$f $TARGETDIR/$f >$LOG 2>&1 + done +} + +umount_filesystems() { + local f + + for f in sys proc dev; do + echo "Unmounting $TARGETDIR/$f..." >$LOG + umount $TARGETDIR/$f >$LOG 2>&1 + done + local mnts=$(grep -E '^MOUNTPOINT.*$' $CONF_FILE) + set -- ${mnts} + while [ $# -ne 0 ]; do + local dev=$2; local fstype=$3; local mntpt=$5 + shift 6 + if [ "$fstype" = "swap" ]; then + echo "Disabling swap space on $dev..." >$LOG + swapoff $dev >$LOG 2>&1 + continue + fi + if [ "$mntpt" != "/" ]; then + echo "Unmounting $TARGETDIR/$mntpt..." >$LOG + umount $TARGETDIR/$mntpt >$LOG 2>&1 + fi + done + echo "Unmounting $TARGETDIR..." >$LOG + umount $TARGETDIR >$LOG 2>&1 +} + +install_packages() { + local _grub= + + if [ -n "$EFI_SYSTEM" ]; then + _grub="grub-x86_64-efi" + else + _grub="grub" + fi + + mkdir -p $TARGETDIR/boot/grub + stdbuf -oL xbps-install -C /tmp/xbps.conf \ + -r $TARGETDIR -Sy base-system ${_grub} 2>&1 | \ + DIALOG --title "Installing base system packages..." \ + --programbox 24 80 + if [ $? -ne 0 ]; then + DIE 1 + fi +} + +menu_install() { + # Don't continue if filesystems are not ready. + validate_filesystems || return 1 + + ROOTPASSWORD_DONE="$(get_option ROOTPASSWORD)" + BOOTLOADER_DONE="$(get_option BOOTLOADER)" + + if [ -z "$FILESYSTEMS_DONE" ]; then + DIALOG --msgbox "${BOLD}Required filesystems were not configured, \ +please do so before starting the installation.${RESET}" ${MSGBOXSIZE} + return 1 + elif [ -z "$ROOTPASSWORD_DONE" ]; then + DIALOG --msgbox "${BOLD}The root password has not been configured, \ +please do so before starting the installation.${RESET}" ${MSGBOXSIZE} + return 1 + elif [ -z "$BOOTLOADER_DONE" ]; then + DIALOG --msgbox "${BOLD}The disk to install the bootloader has not been \ +configured, please do so before starting the installation.${RESET}" ${MSGBOXSIZE} + return 1 + fi + + DIALOG --yesno "${BOLD}The following operations will be executed:${RESET}\n\n +${BOLD}${TARGETFS}${RESET}\n +${BOLD}${RED}WARNING: data on partitions will be COMPLETELY DESTROYED for new \ +filesystems.${RESET}\n\n +${BOLD}Do you want to continue?${RESET}" 20 80 || return + unset TARGETFS + + # Create and mount filesystems + create_filesystems + + # mount required fs + mount_filesystems + + # If source not set use defaults. + if [ -z "$SOURCE_DONE" ]; then + enable_localsrc + fi + # Install required packages. + install_packages + + DIALOG --infobox "Applying installer settings..." 4 60 + + # copy target fstab. + install -Dm644 $TARGET_FSTAB $TARGETDIR/etc/fstab + + # set up keymap, locale, timezone, hostname and root passwd. + set_keymap + set_locale + set_timezone + set_hostname + set_rootpassword + + # Copy /etc/skel files for root. + cp $TARGETDIR/etc/skel/.[bix]* $TARGETDIR/root + + # network settings for target + if [ -n "$NETWORK_DONE" ]; then + local net=$(grep -E '^NETWORK.*' $CONF_FILE) + set -- ${net} + local dev=$2; local type=$3; local ip=$4; local gw=$5 + local dns1=$6; local dns2=$7 + if [ "$type" = "dhcp" ]; then + # if user had dhcp enabled, enable dhcpcd service for that device. + chroot $TARGETDIR systemctl enable dhcpcd.service >$LOG 2>&1 + else + # static IP through dhcpcd. + mv $TARGETDIR/etc/dhcpcd.conf $TARGETDIR/etc/dhdpcd.conf.orig + echo "# Static IP configuration set by the void-installer for $dev." \ + >$TARGETDIR/etc/dhcpcd.conf + echo "interface $dev" >>$TARGETDIR/etc/dhcpcd.conf + echo "static ip_address=$ip" >>$TARGETDIR/etc/dhcpcd.conf + echo "static routers=$gw" >>$TARGETDIR/etc/dhcpcd.conf + echo "static domain_name_servers=$dns1 $dns2" >>$TARGETDIR/etc/dhcpcd.conf + chroot $TARGETDIR systemctl enable dhcpcd.service >$LOG 2>&1 + fi + fi + + # install bootloader. + set_bootloader + sync && sync && sync + + # unmount all filesystems. + umount_filesystems + + # installed successfully. + DIALOG --yesno "${BOLD}Void Linux has been installed successfully!${RESET}\n +Do you want to reboot the system?" ${YESNOSIZE} + if [ $? -eq 0 ]; then + shutdown -r now + else + return + fi +} + +enable_localsrc() { + # local and fallback to official remote. + echo "repositories = { /packages, http://xbps.nopcode.org/repos/current }" >/tmp/xbps.conf +} + +enable_netsrc() { + # only remote. + echo "repositories = { http://xbps.nopcode.org/repos/current }" > /tmp/xbps.conf +} + +menu_source() { + local src= + + DIALOG --title " Select installation source " \ + --menu "$MENULABEL" 8 70 0 \ + "Local" "Packages from ISO image" \ + "Network" "Packages from official remote reposity" + case "$(cat $ANSWER)" in + "Local") src="local"; enable_localsrc;; + "Network") src="net"; enable_netsrc; menu_network;; + *) return 1;; + esac + SOURCE_DONE=1 + set_option SOURCE $src +} + +menu() { + if [ -z "$DEFITEM" ]; then + DEFITEM="Keyboard" + fi + + DIALOG --default-item $DEFITEM \ + --extra-button --extra-label "Settings" \ + --title " Void Linux installation menu " \ + --menu "$MENULABEL" 10 70 0 \ + "Keyboard" "Set system keyboard" \ + "Source" "Set source installation" \ + "Hostname" "Set system hostname" \ + "Locale" "Set system locale" \ + "Timezone" "Set system time zone" \ + "RootPassword" "Set system root password" \ + "BootLoader" "Set disk to install bootloader" \ + "Partition" "Partition disk(s)" \ + "Filesystems" "Configure filesystems and mount points" \ + "Install" "Start installation with saved settings" \ + "Exit" "Exit installation" + + if [ $? -eq 3 ]; then + # Show settings + DIALOG --title "Saved settings for installation" --textbox $CONF_FILE 14 60 + return + fi + + case $(cat $ANSWER) in + "Keyboard") menu_keymap && [ -n "$KEYBOARD_DONE" ] && DEFITEM="Source";; + "Source") menu_source && [ -n "$SOURCE_DONE" ] && DEFITEM="Hostname";; + "Hostname") menu_hostname && [ -n "$HOSTNAME_DONE" ] && DEFITEM="Locale";; + "Locale") menu_locale && [ -n "$LOCALE_DONE" ] && DEFITEM="Timezone";; + "Timezone") menu_timezone && [ -n "$TIMEZONE_DONE" ] && DEFITEM="RootPassword";; + "RootPassword") menu_rootpassword && [ -n "$ROOTPASSWORD_DONE" ] && DEFITEM="BootLoader";; + "BootLoader") menu_bootloader && [ -n "$BOOTLOADER_DONE" ] && DEFITEM="Partition";; + "Partition") menu_partitions && [ -n "$PARTITIONS_DONE" ] && DEFITEM="Filesystems";; + "Filesystems") menu_filesystems && [ -n "$FILESYSTEMS_DONE" ] && DEFITEM="Install";; + "Install") menu_install;; + "Exit") DIE;; + *) DIALOG --yesno "Abort Installation?" ${YESNOSIZE} && DIE + esac +} + +# +# main() +# +DIALOG --title "${BOLD}${RED} Enter the void ... ${RESET}" --msgbox "\n +Welcome to the Void Linux installation. A simple and minimal \ +Linux distribution made from scratch and built from the source package tree \ +available for XBPS, a new alternative binary package system.\n\n +The installation should be pretty straightforward, if you are in trouble \ +please join us at ${BOLD}#xbps on irc.freenode.org${RESET}.\n\n +${BOLD}http://www.voidlinux.eu${RESET}\n\n" 16 80 + +while true; do + menu +done + +exit 0 +# vim: set ts=4 sw=4 et: -- cgit 1.4.1