installer.sh 51 KB

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