├── .gitignore ├── Makefile ├── README.md ├── create-iso.sh ├── dialogs.sh ├── dist └── install ├── funcs.sh ├── mirror-selector.sh ├── steps.sh ├── timezone-selector.sh └── vars.sh /.gitignore: -------------------------------------------------------------------------------- 1 | install-vars install-errors iso/ iso iso/* -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: clean build 2 | 3 | create-iso: clean build 4 | @./create-iso.sh 5 | 6 | build: 7 | @echo "Building dist/install" 8 | @mkdir -p dist 9 | @cat vars.sh timezone-selector.sh mirror-selector.sh funcs.sh dialogs.sh steps.sh > dist/install 10 | @chmod +x ./dist/install 11 | 12 | clean: 13 | @echo "Cleaning..." 14 | @-rm dist/install 2> /dev/null || true 15 | @-rm install-vars* 2> /dev/null || true 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## installer 2 | 3 | Graphical installation wizard for Happy Hacking Linux. 4 | 5 | ## Usage 6 | 7 | #### Creating ISO 8 | 9 | You'll get an iso file under `./iso/out` folder after running; 10 | 11 | ```bash 12 | $ make create-iso 13 | ``` 14 | 15 | #### In Arch Linux 16 | 17 | You can install Arch Linux with this wizard by simply calling it; 18 | 19 | ``` 20 | curl -L https://git.io/v1JNj | bash 21 | ``` 22 | 23 | ## Todo 24 | 25 | Tasks need to be done for the next release: 26 | 27 | * Add `playerctl` to the default setup. Xmonad config is ready to hook up with it. 28 | * Add `pacaur` to the default setup. 29 | * Detect if the system is a notebook by running `dmidecode --string chassis-type` and do some customizations for laptops such as installing `laptop-mode-tools` 30 | * Add `fd-rs` to the default setup. 31 | * Install Asian font sets by default. (adobe-source-han-serif-otc-fonts and adobe-source-han-sans-otc-fonts) 32 | * Read partition names under selected disk using `lsblk`. 33 | * Install Rofi & make it default app selector 34 | * Diff http://termbin.com/3vfor 35 | * Install `ttf-symbola` 36 | * Install `udevil` instead of `udiskie` 37 | * trash-cli 38 | -------------------------------------------------------------------------------- /create-iso.sh: -------------------------------------------------------------------------------- 1 | TMP=./iso 2 | 3 | prepare () { 4 | sudo pacman -S archiso 5 | git clone git@github.com:happy-hacking-linux/iso.git $TMP 6 | cp dist/install $TMP/airootfs/root/autorun.sh 7 | build 8 | } 9 | 10 | build () { 11 | cd $TMP 12 | sudo ./build.sh -v 13 | } 14 | 15 | prepare 16 | -------------------------------------------------------------------------------- /dialogs.sh: -------------------------------------------------------------------------------- 1 | CHECK="[OK]" 2 | 3 | battery() { 4 | echo "| Battery: $(cat /sys/class/power_supply/BAT0/capacity)%" 5 | } 6 | 7 | startingDialogs () { 8 | nameDialog 9 | usernameDialog 10 | 11 | dotFilesRepo=$(dialog --stdout \ 12 | --title "=^.^=" \ 13 | --backtitle "Happy Hacking Linux $(battery)" \ 14 | --ok-label "Next" \ 15 | --cancel-label "Skip" \ 16 | --inputbox "Where is your dotfiles, $name?" 8 55 "https://github.com/$username/dotfiles.git") 17 | } 18 | 19 | mainMenu () { 20 | icon1="" 21 | icon2="" 22 | icon3="" 23 | icon4="" 24 | icon5="" 25 | 26 | getvar "partition-step" 27 | if [ "$value" = "done" ]; then 28 | icon1="${CHECK} " 29 | fi 30 | 31 | getvar "core-install-step" 32 | if [ "$value" = "done" ]; then 33 | icon2="${CHECK} " 34 | fi 35 | 36 | getvar "users-step" 37 | if [ "$value" = "done" ]; then 38 | icon3="${CHECK} " 39 | fi 40 | 41 | getvar "install-packages-step" 42 | if [ "$value" = "done" ]; then 43 | icon4="${CHECK} " 44 | fi 45 | 46 | getvar "localization-step" 47 | if [ "$value" = "done" ]; then 48 | icon5="${CHECK} " 49 | fi 50 | 51 | selected=$(dialog --stdout \ 52 | --title "=^.^=" \ 53 | --backtitle "Happy Hacking Linux $(battery)" \ 54 | --ok-label "Select" \ 55 | --cancel-label "Welcome Screen" \ 56 | --menu "Complete the following installation steps one by one." 16 55 8 \ 57 | 1 "${icon1}Setup Disk Partitions" \ 58 | 2 "${icon2}Install Core System" \ 59 | 3 "${icon3}Create Users" \ 60 | 4 "${icon4}Install Packages" \ 61 | 5 "${icon5}Localize" \ 62 | 6 "Reboot") 63 | 64 | button=$? 65 | } 66 | 67 | diskMenu () { 68 | disks=$(lsblk -r | grep disk | cut -d" " -f1,4 | nl) 69 | disksArray=() 70 | while read i name size; do 71 | disksArray+=($i "/dev/$name ($size)") 72 | done <<< "$disks" 73 | 74 | selected=$(dialog --stdout \ 75 | --title "Installation Disk" \ 76 | --backtitle "Happy Hacking Linux $(battery)" \ 77 | --ok-label "Next" \ 78 | --cancel-label "Main Menu" \ 79 | --menu "Select A Disk" \ 80 | 15 30 30 \ 81 | "${disksArray[@]}") 82 | 83 | button=$? 84 | 85 | selected=$(lsblk -r | grep disk | cut -d" " -f1 | sed -n "${selected}p") 86 | selected="/dev/${selected}" 87 | setvar "disk" "$selected" 88 | } 89 | 90 | partitionMenu () { 91 | selected=$(dialog --stdout \ 92 | --title "Setup Disk Partitions" \ 93 | --backtitle "Happy Hacking Linux $(battery)" \ 94 | --ok-label "Select" \ 95 | --cancel-label "Main Menu" \ 96 | --menu "How do you want to create partitions? If you got nothing to lose in $1, just go with the simple option and format the disk completely. Or, choose one of the tools to modify your disk in your own risk." 17 55 5 \ 97 | 1 "Simple: Erase Everything on $1" \ 98 | 2 "Manual: Using cfdisk" \ 99 | 3 "Manual: Using fdisk" \ 100 | 4 "Manual: Using GNU Parted") 101 | } 102 | 103 | partitionSelectionForm () { 104 | values=$(dialog --stdout \ 105 | --ok-label "Done" \ 106 | --backtitle "Happy Hacking Linux $(battery)" \ 107 | --title "Select Partitions" \ 108 | --nocancel \ 109 | --form "" \ 110 | 7 50 0 \ 111 | "Root Partition:" 2 1 "${1}X" 2 18 35 0) 112 | 113 | systempt=$(echo "$values" | tail -n1) 114 | 115 | dialog --title "Select Partitions" --yesno "Warning: $systempt will be formatted, continue?" 7 40 116 | 117 | if [ "$?" != "0" ]; then 118 | systempt="" 119 | fi 120 | 121 | if [[ -z "${systempt// }" ]]; then 122 | dialog --title "Select System Partition" \ 123 | --backtitle "Happy Hacking Linux $(battery)" \ 124 | --msgbox "Sorry, you have to choose the partition you'd like to install the system." 6 50 125 | partitionSelectionForm 126 | else 127 | yes | mkfs.ext4 $systempt > /dev/null 2> /tmp/err || error "Failed to format the root partition" 128 | mount $systempt /mnt > /dev/null 2> /tmp/err || error "Failed to mount the root partition" 129 | setvar "system-partition" $systempt 130 | fi 131 | } 132 | 133 | 134 | 135 | nameDialog () { 136 | name=$(dialog --stdout \ 137 | --title "=^.^" \ 138 | --backtitle "Happy Hacking Linux $(battery)" \ 139 | --ok-label "Next" \ 140 | --nocancel \ 141 | --inputbox "Oh, hai! What's your name?" 8 55) 142 | 143 | if [[ -z "${name// }" ]]; then 144 | dialog --title "=^.^=" \ 145 | --backtitle "Happy Hacking Linux $(battery)" \ 146 | --msgbox "Type your name please, or make something up" 5 55 147 | nameDialog 148 | fi 149 | } 150 | 151 | usernameDialog () { 152 | username=$(echo "$name" | sed -e 's/[^[:alnum:]]/-/g' | tr -s '-' | tr A-Z a-z) 153 | 154 | username=$(dialog --stdout \ 155 | --title "=^.^" \ 156 | --backtitle "Happy Hacking Linux $(battery)" \ 157 | --ok-label "Next" \ 158 | --nocancel \ 159 | --inputbox "...and your favorite username?" 8 55 "$username") 160 | 161 | if [[ -z "${username// }" ]]; then 162 | dialog --title "=^.^=" \ 163 | --backtitle "Happy Hacking Linux $(battery)" \ 164 | --msgbox "A username is required, try again" 5 55 165 | usernamedDialog 166 | fi 167 | } 168 | 169 | passwordDialog () { 170 | password=$(dialog --stdout \ 171 | --title "Creating User" \ 172 | --backtitle "Happy Hacking Linux $(battery)" \ 173 | --ok-label "Done" \ 174 | --nocancel \ 175 | --passwordbox "Type a new password:" 8 50) 176 | 177 | passwordRepeat=$(dialog --stdout \ 178 | --title "Creating User" \ 179 | --backtitle "Happy Hacking Linux $(battery)" \ 180 | --ok-label "Done" \ 181 | --nocancel \ 182 | --passwordbox "Verify your new password:" 8 50) 183 | 184 | if [ "$password" != "$passwordRepeat" ]; then 185 | dialog --title "Password" \ 186 | --backtitle "Happy Hacking Linux $(battery)" \ 187 | --msgbox "Passwords you've typed don't match. Try again." 5 50 188 | passwordDialog 189 | fi 190 | 191 | if [[ -z "${password// }" ]]; then 192 | dialog --title "Password" \ 193 | --backtitle "Happy Hacking Linux $(battery)" \ 194 | --msgbox "A password is required. Try again please." 5 50 195 | passwordDialog 196 | fi 197 | } 198 | 199 | errorDialog () { 200 | echo "$1\n\n" > ./install-errors.log 201 | [[ -f /tmp/err ]] && cat /tmp/err >> ./install-errors.log 202 | 203 | echo "Message: $1\nOutput: \n" | cat - /tmp/err > /tmp/err.bak && mv /tmp/err.bak /tmp/err 204 | 205 | dialog --title "Oops, there was an error" \ 206 | --backtitle "Happy Hacking Linux $(battery)" \ 207 | --textbox /tmp/err 20 50 208 | 209 | rm /tmp/err 210 | mainMenuStep 211 | } 212 | 213 | installationProgress () { 214 | total=72 215 | instcounter=$((instcounter+1)) 216 | percent=$((100*$instcounter/$total)) 217 | 218 | echo $percent | dialog --title "Installation" \ 219 | --backtitle "Happy Hacking Linux $(battery)" \ 220 | --gauge "Downloading package: $1" \ 221 | 7 70 0 222 | } 223 | -------------------------------------------------------------------------------- /dist/install: -------------------------------------------------------------------------------- 1 | touch ./install-vars 2 | 3 | setvar () { 4 | grep -v "^$1=" ./install-vars > ./install-vars.new && mv ./install-vars.new ./install-vars 5 | echo "$1=$2" >> ./install-vars 6 | } 7 | 8 | getvar () { 9 | value=$(grep "^$1=" ./install-vars | tail -n 1 | sed "s/^$1=//") 10 | } 11 | detectTimezone () { 12 | if command_exists tzupdate ; then 13 | dialog --infobox "Please wait, detecting your timezone... " 5 50; detected=$(tzupdate -p | sed "s/Detected timezone is //" | sed "s/\.//") 14 | return 15 | fi 16 | 17 | detected="" 18 | } 19 | 20 | tzOptionsByRegion () { 21 | options=$(cd /usr/share/zoneinfo/$1 && find . | sed "s|^\./||" | sed "s/^\.//" | sed '/^$/d') 22 | } 23 | 24 | tzRegions () { 25 | regions=$(find /usr/share/zoneinfo/. -maxdepth 1 -type d | cut -d "/" -f6 | sed '/^$/d') 26 | } 27 | 28 | tzSelectionMenu () { 29 | detectTimezone 30 | 31 | if [[ -n "${detected// }" ]]; then 32 | if [ -f "/usr/share/zoneinfo/$detected" ]; then 33 | offset=$(TZ="$detected" date +%z | sed "s/00$/:00/g") 34 | 35 | dialog --title "Timezones" \ 36 | --backtitle "Happy Hacking Linux" \ 37 | --yes-label "Yes, correct" \ 38 | --no-label "No, I'll choose it" \ 39 | --yesno "Your timezone was detected as $detected ($offset). Is it correct?" 7 50 40 | selected=$? 41 | 42 | if [ "$selected" = "0" ]; then 43 | tzupdate > /dev/null 44 | return 45 | fi 46 | fi 47 | fi 48 | 49 | tzRegions 50 | regionsArray=() 51 | while read name; do 52 | regionsArray+=($name "") 53 | done <<< "$regions" 54 | 55 | region=$(dialog --stdout \ 56 | --title "Timezones" \ 57 | --backtitle "$1" \ 58 | --ok-label "Next" \ 59 | --no-cancel \ 60 | --menu "Select a continent or ocean from the menu:" \ 61 | 20 30 30 \ 62 | "${regionsArray[@]}") 63 | 64 | tzOptionsByRegion $region 65 | 66 | optionsArray=() 67 | while read name; do 68 | offset=$(TZ="$region/$name" date +%z | sed "s/00$/:00/g") 69 | optionsArray+=($name "($offset)") 70 | done <<< "$options" 71 | 72 | tz=$(dialog --stdout \ 73 | --title "Timezones" \ 74 | --backtitle "$1" \ 75 | --ok-label "Next" \ 76 | --cancel-label "Back to Regions" \ 77 | --menu "Select your timezone in ${region}:" \ 78 | 20 40 30 \ 79 | "${optionsArray[@]}") 80 | 81 | if [[ -z "${tz// }" ]]; then 82 | tzSelectionMenu 83 | else 84 | selected="/usr/share/zoneinfo/$region/$tz" 85 | fi 86 | } 87 | 88 | command_exists () { 89 | type "$1" &> /dev/null ; 90 | } 91 | declare -A countries 92 | countries[1]="Australia" 93 | countries[2]="Austria" 94 | countries[3]="Bangladesh" 95 | countries[4]="Belarus" 96 | countries[5]="Belgium" 97 | countries[6]="Bosnia_and_Herzegovina" 98 | countries[7]="Brazil" 99 | countries[8]="Bulgaria" 100 | countries[9]="Canada" 101 | countries[10]="Chile" 102 | countries[11]="China" 103 | countries[12]="Colombia" 104 | countries[13]="Croatia" 105 | countries[14]="Czechia" 106 | countries[15]="Denmark" 107 | countries[16]="Ecuador" 108 | countries[17]="Finland" 109 | countries[18]="France" 110 | countries[19]="Georgia" 111 | countries[20]="Germany" 112 | countries[21]="Greece" 113 | countries[22]="Hong_Kong" 114 | countries[23]="Hungary" 115 | countries[24]="Iceland" 116 | countries[25]="India" 117 | countries[26]="Indonesia" 118 | countries[27]="Iran" 119 | countries[28]="Ireland" 120 | countries[29]="Israel" 121 | countries[30]="Italy" 122 | countries[31]="Japan" 123 | countries[32]="Kazakhstan" 124 | countries[33]="Kenya" 125 | countries[34]="Latvia" 126 | countries[35]="Lithuania" 127 | countries[36]="Luxembourg" 128 | countries[37]="Netherlands" 129 | countries[38]="New_Caledonia" 130 | countries[39]="New_Zealand" 131 | countries[40]="North_Macedonia" 132 | countries[41]="Norway" 133 | countries[42]="Paraguay" 134 | countries[43]="Philippines" 135 | countries[44]="Poland" 136 | countries[45]="Portugal" 137 | countries[46]="Romania" 138 | countries[47]="Russia" 139 | countries[48]="Serbia" 140 | countries[49]="Singapore" 141 | countries[50]="Slovakia" 142 | countries[51]="Slovenia" 143 | countries[52]="South_Africa" 144 | countries[53]="South_Korea" 145 | countries[54]="Spain" 146 | countries[55]="Sweden" 147 | countries[56]="Switzerland" 148 | countries[57]="Taiwan" 149 | countries[58]="Thailand" 150 | countries[59]="Turkey" 151 | countries[60]="Ukraine" 152 | countries[61]="United_Kingdom" 153 | countries[62]="United_States" 154 | countries[63]="Vietnam" 155 | 156 | declare -A country_codes 157 | country_codes[1]="AU" 158 | country_codes[2]="AT" 159 | country_codes[3]="BD" 160 | country_codes[4]="BY" 161 | country_codes[5]="BE" 162 | country_codes[6]="BA" 163 | country_codes[7]="BR" 164 | country_codes[8]="BG" 165 | country_codes[9]="CA" 166 | country_codes[10]="CL" 167 | country_codes[11]="CN" 168 | country_codes[12]="CO" 169 | country_codes[13]="HR" 170 | country_codes[14]="CZ" 171 | country_codes[15]="DK" 172 | country_codes[16]="EC" 173 | country_codes[17]="FI" 174 | country_codes[18]="FR" 175 | country_codes[19]="GE" 176 | country_codes[20]="DE" 177 | country_codes[21]="GR" 178 | country_codes[22]="HK" 179 | country_codes[23]="HU" 180 | country_codes[24]="IS" 181 | country_codes[25]="IN" 182 | country_codes[26]="ID" 183 | country_codes[27]="IR" 184 | country_codes[28]="IE" 185 | country_codes[29]="IL" 186 | country_codes[30]="IT" 187 | country_codes[31]="JP" 188 | country_codes[32]="KZ" 189 | country_codes[33]="KE" 190 | country_codes[34]="LV" 191 | country_codes[35]="LT" 192 | country_codes[36]="LU" 193 | country_codes[37]="NL" 194 | country_codes[38]="NC" 195 | country_codes[39]="NZ" 196 | country_codes[40]="MK" 197 | country_codes[41]="NO" 198 | country_codes[42]="PY" 199 | country_codes[43]="PH" 200 | country_codes[44]="PL" 201 | country_codes[45]="PT" 202 | country_codes[46]="RO" 203 | country_codes[47]="RU" 204 | country_codes[48]="RS" 205 | country_codes[49]="SG" 206 | country_codes[50]="SK" 207 | country_codes[51]="SI" 208 | country_codes[52]="ZA" 209 | country_codes[53]="KR" 210 | country_codes[54]="ES" 211 | country_codes[55]="SE" 212 | country_codes[56]="CH" 213 | country_codes[57]="TW" 214 | country_codes[58]="TH" 215 | country_codes[59]="TR" 216 | country_codes[60]="UA" 217 | country_codes[61]="GB" 218 | country_codes[62]="US" 219 | country_codes[63]="VN" 220 | 221 | selectMirrorRegions() { 222 | checklist="" 223 | for i in {1..63} 224 | do 225 | checklist="$checklist $i ${countries[$i]} off" 226 | done 227 | 228 | mirror_regions=$(dialog --stdout --checklist "Choose Mirror Regions:" 25 40 15 $checklist) 229 | if [[ -z "${mirror_regions// }" ]]; then 230 | selectMirrorRegions 231 | fi 232 | } 233 | 234 | createMirrorList() { 235 | selectMirrorRegions 236 | 237 | args="" 238 | for i in $mirror_regions 239 | do 240 | echo "$i" 241 | args="$args --country ${country_codes[$i]}" 242 | done 243 | 244 | 245 | cmd="reflector $args --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist" 246 | dialog --infobox "Searching the best mirror in given regions... " 5 50; eval $cmd 247 | } 248 | init () { 249 | timedetect1 set-ntp true 250 | } 251 | 252 | autoPartition () { 253 | parted $1 --script mklabel msdos \ 254 | mkpart primary ext4 3MiB 100% \ 255 | set 1 boot on 2> /tmp/err || errorDialog "Failed to create disk partitions" 256 | 257 | yes | mkfs.ext4 "${1}1" > /dev/null 2> /tmp/err || error "Failed to format the boot partition" 258 | yes | mkfs.ext4 "${1}2" > /dev/null 2> /tmp/err || error "Failed to format the root partition" 259 | 260 | mount "${1}1" /mnt 261 | setvar "system-partition" "${1}2" 262 | } 263 | 264 | installCoreSystem () { 265 | getvar "system-partition" 266 | systempt=$value 267 | 268 | getvar "disk" 269 | disk=$value 270 | 271 | dialog --infobox "Looking for faster and more up-to-date mirrors for rest of the installation..." 6 50; findBestMirrors 272 | 273 | pacstrap /mnt base linux linux-firmware 274 | genfstab -U /mnt >> /mnt/etc/fstab 275 | 276 | setvar "core-install-step" "done" 277 | 278 | mkdir -p /mnt/usr/local/installer 279 | cp install-vars /mnt/usr/local/installer/. 280 | cp autorun.sh /mnt/usr/local/installer/install 281 | cp /etc/pacman.d/mirrorlist /mnt/etc/pacman.d/mirrorlist 282 | 283 | mkdir -p /mnt/etc/netctl 284 | cp /etc/netctl/* /mnt/etc/netctl/. 285 | 286 | arch-chroot /mnt < ./error-logs 290 | EOF 291 | 292 | if [ -f /mnt/tmp/reboot ]; then 293 | echo "Ciao!" 294 | reboot 295 | fi 296 | } 297 | 298 | installGRUB () { 299 | installPkg "grub" 300 | getvar "disk" 301 | grub-install --target=i386-pc --recheck $value > /dev/null 2> /tmp/err || errorDialog "Something got screwed and we failed to run grub-install" 302 | grub-mkconfig -o /boot/grub/grub.cfg > /dev/null 2> /tmp/err || errorDiaolog "Something got screwed up and we failed to create GRUB config." 303 | } 304 | 305 | localize () { 306 | yes | pip install tzupdate > /dev/null 2> /dev/null # ignore if it fails, let user choose tz 307 | 308 | tzSelectionMenu "Happy Hacking Linux" 309 | 310 | hwclock --systohc 311 | sed -i -e '/^#en_US/s/^#//' /etc/locale.gen # uncomment lines starting with #en_US 312 | locale-gen 2> /tmp/err || errorDialog "locale-gen is missing" 313 | 314 | # FIX ME: Allow user to choose language and keyboard 315 | echo "LANG=en_US.UTF-8" >> /etc/locale.conf 316 | echo "FONT=Lat2-Terminus16" >> /etc/vconsole.conf 317 | } 318 | 319 | createUser () { 320 | useradd -m -s /usr/bin/zsh $1 321 | echo "$1:$2" | chpasswd 322 | 323 | echo "$1 ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers 324 | echo $1 > /etc/hostname 325 | echo "127.0.1.1 $1.localdomain $1" >> /etc/hosts 326 | } 327 | 328 | linkDotFiles () { 329 | getvar "username" 330 | username=$value 331 | dotFilesBase=$(basename "$1" | cut -f 1 -d '.') 332 | target=/home/$username/$dotFilesBase 333 | runuser -l $username -c "git clone $1 $target" 334 | #runuser -l $username -c "git clone $1 $target && cd $target && for file in .*; do cd /home/$username && rm -rf \$file && ln -s $target/\$file \$file; done" > /dev/null 2> /tmp/err || errorDialog "Can not install dotfiles at $1 :/" 335 | } 336 | 337 | installHappyDesktopConfig () { 338 | getvar "username" 339 | username=$value 340 | runuser -l $username -c "git clone https://github.com/happy-hacking-linux/happy-desktop.git /home/$username/.happy-desktop" > /dev/null 2> /tmp/err || errorDialog "Failed to clone the default desktop configuration. Please check your connection." 341 | runuser -l $username -c "mkdir -p /home/$username/.config" 342 | runuser -l $username -c "cd /home/$username/.config && ln -sf /home/$username/.happy-desktop/config/* ." > /dev/null 2>> /tmp/err || errorDialog "Failed to link desktop configuration." 343 | runuser -l $username -c "cd /home/$username && ln -sf /home/$username/.happy-desktop/dotfiles/.* ." > /dev/null 2>> /tmp/err || errorDialog "Failed to link default dotfiles." 344 | } 345 | 346 | installZSH () { 347 | installPkg "zsh" 348 | 349 | chsh -s $(which zsh) > /dev/null 2> /tmp/err || errorDialog "Something got screwed up, we can't change the default shell to ZSH." 350 | getvar "username" 351 | username=$value 352 | chsh -s $(which zsh) $username > /dev/null 2> /tmp/err || errorDialog "Something got screwed up, we can't change the default shell to ZSH." 353 | } 354 | 355 | installOhMyZSH () { 356 | getvar "username" 357 | username=$value 358 | 359 | installAurPkg "oh-my-zsh-git" 360 | cp /usr/share/oh-my-zsh/zshrc /home/$username/.zshrc 361 | } 362 | 363 | installYay () { 364 | installAurPkg "yay" 365 | } 366 | 367 | installVirtualBox () { 368 | installPkg "virtualbox-guest-modules-arch" 369 | installPkg "virtualbox-guest-utils" 370 | echo -e "vboxguest\nvboxsf\nvboxvideo" > /etc/modules-load.d/virtualbox.conf 371 | systemctl enable vboxservice.service 372 | } 373 | 374 | installMacbook () { 375 | echo "options snd-hda-intel index=1,0" > /etc/modprobe.d/alsa.conf 376 | installAurPkg "bcwc-pcie-git" # Webcam support 377 | systemctl enable bluetooth 378 | } 379 | 380 | installBasicPackages () { 381 | installPkg "base-devel" 382 | installPkg "net-tools" 383 | installPkg "pkgfile" 384 | installPkg "xf86-video-vesa" 385 | installPkg "openssh" 386 | installPkg "wget" 387 | installPkg "git" 388 | installPkg "acpi" 389 | installPkg "powertop" 390 | installPkg "htop" 391 | installPkg "python" 392 | installPkg "python-pip" 393 | installPkg "wpa_supplicant" 394 | installPkg "mc" 395 | installPkg "httpie" 396 | installPkg "dnsutils" 397 | installPkg "tlp" 398 | installPkg "unzip" 399 | installPkg "xf86-input-synaptics" 400 | installPkg "bat" 401 | installPkg "prettyping" 402 | installPkg "fzf" 403 | installPkg "tldr" 404 | installPkg "ack" 405 | installPkg "tmux" 406 | installPkg "ranger" 407 | installPkg "lsd" 408 | installPkg "fd" 409 | installPkg "ripgrep" 410 | installPkg "irssi" 411 | installPkg "tree" 412 | installPkg "bandwhich" 413 | installPkg "wireless-regdb" 414 | installPkg "wireless_tools" 415 | installPkg "netctl" 416 | installPkg "ntfs-3g" 417 | installPkg "dhclient" 418 | installPkg "dhcpcd" 419 | installPkg "b43-fwcutter" 420 | installPkg "broadcom-wl" 421 | installPkg "vim" 422 | installAurPkg "skm" 423 | installZSH 424 | } 425 | 426 | installPrinterSupport () { 427 | installPkg "cups" 428 | installPkg "avahi" 429 | } 430 | 431 | upgrade () { 432 | pacman --noconfirm -Syu > /dev/null 2> /tmp/err || errorDialog "Failed to upgrade the system. Make sure being connected to internet." 433 | } 434 | 435 | findBestMirrors () { 436 | createMirrorList > /dev/null 2> /tmp/err || errorDialog "Something got screwed up and we couldn't accomplish finding some fast and up-to-date servers :(" 437 | } 438 | 439 | installYaourt () { 440 | runAsUser "git clone https://aur.archlinux.org/package-query.git /tmp/package-query" > /dev/null 2> /tmp/err || errorDialog "Can not access Arch Linux repositories, check your internet connection." 441 | runAsUser "cd /tmp/package-query && yes | makepkg -si" > /dev/null 2> /tmp/err || errorDialog "Failed to build package-query." 442 | runAsUser "git clone https://aur.archlinux.org/yaourt.git /tmp/yaourt" > /dev/null 2> /tmp/err || errorDialog "Can not access Arch Linux repositories, check your internet connection." 443 | runAsUser "cd /tmp/yaourt && yes | makepkg -si" > /dev/null 2> /tmp/err || errorDialog "Failed to build Yaourt" 444 | } 445 | 446 | installSwayDesktop () { 447 | installPkg "sway" 448 | installPkg "swaybg" 449 | installPkg "swayidle" 450 | installPkg "swaylock" 451 | installPkg "alacritty" 452 | installPkg "grim" 453 | installPkg "rofi" 454 | installPkg "waybar" 455 | installPkg "feh" 456 | installPkg "alsa-utils" 457 | installPkg "playerctl" 458 | installPkg "mako" 459 | installPkg "qalculate-gtk" 460 | installPkg "waybar" 461 | installPkg "ffmpeg" 462 | installPkg "jq" 463 | installPkg "xorg-server-xwayland" 464 | } 465 | 466 | installI3Desktop () { 467 | installPkg "xorg" 468 | installPkg "xorg-xinit" 469 | installPkg "compton" 470 | installPkg "i3-gaps" 471 | installPkg "i3status" 472 | installPkg "i3lock" 473 | installPkg "rofi" 474 | installPkg "feh" 475 | installPkg "unclutter" 476 | installPkg "scrot" 477 | installPkg "dmenu" 478 | installPkg "alsa-utils" 479 | installPkg "moc" 480 | installPkg "slop" 481 | installPkg "playerctl" 482 | installPkg "libnotify" 483 | installPkg "dunst" 484 | installPkg "qalculate-gtk" 485 | installPkg "compton" 486 | installPkg "udisks2" 487 | installPkg "udiskie" 488 | installPkg "imagemagick" 489 | installPkg "maim" 490 | installPkg "network-manager-applet" 491 | installAurPkg "polybar" 492 | installAurPkg "light-git" 493 | } 494 | 495 | installXfce4Desktop () { 496 | installPkg "xfce4" 497 | } 498 | 499 | installFonts () { 500 | installPkg "ttf-dejavu" 501 | installPkg "adobe-source-han-serif-otc-fonts" 502 | installPkg "adobe-source-han-sans-otc-fonts" 503 | installAurPkg "ttf-monaco" 504 | installAurPkg "noto-fonts-emoji" 505 | } 506 | 507 | installURXVT () { 508 | installAurPkg "rxvt-unicode-256xresources" > /dev/null 2> /tmp/err || errorDialog "Failed to install RXVT-Unicode with 256 colors" 509 | installPkg "urxvt-perls" 510 | } 511 | 512 | installRefind () { 513 | installPkg "refind-efi" 514 | runuser -l $username -c "refind-install" > /dev/null 2> /tmp/err 515 | getvar "system-partition" 516 | systempt=$value 517 | getUUID $systempt 518 | echo "\"Boot using default options\" \"root=UUID=$uuid rw add_efi_memmap\"" > /boot/refind_linux.conf 519 | echo "\"Boot using fallback initramfs\" \"root=UUID=$uuid rw add_efi_memmap initrd=/boot/initramfs-linux-fallback.img\"" >> /boot/refind_linux.conf 520 | echo "\"Boot to terminal\" \"root=UUID=$uuid rw add_efi_memmap systemd.unit=multi-user.target\"" >> /boot/refind_linux.conf 521 | } 522 | 523 | installPkg () { 524 | installationProgress "$1" 525 | pacman -S --noconfirm "$1" > /dev/null 2> /tmp/err || errorDialog "Something went wrong with installing $1. Try again." 526 | } 527 | 528 | installAurPkg () { 529 | installationProgress "$1" 530 | runAsUser "yaourt -S --noconfirm $1" > /dev/null 2> /tmp/err || errorDialog "Something went wrong with installing $1. Try again." 531 | } 532 | 533 | runAsUser () { 534 | # run given command as a non-root user 535 | getvar "username" 536 | username=$value 537 | runuser -l $username -c "$1" 538 | } 539 | 540 | getUUID() { 541 | name=$(sed 's/^\/dev\///' <<< $1) 542 | uuid=$(/bin/ls -la /dev/disk/by-uuid | grep "$name" | awk '{print $9}') 543 | } 544 | CHECK="[OK]" 545 | 546 | battery() { 547 | echo "| Battery: $(acpi | grep 'Battery' | sed 's/Battery\s[0-9]*: \w*, //' | sed 's/\%.*//')%" 548 | } 549 | 550 | startingDialogs () { 551 | nameDialog 552 | usernameDialog 553 | 554 | dotFilesRepo=$(dialog --stdout \ 555 | --title "=^.^=" \ 556 | --backtitle "Happy Hacking Linux $(battery)" \ 557 | --ok-label "Next" \ 558 | --cancel-label "Skip" \ 559 | --inputbox "Where is your dotfiles, $name?" 8 55 "https://github.com/$username/dotfiles.git") 560 | } 561 | 562 | mainMenu () { 563 | icon1="" 564 | icon2="" 565 | icon3="" 566 | icon4="" 567 | icon5="" 568 | 569 | getvar "partition-step" 570 | if [ "$value" = "done" ]; then 571 | icon1="${CHECK} " 572 | fi 573 | 574 | getvar "core-install-step" 575 | if [ "$value" = "done" ]; then 576 | icon2="${CHECK} " 577 | fi 578 | 579 | getvar "users-step" 580 | if [ "$value" = "done" ]; then 581 | icon3="${CHECK} " 582 | fi 583 | 584 | getvar "install-packages-step" 585 | if [ "$value" = "done" ]; then 586 | icon4="${CHECK} " 587 | fi 588 | 589 | getvar "localization-step" 590 | if [ "$value" = "done" ]; then 591 | icon5="${CHECK} " 592 | fi 593 | 594 | selected=$(dialog --stdout \ 595 | --title "=^.^=" \ 596 | --backtitle "Happy Hacking Linux $(battery)" \ 597 | --ok-label "Select" \ 598 | --cancel-label "Welcome Screen" \ 599 | --menu "Complete the following installation steps one by one." 16 55 8 \ 600 | 1 "${icon1}Setup Disk Partitions" \ 601 | 2 "${icon2}Install Core System" \ 602 | 3 "${icon3}Create Users" \ 603 | 4 "${icon4}Install Packages" \ 604 | 5 "${icon5}Localize" \ 605 | 6 "Reboot") 606 | 607 | button=$? 608 | } 609 | 610 | diskMenu () { 611 | disks=$(lsblk -r | grep disk | cut -d" " -f1,4 | nl) 612 | disksArray=() 613 | while read i name size; do 614 | disksArray+=($i "/dev/$name ($size)") 615 | done <<< "$disks" 616 | 617 | selected=$(dialog --stdout \ 618 | --title "Installation Disk" \ 619 | --backtitle "Happy Hacking Linux $(battery)" \ 620 | --ok-label "Next" \ 621 | --cancel-label "Main Menu" \ 622 | --menu "Select A Disk" \ 623 | 15 30 30 \ 624 | "${disksArray[@]}") 625 | 626 | button=$? 627 | 628 | selected=$(lsblk -r | grep disk | cut -d" " -f1 | sed -n "${selected}p") 629 | selected="/dev/${selected}" 630 | setvar "disk" "$selected" 631 | } 632 | 633 | partitionMenu () { 634 | selected=$(dialog --stdout \ 635 | --title "Setup Disk Partitions" \ 636 | --backtitle "Happy Hacking Linux $(battery)" \ 637 | --ok-label "Select" \ 638 | --cancel-label "Main Menu" \ 639 | --menu "How do you want to create partitions? If you got nothing to lose in $1, just go with the simple option and format the disk completely. Or, choose one of the tools to modify your disk in your own risk." 17 55 5 \ 640 | 1 "Simple: Erase Everything on $1" \ 641 | 2 "Manual: Using cfdisk" \ 642 | 3 "Manual: Using fdisk" \ 643 | 4 "Manual: Using GNU Parted") 644 | } 645 | 646 | partitionSelectionForm () { 647 | values=$(dialog --stdout \ 648 | --ok-label "Done" \ 649 | --backtitle "Happy Hacking Linux $(battery)" \ 650 | --title "Select Partitions" \ 651 | --nocancel \ 652 | --form "" \ 653 | 7 50 0 \ 654 | "Root Partition:" 2 1 "${1}X" 2 18 35 0) 655 | 656 | systempt=$(echo "$values" | tail -n1) 657 | 658 | dialog --title "Select Partitions" --yesno "Warning: $systempt will be formatted, continue?" 7 40 659 | 660 | if [ "$?" != "0" ]; then 661 | systempt="" 662 | fi 663 | 664 | if [[ -z "${systempt// }" ]]; then 665 | dialog --title "Select System Partition" \ 666 | --backtitle "Happy Hacking Linux $(battery)" \ 667 | --msgbox "Sorry, you have to choose the partition you'd like to install the system." 6 50 668 | partitionSelectionForm 669 | else 670 | yes | mkfs.ext4 $systempt > /dev/null 2> /tmp/err || error "Failed to format the root partition" 671 | mount $systempt /mnt > /dev/null 2> /tmp/err || error "Failed to mount the root partition" 672 | setvar "system-partition" $systempt 673 | fi 674 | } 675 | 676 | 677 | 678 | nameDialog () { 679 | name=$(dialog --stdout \ 680 | --title "=^.^" \ 681 | --backtitle "Happy Hacking Linux $(battery)" \ 682 | --ok-label "Next" \ 683 | --nocancel \ 684 | --inputbox "Oh, hai! What's your name?" 8 55) 685 | 686 | if [[ -z "${name// }" ]]; then 687 | dialog --title "=^.^=" \ 688 | --backtitle "Happy Hacking Linux $(battery)" \ 689 | --msgbox "Type your name please, or make something up" 5 55 690 | nameDialog 691 | fi 692 | } 693 | 694 | usernameDialog () { 695 | username=$(echo "$name" | sed -e 's/[^[:alnum:]]/-/g' | tr -s '-' | tr A-Z a-z) 696 | 697 | username=$(dialog --stdout \ 698 | --title "=^.^" \ 699 | --backtitle "Happy Hacking Linux $(battery)" \ 700 | --ok-label "Next" \ 701 | --nocancel \ 702 | --inputbox "...and your favorite username?" 8 55 "$username") 703 | 704 | if [[ -z "${username// }" ]]; then 705 | dialog --title "=^.^=" \ 706 | --backtitle "Happy Hacking Linux $(battery)" \ 707 | --msgbox "A username is required, try again" 5 55 708 | usernamedDialog 709 | fi 710 | } 711 | 712 | passwordDialog () { 713 | password=$(dialog --stdout \ 714 | --title "Creating User" \ 715 | --backtitle "Happy Hacking Linux $(battery)" \ 716 | --ok-label "Done" \ 717 | --nocancel \ 718 | --passwordbox "Type a new password:" 8 50) 719 | 720 | passwordRepeat=$(dialog --stdout \ 721 | --title "Creating User" \ 722 | --backtitle "Happy Hacking Linux $(battery)" \ 723 | --ok-label "Done" \ 724 | --nocancel \ 725 | --passwordbox "Verify your new password:" 8 50) 726 | 727 | if [ "$password" != "$passwordRepeat" ]; then 728 | dialog --title "Password" \ 729 | --backtitle "Happy Hacking Linux $(battery)" \ 730 | --msgbox "Passwords you've typed don't match. Try again." 5 50 731 | passwordDialog 732 | fi 733 | 734 | if [[ -z "${password// }" ]]; then 735 | dialog --title "Password" \ 736 | --backtitle "Happy Hacking Linux $(battery)" \ 737 | --msgbox "A password is required. Try again please." 5 50 738 | passwordDialog 739 | fi 740 | } 741 | 742 | errorDialog () { 743 | echo "$1\n\n" > ./install-errors.log 744 | [[ -f /tmp/err ]] && cat /tmp/err >> ./install-errors.log 745 | 746 | echo "Message: $1\nOutput: \n" | cat - /tmp/err > /tmp/err.bak && mv /tmp/err.bak /tmp/err 747 | 748 | dialog --title "Oops, there was an error" \ 749 | --backtitle "Happy Hacking Linux $(battery)" \ 750 | --textbox /tmp/err 20 50 751 | 752 | rm /tmp/err 753 | mainMenuStep 754 | } 755 | 756 | installationProgress () { 757 | total=72 758 | instcounter=$((instcounter+1)) 759 | percent=$((100*$instcounter/$total)) 760 | 761 | echo $percent | dialog --title "Installation" \ 762 | --backtitle "Happy Hacking Linux $(battery)" \ 763 | --gauge "Downloading package: $1" \ 764 | 7 70 0 765 | } 766 | command=$1 767 | 768 | mainMenuStep () { 769 | mainMenu 770 | 771 | if [ "$button" = "1" ]; then 772 | setvar "starting-step" "" 773 | startingStep 774 | return 775 | fi 776 | 777 | if [ "$selected" = "1" ]; then 778 | partitionStep 779 | elif [ "$selected" = "2" ]; then 780 | coreInstallStep 781 | elif [ "$selected" = "3" ]; then 782 | usersStep 783 | elif [ "$selected" = "4" ]; then 784 | installPackagesStep 785 | elif [ "$selected" = "5" ]; then 786 | localizeStep 787 | elif [ "$selected" = "6" ]; then 788 | exitStep 789 | fi 790 | } 791 | 792 | installVirtualBoxStep () { 793 | # Install VirtualBox Guest additions if the installation is running in a VirtualBox machine 794 | if lspci | grep -i virtualbox -q; then 795 | dialog --infobox "Looks like this is a VirtualBox setup, hold on please..." 5 50; installVirtualBox 796 | fi 797 | } 798 | 799 | installMacbookStep () { 800 | # Install Macbook if the installation is running in a Macbook 801 | if lspci | grep -i thunderbolt -q; then 802 | dialog --infobox "Looks like this is a Macbook, I'll do some adjustments for you..." 5 50; installMacbook 803 | fi 804 | } 805 | 806 | installDotFilesStep () { 807 | getvar "dot-files-repo" 808 | dotFilesRepo=$value 809 | 810 | if [[ -n "${dotFilesRepo// }" ]]; then 811 | dialog --infobox "Fingers crossed, we're linking your dotfiles into ~/" 5 50; linkDotFiles $dotFilesRepo 812 | fi 813 | } 814 | 815 | installBootStep () { 816 | getvar "boot-install-step" 817 | if [ "$value" != "done" ]; then 818 | dialog --title "Setup Boot" --yesno "Do you want me to override existing boot with new one ? Warning: You may lose access to a parallel system if exists." 8 40 819 | 820 | if [ "$?" == "0" ]; then 821 | dialog --infobox "Installing GRUB for /boot" 5 50; installGRUB 822 | setvar "boot-install-step" "done" 823 | else 824 | installRefindStep 825 | fi 826 | fi 827 | } 828 | 829 | installRefindStep () { 830 | getvar "boot-install-step" 831 | if [ "$value" != "done" ]; then 832 | dialog --title "Setup rEFInd" --yesno "Do you need rEFInd to be installed?" 8 40 833 | 834 | if [ "$?" == "0" ]; then 835 | dialog --infobox "Installing rEFInd" 5 50; installRefind 836 | fi 837 | fi 838 | } 839 | 840 | installYaourtStep () { 841 | getvar "install-yaourt-step" 842 | if [ "$value" == "done" ]; then 843 | return 844 | fi 845 | 846 | dialog --infobox "Installing AUR and Yaourt..." 5 50; installYaourt 847 | setvar "install-yaourt-step" "done" 848 | } 849 | 850 | findBestMirrorsStep () { 851 | getvar "find-best-mirrors-step" 852 | if [ "$value" == "done" ]; then 853 | return 854 | fi 855 | 856 | dialog --infobox "Looking for faster and more up-to-date mirrors for rest of the installation..." 6 50; findBestMirrors 857 | 858 | setvar "find-best-mirrors-step" "done" 859 | } 860 | 861 | installBasicPackagesStep () { 862 | getvar "install-basic-packages-step" 863 | if [ "$value" == "done" ]; then 864 | return 865 | fi 866 | 867 | installBasicPackages "Basic Packages" 868 | setvar "install-basic-packages-step" "done" 869 | } 870 | 871 | upgradeStep () { 872 | getvar "upgrade-step" 873 | if [ "$value" == "done" ]; then 874 | return 875 | fi 876 | 877 | dialog --infobox "Upgrading the system..." 5 50; upgrade 878 | 879 | setvar "upgrade-step" "done" 880 | } 881 | 882 | installPackagesStep () { 883 | getvar "install-packages-step" 884 | if [ "$value" == "done" ]; then 885 | localizeStep 886 | return 887 | fi 888 | 889 | upgradeStep 890 | installBasicPackagesStep 891 | installYaourtStep 892 | installYay 893 | installOhMyZSH 894 | installFonts 895 | installURXVT 896 | installSwayDesktop 897 | installDotFilesStep 898 | dialog --infobox "Configuring Happy Desktop..." 5 50; installHappyDesktopConfig 899 | installVirtualBoxStep 900 | installMacbookStep 901 | installBootStep 902 | 903 | setvar "install-packages-step" "done" 904 | 905 | localizeStep 906 | } 907 | 908 | finishingStep() { 909 | # Make sure brcmfmac is not blacklisted 910 | sed -i '/brcmfmac/d' /usr/lib/modprobe.d/broadcom-wl.conf 2> /dev/null 911 | # Enable the wifi interface 912 | systemctl enable netctl-auto@$(iw dev | awk '$1=="Interface"{print $2}') 913 | tlp start 914 | } 915 | 916 | exitStep () { 917 | dialog --infobox "Finishing touches..." 5 50; finishingStep 918 | 919 | dialog --title "=^.^=" \ 920 | --backtitle "Happy Hacking Linux" \ 921 | --yes-label "Reboot" \ 922 | --no-label "Main Menu" \ 923 | --yesno "Installation seems to be done, let's reboot your system. Don't forget ejecting the installation disk." 13 55 924 | if [ "$?" = "0" ]; then 925 | touch /tmp/reboot 926 | exit 927 | else 928 | mainMenuStep 929 | fi 930 | } 931 | 932 | usersStep () { 933 | getvar "users-step" 934 | 935 | if [ "$value" == "done" ]; then 936 | installPackagesStep 937 | return 938 | fi 939 | 940 | passwordDialog 941 | 942 | getvar "username" 943 | username=$value 944 | 945 | createUser $username $password 946 | 947 | setvar "users-step" "done" 948 | installPackagesStep 949 | } 950 | 951 | localizeStep () { 952 | getvar "localization-step" 953 | if [ "$value" != "done" ]; then 954 | localize 955 | setvar "localization-step" "done" 956 | fi 957 | 958 | exitStep 959 | } 960 | 961 | coreInstallStep () { 962 | getvar "core-install-step" 963 | if [ "$value" != "done" ]; then 964 | dialog --infobox "Bootstrapping the core system, it may take a while depending on your connection." 6 50; installCoreSystem 965 | setvar "core-install-step" "done" 966 | fi 967 | 968 | usersStep 969 | } 970 | 971 | partitionStep () { 972 | diskMenu 973 | 974 | if [ "$button" = "1" ]; then 975 | mainMenuStep 976 | return 977 | fi 978 | 979 | disk=$selected 980 | 981 | partitionMenu $disk 982 | 983 | if [ "$selected" = "1" ]; then 984 | dialog --title "Select Partitions" --yesno "Warning: Disk $disk will be formatted, continue?" 7 40 985 | if [ "$?" == "0" ]; then 986 | autoPartition $disk 987 | else 988 | partitionStep 989 | fi 990 | elif [ "$selected" = "2" ]; then 991 | cfdisk $disk 992 | partitionSelectionForm $disk 993 | elif [ "$selected" = "3" ]; then 994 | fdisk $disk 995 | partitionSelectionForm $disk 996 | elif [ "$selected" = "4" ]; then 997 | parted $disk 998 | partitionSelectionForm $disk 999 | elif [ "$selected" = "5" ]; then 1000 | mainMenuStep 1001 | return 1002 | else 1003 | mainMenuStep 1004 | return 1005 | fi 1006 | 1007 | setvar "partition-step" "done" 1008 | coreInstallStep 1009 | } 1010 | 1011 | networkStep () { 1012 | getvar "network-step" 1013 | if [ "$value" == "done" ]; then 1014 | partitionStep 1015 | fi 1016 | 1017 | gateway=`ip r | grep default | cut -d ' ' -f 3` 1018 | test=$(ping -q -w 1 -c 1 $gateway> /dev/null && echo 1 || echo 0) 1019 | 1020 | if [ $test -eq 1 ]; then 1021 | setvar "network-step" "done" 1022 | partitionStep 1023 | else 1024 | wifi-menu 1025 | sleep 1 1026 | ./autorun.sh network 1027 | fi 1028 | } 1029 | 1030 | startingStep () { 1031 | getvar "starting-step" 1032 | if [ "$value" == "done" ]; then 1033 | mainMenuStep 1034 | fi 1035 | 1036 | init 1037 | startingDialogs 1038 | 1039 | setvar "name" $name 1040 | setvar "username" $username 1041 | setvar "dot-files-repo" $dotFilesRepo 1042 | 1043 | setvar "starting-step" "done" 1044 | networkStep 1045 | } 1046 | 1047 | if [ "$command" = "continue" ]; then 1048 | usersStep 1049 | elif [ "$command" = "network" ]; then 1050 | networkStep 1051 | else 1052 | startingStep 1053 | fi 1054 | -------------------------------------------------------------------------------- /funcs.sh: -------------------------------------------------------------------------------- 1 | init () { 2 | timedetect1 set-ntp true 3 | } 4 | 5 | autoPartition () { 6 | parted $1 --script mklabel msdos \ 7 | mkpart primary ext4 3MiB 100% \ 8 | set 1 boot on 2> /tmp/err || errorDialog "Failed to create disk partitions" 9 | 10 | yes | mkfs.ext4 "${1}1" > /dev/null 2> /tmp/err || error "Failed to format the boot partition" 11 | yes | mkfs.ext4 "${1}2" > /dev/null 2> /tmp/err || error "Failed to format the root partition" 12 | 13 | mount "${1}1" /mnt 14 | setvar "system-partition" "${1}2" 15 | } 16 | 17 | installCoreSystem () { 18 | getvar "system-partition" 19 | systempt=$value 20 | 21 | getvar "disk" 22 | disk=$value 23 | 24 | dialog --infobox "Looking for faster and more up-to-date mirrors for rest of the installation..." 6 50; findBestMirrors 25 | 26 | pacstrap /mnt base linux linux-firmware 27 | genfstab -U /mnt >> /mnt/etc/fstab 28 | 29 | setvar "core-install-step" "done" 30 | 31 | mkdir -p /mnt/usr/local/installer 32 | cp install-vars /mnt/usr/local/installer/. 33 | cp autorun.sh /mnt/usr/local/installer/install 34 | cp /etc/pacman.d/mirrorlist /mnt/etc/pacman.d/mirrorlist 35 | 36 | mkdir -p /mnt/etc/netctl 37 | cp /etc/netctl/* /mnt/etc/netctl/. 38 | 39 | arch-chroot /mnt < ./error-logs 43 | EOF 44 | 45 | if [ -f /mnt/tmp/reboot ]; then 46 | echo "Ciao!" 47 | reboot 48 | fi 49 | } 50 | 51 | installGRUB () { 52 | installPkg "grub" 53 | getvar "disk" 54 | grub-install --target=i386-pc --recheck $value > /dev/null 2> /tmp/err || errorDialog "Something got screwed and we failed to run grub-install" 55 | grub-mkconfig -o /boot/grub/grub.cfg > /dev/null 2> /tmp/err || errorDiaolog "Something got screwed up and we failed to create GRUB config." 56 | } 57 | 58 | localize () { 59 | yes | pip install tzupdate > /dev/null 2> /dev/null # ignore if it fails, let user choose tz 60 | 61 | tzSelectionMenu "Happy Hacking Linux" 62 | 63 | hwclock --systohc 64 | sed -i -e '/^#en_US/s/^#//' /etc/locale.gen # uncomment lines starting with #en_US 65 | locale-gen 2> /tmp/err || errorDialog "locale-gen is missing" 66 | 67 | # FIX ME: Allow user to choose language and keyboard 68 | echo "LANG=en_US.UTF-8" >> /etc/locale.conf 69 | echo "FONT=Lat2-Terminus16" >> /etc/vconsole.conf 70 | } 71 | 72 | createUser () { 73 | useradd -m -s /usr/bin/zsh $1 74 | echo "$1:$2" | chpasswd 75 | 76 | echo "$1 ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers 77 | echo $1 > /etc/hostname 78 | echo "127.0.1.1 $1.localdomain $1" >> /etc/hosts 79 | } 80 | 81 | linkDotFiles () { 82 | getvar "username" 83 | username=$value 84 | dotFilesBase=$(basename "$1" | cut -f 1 -d '.') 85 | target=/home/$username/$dotFilesBase 86 | runuser -l $username -c "git clone $1 $target" 87 | #runuser -l $username -c "git clone $1 $target && cd $target && for file in .*; do cd /home/$username && rm -rf \$file && ln -s $target/\$file \$file; done" > /dev/null 2> /tmp/err || errorDialog "Can not install dotfiles at $1 :/" 88 | } 89 | 90 | installHappyDesktopConfig () { 91 | getvar "username" 92 | username=$value 93 | runuser -l $username -c "git clone https://github.com/happy-hacking-linux/happy-desktop.git /home/$username/.happy-desktop" > /dev/null 2> /tmp/err || errorDialog "Failed to clone the default desktop configuration. Please check your connection." 94 | runuser -l $username -c "mkdir -p /home/$username/.config" 95 | runuser -l $username -c "cd /home/$username/.config && ln -sf /home/$username/.happy-desktop/config/* ." > /dev/null 2>> /tmp/err || errorDialog "Failed to link desktop configuration." 96 | runuser -l $username -c "cd /home/$username && ln -sf /home/$username/.happy-desktop/dotfiles/.* ." > /dev/null 2>> /tmp/err || errorDialog "Failed to link default dotfiles." 97 | } 98 | 99 | installZSH () { 100 | installPkg "zsh" 101 | 102 | chsh -s $(which zsh) > /dev/null 2> /tmp/err || errorDialog "Something got screwed up, we can't change the default shell to ZSH." 103 | getvar "username" 104 | username=$value 105 | chsh -s $(which zsh) $username > /dev/null 2> /tmp/err || errorDialog "Something got screwed up, we can't change the default shell to ZSH." 106 | } 107 | 108 | installOhMyZSH () { 109 | getvar "username" 110 | username=$value 111 | 112 | installAurPkg "oh-my-zsh-git" 113 | cp /usr/share/oh-my-zsh/zshrc /home/$username/.zshrc 114 | } 115 | 116 | installYay () { 117 | installAurPkg "yay" 118 | } 119 | 120 | installVirtualBox () { 121 | installPkg "virtualbox-guest-modules-arch" 122 | installPkg "virtualbox-guest-utils" 123 | echo -e "vboxguest\nvboxsf\nvboxvideo" > /etc/modules-load.d/virtualbox.conf 124 | systemctl enable vboxservice.service 125 | } 126 | 127 | installMacbook () { 128 | # Fix sound 129 | echo "options snd-hda-intel index=1,0" > /etc/modprobe.d/alsa.conf 130 | 131 | # Create a service to make fix suspend issues 132 | cat <> /etc/systemd/system/suspend-fix.service 133 | [Unit] 134 | Description=System service that makes sure Macbook Pro doesn't wake up when lid is closed 135 | 136 | [Service] 137 | Type=oneshot 138 | ExecStart=/bin/sh -c "echo XHC1 > /proc/acpi/wakeup && echo LID0 > /proc/acpi/wakeup" 139 | 140 | [Install] 141 | WantedBy=multi-user.target 142 | EOT 143 | 144 | systemctl enable suspend-fix 145 | 146 | # Create a service to make fix suspend issues 147 | cat <> /etc/systemd/system/restart-network-after-suspend.service 148 | [Unit] 149 | Description=Restart network when resumed after suspend 150 | 151 | [Service] 152 | ExecStart=/bin/sh -c "modprobe -r brcmfmac && modprobe brcmfmac && sleep 1 && systemctl restart netctl" 153 | 154 | [Install] 155 | WantedBy=suspend.target 156 | EOT 157 | 158 | systemctl enable restart-network-after-suspend 159 | 160 | installAurPkg "bcwc-pcie-git" # Webcam support 161 | systemctl enable bluetooth 162 | 163 | } 164 | 165 | installBasicPackages () { 166 | installPkg "base-devel" 167 | installPkg "net-tools" 168 | installPkg "pkgfile" 169 | installPkg "xf86-video-vesa" 170 | installPkg "openssh" 171 | installPkg "wget" 172 | installPkg "git" 173 | installPkg "acpi" 174 | installPkg "powertop" 175 | installPkg "htop" 176 | installPkg "python" 177 | installPkg "python-pip" 178 | installPkg "wpa_supplicant" 179 | installPkg "mc" 180 | installPkg "httpie" 181 | installPkg "dnsutils" 182 | installPkg "tlp" 183 | installPkg "unzip" 184 | installPkg "xf86-input-synaptics" 185 | installPkg "bat" 186 | installPkg "prettyping" 187 | installPkg "fzf" 188 | installPkg "tldr" 189 | installPkg "ack" 190 | installPkg "tmux" 191 | installPkg "ranger" 192 | installPkg "lsd" 193 | installPkg "fd" 194 | installPkg "ripgrep" 195 | installPkg "irssi" 196 | installPkg "tree" 197 | installPkg "bandwhich" 198 | installPkg "wireless-regdb" 199 | installPkg "wireless_tools" 200 | installPkg "netctl" 201 | installPkg "ntfs-3g" 202 | installPkg "dhclient" 203 | installPkg "dhcpcd" 204 | installPkg "b43-fwcutter" 205 | installPkg "broadcom-wl" 206 | installPkg "vim" 207 | installPkg "libnotify" 208 | installAurPkg "skm" 209 | installZSH 210 | } 211 | 212 | installPrinterSupport () { 213 | installPkg "cups" 214 | installPkg "avahi" 215 | } 216 | 217 | upgrade () { 218 | pacman --noconfirm -Syu > /dev/null 2> /tmp/err || errorDialog "Failed to upgrade the system. Make sure being connected to internet." 219 | } 220 | 221 | findBestMirrors () { 222 | createMirrorList > /dev/null 2> /tmp/err || errorDialog "Something got screwed up and we couldn't accomplish finding some fast and up-to-date servers :(" 223 | } 224 | 225 | installYaourt () { 226 | runAsUser "git clone https://aur.archlinux.org/package-query.git /tmp/package-query" > /dev/null 2> /tmp/err || errorDialog "Can not access Arch Linux repositories, check your internet connection." 227 | runAsUser "cd /tmp/package-query && yes | makepkg -si" > /dev/null 2> /tmp/err || errorDialog "Failed to build package-query." 228 | runAsUser "git clone https://aur.archlinux.org/yaourt.git /tmp/yaourt" > /dev/null 2> /tmp/err || errorDialog "Can not access Arch Linux repositories, check your internet connection." 229 | runAsUser "cd /tmp/yaourt && yes | makepkg -si" > /dev/null 2> /tmp/err || errorDialog "Failed to build Yaourt" 230 | } 231 | 232 | installSwayDesktop () { 233 | installPkg "sway" 234 | installPkg "swaybg" 235 | installPkg "swayidle" 236 | installPkg "swaylock" 237 | installPkg "alacritty" 238 | installPkg "grim" 239 | installPkg "rofi" 240 | installPkg "waybar" 241 | installPkg "feh" 242 | installPkg "alsa-utils" 243 | installPkg "playerctl" 244 | installPkg "mako" 245 | installPkg "qalculate-gtk" 246 | installPkg "waybar" 247 | installPkg "ffmpeg" 248 | installPkg "jq" 249 | installPkg "xorg-server-xwayland" 250 | installPkg "imagemagick" 251 | installPkg "xdpyinfo" 252 | installPkg "slurp" 253 | } 254 | 255 | installI3Desktop () { 256 | installPkg "xorg" 257 | installPkg "xorg-xinit" 258 | installPkg "compton" 259 | installPkg "i3-gaps" 260 | installPkg "i3status" 261 | installPkg "i3lock" 262 | installPkg "rofi" 263 | installPkg "feh" 264 | installPkg "unclutter" 265 | installPkg "scrot" 266 | installPkg "dmenu" 267 | installPkg "alsa-utils" 268 | installPkg "moc" 269 | installPkg "slop" 270 | installPkg "playerctl" 271 | installPkg "libnotify" 272 | installPkg "dunst" 273 | installPkg "qalculate-gtk" 274 | installPkg "compton" 275 | installPkg "udisks2" 276 | installPkg "udiskie" 277 | installPkg "imagemagick" 278 | installPkg "maim" 279 | installAurPkg "polybar" 280 | installAurPkg "light-git" 281 | } 282 | 283 | installXfce4Desktop () { 284 | installPkg "xfce4" 285 | } 286 | 287 | installFonts () { 288 | installPkg "ttf-dejavu" 289 | installPkg "adobe-source-han-serif-otc-fonts" 290 | installPkg "adobe-source-han-sans-otc-fonts" 291 | installAurPkg "ttf-monaco" 292 | installAurPkg "noto-fonts-emoji" 293 | installAurPkg "system-san-francisco-font-git" 294 | } 295 | 296 | installURXVT () { 297 | installAurPkg "rxvt-unicode-256xresources" > /dev/null 2> /tmp/err || errorDialog "Failed to install RXVT-Unicode with 256 colors" 298 | installPkg "urxvt-perls" 299 | } 300 | 301 | installRefind () { 302 | installPkg "refind-efi" 303 | runuser -l $username -c "refind-install" > /dev/null 2> /tmp/err 304 | getvar "system-partition" 305 | systempt=$value 306 | getUUID $systempt 307 | echo "\"Boot using default options\" \"root=UUID=$uuid rw add_efi_memmap\"" > /boot/refind_linux.conf 308 | echo "\"Boot using fallback initramfs\" \"root=UUID=$uuid rw add_efi_memmap initrd=/boot/initramfs-linux-fallback.img\"" >> /boot/refind_linux.conf 309 | echo "\"Boot to terminal\" \"root=UUID=$uuid rw add_efi_memmap systemd.unit=multi-user.target\"" >> /boot/refind_linux.conf 310 | } 311 | 312 | installPkg () { 313 | installationProgress "$1" 314 | pacman -S --noconfirm "$1" > /dev/null 2> /tmp/err || errorDialog "Something went wrong with installing $1. Try again." 315 | } 316 | 317 | installAurPkg () { 318 | installationProgress "$1" 319 | runAsUser "yaourt -S --noconfirm $1" > /dev/null 2> /tmp/err || errorDialog "Something went wrong with installing $1. Try again." 320 | } 321 | 322 | runAsUser () { 323 | # run given command as a non-root user 324 | getvar "username" 325 | username=$value 326 | runuser -l $username -c "$1" 327 | } 328 | 329 | getUUID() { 330 | name=$(sed 's/^\/dev\///' <<< $1) 331 | uuid=$(/bin/ls -la /dev/disk/by-uuid | grep "$name" | awk '{print $9}') 332 | } 333 | -------------------------------------------------------------------------------- /mirror-selector.sh: -------------------------------------------------------------------------------- 1 | declare -A countries 2 | countries[1]="Australia" 3 | countries[2]="Austria" 4 | countries[3]="Bangladesh" 5 | countries[4]="Belarus" 6 | countries[5]="Belgium" 7 | countries[6]="Bosnia_and_Herzegovina" 8 | countries[7]="Brazil" 9 | countries[8]="Bulgaria" 10 | countries[9]="Canada" 11 | countries[10]="Chile" 12 | countries[11]="China" 13 | countries[12]="Colombia" 14 | countries[13]="Croatia" 15 | countries[14]="Czechia" 16 | countries[15]="Denmark" 17 | countries[16]="Ecuador" 18 | countries[17]="Finland" 19 | countries[18]="France" 20 | countries[19]="Georgia" 21 | countries[20]="Germany" 22 | countries[21]="Greece" 23 | countries[22]="Hong_Kong" 24 | countries[23]="Hungary" 25 | countries[24]="Iceland" 26 | countries[25]="India" 27 | countries[26]="Indonesia" 28 | countries[27]="Iran" 29 | countries[28]="Ireland" 30 | countries[29]="Israel" 31 | countries[30]="Italy" 32 | countries[31]="Japan" 33 | countries[32]="Kazakhstan" 34 | countries[33]="Kenya" 35 | countries[34]="Latvia" 36 | countries[35]="Lithuania" 37 | countries[36]="Luxembourg" 38 | countries[37]="Netherlands" 39 | countries[38]="New_Caledonia" 40 | countries[39]="New_Zealand" 41 | countries[40]="North_Macedonia" 42 | countries[41]="Norway" 43 | countries[42]="Paraguay" 44 | countries[43]="Philippines" 45 | countries[44]="Poland" 46 | countries[45]="Portugal" 47 | countries[46]="Romania" 48 | countries[47]="Russia" 49 | countries[48]="Serbia" 50 | countries[49]="Singapore" 51 | countries[50]="Slovakia" 52 | countries[51]="Slovenia" 53 | countries[52]="South_Africa" 54 | countries[53]="South_Korea" 55 | countries[54]="Spain" 56 | countries[55]="Sweden" 57 | countries[56]="Switzerland" 58 | countries[57]="Taiwan" 59 | countries[58]="Thailand" 60 | countries[59]="Turkey" 61 | countries[60]="Ukraine" 62 | countries[61]="United_Kingdom" 63 | countries[62]="United_States" 64 | countries[63]="Vietnam" 65 | 66 | declare -A country_codes 67 | country_codes[1]="AU" 68 | country_codes[2]="AT" 69 | country_codes[3]="BD" 70 | country_codes[4]="BY" 71 | country_codes[5]="BE" 72 | country_codes[6]="BA" 73 | country_codes[7]="BR" 74 | country_codes[8]="BG" 75 | country_codes[9]="CA" 76 | country_codes[10]="CL" 77 | country_codes[11]="CN" 78 | country_codes[12]="CO" 79 | country_codes[13]="HR" 80 | country_codes[14]="CZ" 81 | country_codes[15]="DK" 82 | country_codes[16]="EC" 83 | country_codes[17]="FI" 84 | country_codes[18]="FR" 85 | country_codes[19]="GE" 86 | country_codes[20]="DE" 87 | country_codes[21]="GR" 88 | country_codes[22]="HK" 89 | country_codes[23]="HU" 90 | country_codes[24]="IS" 91 | country_codes[25]="IN" 92 | country_codes[26]="ID" 93 | country_codes[27]="IR" 94 | country_codes[28]="IE" 95 | country_codes[29]="IL" 96 | country_codes[30]="IT" 97 | country_codes[31]="JP" 98 | country_codes[32]="KZ" 99 | country_codes[33]="KE" 100 | country_codes[34]="LV" 101 | country_codes[35]="LT" 102 | country_codes[36]="LU" 103 | country_codes[37]="NL" 104 | country_codes[38]="NC" 105 | country_codes[39]="NZ" 106 | country_codes[40]="MK" 107 | country_codes[41]="NO" 108 | country_codes[42]="PY" 109 | country_codes[43]="PH" 110 | country_codes[44]="PL" 111 | country_codes[45]="PT" 112 | country_codes[46]="RO" 113 | country_codes[47]="RU" 114 | country_codes[48]="RS" 115 | country_codes[49]="SG" 116 | country_codes[50]="SK" 117 | country_codes[51]="SI" 118 | country_codes[52]="ZA" 119 | country_codes[53]="KR" 120 | country_codes[54]="ES" 121 | country_codes[55]="SE" 122 | country_codes[56]="CH" 123 | country_codes[57]="TW" 124 | country_codes[58]="TH" 125 | country_codes[59]="TR" 126 | country_codes[60]="UA" 127 | country_codes[61]="GB" 128 | country_codes[62]="US" 129 | country_codes[63]="VN" 130 | 131 | selectMirrorRegions() { 132 | checklist="" 133 | for i in {1..63} 134 | do 135 | checklist="$checklist $i ${countries[$i]} off" 136 | done 137 | 138 | mirror_regions=$(dialog --stdout --checklist "Choose Mirror Regions:" 25 40 15 $checklist) 139 | if [[ -z "${mirror_regions// }" ]]; then 140 | selectMirrorRegions 141 | fi 142 | } 143 | 144 | createMirrorList() { 145 | selectMirrorRegions 146 | 147 | args="" 148 | for i in $mirror_regions 149 | do 150 | echo "$i" 151 | args="$args --country ${country_codes[$i]}" 152 | done 153 | 154 | 155 | cmd="reflector $args --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist" 156 | dialog --infobox "Searching the best mirror in given regions... " 5 50; eval $cmd 157 | } 158 | -------------------------------------------------------------------------------- /steps.sh: -------------------------------------------------------------------------------- 1 | 2 | command=$1 3 | 4 | mainMenuStep () { 5 | mainMenu 6 | 7 | if [ "$button" = "1" ]; then 8 | setvar "starting-step" "" 9 | startingStep 10 | return 11 | fi 12 | 13 | if [ "$selected" = "1" ]; then 14 | partitionStep 15 | elif [ "$selected" = "2" ]; then 16 | coreInstallStep 17 | elif [ "$selected" = "3" ]; then 18 | usersStep 19 | elif [ "$selected" = "4" ]; then 20 | installPackagesStep 21 | elif [ "$selected" = "5" ]; then 22 | localizeStep 23 | elif [ "$selected" = "6" ]; then 24 | exitStep 25 | fi 26 | } 27 | 28 | installVirtualBoxStep () { 29 | # Install VirtualBox Guest additions if the installation is running in a VirtualBox machine 30 | if lspci | grep -i virtualbox -q; then 31 | dialog --infobox "Looks like this is a VirtualBox setup, hold on please..." 5 50; installVirtualBox 32 | fi 33 | } 34 | 35 | installMacbookStep () { 36 | # Install Macbook if the installation is running in a Macbook 37 | if lspci | grep -i thunderbolt -q; then 38 | dialog --infobox "Looks like this is a Macbook, I'll do some adjustments for you..." 5 50; installMacbook 39 | fi 40 | } 41 | 42 | installDotFilesStep () { 43 | getvar "dot-files-repo" 44 | dotFilesRepo=$value 45 | 46 | if [[ -n "${dotFilesRepo// }" ]]; then 47 | dialog --infobox "Fingers crossed, we're linking your dotfiles into ~/" 5 50; linkDotFiles $dotFilesRepo 48 | fi 49 | } 50 | 51 | installBootStep () { 52 | getvar "boot-install-step" 53 | if [ "$value" != "done" ]; then 54 | dialog --title "Setup Boot" --yesno "Do you want me to override existing boot with new one ? Warning: You may lose access to a parallel system if exists." 8 40 55 | 56 | if [ "$?" == "0" ]; then 57 | dialog --infobox "Installing GRUB for /boot" 5 50; installGRUB 58 | setvar "boot-install-step" "done" 59 | else 60 | installRefindStep 61 | fi 62 | fi 63 | } 64 | 65 | installRefindStep () { 66 | getvar "boot-install-step" 67 | if [ "$value" != "done" ]; then 68 | dialog --title "Setup rEFInd" --yesno "Do you need rEFInd to be installed?" 8 40 69 | 70 | if [ "$?" == "0" ]; then 71 | dialog --infobox "Installing rEFInd" 5 50; installRefind 72 | fi 73 | fi 74 | } 75 | 76 | installYaourtStep () { 77 | getvar "install-yaourt-step" 78 | if [ "$value" == "done" ]; then 79 | return 80 | fi 81 | 82 | dialog --infobox "Installing AUR and Yaourt..." 5 50; installYaourt 83 | setvar "install-yaourt-step" "done" 84 | } 85 | 86 | findBestMirrorsStep () { 87 | getvar "find-best-mirrors-step" 88 | if [ "$value" == "done" ]; then 89 | return 90 | fi 91 | 92 | dialog --infobox "Looking for faster and more up-to-date mirrors for rest of the installation..." 6 50; findBestMirrors 93 | 94 | setvar "find-best-mirrors-step" "done" 95 | } 96 | 97 | installBasicPackagesStep () { 98 | getvar "install-basic-packages-step" 99 | if [ "$value" == "done" ]; then 100 | return 101 | fi 102 | 103 | installBasicPackages "Basic Packages" 104 | setvar "install-basic-packages-step" "done" 105 | } 106 | 107 | upgradeStep () { 108 | getvar "upgrade-step" 109 | if [ "$value" == "done" ]; then 110 | return 111 | fi 112 | 113 | dialog --infobox "Upgrading the system..." 5 50; upgrade 114 | 115 | setvar "upgrade-step" "done" 116 | } 117 | 118 | installPackagesStep () { 119 | getvar "install-packages-step" 120 | if [ "$value" == "done" ]; then 121 | localizeStep 122 | return 123 | fi 124 | 125 | upgradeStep 126 | installBasicPackagesStep 127 | installYaourtStep 128 | installYay 129 | installOhMyZSH 130 | installFonts 131 | installSwayDesktop 132 | installDotFilesStep 133 | dialog --infobox "Configuring Happy Desktop..." 5 50; installHappyDesktopConfig 134 | installVirtualBoxStep 135 | installMacbookStep 136 | installBootStep 137 | 138 | setvar "install-packages-step" "done" 139 | 140 | localizeStep 141 | } 142 | 143 | finishingStep() { 144 | # Make sure brcmfmac is not blacklisted 145 | sed -i '/brcmfmac/d' /usr/lib/modprobe.d/broadcom-wl.conf 2> /dev/null 146 | # Enable the wifi interface 147 | systemctl enable netctl-auto@$(iw dev | awk '$1=="Interface"{print $2}') 148 | tlp start 149 | } 150 | 151 | exitStep () { 152 | dialog --infobox "Finishing touches..." 5 50; finishingStep 153 | 154 | dialog --title "=^.^=" \ 155 | --backtitle "Happy Hacking Linux" \ 156 | --yes-label "Reboot" \ 157 | --no-label "Main Menu" \ 158 | --yesno "Installation seems to be done, let's reboot your system. Don't forget ejecting the installation disk." 13 55 159 | if [ "$?" = "0" ]; then 160 | touch /tmp/reboot 161 | exit 162 | else 163 | mainMenuStep 164 | fi 165 | } 166 | 167 | usersStep () { 168 | getvar "users-step" 169 | 170 | if [ "$value" == "done" ]; then 171 | installPackagesStep 172 | return 173 | fi 174 | 175 | passwordDialog 176 | 177 | getvar "username" 178 | username=$value 179 | 180 | createUser $username $password 181 | 182 | setvar "users-step" "done" 183 | installPackagesStep 184 | } 185 | 186 | localizeStep () { 187 | getvar "localization-step" 188 | if [ "$value" != "done" ]; then 189 | localize 190 | setvar "localization-step" "done" 191 | fi 192 | 193 | exitStep 194 | } 195 | 196 | coreInstallStep () { 197 | getvar "core-install-step" 198 | if [ "$value" != "done" ]; then 199 | dialog --infobox "Bootstrapping the core system, it may take a while depending on your connection." 6 50; installCoreSystem 200 | setvar "core-install-step" "done" 201 | fi 202 | 203 | usersStep 204 | } 205 | 206 | partitionStep () { 207 | diskMenu 208 | 209 | if [ "$button" = "1" ]; then 210 | mainMenuStep 211 | return 212 | fi 213 | 214 | disk=$selected 215 | 216 | partitionMenu $disk 217 | 218 | if [ "$selected" = "1" ]; then 219 | dialog --title "Select Partitions" --yesno "Warning: Disk $disk will be formatted, continue?" 7 40 220 | if [ "$?" == "0" ]; then 221 | autoPartition $disk 222 | else 223 | partitionStep 224 | fi 225 | elif [ "$selected" = "2" ]; then 226 | cfdisk $disk 227 | partitionSelectionForm $disk 228 | elif [ "$selected" = "3" ]; then 229 | fdisk $disk 230 | partitionSelectionForm $disk 231 | elif [ "$selected" = "4" ]; then 232 | parted $disk 233 | partitionSelectionForm $disk 234 | elif [ "$selected" = "5" ]; then 235 | mainMenuStep 236 | return 237 | else 238 | mainMenuStep 239 | return 240 | fi 241 | 242 | setvar "partition-step" "done" 243 | coreInstallStep 244 | } 245 | 246 | networkStep () { 247 | getvar "network-step" 248 | if [ "$value" == "done" ]; then 249 | partitionStep 250 | fi 251 | 252 | gateway=`ip r | grep default | cut -d ' ' -f 3` 253 | test=$(ping -q -w 1 -c 1 $gateway> /dev/null && echo 1 || echo 0) 254 | 255 | if [ $test -eq 1 ]; then 256 | setvar "network-step" "done" 257 | partitionStep 258 | else 259 | wifi-menu 260 | sleep 1 261 | ./autorun.sh network 262 | fi 263 | } 264 | 265 | startingStep () { 266 | getvar "starting-step" 267 | if [ "$value" == "done" ]; then 268 | mainMenuStep 269 | fi 270 | 271 | init 272 | startingDialogs 273 | 274 | setvar "name" $name 275 | setvar "username" $username 276 | setvar "dot-files-repo" $dotFilesRepo 277 | 278 | setvar "starting-step" "done" 279 | networkStep 280 | } 281 | 282 | if [ "$command" = "continue" ]; then 283 | usersStep 284 | elif [ "$command" = "network" ]; then 285 | networkStep 286 | else 287 | startingStep 288 | fi 289 | -------------------------------------------------------------------------------- /timezone-selector.sh: -------------------------------------------------------------------------------- 1 | detectTimezone () { 2 | if command_exists tzupdate ; then 3 | dialog --infobox "Please wait, detecting your timezone... " 5 50; detected=$(tzupdate -p | sed "s/Detected timezone is //" | sed "s/\.//") 4 | return 5 | fi 6 | 7 | detected="" 8 | } 9 | 10 | tzOptionsByRegion () { 11 | options=$(cd /usr/share/zoneinfo/$1 && find . | sed "s|^\./||" | sed "s/^\.//" | sed '/^$/d') 12 | } 13 | 14 | tzRegions () { 15 | regions=$(find /usr/share/zoneinfo/. -maxdepth 1 -type d | cut -d "/" -f6 | sed '/^$/d') 16 | } 17 | 18 | tzSelectionMenu () { 19 | detectTimezone 20 | 21 | if [[ -n "${detected// }" ]]; then 22 | if [ -f "/usr/share/zoneinfo/$detected" ]; then 23 | offset=$(TZ="$detected" date +%z | sed "s/00$/:00/g") 24 | 25 | dialog --title "Timezones" \ 26 | --backtitle "Happy Hacking Linux" \ 27 | --yes-label "Yes, correct" \ 28 | --no-label "No, I'll choose it" \ 29 | --yesno "Your timezone was detected as $detected ($offset). Is it correct?" 7 50 30 | selected=$? 31 | 32 | if [ "$selected" = "0" ]; then 33 | tzupdate > /dev/null 34 | return 35 | fi 36 | fi 37 | fi 38 | 39 | tzRegions 40 | regionsArray=() 41 | while read name; do 42 | regionsArray+=($name "") 43 | done <<< "$regions" 44 | 45 | region=$(dialog --stdout \ 46 | --title "Timezones" \ 47 | --backtitle "$1" \ 48 | --ok-label "Next" \ 49 | --no-cancel \ 50 | --menu "Select a continent or ocean from the menu:" \ 51 | 20 30 30 \ 52 | "${regionsArray[@]}") 53 | 54 | tzOptionsByRegion $region 55 | 56 | optionsArray=() 57 | while read name; do 58 | offset=$(TZ="$region/$name" date +%z | sed "s/00$/:00/g") 59 | optionsArray+=($name "($offset)") 60 | done <<< "$options" 61 | 62 | tz=$(dialog --stdout \ 63 | --title "Timezones" \ 64 | --backtitle "$1" \ 65 | --ok-label "Next" \ 66 | --cancel-label "Back to Regions" \ 67 | --menu "Select your timezone in ${region}:" \ 68 | 20 40 30 \ 69 | "${optionsArray[@]}") 70 | 71 | if [[ -z "${tz// }" ]]; then 72 | tzSelectionMenu 73 | else 74 | selected="/usr/share/zoneinfo/$region/$tz" 75 | fi 76 | } 77 | 78 | command_exists () { 79 | type "$1" &> /dev/null ; 80 | } 81 | -------------------------------------------------------------------------------- /vars.sh: -------------------------------------------------------------------------------- 1 | touch ./install-vars 2 | 3 | setvar () { 4 | grep -v "^$1=" ./install-vars > ./install-vars.new && mv ./install-vars.new ./install-vars 5 | echo "$1=$2" >> ./install-vars 6 | } 7 | 8 | getvar () { 9 | value=$(grep "^$1=" ./install-vars | tail -n 1 | sed "s/^$1=//") 10 | } 11 | --------------------------------------------------------------------------------