installer.sh.in 33 KB

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