installer.sh.in 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. #!/bin/sh
  2. #-
  3. # Copyright (c) 2012-2014 Juan Romero Pardines <[email protected]>.
  4. # 2012 Dave Elusive <[email protected]>.
  5. # All rights reserved.
  6. #
  7. # Redistribution and use in source and binary forms, with or without
  8. # modification, are permitted provided that the following conditions
  9. # are met:
  10. # 1. Redistributions of source code must retain the above copyright
  11. # notice, this list of conditions and the following disclaimer.
  12. # 2. Redistributions in binary form must reproduce the above copyright
  13. # notice, this list of conditions and the following disclaimer in the
  14. # documentation and/or other materials provided with the distribution.
  15. #
  16. # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17. # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  20. # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  21. # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  25. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. #-
  27. # Make sure we don't inherit these from env.
  28. SOURCE_DONE=
  29. HOSTNAME_DONE=
  30. KEYBOARD_DONE=
  31. LOCALE_DONE=
  32. TIMEZONE_DONE=
  33. ROOTPASSWORD_DONE=
  34. BOOTLOADER_DONE=
  35. PARTITIONS_DONE=
  36. NETWORK_DONE=
  37. FILESYSTEMS_DONE=
  38. TARGETDIR=/mnt/target
  39. LOG=/dev/tty7
  40. CONF_FILE=/tmp/.void-installer.conf
  41. if [ ! -f $CONF_FILE ]; then
  42. touch -f $CONF_FILE
  43. fi
  44. ANSWER=$(mktemp -t vinstall-XXXXXXXX || exit 1)
  45. TARGET_FSTAB=$(mktemp -t vinstall-fstab-XXXXXXXX || exit 1)
  46. trap "DIE" INT TERM QUIT
  47. # disable printk
  48. if [ -w /proc/sys/kernel/printk ]; then
  49. echo 0 >/proc/sys/kernel/printk
  50. fi
  51. # Detect if this is an EFI system.
  52. if [ -e /sys/firmware/efi/systab ]; then
  53. EFI_SYSTEM=1
  54. fi
  55. # dialog colors
  56. BLACK="\Z0"
  57. RED="\Z1"
  58. GREEN="\Z2"
  59. YELLOW="\Z3"
  60. BLUE="\Z4"
  61. MAGENTA="\Z5"
  62. CYAN="\Z6"
  63. WHITE="\Z7"
  64. BOLD="\Zb"
  65. REVERSE="\Zr"
  66. UNDERLINE="\Zu"
  67. RESET="\Zn"
  68. # Properties shared per widget.
  69. MENULABEL="${BOLD}Use UP and DOWN keys to navigate \
  70. menus. Use TAB to switch between buttons and ENTER to select.${RESET}"
  71. MENUSIZE="14 60 0"
  72. INPUTSIZE="8 60"
  73. MSGBOXSIZE="8 70"
  74. YESNOSIZE="$INPUTSIZE"
  75. WIDGET_SIZE="10 70"
  76. DIALOG() {
  77. rm -f $ANSWER
  78. dialog --colors --keep-tite --no-shadow --no-mouse \
  79. --backtitle "${BOLD}${WHITE}Void Linux installation -- http://www.voidlinux.eu/ (@@MKLIVE_VERSION@@)${RESET}" \
  80. --cancel-label "Back" --aspect 20 "$@" 2>$ANSWER
  81. return $?
  82. }
  83. DIE() {
  84. rval=$1
  85. [ -z "$rval" ] && rval=0
  86. clear
  87. rm -f $ANSWER $TARGET_FSTAB
  88. # reenable printk
  89. if [ -w /proc/sys/kernel/printk ]; then
  90. echo 4 >/proc/sys/kernel/printk
  91. fi
  92. umount_filesystems
  93. exit $rval
  94. }
  95. set_option() {
  96. if grep -Eq "^${1}.*" $CONF_FILE; then
  97. sed -i -e "/^${1}.*/d" $CONF_FILE
  98. fi
  99. echo "${1} ${2}" >>$CONF_FILE
  100. }
  101. get_option() {
  102. echo $(grep -E "^${1}.*" $CONF_FILE|sed -e "s|${1}||")
  103. }
  104. show_disks() {
  105. local dev size sectorsize gbytes
  106. # IDE
  107. for dev in $(ls /sys/block|grep -E '^hd'); do
  108. if [ "$(cat /sys/block/$dev/device/media)" = "disk" ]; then
  109. # Find out nr sectors and bytes per sector;
  110. echo "/dev/$dev"
  111. size=$(cat /sys/block/$dev/size)
  112. sectorsize=$(cat /sys/block/$dev/queue/hw_sector_size)
  113. gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))"
  114. echo "size:${gbytes}GB;sector_size:$sectorsize"
  115. fi
  116. done
  117. # SATA/SCSI and Virtual disks (virtio)
  118. for dev in $(ls /sys/block|grep -E '^([sv]|xv)d'); do
  119. echo "/dev/$dev"
  120. size=$(cat /sys/block/$dev/size)
  121. sectorsize=$(cat /sys/block/$dev/queue/hw_sector_size)
  122. gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))"
  123. echo "size:${gbytes}GB;sector_size:$sectorsize"
  124. done
  125. }
  126. show_partitions() {
  127. local dev fstype fssize p part
  128. set -- $(show_disks)
  129. while [ $# -ne 0 ]; do
  130. disk=$(basename $1)
  131. shift 2
  132. # ATA/SCSI/SATA
  133. for p in /sys/block/$disk/$disk*; do
  134. if [ -d $p ]; then
  135. part=$(basename $p)
  136. fstype=$(lsblk -nfr /dev/$part|awk '{print $2}')
  137. [ "$fstype" = "iso9660" ] && continue
  138. fssize=$(lsblk -nr /dev/$part|awk '{print $4}')
  139. echo "/dev/$part"
  140. echo "size:${fssize:-unknown};fstype:${fstype:-none}"
  141. fi
  142. done
  143. # LVM
  144. for p in $(ls /dev/mapper 2>/dev/null|grep -v control); do
  145. [ "$p" = "live-rw" ] && continue
  146. [ "$p" = "live-base" ] && continue
  147. fstype=$(lsblk -nfr /dev/$part|awk '{print $2}')
  148. fssize=$(lsblk -nr /dev/mapper/$p|awk '{print $4}')
  149. echo "/dev/mapper/$p"
  150. echo "size:${fssize:-unknown};fstype:${fstype:-none}"
  151. done
  152. # Software raid (md)
  153. for p in $(ls -d /dev/md* 2>/dev/null|grep '[0-9]'); do
  154. if cat /proc/mdstat|grep -qw $(echo $p|sed -e 's|/dev/||g'); then
  155. fstype=$(lsblk -nfr /dev/$part|awk '{print $2}')
  156. fssize=$(lsblk -nr /dev/$p|awk '{print $4}')
  157. echo "$p"
  158. echo "size:${fssize:-unknown};fstype:${fstype:-none}"
  159. fi
  160. done
  161. done
  162. }
  163. menu_filesystems() {
  164. local dev fstype fssize mntpoint reformat
  165. while true; do
  166. DIALOG --title " Select the partition to edit " --menu "$MENULABEL" \
  167. ${MENUSIZE} $(show_partitions)
  168. [ $? -ne 0 ] && return
  169. dev=$(cat $ANSWER)
  170. DIALOG --title " Select the filesystem type for $dev " \
  171. --menu "$MENULABEL" ${MENUSIZE} \
  172. "btrfs" "Oracle's Btrfs" \
  173. "ext2" "Linux ext2 (no journaling)" \
  174. "ext3" "Linux ext3 (journal)" \
  175. "ext4" "Linux ext4 (journal)" \
  176. "f2fs" "Flash-Friendly Filesystem" \
  177. "swap" "Linux swap" \
  178. "vfat" "FAT32" \
  179. "xfs" "SGI's XFS"
  180. if [ $? -eq 0 ]; then
  181. fstype=$(cat $ANSWER)
  182. else
  183. continue
  184. fi
  185. if [ "$fstype" != "swap" ]; then
  186. DIALOG --inputbox "Please specify the mount point for $dev:" ${INPUTSIZE}
  187. if [ $? -eq 0 ]; then
  188. mntpoint=$(cat $ANSWER)
  189. elif [ $? -eq 1 ]; then
  190. continue
  191. fi
  192. else
  193. mntpoint=swap
  194. fi
  195. DIALOG --yesno "Do you want to create a new filesystem on $dev?" ${YESNOSIZE}
  196. if [ $? -eq 0 ]; then
  197. reformat=1
  198. elif [ $? -eq 1 ]; then
  199. reformat=0
  200. else
  201. continue
  202. fi
  203. fssize=$(lsblk -nr $dev|awk '{print $4}')
  204. set -- "$fstype" "$fssize" "$mntpoint" "$reformat"
  205. if [ -n "$1" -a -n "$2" -a -n "$3" -a -n "$4" ]; then
  206. local bdev=$(basename $dev)
  207. if grep -Eq "^MOUNTPOINT \/dev\/${bdev}.*" $CONF_FILE; then
  208. sed -i -e "/^MOUNTPOINT \/dev\/${bdev}.*/d" $CONF_FILE
  209. fi
  210. echo "MOUNTPOINT $dev $1 $2 $3 $4" >>$CONF_FILE
  211. fi
  212. done
  213. }
  214. menu_partitions() {
  215. DIALOG --title " Select the disk to partition " \
  216. --menu "$MENULABEL" ${MENUSIZE} $(show_disks)
  217. if [ $? -eq 0 ]; then
  218. local device=$(cat $ANSWER)
  219. DIALOG --title "Modify Partition Table on $device" --msgbox "\n
  220. ${BOLD}GNU parted will be executed in disk $device.${RESET}\n\n
  221. For BIOS systems, MBR or GPT partition tables are supported.\n
  222. To use GPT on PC BIOS systems an empty partition of 1MB must be added\n
  223. at the first 2GB of the disk with the TOGGLE \`bios_grub' enabled.\n
  224. ${BOLD}NOTE: you don't need this on EFI systems.${RESET}\n\n
  225. For EFI systems GPT is mandatory and a FAT32 partition with at least\n
  226. 100MB must be created with the TOGGLE \`boot', this will be used as\n
  227. EFI System Partition. This partition must have mountpoint as \`/boot/efi'.\n\n
  228. At least 2 partitions are required: swap and rootfs (/).\n
  229. For swap, RAM*2 must be really enough. For / 600MB are required.\n\n
  230. ${BOLD}WARNING: /usr is not supported as a separate partition.${RESET}\n
  231. ${BOLD}WARNING: changes made by parted are destructive, you've been warned.
  232. ${RESET}\n" 18 80
  233. if [ $? -eq 0 ]; then
  234. while true; do
  235. clear; parted $device; PARTITIONS_DONE=1; partprobe $device
  236. break
  237. done
  238. else
  239. return
  240. fi
  241. fi
  242. }
  243. menu_keymap() {
  244. if [ -x "/usr/bin/localectl" ]; then
  245. local _keymaps="$(localectl --no-pager list-keymaps)"
  246. else
  247. local _keymaps="$(find /usr/share/kbd/keymaps/ -type f -iname "*.map.gz" -printf "%f\n" | sed 's|.map.gz||g' | sort)"
  248. fi
  249. local _KEYMAPS=
  250. for f in ${_keymaps}; do
  251. _KEYMAPS="${_KEYMAPS} ${f} -"
  252. done
  253. while true; do
  254. DIALOG --title " Select your keymap " --menu "$MENULABEL" 14 70 14 ${_KEYMAPS}
  255. if [ $? -eq 0 ]; then
  256. set_option KEYMAP "$(cat $ANSWER)"
  257. loadkeys "$(cat $ANSWER)"
  258. KEYBOARD_DONE=1
  259. break
  260. else
  261. return
  262. fi
  263. done
  264. }
  265. set_keymap() {
  266. local KEYMAP=$(get_option KEYMAP)
  267. if [ -f "/etc/vconsole.conf" ]; then
  268. sed -i -e "s|KEYMAP=.*|KEYMAP=$KEYMAP|g" $TARGETDIR/etc/vconsole.conf
  269. else
  270. sed -i -e "s|KEYMAP=.*|KEYMAP=$KEYMAP|g" $TARGETDIR/etc/rc.conf
  271. fi
  272. }
  273. menu_locale() {
  274. local _locales="$(grep -E '\.UTF-8' /etc/default/libc-locales|awk '{print $1}'|sed -e 's/^#//')"
  275. local _LOCALES=
  276. for f in ${_locales}; do
  277. _LOCALES="${_LOCALES} ${f} -"
  278. done
  279. while true; do
  280. DIALOG --title " Select your locale " --menu "$MENULABEL" 14 70 14 ${_LOCALES}
  281. if [ $? -eq 0 ]; then
  282. set_option LOCALE "$(cat $ANSWER)"
  283. LOCALE_DONE=1
  284. break
  285. else
  286. return
  287. fi
  288. done
  289. }
  290. set_locale() {
  291. local LOCALE=$(get_option LOCALE)
  292. sed -i -e "s|LANG=.*|LANG=$LOCALE|g" $TARGETDIR/etc/locale.conf
  293. # Uncomment locale from /etc/default/libc-locales and regenerate it.
  294. sed -e "/${LOCALE}/s/^\#//" -i $TARGETDIR/etc/default/libc-locales
  295. echo "Running xbps-reconfigure -f glibc-locales ..." >$LOG
  296. chroot $TARGETDIR xbps-reconfigure -f glibc-locales >$LOG 2>&1
  297. }
  298. menu_timezone() {
  299. if [ -x "/usr/bin/timedatectl" ]; then
  300. local _tzones="$(timedatectl --no-pager list-timezones)"
  301. else
  302. local _tzones="$(find /usr/share/zoneinfo Africa/ America/ Antarctica/ Arctic/ Asia/ Atlantic/ Australia/ Europe/ Indian/ Pacific/ -type f | sort)"
  303. fi
  304. local _TIMEZONES=
  305. for f in ${_tzones}; do
  306. _TIMEZONES="${_TIMEZONES} ${f} -"
  307. done
  308. while true; do
  309. DIALOG --title " Select your timezone " --menu "$MENULABEL" 14 70 14 ${_TIMEZONES}
  310. if [ $? -eq 0 ]; then
  311. set_option TIMEZONE "$(cat $ANSWER)"
  312. TIMEZONE_DONE=1
  313. break
  314. else
  315. return
  316. fi
  317. done
  318. }
  319. set_timezone() {
  320. local TIMEZONE="$(get_option TIMEZONE)"
  321. ln -sf /usr/share/zoneinfo/${TIMEZONE} $TARGETDIR/etc/localtime
  322. }
  323. menu_hostname() {
  324. while true; do
  325. DIALOG --inputbox "Set the machine hostname:" ${INPUTSIZE}
  326. if [ $? -eq 0 ]; then
  327. set_option HOSTNAME "$(cat $ANSWER)"
  328. HOSTNAME_DONE=1
  329. break
  330. else
  331. return
  332. fi
  333. done
  334. }
  335. set_hostname() {
  336. echo $(get_option HOSTNAME) > $TARGETDIR/etc/hostname
  337. }
  338. menu_rootpassword() {
  339. local _firstpass= _secondpass= _desc=
  340. while true; do
  341. if [ -n "${_firstpass}" ]; then
  342. _desc="Enter the root password again (password won't be displayed)"
  343. else
  344. _desc="Enter the root password (password won't be displayed)"
  345. fi
  346. DIALOG --passwordbox "${_desc}" ${MSGBOXSIZE}
  347. if [ $? -eq 0 ]; then
  348. if [ -z "${_firstpass}" ]; then
  349. _firstpass="$(cat $ANSWER)"
  350. else
  351. _secondpass="$(cat $ANSWER)"
  352. fi
  353. if [ -n "${_firstpass}" -a -n "${_secondpass}" ]; then
  354. if [ "${_firstpass}" != "${_secondpass}" ]; then
  355. DIALOG --infobox "Passwords do not match! please reenter it again" 6 80
  356. unset _firstpass _secondpass
  357. sleep 2 && continue
  358. fi
  359. set_option ROOTPASSWORD "${_firstpass}"
  360. ROOTPASSWORD_DONE=1
  361. break
  362. fi
  363. else
  364. return
  365. fi
  366. done
  367. }
  368. set_rootpassword() {
  369. echo "root:$(get_option ROOTPASSWORD)" | chpasswd -R $TARGETDIR -c SHA512
  370. }
  371. menu_bootloader() {
  372. while true; do
  373. DIALOG --title " Select the disk to install the bootloader" \
  374. --menu "$MENULABEL" ${MENUSIZE} $(show_disks)
  375. if [ $? -eq 0 ]; then
  376. set_option BOOTLOADER "$(cat $ANSWER)"
  377. BOOTLOADER_DONE=1
  378. break
  379. else
  380. return
  381. fi
  382. done
  383. }
  384. set_bootloader() {
  385. local dev=$(get_option BOOTLOADER) grub_args=
  386. # Check if it's an EFI system via efivars module.
  387. if [ -n "$EFI_SYSTEM" ]; then
  388. grub_args="--target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=void_grub --recheck"
  389. fi
  390. echo "Running grub-install $grub_args $dev..." >$LOG
  391. chroot $TARGETDIR grub-install $grub_args $dev >$LOG 2>&1
  392. if [ $? -ne 0 ]; then
  393. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  394. failed to install GRUB to $dev!\nCheck $LOG for errors." ${MSGBOXSIZE}
  395. DIE 1
  396. fi
  397. echo "Running grub-mkconfig on $TARGETDIR..." >$LOG
  398. chroot $TARGETDIR grub-mkconfig -o /boot/grub/grub.cfg >$LOG 2>&1
  399. if [ $? -ne 0 ]; then
  400. DIALOG --msgbox "${BOLD}${RED}ERROR${RESET}: \
  401. failed to run grub-mkconfig!\nCheck $LOG for errors." ${MSGBOXSIZE}
  402. DIE 1
  403. fi
  404. }
  405. test_network() {
  406. rm -f xtraeme.asc && \
  407. xbps-uhelper fetch http://repo.voidlinux.eu/live/xtraeme.asc >$LOG 2>&1
  408. if [ $? -eq 0 ]; then
  409. DIALOG --msgbox "Network is working properly!" ${MSGBOXSIZE}
  410. NETWORK_DONE=1
  411. return 1
  412. fi
  413. DIALOG --msgbox "Network is unaccessible, please setup it properly." ${MSGBOXSIZE}
  414. }
  415. configure_wifi() {
  416. local dev="$1" ssid enc pass _wpasupconf=/etc/wpa_supplicant/wpa_supplicant.conf
  417. DIALOG --form "Wireless configuration for ${dev}\n(encryption type: wep or wpa)" 0 0 0 \
  418. "SSID:" 1 1 "" 1 16 30 0 \
  419. "Encryption:" 2 1 "" 2 16 3 0 \
  420. "Password:" 3 1 "" 3 16 30 0 || return 1
  421. set -- $(cat $ANSWER)
  422. ssid="$1"; enc="$2"; pass="$3";
  423. if [ -z "$ssid" ]; then
  424. DIALOG --msgbox "Invalid SSID." ${MSGBOXSIZE}
  425. return 1
  426. elif [ -z "$enc" -o "$enc" != "wep" -a "$enc" != "wpa" ]; then
  427. DIALOG --msgbox "Invalid encryption type (possible values: wep or wpa)." ${MSXBOXSIZE}
  428. return 1
  429. elif [ -z "$pass" ]; then
  430. DIALOG --msgbox "Invalid AP password." ${MSGBOXSIZE}
  431. fi
  432. rm -f ${_wpasupconf%.conf}-${dev}.conf
  433. cp -f ${_wpasupconf} ${_wpasupconf%.conf}-${dev}.conf
  434. if [ "$enc" = "wep" ]; then
  435. echo "network={" >> ${_wpasupconf%.conf}-${dev}.conf
  436. echo " ssid=\"$ssid\"" >> ${_wpasupconf%.conf}-${dev}.conf
  437. echo " wep_key0=\"$pass\"" >> ${_wpasupconf%.conf}-${dev}.conf
  438. echo " wep_tx_keyidx=0" >> ${_wpasupconf%.conf}-${dev}.conf
  439. echo " auth_alg=SHARED" >> ${_wpasupconf%.conf}-${dev}.conf
  440. echo "}" >> ${_wpasupconf%.conf}-${dev}.conf
  441. else
  442. wpa_passphrase "$ssid" "$pass" >> ${_wpasupconf%.conf}-${dev}.conf
  443. fi
  444. configure_net_dhcp $dev
  445. return $?
  446. }
  447. configure_net() {
  448. local dev="$1" rval
  449. DIALOG --yesno "Do you want to use DHCP for $dev?" ${YESNOSIZE}
  450. rval=$?
  451. if [ $rval -eq 0 ]; then
  452. configure_net_dhcp $dev
  453. elif [ $rval -eq 1 ]; then
  454. configure_net_static $dev
  455. fi
  456. }
  457. iface_setup() {
  458. ip addr show dev $1|grep -q 'inet '
  459. return $?
  460. }
  461. configure_net_dhcp() {
  462. local dev="$1"
  463. iface_setup $dev
  464. if [ $? -eq 1 ]; then
  465. dhcpcd -t 10 -w -4 -L $dev -e "wpa_supplicant_conf=/etc/wpa_supplicant/wpa_supplicant-${dev}.conf" 2>&1 | tee $LOG | \
  466. DIALOG --progressbox "Initializing $dev via DHCP..." ${WIDGET_SIZE}
  467. if [ $? -ne 0 ]; then
  468. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} failed to run dhcpcd. See $LOG for details." ${MSGBOXSIZE}
  469. return 1
  470. fi
  471. iface_setup $dev
  472. if [ $? -eq 1 ]; then
  473. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} DHCP request failed for $dev. Check $LOG for errors." ${MSGBOXSIZE}
  474. return 1
  475. fi
  476. fi
  477. test_network
  478. if [ $? -eq 1 ]; then
  479. set_option NETWORK "${dev} dhcp"
  480. fi
  481. }
  482. configure_net_static() {
  483. local ip gw dns1 dns2 dev=$1
  484. DIALOG --form "Static IP configuration for $dev:" 0 0 0 \
  485. "IP address:" 1 1 "192.168.0.2" 1 21 20 0 \
  486. "Gateway:" 2 1 "192.168.0.1" 2 21 20 0 \
  487. "DNS Primary" 3 1 "8.8.8.8" 3 21 20 0 \
  488. "DNS Secondary" 4 1 "8.8.4.4" 4 21 20 0 || return 1
  489. set -- $(cat $ANSWER)
  490. ip=$1; gw=$2; dns1=$3; dns2=$4
  491. echo "running: ip link set dev $dev up" >$LOG
  492. ip link set dev $dev up >$LOG 2>&1
  493. if [ $? -ne 0 ]; then
  494. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} Failed to bring $dev interface." ${MSGBOXSIZE}
  495. return 1
  496. fi
  497. echo "running: ip addr add $ip dev $dev"
  498. ip addr add $ip dev $dev >$LOG 2>&1
  499. if [ $? -ne 0 ]; then
  500. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} Failed to set ip to the $dev interface." ${MSGBOXSIZE}
  501. return 1
  502. fi
  503. ip route add $gw dev $dev >$LOG 2>&1
  504. if [ $? -ne 0 ]; then
  505. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} failed to setup your gateway." ${MSGBOXSIZE}
  506. return 1
  507. fi
  508. echo "nameserver $dns1" >/etc/resolv.conf
  509. echo "nameserver $dns2" >>/etc/resolv.conf
  510. test_network
  511. if [ $? -eq 1 ]; then
  512. set_option NETWORK "${dev} static $ip $gw $dns1 $dns2"
  513. fi
  514. }
  515. menu_network() {
  516. local dev addr f DEVICES
  517. for f in $(ls /sys/class/net); do
  518. [ "$f" = "lo" ] && continue
  519. addr=$(cat /sys/class/net/$f/address)
  520. DEVICES="$DEVICES $f $addr"
  521. done
  522. DIALOG --title " Select the network interface to configure " \
  523. --menu "$MENULABEL" ${MENUSIZE} ${DEVICES}
  524. if [ $? -eq 0 ]; then
  525. dev=$(cat $ANSWER)
  526. if $(echo $dev|egrep -q "^wl.*" 2>/dev/null); then
  527. configure_wifi $dev
  528. else
  529. configure_net $dev
  530. fi
  531. fi
  532. }
  533. validate_filesystems() {
  534. local mnts dev size fstype mntpt mkfs rootfound swapfound fmt
  535. local usrfound efi_system_partition
  536. unset TARGETFS
  537. mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE)
  538. set -- ${mnts}
  539. while [ $# -ne 0 ]; do
  540. dev=$2; fstype=$3; size=$4; mntpt="$5"; mkfs=$6
  541. shift 6
  542. if [ "$mntpt" = "/" ]; then
  543. rootfound=1
  544. elif [ "$mntpt" = "/usr" ]; then
  545. usrfound=1
  546. elif [ "$fstype" = "vfat" -a "$mntpt" = "/boot/efi" ]; then
  547. efi_system_partition=1
  548. fi
  549. if [ "$mkfs" -eq 1 ]; then
  550. fmt="NEW FILESYSTEM: "
  551. fi
  552. if [ -z "$TARGETFS" ]; then
  553. TARGETFS="${fmt}$dev ($size) mounted on $mntpt as ${fstype}\n"
  554. else
  555. TARGETFS="${TARGETFS}${fmt}${dev} ($size) mounted on $mntpt as ${fstype}\n"
  556. fi
  557. done
  558. if [ -z "$rootfound" ]; then
  559. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  560. the mount point for the root filesystem (/) has not yet been configured." ${MSGBOXSIZE}
  561. return 1
  562. elif [ -n "$usrfound" ]; then
  563. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  564. /usr mount point has been configured but is not supported, please remove it to continue." ${MSGBOXSIZE}
  565. return 1
  566. elif [ -n "$EFI_SYSTEM" -a -z "$efi_system_partition" ]; then
  567. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  568. The EFI System Partition has not yet been configured, please create it\n
  569. as FAT32, mountpoint /boot/efi and at least with 100MB of size." ${MSGBOXSIZE}
  570. fi
  571. FILESYSTEMS_DONE=1
  572. }
  573. create_filesystems() {
  574. local mnts dev mntpt fstype mkfs size rv uuid
  575. mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE)
  576. set -- ${mnts}
  577. while [ $# -ne 0 ]; do
  578. dev=$2; fstype=$3; mntpt="$5"; mkfs=$6
  579. shift 6
  580. # swap partitions
  581. if [ "$fstype" = "swap" ]; then
  582. swapoff $dev >/dev/null 2>&1
  583. if [ "$mkfs" -eq 1 ]; then
  584. mkswap $dev >$LOG 2>&1
  585. if [ $? -ne 0 ]; then
  586. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  587. failed to create swap on ${dev}!\ncheck $LOG for errors." ${MSGBOXSIZE}
  588. DIE 1
  589. fi
  590. fi
  591. swapon $dev >$LOG 2>&1
  592. if [ $? -ne 0 ]; then
  593. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  594. failed to activate swap on $dev!\ncheck $LOG for errors." ${MSGBOXSIZE}
  595. DIE 1
  596. fi
  597. # Add entry for target fstab
  598. uuid=$(blkid -o value -s UUID "$dev")
  599. echo "UUID=$uuid none swap sw 0 0" >>$TARGET_FSTAB
  600. continue
  601. fi
  602. if [ "$mkfs" -eq 1 ]; then
  603. case "$fstype" in
  604. btrfs) MKFS="mkfs.btrfs -f"; modprobe btrfs >$LOG 2>&1;;
  605. ext2) MKFS="mke2fs"; modprobe ext2 >$LOG 2>&1;;
  606. ext3) MKFS="mke2fs -j"; modprobe ext3 >$LOG 2>&1;;
  607. ext4) MKFS="mke2fs -t ext4"; modprobe ext4 >$LOG 2>&1;;
  608. f2fs) MKFS="mkfs.f2fs"; modprobe f2fs >$LOG 2>&1;;
  609. vfat) MKFS="mkfs.vfat -F32"; modprobe vfat >$LOG 2>&1;;
  610. xfs) MKFS="mkfs.xfs -f"; modprobe xfs >$LOG 2>&1;;
  611. esac
  612. DIALOG --infobox "Creating filesystem $fstype on $dev for $mntpt ..." 8 60
  613. echo "Running $MKFS $dev..." >$LOG
  614. $MKFS $dev >$LOG 2>&1; rv=$?
  615. if [ $rv -ne 0 ]; then
  616. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  617. failed to create filesystem $fstype on $dev!\ncheck $LOG for errors." ${MSGBOXSIZE}
  618. DIE 1
  619. fi
  620. fi
  621. # Mount rootfs the first one.
  622. [ "$mntpt" != "/" ] && continue
  623. mkdir -p $TARGETDIR
  624. echo "Mounting $dev on $mntpt ($fstype)..." >$LOG
  625. mount -t $fstype $dev $TARGETDIR >$LOG 2>&1
  626. if [ $? -ne 0 ]; then
  627. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  628. failed to mount $dev on ${mntpt}! check $LOG for errors." ${MSGBOXSIZE}
  629. DIE 1
  630. fi
  631. # Add entry to target fstab
  632. uuid=$(blkid -o value -s UUID "$dev")
  633. echo "UUID=$uuid $mntpt $fstype defaults 0 1" >>$TARGET_FSTAB
  634. done
  635. # mount all filesystems in target rootfs
  636. mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE)
  637. set -- ${mnts}
  638. while [ $# -ne 0 ]; do
  639. dev=$2; fstype=$3; mntpt="$5"
  640. shift 6
  641. [ "$mntpt" = "/" -o "$fstype" = "swap" ] && continue
  642. mkdir -p ${TARGETDIR}${mntpt}
  643. echo "Mounting $dev on $mntpt ($fstype)..." >$LOG
  644. mount -t $fstype $dev ${TARGETDIR}${mntpt} >$LOG 2>&1
  645. if [ $? -ne 0 ]; then
  646. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  647. failed to mount $dev on $mntpt! check $LOG for errors." ${MSGBOXSIZE}
  648. DIE
  649. fi
  650. # Add entry to target fstab
  651. uuid=$(blkid -o value -s UUID "$dev")
  652. echo "UUID=$uuid $mntpt $fstype defaults 0 1" >>$TARGET_FSTAB
  653. done
  654. }
  655. mount_filesystems() {
  656. for f in sys proc dev; do
  657. [ ! -d $TARGETDIR/$f ] && mkdir $TARGETDIR/$f
  658. echo "Mounting $TARGETDIR/$f..." >$LOG
  659. mount --bind /$f $TARGETDIR/$f >$LOG 2>&1
  660. done
  661. }
  662. umount_filesystems() {
  663. local f
  664. for f in sys/fs/fuse/connections sys proc dev; do
  665. echo "Unmounting $TARGETDIR/$f..." >$LOG
  666. umount $TARGETDIR/$f >$LOG 2>&1
  667. done
  668. local mnts="$(grep -E '^MOUNTPOINT.*$' $CONF_FILE)"
  669. set -- ${mnts}
  670. while [ $# -ne 0 ]; do
  671. local dev=$2; local fstype=$3; local mntpt=$5
  672. shift 6
  673. if [ "$fstype" = "swap" ]; then
  674. echo "Disabling swap space on $dev..." >$LOG
  675. swapoff $dev >$LOG 2>&1
  676. continue
  677. fi
  678. if [ "$mntpt" != "/" ]; then
  679. echo "Unmounting $TARGETDIR/$mntpt..." >$LOG
  680. umount $TARGETDIR/$mntpt >$LOG 2>&1
  681. fi
  682. done
  683. echo "Unmounting $TARGETDIR..." >$LOG
  684. umount $TARGETDIR >$LOG 2>&1
  685. }
  686. copy_rootfs() {
  687. DIALOG --title "Check /dev/tty7 for details" \
  688. --infobox "Copying live image to target rootfs, please wait ..." 4 60
  689. LANG=C cp -axvnu / $TARGETDIR >$LOG 2>&1
  690. if [ $? -ne 0 ]; then
  691. DIE 1
  692. fi
  693. }
  694. install_packages() {
  695. local _grub=
  696. if [ -n "$EFI_SYSTEM" ]; then
  697. _grub="grub-x86_64-efi"
  698. else
  699. _grub="grub"
  700. fi
  701. mkdir -p $TARGETDIR/var/db/xbps/keys
  702. cp /var/db/xbps/keys/*.plist $TARGETDIR/var/db/xbps/keys
  703. mkdir -p $TARGETDIR/boot/grub
  704. stdbuf -oL xbps-install -r $TARGETDIR -Sy base-system ${_grub} 2>&1 | \
  705. DIALOG --title "Installing base system packages..." \
  706. --programbox 24 80
  707. if [ $? -ne 0 ]; then
  708. DIE 1
  709. fi
  710. }
  711. enable_dhcpd() {
  712. if [ -x "/usr/bin/systemctl" ]; then
  713. chroot $TARGETDIR systemctl enable dhcpcd.service >$LOG 2>&1
  714. else
  715. ln -s /etc/sv/dhcpcd $TARGETDIR/etc/runit/runsvdir/default/dhcpcd
  716. fi
  717. }
  718. menu_install() {
  719. # Don't continue if filesystems are not ready.
  720. validate_filesystems || return 1
  721. ROOTPASSWORD_DONE="$(get_option ROOTPASSWORD)"
  722. BOOTLOADER_DONE="$(get_option BOOTLOADER)"
  723. if [ -z "$FILESYSTEMS_DONE" ]; then
  724. DIALOG --msgbox "${BOLD}Required filesystems were not configured, \
  725. please do so before starting the installation.${RESET}" ${MSGBOXSIZE}
  726. return 1
  727. elif [ -z "$ROOTPASSWORD_DONE" ]; then
  728. DIALOG --msgbox "${BOLD}The root password has not been configured, \
  729. please do so before starting the installation.${RESET}" ${MSGBOXSIZE}
  730. return 1
  731. elif [ -z "$BOOTLOADER_DONE" ]; then
  732. DIALOG --msgbox "${BOLD}The disk to install the bootloader has not been \
  733. configured, please do so before starting the installation.${RESET}" ${MSGBOXSIZE}
  734. return 1
  735. fi
  736. DIALOG --yesno "${BOLD}The following operations will be executed:${RESET}\n\n
  737. ${BOLD}${TARGETFS}${RESET}\n
  738. ${BOLD}${RED}WARNING: data on partitions will be COMPLETELY DESTROYED for new \
  739. filesystems.${RESET}\n\n
  740. ${BOLD}Do you want to continue?${RESET}" 20 80 || return
  741. unset TARGETFS
  742. # Create and mount filesystems
  743. create_filesystems
  744. # If source not set use defaults.
  745. if [ "$(get_option SOURCE)" = "local" -o -z "$SOURCE_DONE" ]; then
  746. copy_rootfs
  747. # Disable autologin and remove motd from live image.
  748. rm -f $TARGETDIR/etc/motd $TARGETDIR/etc/systemd/system/[email protected]
  749. # Remove live user.
  750. . /etc/default/live.conf
  751. echo "Removing $USERNAME live user from targetdir ..." >$LOG
  752. chroot $TARGETDIR userdel -r $USERNAME >$LOG 2>&1
  753. DIALOG --title "Check /dev/tty7 for details" \
  754. --infobox "Rebuilding initramfs for target ..." 4 60
  755. echo "Rebuilding initramfs for target ..." >$LOG
  756. chroot $TARGETDIR dracut --force >>$LOG 2>&1
  757. DIALOG --title "Check /dev/tty7 for details" \
  758. --infobox "Removing temporary packages from target ..." 4 60
  759. echo "Removing temporaray packages from target ..." >$LOG
  760. xbps-remove -r $TARGETDIR -Ry dialog >>$LOG 2>&1
  761. rmdir $TARGETDIR/mnt/target
  762. # mount required fs
  763. mount_filesystems
  764. else
  765. # mount required fs
  766. mount_filesystems
  767. # network install, use packages.
  768. install_packages
  769. fi
  770. DIALOG --infobox "Applying installer settings..." 4 60
  771. # copy target fstab.
  772. install -Dm644 $TARGET_FSTAB $TARGETDIR/etc/fstab
  773. # set up keymap, locale, timezone, hostname and root passwd.
  774. set_keymap
  775. set_locale
  776. set_timezone
  777. set_hostname
  778. set_rootpassword
  779. # Copy /etc/skel files for root.
  780. cp $TARGETDIR/etc/skel/.[bix]* $TARGETDIR/root
  781. # network settings for target
  782. if [ -n "$NETWORK_DONE" ]; then
  783. local net="$(get_option NETWORK)"
  784. set -- ${net}
  785. local _dev="$1" _type="$2" _ip="$3" _gw="$4" _dns1="$5" _dns2="$6"
  786. if [ -z "$_type" ]; then
  787. # network type empty??!!!
  788. :
  789. elif [ "$_type" = "dhcp" ]; then
  790. if [ -f /etc/wpa_supplicant/wpa_supplicant-${_dev}.conf ]; then
  791. cp /etc/wpa_supplicant/wpa_supplicant-${_dev}.conf $TARGETDIR/etc/wpa_supplicant
  792. if [ -x "/usr/bin/systemctl" ]; then
  793. chroot $TARGETDIR systemctl enable dhcpcd@${_dev}.service >$LOG 2>&1
  794. else
  795. ln -s /etc/sv/dhcpcd-${_dev} $TARGETDIR/etc/runit/runsvdir/default/dhcpcd-${_dev}
  796. fi
  797. else
  798. enable_dhcpd
  799. fi
  800. elif [ -n "$dev" -a -n "$type" = "static" ]; then
  801. # static IP through dhcpcd.
  802. mv $TARGETDIR/etc/dhcpcd.conf $TARGETDIR/etc/dhdpcd.conf.orig
  803. echo "# Static IP configuration set by the void-installer for $_dev." \
  804. >$TARGETDIR/etc/dhcpcd.conf
  805. echo "interface $_dev" >>$TARGETDIR/etc/dhcpcd.conf
  806. echo "static ip_address=$_ip" >>$TARGETDIR/etc/dhcpcd.conf
  807. echo "static routers=$_gw" >>$TARGETDIR/etc/dhcpcd.conf
  808. echo "static domain_name_servers=$_dns1 $_dns2" >>$TARGETDIR/etc/dhcpcd.conf
  809. enable_dhcpd
  810. fi
  811. fi
  812. # install bootloader.
  813. set_bootloader
  814. sync && sync && sync
  815. # unmount all filesystems.
  816. umount_filesystems
  817. # installed successfully.
  818. DIALOG --yesno "${BOLD}Void Linux has been installed successfully!${RESET}\n
  819. Do you want to reboot the system?" ${YESNOSIZE}
  820. if [ $? -eq 0 ]; then
  821. shutdown -r now
  822. else
  823. return
  824. fi
  825. }
  826. menu_source() {
  827. local src=
  828. DIALOG --title " Select installation source " \
  829. --menu "$MENULABEL" 8 70 0 \
  830. "Local" "Packages from ISO image" \
  831. "Network" "Packages from official remote reposity"
  832. case "$(cat $ANSWER)" in
  833. "Local") src="local";;
  834. "Network") src="net"; menu_network;;
  835. *) return 1;;
  836. esac
  837. SOURCE_DONE=1
  838. set_option SOURCE $src
  839. }
  840. menu() {
  841. if [ -z "$DEFITEM" ]; then
  842. DEFITEM="Keyboard"
  843. fi
  844. DIALOG --default-item $DEFITEM \
  845. --extra-button --extra-label "Settings" \
  846. --title " Void Linux installation menu " \
  847. --menu "$MENULABEL" 10 70 0 \
  848. "Keyboard" "Set system keyboard" \
  849. "Network" "Set up the network" \
  850. "Source" "Set source installation" \
  851. "Hostname" "Set system hostname" \
  852. "Locale" "Set system locale" \
  853. "Timezone" "Set system time zone" \
  854. "RootPassword" "Set system root password" \
  855. "BootLoader" "Set disk to install bootloader" \
  856. "Partition" "Partition disk(s)" \
  857. "Filesystems" "Configure filesystems and mount points" \
  858. "Install" "Start installation with saved settings" \
  859. "Exit" "Exit installation"
  860. if [ $? -eq 3 ]; then
  861. # Show settings
  862. cp $CONF_FILE /tmp/conf_hidden.$$;
  863. sed -i "s/^ROOTPASSWORD.*/ROOTPASSWORD <-hidden->/" /tmp/conf_hidden.$$
  864. DIALOG --title "Saved settings for installation" --textbox /tmp/conf_hidden.$$ 14 60
  865. rm /tmp/conf_hidden.$$
  866. return
  867. fi
  868. case $(cat $ANSWER) in
  869. "Keyboard") menu_keymap && [ -n "$KEYBOARD_DONE" ] && DEFITEM="Network";;
  870. "Network") menu_network && [ -n "$NETWORK_DONE" ] && DEFITEM="Source";;
  871. "Source") menu_source && [ -n "$SOURCE_DONE" ] && DEFITEM="Hostname";;
  872. "Hostname") menu_hostname && [ -n "$HOSTNAME_DONE" ] && DEFITEM="Locale";;
  873. "Locale") menu_locale && [ -n "$LOCALE_DONE" ] && DEFITEM="Timezone";;
  874. "Timezone") menu_timezone && [ -n "$TIMEZONE_DONE" ] && DEFITEM="RootPassword";;
  875. "RootPassword") menu_rootpassword && [ -n "$ROOTPASSWORD_DONE" ] && DEFITEM="BootLoader";;
  876. "BootLoader") menu_bootloader && [ -n "$BOOTLOADER_DONE" ] && DEFITEM="Partition";;
  877. "Partition") menu_partitions && [ -n "$PARTITIONS_DONE" ] && DEFITEM="Filesystems";;
  878. "Filesystems") menu_filesystems && [ -n "$FILESYSTEMS_DONE" ] && DEFITEM="Install";;
  879. "Install") menu_install;;
  880. "Exit") DIE;;
  881. *) DIALOG --yesno "Abort Installation?" ${YESNOSIZE} && DIE
  882. esac
  883. }
  884. #
  885. # main()
  886. #
  887. DIALOG --title "${BOLD}${RED} Enter the void ... ${RESET}" --msgbox "\n
  888. Welcome to the Void Linux installation. A simple and minimal \
  889. Linux distribution made from scratch and built from the source package tree \
  890. available for XBPS, a new alternative binary package system.\n\n
  891. The installation should be pretty straightforward, if you are in trouble \
  892. please join us at ${BOLD}#xbps on irc.freenode.org${RESET}.\n\n
  893. ${BOLD}http://www.voidlinux.eu${RESET}\n\n" 16 80
  894. while true; do
  895. menu
  896. done
  897. exit 0
  898. # vim: set ts=4 sw=4 et: