installer.sh.in 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. #!/bin/bash
  2. #-
  3. # Copyright (c) 2012-2015 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. USERLOGIN_DONE=
  35. USERPASSWORD_DONE=
  36. USERNAME_DONE=
  37. USERGROUPS_DONE=
  38. BOOTLOADER_DONE=
  39. PARTITIONS_DONE=
  40. NETWORK_DONE=
  41. FILESYSTEMS_DONE=
  42. TARGETDIR=/mnt/target
  43. LOG=/dev/tty8
  44. CONF_FILE=/tmp/.void-installer.conf
  45. if [ ! -f $CONF_FILE ]; then
  46. touch -f $CONF_FILE
  47. fi
  48. ANSWER=$(mktemp -t vinstall-XXXXXXXX || exit 1)
  49. TARGET_FSTAB=$(mktemp -t vinstall-fstab-XXXXXXXX || exit 1)
  50. trap "DIE" INT TERM QUIT
  51. # disable printk
  52. if [ -w /proc/sys/kernel/printk ]; then
  53. echo 0 >/proc/sys/kernel/printk
  54. fi
  55. # Detect if this is an EFI system.
  56. if [ -e /sys/firmware/efi/systab ]; then
  57. EFI_SYSTEM=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. INFOBOX() {
  88. # Note: dialog --infobox and --keep-tite don't work together
  89. dialog --colors --no-shadow --no-mouse \
  90. --backtitle "${BOLD}${WHITE}Void Linux installation -- http://www.voidlinux.eu/ (@@MKLIVE_VERSION@@)${RESET}" \
  91. --title "${TITLE}" --aspect 20 --infobox "$@"
  92. }
  93. DIE() {
  94. rval=$1
  95. [ -z "$rval" ] && rval=0
  96. clear
  97. rm -f $ANSWER $TARGET_FSTAB
  98. # reenable printk
  99. if [ -w /proc/sys/kernel/printk ]; then
  100. echo 4 >/proc/sys/kernel/printk
  101. fi
  102. umount_filesystems
  103. exit $rval
  104. }
  105. set_option() {
  106. if grep -Eq "^${1}.*" $CONF_FILE; then
  107. sed -i -e "/^${1}.*/d" $CONF_FILE
  108. fi
  109. echo "${1} ${2}" >>$CONF_FILE
  110. }
  111. get_option() {
  112. echo $(grep -E "^${1}.*" $CONF_FILE|sed -e "s|${1}||")
  113. }
  114. # ISO-639 language names for locales
  115. iso639_language() {
  116. case "$1" in
  117. aa) echo "Afar" ;;
  118. af) echo "Afrikaans" ;;
  119. an) echo "Aragonese" ;;
  120. ar) echo "Arabic" ;;
  121. ast) echo "Asturian" ;;
  122. be) echo "Belgian" ;;
  123. bg) echo "Bulgarian" ;;
  124. bhb) echo "Bhili" ;;
  125. br) echo "Breton" ;;
  126. bs) echo "Bosnian" ;;
  127. ca) echo "Catalan" ;;
  128. cs) echo "Czech" ;;
  129. cy) echo "Welsh" ;;
  130. da) echo "Danish" ;;
  131. de) echo "German" ;;
  132. el) echo "Greek" ;;
  133. en) echo "English" ;;
  134. es) echo "Spanish" ;;
  135. et) echo "Estonian" ;;
  136. eu) echo "Basque" ;;
  137. fi) echo "Finnish" ;;
  138. fo) echo "Faroese" ;;
  139. fr) echo "French" ;;
  140. ga) echo "Irish" ;;
  141. gd) echo "Scottish Gaelic" ;;
  142. gl) echo "Galician" ;;
  143. gv) echo "Manx" ;;
  144. he) echo "Hebrew" ;;
  145. hr) echo "Croatian" ;;
  146. hsb) echo "Upper Sorbian" ;;
  147. hu) echo "Hungarian" ;;
  148. id) echo "Indonesian" ;;
  149. is) echo "Icelandic" ;;
  150. it) echo "Italian" ;;
  151. iw) echo "Hebrew" ;;
  152. ja) echo "Japanese" ;;
  153. ka) echo "Georgian" ;;
  154. kk) echo "Kazakh" ;;
  155. kl) echo "Kalaallisut" ;;
  156. ko) echo "Korean" ;;
  157. ku) echo "Kurdish" ;;
  158. kw) echo "Cornish" ;;
  159. lg) echo "Ganda" ;;
  160. lt) echo "Lithuanian" ;;
  161. lv) echo "Latvian" ;;
  162. mg) echo "Malagasy" ;;
  163. mi) echo "Maori" ;;
  164. mk) echo "Macedonian" ;;
  165. ms) echo "Malay" ;;
  166. mt) echo "Maltese" ;;
  167. nb) echo "Norwegian Bokmål" ;;
  168. nl) echo "Dutch" ;;
  169. nn) echo "Norwegian Nynorsk" ;;
  170. oc) echo "Occitan" ;;
  171. om) echo "Oromo" ;;
  172. pl) echo "Polish" ;;
  173. pt) echo "Portugese" ;;
  174. ro) echo "Romanian" ;;
  175. ru) echo "Russian" ;;
  176. sk) echo "Slovak" ;;
  177. sl) echo "Slovenian" ;;
  178. so) echo "Somali" ;;
  179. sq) echo "Albanian" ;;
  180. st) echo "Southern Sotho" ;;
  181. sv) echo "Swedish" ;;
  182. tcy) echo "Tulu" ;;
  183. tg) echo "Tajik" ;;
  184. th) echo "Thai" ;;
  185. tl) echo "Tagalog" ;;
  186. tr) echo "Turkish" ;;
  187. uk) echo "Ukrainian" ;;
  188. uz) echo "Uzbek" ;;
  189. wa) echo "Walloon" ;;
  190. xh) echo "Xhosa" ;;
  191. yi) echo "Yiddish" ;;
  192. zh) echo "Chinese" ;;
  193. zu) echo "Zulu" ;;
  194. *) echo "$1" ;;
  195. esac
  196. }
  197. # ISO-3166 country codes for locales
  198. iso3166_country() {
  199. case "$1" in
  200. AD) echo "Andorra" ;;
  201. AE) echo "United Arab Emirates" ;;
  202. AL) echo "Albania" ;;
  203. AR) echo "Argentina" ;;
  204. AT) echo "Austria" ;;
  205. AU) echo "Australia" ;;
  206. BA) echo "Bonsia and Herzegovina" ;;
  207. BE) echo "Belgium" ;;
  208. BG) echo "Bulgaria" ;;
  209. BH) echo "Bahrain" ;;
  210. BO) echo "Bolivia" ;;
  211. BR) echo "Brazil" ;;
  212. BW) echo "Botswana" ;;
  213. BY) echo "Belarus" ;;
  214. CA) echo "Canada" ;;
  215. CH) echo "Switzerland" ;;
  216. CL) echo "Chile" ;;
  217. CN) echo "China" ;;
  218. CO) echo "Colombia" ;;
  219. CR) echo "Costa Rica" ;;
  220. CY) echo "Cyprus" ;;
  221. CZ) echo "Czech Republic" ;;
  222. DE) echo "Germany" ;;
  223. DJ) echo "Djibouti" ;;
  224. DK) echo "Denmark" ;;
  225. DO) echo "Dominican Republic" ;;
  226. DZ) echo "Algeria" ;;
  227. EC) echo "Ecuador" ;;
  228. EE) echo "Estonia" ;;
  229. EG) echo "Egypt" ;;
  230. ES) echo "Spain" ;;
  231. FI) echo "Finland" ;;
  232. FO) echo "Faroe Islands" ;;
  233. FR) echo "France" ;;
  234. GB) echo "Great Britain" ;;
  235. GE) echo "Georgia" ;;
  236. GL) echo "Greenland" ;;
  237. GR) echo "Greece" ;;
  238. GT) echo "Guatemala" ;;
  239. HK) echo "Hong Kong" ;;
  240. HN) echo "Honduras" ;;
  241. HR) echo "Croatia" ;;
  242. HU) echo "Hungary" ;;
  243. ID) echo "Indonesia" ;;
  244. IE) echo "Ireland" ;;
  245. IL) echo "Israel" ;;
  246. IN) echo "India" ;;
  247. IQ) echo "Iraq" ;;
  248. IS) echo "Iceland" ;;
  249. IT) echo "Italy" ;;
  250. JO) echo "Jordan" ;;
  251. JP) echo "Japan" ;;
  252. KE) echo "Kenya" ;;
  253. KR) echo "Korea, Republic of" ;;
  254. KW) echo "Kuwait" ;;
  255. KZ) echo "Kazakhstan" ;;
  256. LB) echo "Lebanon" ;;
  257. LT) echo "Lithuania" ;;
  258. LU) echo "Luxembourg" ;;
  259. LV) echo "Latvia" ;;
  260. LY) echo "Libya" ;;
  261. MA) echo "Morocco" ;;
  262. MG) echo "Madagascar" ;;
  263. MK) echo "Macedonia" ;;
  264. MT) echo "Malta" ;;
  265. MX) echo "Mexico" ;;
  266. MY) echo "Malaysia" ;;
  267. NI) echo "Nicaragua" ;;
  268. NL) echo "Netherlands" ;;
  269. NO) echo "Norway" ;;
  270. NZ) echo "New Zealand" ;;
  271. OM) echo "Oman" ;;
  272. PA) echo "Panama" ;;
  273. PE) echo "Peru" ;;
  274. PH) echo "Philippines" ;;
  275. PL) echo "Poland" ;;
  276. PR) echo "Puerto Rico" ;;
  277. PT) echo "Portugal" ;;
  278. PY) echo "Paraguay" ;;
  279. QA) echo "Qatar" ;;
  280. RO) echo "Romania" ;;
  281. RU) echo "Russian Federation" ;;
  282. SA) echo "Saudi Arabia" ;;
  283. SD) echo "Sudan" ;;
  284. SE) echo "Sweden" ;;
  285. SG) echo "Singapore" ;;
  286. SI) echo "Slovenia" ;;
  287. SK) echo "Slovakia" ;;
  288. SO) echo "Somalia" ;;
  289. SV) echo "El Salvador" ;;
  290. SY) echo "Syria" ;;
  291. TH) echo "Thailand" ;;
  292. TJ) echo "Tajikistan" ;;
  293. TN) echo "Tunisia" ;;
  294. TR) echo "Turkey" ;;
  295. TW) echo "Taiwan" ;;
  296. UA) echo "Ukraine" ;;
  297. UG) echo "Uganda" ;;
  298. US) echo "United States of America" ;;
  299. UY) echo "Uruguay" ;;
  300. UZ) echo "Uzbekistan" ;;
  301. VE) echo "Venezuela" ;;
  302. YE) echo "Yemen" ;;
  303. ZA) echo "South Africa" ;;
  304. ZW) echo "Zimbabwe" ;;
  305. *) echo "$1" ;;
  306. esac
  307. }
  308. show_disks() {
  309. local dev size sectorsize gbytes
  310. # IDE
  311. for dev in $(ls /sys/block|grep -E '^hd'); do
  312. if [ "$(cat /sys/block/$dev/device/media)" = "disk" ]; then
  313. # Find out nr sectors and bytes per sector;
  314. echo "/dev/$dev"
  315. size=$(cat /sys/block/$dev/size)
  316. sectorsize=$(cat /sys/block/$dev/queue/hw_sector_size)
  317. gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))"
  318. echo "size:${gbytes}GB;sector_size:$sectorsize"
  319. fi
  320. done
  321. # SATA/SCSI and Virtual disks (virtio)
  322. for dev in $(ls /sys/block|grep -E '^([sv]|xv)d|mmcblk|nvme'); do
  323. echo "/dev/$dev"
  324. size=$(cat /sys/block/$dev/size)
  325. sectorsize=$(cat /sys/block/$dev/queue/hw_sector_size)
  326. gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))"
  327. echo "size:${gbytes}GB;sector_size:$sectorsize"
  328. done
  329. # cciss(4) devices
  330. for dev in $(ls /dev/cciss 2>/dev/null|grep -E 'c[0-9]d[0-9]$'); do
  331. echo "/dev/cciss/$dev"
  332. size=$(cat /sys/block/cciss\!$dev/size)
  333. sectorsize=$(cat /sys/block/cciss\!$dev/queue/hw_sector_size)
  334. gbytes="$(($size * $sectorsize / 1024 / 1024 / 1024))"
  335. echo "size:${gbytes}GB;sector_size:$sectorsize"
  336. done
  337. }
  338. show_partitions() {
  339. local dev fstype fssize p part
  340. set -- $(show_disks)
  341. while [ $# -ne 0 ]; do
  342. disk=$(basename $1)
  343. shift 2
  344. # ATA/SCSI/SATA
  345. for p in /sys/block/$disk/$disk*; do
  346. if [ -d $p ]; then
  347. part=$(basename $p)
  348. fstype=$(lsblk -nfr /dev/$part|awk '{print $2}'|head -1)
  349. [ "$fstype" = "iso9660" ] && continue
  350. [ "$fstype" = "crypto_LUKS" ] && continue
  351. [ "$fstype" = "LVM2_member" ] && continue
  352. fssize=$(lsblk -nr /dev/$part|awk '{print $4}'|head -1)
  353. echo "/dev/$part"
  354. echo "size:${fssize:-unknown};fstype:${fstype:-none}"
  355. fi
  356. done
  357. done
  358. # Software raid (md)
  359. for p in $(ls -d /dev/md* 2>/dev/null|grep '[0-9]'); do
  360. part=$(basename $p)
  361. if cat /proc/mdstat|grep -qw $part; then
  362. fstype=$(lsblk -nfr /dev/$part|awk '{print $2}')
  363. [ "$fstype" = "crypto_LUKS" ] && continue
  364. [ "$fstype" = "LVM2_member" ] && continue
  365. fssize=$(lsblk -nr /dev/$part|awk '{print $4}')
  366. echo "$p"
  367. echo "size:${fssize:-unknown};fstype:${fstype:-none}"
  368. fi
  369. done
  370. # cciss(4) devices
  371. for part in $(ls /dev/cciss 2>/dev/null|grep -E 'c[0-9]d[0-9]p[0-9]+'); do
  372. fstype=$(lsblk -nfr /dev/cciss/$part|awk '{print $2}')
  373. [ "$fstype" = "crypto_LUKS" ] && continue
  374. [ "$fstype" = "LVM2_member" ] && continue
  375. fssize=$(lsblk -nr /dev/cciss/$part|awk '{print $4}')
  376. echo "/dev/cciss/$part"
  377. echo "size:${fssize:-unknown};fstype:${fstype:-none}"
  378. done
  379. if [ -e /sbin/lvs ]; then
  380. # LVM
  381. lvs --noheadings|while read lvname vgname perms size; do
  382. echo "/dev/mapper/${vgname}-${lvname}"
  383. echo "size:${size};fstype:lvm"
  384. done
  385. fi
  386. }
  387. menu_filesystems() {
  388. local dev fstype fssize mntpoint reformat
  389. while true; do
  390. DIALOG --title " Select the partition to edit " --menu "$MENULABEL" \
  391. ${MENUSIZE} $(show_partitions)
  392. [ $? -ne 0 ] && return
  393. dev=$(cat $ANSWER)
  394. DIALOG --title " Select the filesystem type for $dev " \
  395. --menu "$MENULABEL" ${MENUSIZE} \
  396. "btrfs" "Oracle's Btrfs" \
  397. "ext2" "Linux ext2 (no journaling)" \
  398. "ext3" "Linux ext3 (journal)" \
  399. "ext4" "Linux ext4 (journal)" \
  400. "f2fs" "Flash-Friendly Filesystem" \
  401. "swap" "Linux swap" \
  402. "vfat" "FAT32" \
  403. "xfs" "SGI's XFS"
  404. if [ $? -eq 0 ]; then
  405. fstype=$(cat $ANSWER)
  406. else
  407. continue
  408. fi
  409. if [ "$fstype" != "swap" ]; then
  410. DIALOG --inputbox "Please specify the mount point for $dev:" ${INPUTSIZE}
  411. if [ $? -eq 0 ]; then
  412. mntpoint=$(cat $ANSWER)
  413. elif [ $? -eq 1 ]; then
  414. continue
  415. fi
  416. else
  417. mntpoint=swap
  418. fi
  419. DIALOG --yesno "Do you want to create a new filesystem on $dev?" ${YESNOSIZE}
  420. if [ $? -eq 0 ]; then
  421. reformat=1
  422. elif [ $? -eq 1 ]; then
  423. reformat=0
  424. else
  425. continue
  426. fi
  427. fssize=$(lsblk -nr $dev|awk '{print $4}')
  428. set -- "$fstype" "$fssize" "$mntpoint" "$reformat"
  429. if [ -n "$1" -a -n "$2" -a -n "$3" -a -n "$4" ]; then
  430. local bdev=$(basename $dev)
  431. local ddev=$(basename $(dirname $dev))
  432. if [ "$ddev" != "dev" ]; then
  433. sed -i -e "/^MOUNTPOINT \/dev\/${ddev}\/${bdev}.*/d" $CONF_FILE
  434. else
  435. sed -i -e "/^MOUNTPOINT \/dev\/${bdev}.*/d" $CONF_FILE
  436. fi
  437. echo "MOUNTPOINT $dev $1 $2 $3 $4" >>$CONF_FILE
  438. fi
  439. done
  440. }
  441. menu_partitions() {
  442. DIALOG --title " Select the disk to partition " \
  443. --menu "$MENULABEL" ${MENUSIZE} $(show_disks)
  444. if [ $? -eq 0 ]; then
  445. local device=$(cat $ANSWER)
  446. DIALOG --title "Modify Partition Table on $device" --msgbox "\n
  447. ${BOLD}cfdisk will be executed in disk $device.${RESET}\n\n
  448. For BIOS systems, MBR or GPT partition tables are supported.\n
  449. To use GPT on PC BIOS systems an empty partition of 1MB must be added\n
  450. at the first 2GB of the disk with the TOGGLE \`bios_grub' enabled.\n
  451. ${BOLD}NOTE: you don't need this on EFI systems.${RESET}\n\n
  452. For EFI systems GPT is mandatory and a FAT32 partition with at least\n
  453. 100MB must be created with the TOGGLE \`boot', this will be used as\n
  454. EFI System Partition. This partition must have mountpoint as \`/boot/efi'.\n\n
  455. At least 1 partitions is required for the rootfs (/).\n
  456. For swap, RAM*2 must be really enough. For / 600MB are required.\n\n
  457. ${BOLD}WARNING: /usr is not supported as a separate partition.${RESET}\n
  458. ${RESET}\n" 18 80
  459. if [ $? -eq 0 ]; then
  460. while true; do
  461. clear; cfdisk $device; PARTITIONS_DONE=1
  462. break
  463. done
  464. else
  465. return
  466. fi
  467. fi
  468. }
  469. menu_keymap() {
  470. local _keymaps="$(find /usr/share/kbd/keymaps/ -type f -iname "*.map.gz" -printf "%f\n" | sed 's|.map.gz||g' | sort)"
  471. local _KEYMAPS=
  472. for f in ${_keymaps}; do
  473. _KEYMAPS="${_KEYMAPS} ${f} -"
  474. done
  475. while true; do
  476. DIALOG --title " Select your keymap " --menu "$MENULABEL" 14 70 14 ${_KEYMAPS}
  477. if [ $? -eq 0 ]; then
  478. set_option KEYMAP "$(cat $ANSWER)"
  479. loadkeys "$(cat $ANSWER)"
  480. KEYBOARD_DONE=1
  481. break
  482. else
  483. return
  484. fi
  485. done
  486. }
  487. set_keymap() {
  488. local KEYMAP=$(get_option KEYMAP)
  489. if [ -f /etc/vconsole.conf ]; then
  490. sed -i -e "s|KEYMAP=.*|KEYMAP=$KEYMAP|g" $TARGETDIR/etc/vconsole.conf
  491. else
  492. sed -i -e "s|#\?KEYMAP=.*|KEYMAP=$KEYMAP|g" $TARGETDIR/etc/rc.conf
  493. fi
  494. }
  495. menu_locale() {
  496. local _locales="$(grep -E '\.UTF-8' /etc/default/libc-locales|awk '{print $1}'|sed -e 's/^#//')"
  497. local LOCALES ISO639 ISO3166
  498. local TMPFILE=$(mktemp -t vinstall-XXXXXXXX || exit 1)
  499. INFOBOX "Scanning locales ..." 4 60
  500. for f in ${_locales}; do
  501. eval $(echo $f | awk 'BEGIN { FS="." } \
  502. { FS="_"; split($1, a); printf "ISO639=%s ISO3166=%s\n", a[1], a[2] }')
  503. echo "$f|$(iso639_language $ISO639) ($(iso3166_country $ISO3166))|" >> $TMPFILE
  504. done
  505. clear
  506. # Sort by ISO-639 language names
  507. LOCALES=$(sort -t '|' -k 2 < $TMPFILE | xargs | sed -e's/| /|/g')
  508. rm -f $TMPFILE
  509. while true; do
  510. (IFS="|"; DIALOG --title " Select your locale " --menu "$MENULABEL" 18 70 18 ${LOCALES})
  511. if [ $? -eq 0 ]; then
  512. set_option LOCALE "$(cat $ANSWER)"
  513. LOCALE_DONE=1
  514. break
  515. else
  516. return
  517. fi
  518. done
  519. }
  520. set_locale() {
  521. if [ -f $TARGETDIR/etc/default/libc-locales ]; then
  522. local LOCALE=$(get_option LOCALE)
  523. sed -i -e "s|LANG=.*|LANG=$LOCALE|g" $TARGETDIR/etc/locale.conf
  524. # Uncomment locale from /etc/default/libc-locales and regenerate it.
  525. sed -e "/${LOCALE}/s/^\#//" -i $TARGETDIR/etc/default/libc-locales
  526. echo "Running xbps-reconfigure -f glibc-locales ..." >$LOG
  527. chroot $TARGETDIR xbps-reconfigure -f glibc-locales >$LOG 2>&1
  528. fi
  529. }
  530. menu_timezone() {
  531. local _tzones="$(cd /usr/share/zoneinfo; find Africa/ America/ Antarctica/ Arctic/ Asia/ Atlantic/ Australia/ Europe/ Indian/ Pacific/ posix/ -type f | sort)"
  532. local _TIMEZONES=
  533. for f in ${_tzones}; do
  534. _TIMEZONES="${_TIMEZONES} ${f} -"
  535. done
  536. while true; do
  537. DIALOG --title " Select your timezone " --menu "$MENULABEL" 14 70 14 ${_TIMEZONES}
  538. if [ $? -eq 0 ]; then
  539. set_option TIMEZONE "$(cat $ANSWER)"
  540. TIMEZONE_DONE=1
  541. break
  542. else
  543. return
  544. fi
  545. done
  546. }
  547. set_timezone() {
  548. local TIMEZONE="$(get_option TIMEZONE)"
  549. sed -i -e "s|#TIMEZONE=.*|TIMEZONE=$TIMEZONE|g" $TARGETDIR/etc/rc.conf
  550. }
  551. menu_hostname() {
  552. while true; do
  553. DIALOG --inputbox "Set the machine hostname:" ${INPUTSIZE}
  554. if [ $? -eq 0 ]; then
  555. set_option HOSTNAME "$(cat $ANSWER)"
  556. HOSTNAME_DONE=1
  557. break
  558. else
  559. return
  560. fi
  561. done
  562. }
  563. set_hostname() {
  564. echo $(get_option HOSTNAME) > $TARGETDIR/etc/hostname
  565. }
  566. menu_rootpassword() {
  567. local _firstpass _secondpass _desc
  568. while true; do
  569. if [ -z "${_firstpass}" ]; then
  570. _desc="Enter the root password"
  571. else
  572. _desc="$_desc again"
  573. fi
  574. DIALOG --insecure --passwordbox "${_desc}" ${INPUTSIZE}
  575. if [ $? -eq 0 ]; then
  576. if [ -z "${_firstpass}" ]; then
  577. _firstpass="$(cat $ANSWER)"
  578. else
  579. _secondpass="$(cat $ANSWER)"
  580. fi
  581. if [ -n "${_firstpass}" -a -n "${_secondpass}" ]; then
  582. if [ "${_firstpass}" != "${_secondpass}" ]; then
  583. INFOBOX "Passwords do not match! Please enter again." 6 60
  584. unset _firstpass _secondpass
  585. sleep 2 && clear && continue
  586. fi
  587. set_option ROOTPASSWORD "${_firstpass}"
  588. ROOTPASSWORD_DONE=1
  589. break
  590. fi
  591. else
  592. return
  593. fi
  594. done
  595. }
  596. set_rootpassword() {
  597. echo "root:$(get_option ROOTPASSWORD)" | chpasswd -R $TARGETDIR -c SHA512
  598. }
  599. menu_useraccount() {
  600. local _firstpass _secondpass _desc
  601. local _groups _status _group _checklist
  602. local _preset
  603. while true; do
  604. _preset=$(get_option USERLOGIN)
  605. [ -z "$_preset" ] && _preset="void"
  606. DIALOG --inputbox "Enter a primary login name:" ${INPUTSIZE} "$_preset"
  607. if [ $? -eq 0 ]; then
  608. set_option USERLOGIN "$(cat $ANSWER)"
  609. USERLOGIN_DONE=1
  610. break
  611. else
  612. return
  613. fi
  614. done
  615. while true; do
  616. _preset=$(get_option USERNAME)
  617. [ -z "$_preset" ] && _preset="Void User"
  618. DIALOG --inputbox "Enter a user name for login '$(get_option USERLOGIN)' :" \
  619. ${INPUTSIZE} "$_preset"
  620. if [ $? -eq 0 ]; then
  621. set_option USERNAME "$(cat $ANSWER)"
  622. USERNAME_DONE=1
  623. break
  624. else
  625. return
  626. fi
  627. done
  628. while true; do
  629. if [ -z "${_firstpass}" ]; then
  630. _desc="Enter the password for login '$(get_option USERLOGIN)'"
  631. else
  632. _desc="$_desc again"
  633. fi
  634. DIALOG --insecure --passwordbox "${_desc}" ${INPUTSIZE}
  635. if [ $? -eq 0 ]; then
  636. if [ -z "${_firstpass}" ]; then
  637. _firstpass="$(cat $ANSWER)"
  638. else
  639. _secondpass="$(cat $ANSWER)"
  640. fi
  641. if [ -n "${_firstpass}" -a -n "${_secondpass}" ]; then
  642. if [ "${_firstpass}" != "${_secondpass}" ]; then
  643. INFOBOX "Passwords do not match! Please enter again." 6 60
  644. unset _firstpass _secondpass
  645. sleep 2 && clear && continue
  646. fi
  647. set_option USERPASSWORD "${_firstpass}"
  648. USERPASSWORD_DONE=1
  649. break
  650. fi
  651. else
  652. return
  653. fi
  654. done
  655. _groups="wheel,audio,video,floppy,cdrom,optical,kvm,xbuilder"
  656. while true; do
  657. _desc="Select group membership for login '$(get_option USERLOGIN)':"
  658. for _group in $(cat /etc/group); do
  659. _gid="$(echo ${_group} | cut -d: -f3)"
  660. _group="$(echo ${_group} | cut -d: -f1)"
  661. _status="$(echo ${_groups} | grep -w ${_group})"
  662. if [ -z "${_status}" ]; then
  663. _status=off
  664. else
  665. _status=on
  666. fi
  667. if [ -z "${_checklist}" ]; then
  668. _checklist="${_group} ${_group}:${_gid} ${_status}"
  669. else
  670. _checklist="${_checklist} ${_group} ${_group}:${_gid} ${_status}"
  671. fi
  672. done
  673. DIALOG --no-tags --checklist "${_desc}" 20 60 18 ${_checklist}
  674. if [ $? -eq 0 ]; then
  675. set_option USERGROUPS $(cat $ANSWER | sed -e's| |,|g')
  676. USERGROUPS_DONE=1
  677. break
  678. else
  679. return
  680. fi
  681. done
  682. }
  683. set_useraccount() {
  684. [ -z "$USERLOGIN_DONE" ] && return
  685. [ -z "$USERPASSWORD_DONE" ] && return
  686. [ -z "$USERNAME_DONE" ] && return
  687. [ -z "$USERGROUPS_DONE" ] && return
  688. useradd -R $TARGETDIR -m -G $(get_option USERGROUPS) \
  689. -c "$(get_option USERNAME)" $(get_option USERLOGIN)
  690. echo "$(get_option USERLOGIN):$(get_option USERPASSWORD)" | \
  691. chpasswd -R $TARGETDIR -c SHA512
  692. }
  693. menu_bootloader() {
  694. while true; do
  695. DIALOG --title " Select the disk to install the bootloader" \
  696. --menu "$MENULABEL" ${MENUSIZE} $(show_disks) none "Manage bootloader otherwise"
  697. if [ $? -eq 0 ]; then
  698. set_option BOOTLOADER "$(cat $ANSWER)"
  699. BOOTLOADER_DONE=1
  700. break
  701. else
  702. return
  703. fi
  704. done
  705. while true; do
  706. DIALOG --yesno "Use a graphical terminal for the boot loader?" ${YESNOSIZE}
  707. if [ $? -eq 0 ]; then
  708. set_option TEXTCONSOLE 0
  709. break
  710. elif [ $? -eq 1 ]; then
  711. set_option TEXTCONSOLE 1
  712. break
  713. else
  714. return
  715. fi
  716. done
  717. }
  718. set_bootloader() {
  719. local dev=$(get_option BOOTLOADER) grub_args=
  720. if [ "$dev" = "none" ]; then return; fi
  721. # Check if it's an EFI system via efivars module.
  722. if [ -n "$EFI_SYSTEM" ]; then
  723. grub_args="--target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=void_grub --recheck"
  724. fi
  725. echo "Running grub-install $grub_args $dev..." >$LOG
  726. chroot $TARGETDIR grub-install $grub_args $dev >$LOG 2>&1
  727. if [ $? -ne 0 ]; then
  728. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  729. failed to install GRUB to $dev!\nCheck $LOG for errors." ${MSGBOXSIZE}
  730. DIE 1
  731. fi
  732. echo "Running grub-mkconfig on $TARGETDIR..." >$LOG
  733. chroot $TARGETDIR grub-mkconfig -o /boot/grub/grub.cfg >$LOG 2>&1
  734. if [ $? -ne 0 ]; then
  735. DIALOG --msgbox "${BOLD}${RED}ERROR${RESET}: \
  736. failed to run grub-mkconfig!\nCheck $LOG for errors." ${MSGBOXSIZE}
  737. DIE 1
  738. fi
  739. }
  740. test_network() {
  741. rm -f xtraeme.asc && \
  742. xbps-uhelper fetch http://repo.voidlinux.eu/live/xtraeme.asc >$LOG 2>&1
  743. if [ $? -eq 0 ]; then
  744. DIALOG --msgbox "Network is working properly!" ${MSGBOXSIZE}
  745. NETWORK_DONE=1
  746. return 1
  747. fi
  748. DIALOG --msgbox "Network is inaccessible, please set it up properly." ${MSGBOXSIZE}
  749. }
  750. configure_wifi() {
  751. local dev="$1" ssid enc pass _wpasupconf=/etc/wpa_supplicant/wpa_supplicant.conf
  752. DIALOG --form "Wireless configuration for ${dev}\n(encryption type: wep or wpa)" 0 0 0 \
  753. "SSID:" 1 1 "" 1 16 30 0 \
  754. "Encryption:" 2 1 "" 2 16 4 3 \
  755. "Password:" 3 1 "" 3 16 50 0 || return 1
  756. set -- $(cat $ANSWER)
  757. ssid="$1"; enc="$2"; pass="$3";
  758. if [ -z "$ssid" ]; then
  759. DIALOG --msgbox "Invalid SSID." ${MSGBOXSIZE}
  760. return 1
  761. elif [ -z "$enc" -o "$enc" != "wep" -a "$enc" != "wpa" ]; then
  762. DIALOG --msgbox "Invalid encryption type (possible values: wep or wpa)." ${MSXBOXSIZE}
  763. return 1
  764. elif [ -z "$pass" ]; then
  765. DIALOG --msgbox "Invalid AP password." ${MSGBOXSIZE}
  766. fi
  767. rm -f ${_wpasupconf%.conf}-${dev}.conf
  768. cp -f ${_wpasupconf} ${_wpasupconf%.conf}-${dev}.conf
  769. if [ "$enc" = "wep" ]; then
  770. echo "network={" >> ${_wpasupconf%.conf}-${dev}.conf
  771. echo " ssid=\"$ssid\"" >> ${_wpasupconf%.conf}-${dev}.conf
  772. echo " wep_key0=\"$pass\"" >> ${_wpasupconf%.conf}-${dev}.conf
  773. echo " wep_tx_keyidx=0" >> ${_wpasupconf%.conf}-${dev}.conf
  774. echo " auth_alg=SHARED" >> ${_wpasupconf%.conf}-${dev}.conf
  775. echo "}" >> ${_wpasupconf%.conf}-${dev}.conf
  776. else
  777. wpa_passphrase "$ssid" "$pass" >> ${_wpasupconf%.conf}-${dev}.conf
  778. fi
  779. configure_net_dhcp $dev
  780. return $?
  781. }
  782. configure_net() {
  783. local dev="$1" rval
  784. DIALOG --yesno "Do you want to use DHCP for $dev?" ${YESNOSIZE}
  785. rval=$?
  786. if [ $rval -eq 0 ]; then
  787. configure_net_dhcp $dev
  788. elif [ $rval -eq 1 ]; then
  789. configure_net_static $dev
  790. fi
  791. }
  792. iface_setup() {
  793. ip addr show dev $1|grep -q 'inet '
  794. return $?
  795. }
  796. configure_net_dhcp() {
  797. local dev="$1"
  798. iface_setup $dev
  799. if [ $? -eq 1 ]; then
  800. dhcpcd -t 10 -w -4 -L $dev -e "wpa_supplicant_conf=/etc/wpa_supplicant/wpa_supplicant-${dev}.conf" 2>&1 | tee $LOG | \
  801. DIALOG --progressbox "Initializing $dev via DHCP..." ${WIDGET_SIZE}
  802. if [ $? -ne 0 ]; then
  803. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} failed to run dhcpcd. See $LOG for details." ${MSGBOXSIZE}
  804. return 1
  805. fi
  806. iface_setup $dev
  807. if [ $? -eq 1 ]; then
  808. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} DHCP request failed for $dev. Check $LOG for errors." ${MSGBOXSIZE}
  809. return 1
  810. fi
  811. fi
  812. test_network
  813. if [ $? -eq 1 ]; then
  814. set_option NETWORK "${dev} dhcp"
  815. fi
  816. }
  817. configure_net_static() {
  818. local ip gw dns1 dns2 dev=$1
  819. DIALOG --form "Static IP configuration for $dev:" 0 0 0 \
  820. "IP address:" 1 1 "192.168.0.2" 1 21 20 0 \
  821. "Gateway:" 2 1 "192.168.0.1" 2 21 20 0 \
  822. "DNS Primary" 3 1 "8.8.8.8" 3 21 20 0 \
  823. "DNS Secondary" 4 1 "8.8.4.4" 4 21 20 0 || return 1
  824. set -- $(cat $ANSWER)
  825. ip=$1; gw=$2; dns1=$3; dns2=$4
  826. echo "running: ip link set dev $dev up" >$LOG
  827. ip link set dev $dev up >$LOG 2>&1
  828. if [ $? -ne 0 ]; then
  829. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} Failed to bring $dev interface." ${MSGBOXSIZE}
  830. return 1
  831. fi
  832. echo "running: ip addr add $ip dev $dev"
  833. ip addr add $ip dev $dev >$LOG 2>&1
  834. if [ $? -ne 0 ]; then
  835. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} Failed to set ip to the $dev interface." ${MSGBOXSIZE}
  836. return 1
  837. fi
  838. ip route add $gw dev $dev >$LOG 2>&1
  839. if [ $? -ne 0 ]; then
  840. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} failed to setup your gateway." ${MSGBOXSIZE}
  841. return 1
  842. fi
  843. echo "nameserver $dns1" >/etc/resolv.conf
  844. echo "nameserver $dns2" >>/etc/resolv.conf
  845. test_network
  846. if [ $? -eq 1 ]; then
  847. set_option NETWORK "${dev} static $ip $gw $dns1 $dns2"
  848. fi
  849. }
  850. menu_network() {
  851. local dev addr f DEVICES
  852. for f in $(ls /sys/class/net); do
  853. [ "$f" = "lo" ] && continue
  854. addr=$(cat /sys/class/net/$f/address)
  855. DEVICES="$DEVICES $f $addr"
  856. done
  857. DIALOG --title " Select the network interface to configure " \
  858. --menu "$MENULABEL" ${MENUSIZE} ${DEVICES}
  859. if [ $? -eq 0 ]; then
  860. dev=$(cat $ANSWER)
  861. if $(echo $dev|egrep -q "^wl.*" 2>/dev/null); then
  862. configure_wifi $dev
  863. else
  864. configure_net $dev
  865. fi
  866. fi
  867. }
  868. validate_filesystems() {
  869. local mnts dev size fstype mntpt mkfs rootfound fmt
  870. local usrfound efi_system_partition
  871. unset TARGETFS
  872. mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE)
  873. set -- ${mnts}
  874. while [ $# -ne 0 ]; do
  875. dev=$2; fstype=$3; size=$4; mntpt="$5"; mkfs=$6
  876. shift 6
  877. if [ "$mntpt" = "/" ]; then
  878. rootfound=1
  879. elif [ "$mntpt" = "/usr" ]; then
  880. usrfound=1
  881. elif [ "$fstype" = "vfat" -a "$mntpt" = "/boot/efi" ]; then
  882. efi_system_partition=1
  883. fi
  884. if [ "$mkfs" -eq 1 ]; then
  885. fmt="NEW FILESYSTEM: "
  886. fi
  887. if [ -z "$TARGETFS" ]; then
  888. TARGETFS="${fmt}$dev ($size) mounted on $mntpt as ${fstype}\n"
  889. else
  890. TARGETFS="${TARGETFS}${fmt}${dev} ($size) mounted on $mntpt as ${fstype}\n"
  891. fi
  892. done
  893. if [ -z "$rootfound" ]; then
  894. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  895. the mount point for the root filesystem (/) has not yet been configured." ${MSGBOXSIZE}
  896. return 1
  897. elif [ -n "$usrfound" ]; then
  898. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  899. /usr mount point has been configured but is not supported, please remove it to continue." ${MSGBOXSIZE}
  900. return 1
  901. elif [ -n "$EFI_SYSTEM" -a -z "$efi_system_partition" ]; then
  902. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  903. The EFI System Partition has not yet been configured, please create it\n
  904. as FAT32, mountpoint /boot/efi and at least with 100MB of size." ${MSGBOXSIZE}
  905. fi
  906. FILESYSTEMS_DONE=1
  907. }
  908. create_filesystems() {
  909. local mnts dev mntpt fstype fspassno mkfs size rv uuid
  910. mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE)
  911. set -- ${mnts}
  912. while [ $# -ne 0 ]; do
  913. dev=$2; fstype=$3; mntpt="$5"; mkfs=$6
  914. shift 6
  915. # swap partitions
  916. if [ "$fstype" = "swap" ]; then
  917. swapoff $dev >/dev/null 2>&1
  918. if [ "$mkfs" -eq 1 ]; then
  919. mkswap $dev >$LOG 2>&1
  920. if [ $? -ne 0 ]; then
  921. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  922. failed to create swap on ${dev}!\ncheck $LOG for errors." ${MSGBOXSIZE}
  923. DIE 1
  924. fi
  925. fi
  926. swapon $dev >$LOG 2>&1
  927. if [ $? -ne 0 ]; then
  928. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  929. failed to activate swap on $dev!\ncheck $LOG for errors." ${MSGBOXSIZE}
  930. DIE 1
  931. fi
  932. # Add entry for target fstab
  933. uuid=$(blkid -o value -s UUID "$dev")
  934. echo "UUID=$uuid none swap sw 0 0" >>$TARGET_FSTAB
  935. continue
  936. fi
  937. if [ "$mkfs" -eq 1 ]; then
  938. case "$fstype" in
  939. btrfs) MKFS="mkfs.btrfs -f"; modprobe btrfs >$LOG 2>&1;;
  940. ext2) MKFS="mke2fs -F"; modprobe ext2 >$LOG 2>&1;;
  941. ext3) MKFS="mke2fs -F -j"; modprobe ext3 >$LOG 2>&1;;
  942. ext4) MKFS="mke2fs -F -t ext4"; modprobe ext4 >$LOG 2>&1;;
  943. f2fs) MKFS="mkfs.f2fs"; modprobe f2fs >$LOG 2>&1;;
  944. vfat) MKFS="mkfs.vfat -F32"; modprobe vfat >$LOG 2>&1;;
  945. xfs) MKFS="mkfs.xfs -f"; modprobe xfs >$LOG 2>&1;;
  946. esac
  947. TITLE="Check $LOG for details ..."
  948. INFOBOX "Creating filesystem $fstype on $dev for $mntpt ..." 8 60
  949. echo "Running $MKFS $dev..." >$LOG
  950. $MKFS $dev >$LOG 2>&1; rv=$?
  951. if [ $rv -ne 0 ]; then
  952. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  953. failed to create filesystem $fstype on $dev!\ncheck $LOG for errors." ${MSGBOXSIZE}
  954. DIE 1
  955. fi
  956. fi
  957. # Mount rootfs the first one.
  958. [ "$mntpt" != "/" ] && continue
  959. mkdir -p $TARGETDIR
  960. echo "Mounting $dev on $mntpt ($fstype)..." >$LOG
  961. mount -t $fstype $dev $TARGETDIR >$LOG 2>&1
  962. if [ $? -ne 0 ]; then
  963. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  964. failed to mount $dev on ${mntpt}! check $LOG for errors." ${MSGBOXSIZE}
  965. DIE 1
  966. fi
  967. # Add entry to target fstab
  968. uuid=$(blkid -o value -s UUID "$dev")
  969. if [ "$fstype" = "f2fs" ]; then
  970. fspassno=0
  971. else
  972. fspassno=1
  973. fi
  974. echo "UUID=$uuid $mntpt $fstype defaults 0 $fspassno" >>$TARGET_FSTAB
  975. done
  976. # mount all filesystems in target rootfs
  977. mnts=$(grep -E '^MOUNTPOINT.*' $CONF_FILE)
  978. set -- ${mnts}
  979. while [ $# -ne 0 ]; do
  980. dev=$2; fstype=$3; mntpt="$5"
  981. shift 6
  982. [ "$mntpt" = "/" -o "$fstype" = "swap" ] && continue
  983. mkdir -p ${TARGETDIR}${mntpt}
  984. echo "Mounting $dev on $mntpt ($fstype)..." >$LOG
  985. mount -t $fstype $dev ${TARGETDIR}${mntpt} >$LOG 2>&1
  986. if [ $? -ne 0 ]; then
  987. DIALOG --msgbox "${BOLD}${RED}ERROR:${RESET} \
  988. failed to mount $dev on $mntpt! check $LOG for errors." ${MSGBOXSIZE}
  989. DIE
  990. fi
  991. # Add entry to target fstab
  992. uuid=$(blkid -o value -s UUID "$dev")
  993. echo "UUID=$uuid $mntpt $fstype defaults 0 2" >>$TARGET_FSTAB
  994. done
  995. }
  996. mount_filesystems() {
  997. for f in sys proc dev; do
  998. [ ! -d $TARGETDIR/$f ] && mkdir $TARGETDIR/$f
  999. echo "Mounting $TARGETDIR/$f..." >$LOG
  1000. mount --bind /$f $TARGETDIR/$f >$LOG 2>&1
  1001. done
  1002. }
  1003. umount_filesystems() {
  1004. local f
  1005. for f in sys/fs/fuse/connections sys proc dev; do
  1006. echo "Unmounting $TARGETDIR/$f..." >$LOG
  1007. umount $TARGETDIR/$f >$LOG 2>&1
  1008. done
  1009. local mnts="$(grep -E '^MOUNTPOINT.*$' $CONF_FILE)"
  1010. set -- ${mnts}
  1011. while [ $# -ne 0 ]; do
  1012. local dev=$2; local fstype=$3; local mntpt=$5
  1013. shift 6
  1014. if [ "$fstype" = "swap" ]; then
  1015. echo "Disabling swap space on $dev..." >$LOG
  1016. swapoff $dev >$LOG 2>&1
  1017. continue
  1018. fi
  1019. if [ "$mntpt" != "/" ]; then
  1020. echo "Unmounting $TARGETDIR/$mntpt..." >$LOG
  1021. umount $TARGETDIR/$mntpt >$LOG 2>&1
  1022. fi
  1023. done
  1024. echo "Unmounting $TARGETDIR..." >$LOG
  1025. umount $TARGETDIR >$LOG 2>&1
  1026. }
  1027. log_and_count() {
  1028. local progress whole tenth
  1029. while read line; do
  1030. echo "$line" >$LOG
  1031. copy_count=$((copy_count + 1))
  1032. progress=$((1000 * copy_count / copy_total))
  1033. if [ "$progress" != "$copy_progress" ]; then
  1034. whole=$((progress / 10))
  1035. tenth=$((progress % 10))
  1036. printf "Progress: %d.%d%% (%d of %d files)\n" $whole $tenth $copy_count $copy_total
  1037. copy_progress=$progress
  1038. fi
  1039. done
  1040. }
  1041. copy_rootfs() {
  1042. local tar_in="--create --one-file-system --xattrs"
  1043. TITLE="Check $LOG for details ..."
  1044. INFOBOX "Counting files, please be patient ..." 4 60
  1045. copy_total=$(tar ${tar_in} -v -f /dev/null / 2>/dev/null | wc -l)
  1046. export copy_total copy_count=0 copy_progress=
  1047. clear
  1048. tar ${tar_in} -f - / 2>/dev/null | \
  1049. tar --extract --xattrs --xattrs-include='*' --preserve-permissions -v -f - -C $TARGETDIR | \
  1050. log_and_count | \
  1051. DIALOG --title "${TITLE}" \
  1052. --progressbox "Copying live image to target rootfs." 5 60
  1053. if [ $? -ne 0 ]; then
  1054. DIE 1
  1055. fi
  1056. unset copy_total copy_count copy_percent
  1057. }
  1058. install_packages() {
  1059. local _grub= _syspkg=
  1060. if [ -n "$EFI_SYSTEM" ]; then
  1061. _grub="grub-x86_64-efi"
  1062. else
  1063. _grub="grub"
  1064. fi
  1065. _syspkg="base-system"
  1066. mkdir -p $TARGETDIR/var/db/xbps/keys $TARGETDIR/usr/share
  1067. cp -a /usr/share/xbps.d $TARGETDIR/usr/share/
  1068. cp /var/db/xbps/keys/*.plist $TARGETDIR/var/db/xbps/keys
  1069. mkdir -p $TARGETDIR/boot/grub
  1070. _arch=$(xbps-uhelper arch)
  1071. stdbuf -oL env XBPS_ARCH=${_arch} \
  1072. xbps-install -r $TARGETDIR -SyU ${_syspkg} ${_grub} 2>&1 | \
  1073. DIALOG --title "Installing base system packages..." \
  1074. --programbox 24 80
  1075. if [ $? -ne 0 ]; then
  1076. DIE 1
  1077. fi
  1078. xbps-reconfigure -r $TARGETDIR -f base-files >/dev/null 2>&1
  1079. chroot $TARGETDIR xbps-reconfigure -a
  1080. }
  1081. enable_dhcpd() {
  1082. ln -sf /etc/sv/dhcpcd $TARGETDIR/etc/runit/runsvdir/default/dhcpcd
  1083. }
  1084. menu_install() {
  1085. # Don't continue if filesystems are not ready.
  1086. validate_filesystems || return 1
  1087. ROOTPASSWORD_DONE="$(get_option ROOTPASSWORD)"
  1088. BOOTLOADER_DONE="$(get_option BOOTLOADER)"
  1089. if [ -z "$FILESYSTEMS_DONE" ]; then
  1090. DIALOG --msgbox "${BOLD}Required filesystems were not configured, \
  1091. please do so before starting the installation.${RESET}" ${MSGBOXSIZE}
  1092. return 1
  1093. elif [ -z "$ROOTPASSWORD_DONE" ]; then
  1094. DIALOG --msgbox "${BOLD}The root password has not been configured, \
  1095. please do so before starting the installation.${RESET}" ${MSGBOXSIZE}
  1096. return 1
  1097. elif [ -z "$BOOTLOADER_DONE" ]; then
  1098. DIALOG --msgbox "${BOLD}The disk to install the bootloader has not been \
  1099. configured, please do so before starting the installation.${RESET}" ${MSGBOXSIZE}
  1100. return 1
  1101. fi
  1102. DIALOG --yesno "${BOLD}The following operations will be executed:${RESET}\n\n
  1103. ${BOLD}${TARGETFS}${RESET}\n
  1104. ${BOLD}${RED}WARNING: data on partitions will be COMPLETELY DESTROYED for new \
  1105. filesystems.${RESET}\n\n
  1106. ${BOLD}Do you want to continue?${RESET}" 20 80 || return
  1107. unset TARGETFS
  1108. # Create and mount filesystems
  1109. create_filesystems
  1110. # If source not set use defaults.
  1111. if [ "$(get_option SOURCE)" = "local" -o -z "$SOURCE_DONE" ]; then
  1112. copy_rootfs
  1113. . /etc/default/live.conf
  1114. rm -f $TARGETDIR/etc/motd
  1115. rm -f $TARGETDIR/etc/issue
  1116. rm -f $TARGETDIR/usr/sbin/void-installer
  1117. # Remove live user.
  1118. echo "Removing $USERNAME live user from targetdir ..." >$LOG
  1119. chroot $TARGETDIR userdel -r $USERNAME >$LOG 2>&1
  1120. sed -i -e "/$USERNAME ALL=.*/d" $TARGETDIR/etc/sudoers
  1121. TITLE="Check $LOG for details ..."
  1122. INFOBOX "Rebuilding initramfs for target ..." 4 60
  1123. echo "Rebuilding initramfs for target ..." >$LOG
  1124. # mount required fs
  1125. mount_filesystems
  1126. chroot $TARGETDIR dracut --no-hostonly --add-drivers "ahci" --force >>$LOG 2>&1
  1127. INFOBOX "Removing temporary packages from target ..." 4 60
  1128. echo "Removing temporary packages from target ..." >$LOG
  1129. xbps-remove -r $TARGETDIR -Ry dialog >>$LOG 2>&1
  1130. rmdir $TARGETDIR/mnt/target
  1131. else
  1132. # mount required fs
  1133. mount_filesystems
  1134. # network install, use packages.
  1135. install_packages
  1136. fi
  1137. INFOBOX "Applying installer settings..." 4 60
  1138. # copy target fstab.
  1139. install -Dm644 $TARGET_FSTAB $TARGETDIR/etc/fstab
  1140. # Mount /tmp as tmpfs.
  1141. echo "tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0" >> $TARGETDIR/etc/fstab
  1142. # set up keymap, locale, timezone, hostname, root passwd and user account.
  1143. set_keymap
  1144. set_locale
  1145. set_timezone
  1146. set_hostname
  1147. set_rootpassword
  1148. set_useraccount
  1149. # Copy /etc/skel files for root.
  1150. cp $TARGETDIR/etc/skel/.[bix]* $TARGETDIR/root
  1151. # network settings for target
  1152. if [ -n "$NETWORK_DONE" ]; then
  1153. local net="$(get_option NETWORK)"
  1154. set -- ${net}
  1155. local _dev="$1" _type="$2" _ip="$3" _gw="$4" _dns1="$5" _dns2="$6"
  1156. if [ -z "$_type" ]; then
  1157. # network type empty??!!!
  1158. :
  1159. elif [ "$_type" = "dhcp" ]; then
  1160. if [ -f /etc/wpa_supplicant/wpa_supplicant-${_dev}.conf ]; then
  1161. cp /etc/wpa_supplicant/wpa_supplicant-${_dev}.conf $TARGETDIR/etc/wpa_supplicant
  1162. ln -sf /etc/sv/dhcpcd-${_dev} $TARGETDIR/etc/runit/runsvdir/default/dhcpcd-${_dev}
  1163. else
  1164. enable_dhcpd
  1165. fi
  1166. elif [ -n "$_dev" -a "$_type" = "static" ]; then
  1167. # static IP through dhcpcd.
  1168. mv $TARGETDIR/etc/dhcpcd.conf $TARGETDIR/etc/dhdpcd.conf.orig
  1169. echo "# Static IP configuration set by the void-installer for $_dev." \
  1170. >$TARGETDIR/etc/dhcpcd.conf
  1171. echo "interface $_dev" >>$TARGETDIR/etc/dhcpcd.conf
  1172. echo "static ip_address=$_ip" >>$TARGETDIR/etc/dhcpcd.conf
  1173. echo "static routers=$_gw" >>$TARGETDIR/etc/dhcpcd.conf
  1174. echo "static domain_name_servers=$_dns1 $_dns2" >>$TARGETDIR/etc/dhcpcd.conf
  1175. enable_dhcpd
  1176. fi
  1177. fi
  1178. if [ -f $TARGETDIR/etc/sudoers ]; then
  1179. if [ -z "$(echo $(get_option USERGROUPS) | grep -w wheel)" ]; then
  1180. # enable sudo for primary user USERLOGIN
  1181. echo "# Enable sudo for login '$(get_option USERLOGIN)'" >> $TARGETDIR/etc/sudoers
  1182. echo "$(get_option USERLOGIN) ALL=(ALL) ALL" >> $TARGETDIR/etc/sudoers
  1183. else
  1184. # enable sudoers entry for members of group wheel for primary user
  1185. sed -i $TARGETDIR/etc/sudoers \
  1186. -e "s;#.*%wheel ALL=(ALL) ALL;%wheel ALL=(ALL) ALL;"
  1187. fi
  1188. fi
  1189. # enable text console for grub if chosen
  1190. if [ "$(get_option TEXTCONSOLE)" = "1" ]; then
  1191. sed -i $TARGETDIR/etc/default/grub \
  1192. -e 's|#\(GRUB_TERMINAL_INPUT\).*|\1=console|' \
  1193. -e 's|#\(GRUB_TERMINAL_OUTPUT\).*|\1=console|'
  1194. fi
  1195. # install bootloader.
  1196. set_bootloader
  1197. sync && sync && sync
  1198. # unmount all filesystems.
  1199. umount_filesystems
  1200. # installed successfully.
  1201. DIALOG --yesno "${BOLD}Void Linux has been installed successfully!${RESET}\n
  1202. Do you want to reboot the system?" ${YESNOSIZE}
  1203. if [ $? -eq 0 ]; then
  1204. shutdown -r now
  1205. else
  1206. return
  1207. fi
  1208. }
  1209. menu_source() {
  1210. local src=
  1211. DIALOG --title " Select installation source " \
  1212. --menu "$MENULABEL" 8 70 0 \
  1213. "Local" "Packages from ISO image" \
  1214. "Network" "Packages from official remote reposity"
  1215. case "$(cat $ANSWER)" in
  1216. "Local") src="local";;
  1217. "Network") src="net";
  1218. if [ -z "$NETWORK_DONE" ]; then
  1219. menu_network;
  1220. fi;;
  1221. *) return 1;;
  1222. esac
  1223. SOURCE_DONE=1
  1224. set_option SOURCE $src
  1225. }
  1226. menu() {
  1227. if [ -z "$DEFITEM" ]; then
  1228. DEFITEM="Keyboard"
  1229. fi
  1230. DIALOG --default-item $DEFITEM \
  1231. --extra-button --extra-label "Settings" \
  1232. --title " Void Linux installation menu " \
  1233. --menu "$MENULABEL" 10 70 0 \
  1234. "Keyboard" "Set system keyboard" \
  1235. "Network" "Set up the network" \
  1236. "Source" "Set source installation" \
  1237. "Hostname" "Set system hostname" \
  1238. "Locale" "Set system locale" \
  1239. "Timezone" "Set system time zone" \
  1240. "RootPassword" "Set system root password" \
  1241. "UserAccount" "Set primary user name and password" \
  1242. "BootLoader" "Set disk to install bootloader" \
  1243. "Partition" "Partition disk(s)" \
  1244. "Filesystems" "Configure filesystems and mount points" \
  1245. "Install" "Start installation with saved settings" \
  1246. "Exit" "Exit installation"
  1247. if [ $? -eq 3 ]; then
  1248. # Show settings
  1249. cp $CONF_FILE /tmp/conf_hidden.$$;
  1250. sed -i "s/^ROOTPASSWORD.*/ROOTPASSWORD <-hidden->/" /tmp/conf_hidden.$$
  1251. DIALOG --title "Saved settings for installation" --textbox /tmp/conf_hidden.$$ 14 60
  1252. rm /tmp/conf_hidden.$$
  1253. return
  1254. fi
  1255. case $(cat $ANSWER) in
  1256. "Keyboard") menu_keymap && [ -n "$KEYBOARD_DONE" ] && DEFITEM="Network";;
  1257. "Network") menu_network && [ -n "$NETWORK_DONE" ] && DEFITEM="Source";;
  1258. "Source") menu_source && [ -n "$SOURCE_DONE" ] && DEFITEM="Hostname";;
  1259. "Hostname") menu_hostname && [ -n "$HOSTNAME_DONE" ] && DEFITEM="Locale";;
  1260. "Locale") menu_locale && [ -n "$LOCALE_DONE" ] && DEFITEM="Timezone";;
  1261. "Timezone") menu_timezone && [ -n "$TIMEZONE_DONE" ] && DEFITEM="RootPassword";;
  1262. "RootPassword") menu_rootpassword && [ -n "$ROOTPASSWORD_DONE" ] && DEFITEM="UserAccount";;
  1263. "UserAccount") menu_useraccount && [ -n "$USERNAME_DONE" ] && [ -n "$USERPASSWORD_DONE" ] \
  1264. && DEFITEM="BootLoader";;
  1265. "BootLoader") menu_bootloader && [ -n "$BOOTLOADER_DONE" ] && DEFITEM="Partition";;
  1266. "Partition") menu_partitions && [ -n "$PARTITIONS_DONE" ] && DEFITEM="Filesystems";;
  1267. "Filesystems") menu_filesystems && [ -n "$FILESYSTEMS_DONE" ] && DEFITEM="Install";;
  1268. "Install") menu_install;;
  1269. "Exit") DIE;;
  1270. *) DIALOG --yesno "Abort Installation?" ${YESNOSIZE} && DIE
  1271. esac
  1272. }
  1273. if [ ! -x /bin/dialog ]; then
  1274. echo "ERROR: missing dialog command, exiting..."
  1275. exit 1
  1276. fi
  1277. if [ "$(id -u)" != "0" ]; then
  1278. echo "void-installer must run as root" 1>&2
  1279. exit 1
  1280. fi
  1281. #
  1282. # main()
  1283. #
  1284. DIALOG --title "${BOLD}${RED} Enter the void ... ${RESET}" --msgbox "\n
  1285. Welcome to the Void Linux installation. A simple and minimal \
  1286. Linux distribution made from scratch and built from the source package tree \
  1287. available for XBPS, a new alternative binary package system.\n\n
  1288. The installation should be pretty straightforward. If you are in trouble \
  1289. please join us at ${BOLD}#voidlinux${RESET} on ${BOLD}irc.freenode.org${RESET}.\n\n
  1290. ${BOLD}http://www.voidlinux.eu${RESET}\n\n" 16 80
  1291. while true; do
  1292. menu
  1293. done
  1294. exit 0
  1295. # vim: set ts=4 sw=4 et: