├── sbin └── pentoo-installer └── share ├── applications ├── pentoo-installer.desktop └── sudo-pentoo-installer.desktop └── pentoo-installer ├── FSspec ├── FSspec_add ├── FSspec_edit ├── bootloader_common.sh ├── bootloader_grub2 ├── bootloader_mainmenu ├── bootloader_uefi ├── common.sh ├── config-samples ├── config.bios.msdos.json ├── config.bios.msdos.withexisting.json ├── config.efi.gpt.json └── config.efi.msdos.json ├── configure_system ├── copy_distro ├── error.sh ├── gauge_unsquashfs ├── partition_autoconfig ├── partition_autoprepare ├── partition_autoprepare_uefi ├── partition_common.sh ├── partition_configurations ├── partition_finalise ├── partition_mainmenu ├── partition_manual ├── pentoo-installer ├── rsync.awk ├── save_settings.sh ├── setprofile ├── settzclock ├── template_menu ├── tzselect_dialog ├── welcome.Xdialog.txt └── welcome.dialog.txt /sbin/pentoo-installer: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -n "$(command -v id 2> /dev/null)" ]; then 3 | USERID="$(id -u 2> /dev/null)" 4 | fi 5 | if [ -z "${USERID}" ] && [ -n "$(id -ru)" ]; then 6 | USERID="$(id -ru)" 7 | fi 8 | if [ -n "${USERID}" ] && [ "${USERID}" != "0" ]; then 9 | printf "Please run pentoo-installer as root, ex: 'sudo pentoo-installer'\n" 10 | exit 1 11 | elif [ -z "${USERID}" ]; then 12 | printf "Unable to determine user id, permission errors may occur.\n" 13 | printf "Press any key to continue anyway, or ctrl+c to quit..." 14 | read -r 15 | fi 16 | exec 3>&2 17 | /usr/share/pentoo-installer/pentoo-installer "${@}" 2> /tmp/pentoo-installer.log 18 | -------------------------------------------------------------------------------- /share/applications/pentoo-installer.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Name=pentoo-installer 5 | Comment=Install Pentoo! 6 | Exec=/usr/sbin/pentoo-installer 7 | Icon=pentoo 8 | Path=/root/ 9 | Terminal=true 10 | StartupNotify=false 11 | -------------------------------------------------------------------------------- /share/applications/sudo-pentoo-installer.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Type=Application 4 | Name=pentoo-installer 5 | Comment=Install Pentoo! 6 | Exec=sudo /usr/sbin/pentoo-installer 7 | Icon=pentoo 8 | Path=/root/ 9 | Terminal=true 10 | StartupNotify=false 11 | -------------------------------------------------------------------------------- /share/pentoo-installer/FSspec: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # FSspec 6 | # handler for the FSspec format defined below 7 | # all actions with FSspec should use this 8 | 9 | # FSspec definition 10 | # contains the following key-value pairs: 11 | # partition 12 | # mountpoint 13 | # filesystem 14 | # crypttype (one of: 'swap', 'luks2', 'luks2-gpg', '') 15 | # format (0=no 1=yes) 16 | # cryptname (name used by cryptsetup) 17 | # partuuid (PARTUUID, *not* the UUID) 18 | # cryptkey 19 | # 20 | # mountpoint of a swap partition must be empty 21 | # all non swap partitions must have a mountpoint 22 | # root partition can only be encrypted when /boot is on another partition 23 | # values cannot contain white-space or the ":" character! 24 | # 25 | # internal: 26 | # the definition is stored as one long string of key:value:key:value:... 27 | # order of keys is important! 28 | 29 | # writes errors and noise to STDERR 30 | 31 | # location of other scripts to source 32 | readonly SHAREDIR="$(dirname ${0})" || exit $? 33 | 34 | # source common variables, functions and error handling 35 | source "${SHAREDIR}"/common.sh || exit $? 36 | 37 | # DEBUG_CHECKS if '1', then time-consuming extra checks are done 38 | readonly DEBUG_CHECKS=0 39 | 40 | readonly FSspec_DEFINITION=(partition mountpoint filesystem crypttype format cryptname partuuid cryptkey) || exit $? 41 | readonly CONFIG_SEPARATOR=':' || exit $? 42 | 43 | 44 | ############################# 45 | ## START: utility functions## 46 | 47 | # FSspec_create() 48 | # creates an FSspec string from the input variables and writes it to STDOUT 49 | # for external use, not all values of an FSspec are required as input 50 | # 51 | # returns 0 on success 52 | # anything else is a real error 53 | # 54 | # parameters (required): 55 | # these items of an FSspec in this order 56 | # partition, mountpoint, filesystem, crypttype, format 57 | # 58 | FSspec_create() { 59 | # check input 60 | check_num_args "${FUNCNAME}" 5 $# || return $? 61 | local _PARTUUID= 62 | # set partuuid 63 | _PARTUUID="$(blkid -s PARTUUID -o value "${1}")" || return $? 64 | # simply call the internal create function with empty strings for missing FSspec items 65 | FSspec_createfull "${1}" "${2}" "${3}" "${4}" "${5}" "" "${_PARTUUID}" "" 66 | } 67 | 68 | # FSspec_createfull() 69 | # creates an FSspec string from the input variables and writes it to STDOUT 70 | # 71 | # returns 0 on success 72 | # anything else is a real error 73 | # 74 | # parameters (required): 75 | # all items of an FSspec in correct order 76 | # 77 | FSspec_createfull() { 78 | # check input 79 | check_num_args "${FUNCNAME}" 8 $# || return $? 80 | local _PARTITION="${1}" 81 | local _MOUNTPOINT="${2}" 82 | local _FILESYSTEM="${3}" 83 | local _CRYPTTYPE="${4}" 84 | local _FORMAT="${5}" 85 | local _CRYPTNAME="${6}" 86 | local _PARTUUID="${7}" 87 | local _CRYPTKEY="${8}" 88 | # check values for spaces or delimiter char 89 | while (( "$#" )); do 90 | if echo "${1}" | grep -q "[[:space:]${CONFIG_SEPARATOR}'\"]"; then 91 | echo "Error: value cannot contain spaces or these ${CONFIG_SEPARATOR}'\" characters" 1>&2 92 | return 1 93 | fi 94 | shift 95 | done 96 | # convert boolean values to 0 or 1 97 | [ "${_FORMAT}" != '1' ] && _FORMAT=0 98 | # validate 99 | if [ -z "${_PARTITION}" ] || [ -z "${_FILESYSTEM}" ]; then 100 | echo "error parsing config, partition or filesystem missing" 1>&2 101 | return 1 102 | fi 103 | # swap partition cannot have mountpoint 104 | if [ "${_FILESYSTEM}" = 'swap' ]; then 105 | if [ -n "${_MOUNTPOINT}" ]; then 106 | echo "error parsing config, swap partition cannot have mountpoint" 1>&2 107 | return 1 108 | fi 109 | # non swap partition, must have mountpoint 110 | elif [ -z "${_MOUNTPOINT}" ]; then 111 | echo "error parsing config, partition must have mountpoint" 1>&2 112 | return 1 113 | fi 114 | # validate crypttype 115 | if [ "${_CRYPTTYPE}" != '' ]; then 116 | # check crypttype 117 | # swap must have swap as type 118 | if [ "${_FILESYSTEM}" = 'swap' ]; then 119 | if [ "${_CRYPTTYPE}" != 'swap' ]; then 120 | echo "error parsing config, wrong crypttype for swap partition" 1>&2 121 | return 1 122 | fi 123 | # non-swap 124 | else 125 | # /boot 126 | if [ "${_MOUNTPOINT}" = '/boot' ]; then 127 | echo "error parsing config, partition on mountpoint '/boot' cannot be encrypted" 1>&2 128 | return 1 129 | # root partition 130 | elif [ "${_MOUNTPOINT}" = '/' ]; then 131 | # check crypttype 132 | if [ "${_CRYPTTYPE}" != 'luks2-gpg' ]; then 133 | echo "error parsing config, wrong crypttype for root partition" 1>&2 134 | return 1 135 | fi 136 | # non-root partition, check crypttype 137 | elif [ "${_CRYPTTYPE}" != 'luks2' ] && [ "${_CRYPTTYPE}" != 'luks2-gpg' ]; then 138 | echo "error parsing config, unexpected crypttype '${_CRYPTTYPE}'" 1>&2 139 | return 1 140 | fi 141 | fi 142 | fi 143 | # check partuuid 144 | if [ "${_PARTUUID}" != "$(blkid -s PARTUUID -o value "${_PARTITION}")" ]; then 145 | echo "error parsing config, partition '${_PARTITION}' does not have expected partuuid '${_PARTUUID}'" 1>&2 146 | return 1 147 | fi 148 | # everything ok, write to STDOUT and return 0 149 | echo -n "partition${CONFIG_SEPARATOR}${_PARTITION}" 150 | echo -n "${CONFIG_SEPARATOR}" 151 | echo -n "mountpoint${CONFIG_SEPARATOR}${_MOUNTPOINT}" 152 | echo -n "${CONFIG_SEPARATOR}" 153 | echo -n "filesystem${CONFIG_SEPARATOR}${_FILESYSTEM}" 154 | echo -n "${CONFIG_SEPARATOR}" 155 | echo -n "crypttype${CONFIG_SEPARATOR}${_CRYPTTYPE}" 156 | echo -n "${CONFIG_SEPARATOR}" 157 | echo -n "format${CONFIG_SEPARATOR}${_FORMAT}" 158 | echo -n "${CONFIG_SEPARATOR}" 159 | echo -n "cryptname${CONFIG_SEPARATOR}${_CRYPTNAME}" 160 | echo -n "${CONFIG_SEPARATOR}" 161 | echo -n "partuuid${CONFIG_SEPARATOR}${_PARTUUID}" 162 | echo -n "${CONFIG_SEPARATOR}" 163 | echo -n "cryptkey${CONFIG_SEPARATOR}${_CRYPTKEY}" 164 | return 0 165 | } 166 | 167 | # FSspec_del_keyvalue() 168 | # parses a list of FSspec and deletes all elements with key=value 169 | # all other items from the list are printed to STDOUT 170 | # 171 | # returns 0 on success 172 | # anything else is a real error 173 | # 174 | # parameters (required): 175 | # config_list: see defined FSscpec format 176 | # key: see defined FSscpec format 177 | # value: search for this 178 | # 179 | FSspec_del_keyvalue() { 180 | # check input 181 | check_num_args "${FUNCNAME}" 3 $# || return $? 182 | local _FIRST=1 183 | local _ITEM= 184 | local _TMPVAL= 185 | # loop list and output item if key=value not true 186 | for _ITEM in ${1}; do 187 | _TMPVAL="$(FSspec_parse "${_ITEM}" "${2}")" || return $? 188 | if [ "${_TMPVAL}" != "${3}" ]; then 189 | [ "${_FIRST}" -ne 1 ] && echo -n ' ' 190 | [ "${_FIRST}" -eq 1 ] && _FIRST=0 191 | echo -n "${_ITEM}" 192 | fi 193 | done 194 | return 0 195 | } 196 | 197 | # FSspec_list_haskeyvalue() 198 | # checks if a list of FSspec has a key=value element 199 | # 200 | # returns 0 when found, 1 when not found 201 | # 202 | # parameters (required): 203 | # config_list: see defined FSscpec format 204 | # key: see defined FSscpec format 205 | # value: search for this 206 | # 207 | FSspec_list_haskeyvalue() { 208 | # check input 209 | check_num_args "${FUNCNAME}" 3 $# || return $? 210 | FSspec_listfind "${@}" 1>/dev/null 211 | return $? 212 | } 213 | 214 | # FSspec_listfind() 215 | # parses a list of FSspec-strings, searches for matching key=value 216 | # and prints first matching list item to STDOUT 217 | # 218 | # returns 0 on success 219 | # anything else is a real error 220 | # 221 | # parameters (required): 222 | # config_list: see defined FSscpec format 223 | # varname: an item of the FSspec format 224 | # varvalue: the value to search for 225 | # 226 | FSspec_listfind() { 227 | # check input 228 | check_num_args "${FUNCNAME}" 3 $# || return $? 229 | local _ITEM= 230 | local _TMPVALUE= 231 | for _ITEM in ${1}; do 232 | _TMPVALUE="$(FSspec_parse "${_ITEM}" "${2}")" || return $? 233 | if [ "${_TMPVALUE}" = "${3}" ]; then 234 | echo "${_ITEM}" 235 | return 0 236 | fi 237 | done 238 | # item not found, exit ungracefully 239 | return 1 240 | } 241 | 242 | # FSspec_merge() 243 | # merges a list of old config with a list of new ones by their partition 244 | # partitions in both lists: new config is used 245 | # partitions which do not exist are removed 246 | # all other items from both lists are printed to STDOUT 247 | # 248 | # returns 0 on success 249 | # anything else is a real error 250 | # 251 | # parameters (required): 252 | # list_old_configs: list of FSspec items, see defined FSscpec format 253 | # list_new_configs: list of FSspec items, see defined FSscpec format 254 | # 255 | FSspec_merge() { 256 | # check input 257 | check_num_args "${FUNCNAME}" 2 $# || return $? 258 | local _LIST_OLD="${1}" 259 | local _LIST_NEW="${2}" 260 | local _LIST_RESULT= 261 | local _ITEM_OLD= 262 | local _ITEM_NEW= 263 | local _PARTITION_NEW= 264 | local _PARTITION_OLD= 265 | local _MOUNTPOINT_NEW= 266 | local _MOUNTPOINT_OLD= 267 | local _FOUND= 268 | # loop old list and add item if not found in new list 269 | for _ITEM_OLD in ${_LIST_OLD}; do 270 | _FOUND=0 271 | _PARTITION_OLD="$(FSspec_parse "${_ITEM_OLD}" 'partition')" || return $? 272 | _MOUNTPOINT_OLD="$(FSspec_parse "${_ITEM_OLD}" 'mountpoint')" || return $? 273 | # loop new list 274 | for _ITEM_NEW in ${_LIST_NEW}; do 275 | _PARTITION_NEW="$(FSspec_parse "${_ITEM_NEW}" 'partition')" || return $? 276 | _MOUNTPOINT_NEW="$(FSspec_parse "${_ITEM_NEW}" 'mountpoint')" || return $? 277 | # check partition 278 | if [ "${_PARTITION_OLD}" = "${_PARTITION_NEW}" ]; then 279 | _FOUND=1 280 | echo "INFO: Replacing existing config of ${_PARTITION_OLD}." 1>&2 281 | break 282 | # check mountpoint 283 | elif [ "${_MOUNTPOINT_OLD}" = "${_MOUNTPOINT_NEW}" ]; then 284 | _FOUND=1 285 | echo "INFO: Replacing existing config of ${_PARTITION_OLD}; mountpoint ${_MOUNTPOINT_OLD} now points to ${_PARTITION_NEW}." 1>&2 286 | break 287 | fi 288 | done 289 | if [ "${_FOUND}" -eq 0 ]; then 290 | _LIST_NEW="${_LIST_NEW} ${_ITEM_OLD}" 291 | fi 292 | done 293 | # check if all partitions exist 294 | for _ITEM_NEW in ${_LIST_NEW}; do 295 | _PARTITION_NEW="$(FSspec_parse "${_ITEM_NEW}" 'partition')" || return $? 296 | if [ ! -b "${_PARTITION_NEW}" ]; then 297 | echo "INFO: Device ${_PARTITION_NEW} is not a valid block partition. Removing config for it." 1>&2 298 | else 299 | [ -n "${_LIST_RESULT}" ] && _LIST_RESULT="${_LIST_RESULT} " 300 | _LIST_RESULT="${_LIST_RESULT}${_ITEM_NEW}" 301 | fi 302 | done 303 | # sort result 304 | _LIST_RESULT="$(echo "${_LIST_RESULT}" | tr ' ' '\n' | LC_ALL=C sort | tr '\n' ' ')" || return $? 305 | # write result to STDOUT 306 | echo "${_LIST_RESULT}" 307 | return 0 308 | } 309 | 310 | # FSspec_parse() 311 | # parses an input FSspec and writes desired var to STDOUT 312 | # 313 | # returns 0 on success 314 | # anything else is a real error 315 | # 316 | # parameters (required): 317 | # input: see defined FSscpec format 318 | # varname: an item of the FSspec format 319 | # 320 | FSspec_parse() { 321 | # only for debugging, takes time 322 | if [ "${DEBUG_CHECKS}" -eq 1 ]; then 323 | # check input 324 | check_num_args "${FUNCNAME}" 2 $# || return $? 325 | local _ITEM="${1}" 326 | local _VARNAME="${2}" 327 | local _PARTITION= 328 | local _MOUNTPOINT= 329 | local _FILESYSTEM= 330 | local _CRYPTTYPE= 331 | local _FORMAT= 332 | local _CRYPTNAME= 333 | local _PARTUUID= 334 | local _CRYPTKEY= 335 | local _CHECKKEY= 336 | local _COUNT= 337 | # check if input has correct number of separators 338 | _COUNT="$(echo -n "${_ITEM//[^${CONFIG_SEPARATOR}]}" | wc -m)" || return false; 339 | if [ "${_COUNT}" -ne 15 ]; then 340 | echo "error parsing config, wrong number of separators in '${_ITEM}'" 1>&2 341 | return 1 342 | fi 343 | # parse the item keys 344 | _COUNT=0 345 | for _CHECKKEY in "${FSspec_DEFINITION[@]}"; do 346 | if [ "$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f"$((_COUNT * 2 + 1))")" != "${_CHECKKEY}" ]; then 347 | echo "error parsing config, unexpected key '${_CHECKKEY}' in '${_ITEM}'" 1>&2 348 | return 1 349 | fi 350 | _COUNT="$((_COUNT+1))" 351 | done 352 | # parse the item values 353 | _PARTITION="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f2)" || return $? 354 | _MOUNTPOINT="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f4)" || return $? 355 | _FILESYSTEM="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f6)" || return $? 356 | _CRYPTTYPE="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f8)" || return $? 357 | _FORMAT="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f10)" || return $? 358 | _CRYPTNAME="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f12)" || return $? 359 | _PARTUUID="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f14)" || return $? 360 | _CRYPTKEY="$(echo "${_ITEM}" | cut -d "${CONFIG_SEPARATOR}" -f16)" || return $? 361 | # convert boolean values to 0 or 1 362 | [ "${_FORMAT}" != '1' ] && _FORMAT=0 363 | # validate 364 | FSspec_createfull \ 365 | "${_PARTITION}" \ 366 | "${_MOUNTPOINT}" \ 367 | "${_FILESYSTEM}" \ 368 | "${_CRYPTTYPE}" \ 369 | "${_FORMAT}" \ 370 | "${_CRYPTNAME}" \ 371 | "${_PARTUUID}" \ 372 | "${_CRYPTKEY}" \ 373 | 1>/dev/null \ 374 | || return $? 375 | # print value to STDOUT 376 | case "${_VARNAME}" in 377 | "partition") 378 | echo "${_PARTITION}";; 379 | "mountpoint") 380 | echo "${_MOUNTPOINT}";; 381 | "filesystem") 382 | echo "${_FILESYSTEM}";; 383 | "crypttype") 384 | echo "${_CRYPTTYPE}";; 385 | "format") 386 | echo "${_FORMAT}";; 387 | "cryptname") 388 | echo "${_CRYPTNAME}";; 389 | "partuuid") 390 | echo "${_PARTUUID}";; 391 | "cryptkey") 392 | echo "${_CRYPTKEY}";; 393 | *) 394 | echo "Unexpected varname '${_VARNAME}' in ${FUNCNAME}()" 1>&2 395 | return 1 ;; 396 | esac 397 | # shorthand parsing without extra checks 398 | else 399 | # print value to STDOUT 400 | case "${2}" in 401 | "partition") 402 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f2 || return $? ;; 403 | "mountpoint") 404 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f4 || return $? ;; 405 | "filesystem") 406 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f6 || return $? ;; 407 | "crypttype") 408 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f8 || return $? ;; 409 | "format") 410 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f10 || return $? ;; 411 | "cryptname") 412 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f12 || return $? ;; 413 | "partuuid") 414 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f14 || return $? ;; 415 | "cryptkey") 416 | echo "${1}" | cut -d "${CONFIG_SEPARATOR}" -f16 || return $? ;; 417 | *) 418 | echo "Unexpected varname '${2}' in ${FUNCNAME}()" 1>&2 419 | return 1 ;; 420 | esac 421 | fi 422 | return 0 423 | } 424 | 425 | # FSspec_setvalue() 426 | # replaces the value of a key 427 | # 428 | # returns 0 on success 429 | # anything else is a real error 430 | # 431 | # parameters (required): 432 | # input: see defined FSscpec format 433 | # varname: an item of the FSspec format 434 | # varvalue: the new value 435 | # 436 | FSspec_setvalue() { 437 | # check input 438 | check_num_args "${FUNCNAME}" 3 $# || return $? 439 | local _ITEM="${1}" 440 | local _VARNAME="${2}" 441 | local _VARVALUE="${3}" 442 | local _PARTITION= 443 | local _MOUNTPOINT= 444 | local _FILESYSTEM= 445 | local _CRYPTTYPE= 446 | local _FORMAT= 447 | local _CRYPTNAME= 448 | local _PARTUUID= 449 | local _CRYPTKEY= 450 | # parse the item values 451 | _PARTITION="$(FSspec_parse "${_ITEM}" 'partition')" || return $? 452 | _MOUNTPOINT="$(FSspec_parse "${_ITEM}" 'mountpoint')" || return $? 453 | _FILESYSTEM="$(FSspec_parse "${_ITEM}" 'filesystem')" || return $? 454 | _CRYPTTYPE="$(FSspec_parse "${_ITEM}" 'crypttype')" || return $? 455 | _FORMAT="$(FSspec_parse "${_ITEM}" 'format')" || return $? 456 | _CRYPTNAME="$(FSspec_parse "${_ITEM}" 'cryptname')" || return $? 457 | _PARTUUID="$(FSspec_parse "${_ITEM}" 'partuuid')" || return $? 458 | _CRYPTKEY="$(FSspec_parse "${_ITEM}" 'cryptkey')" || return $? 459 | # replace desired value 460 | case "${_VARNAME}" in 461 | "partition") 462 | _PARTITION="${_VARVALUE}" ;; 463 | "mountpoint") 464 | _MOUNTPOINT="${_VARVALUE}" ;; 465 | "filesystem") 466 | _FILESYSTEM="${_VARVALUE}" ;; 467 | "crypttype") 468 | _CRYPTTYPE="${_VARVALUE}" ;; 469 | "format") 470 | _FORMAT="${_VARVALUE}" ;; 471 | "cryptname") 472 | _CRYPTNAME="${_VARVALUE}" ;; 473 | "partuuid") 474 | _PARTUUID="${_VARVALUE}" ;; 475 | "cryptkey") 476 | _CRYPTKEY="${_VARVALUE}" ;; 477 | *) 478 | echo "Unexpected varname '${_VARNAME}' in ${FUNCNAME}()" 1>&2 479 | return 1 ;; 480 | esac 481 | # validate and print to STDOUT 482 | FSspec_createfull \ 483 | "${_PARTITION}" \ 484 | "${_MOUNTPOINT}" \ 485 | "${_FILESYSTEM}" \ 486 | "${_CRYPTTYPE}" \ 487 | "${_FORMAT}" \ 488 | "${_CRYPTNAME}" \ 489 | "${_PARTUUID}" \ 490 | "${_CRYPTKEY}" \ 491 | || return $? 492 | } 493 | 494 | # FSspec_sort() 495 | # sort a list of FSspec-strings by the values of a key 496 | # 497 | # returns 0 on success 498 | # anything else is a real error 499 | # 500 | # parameters (required): 501 | # config_list: see defined FSscpec format 502 | # varname: an item of the FSspec format 503 | # direction: 0 for ascending, 1 for reverse 504 | # 505 | FSspec_sort() { 506 | # check input 507 | check_num_args "${FUNCNAME}" 3 $# || return $? 508 | local _CONFIG_LIST="${1}" 509 | local _VARNAME="${2}" 510 | local _LIST_RESULT= 511 | local _ITEM= 512 | local _TMPVALUE= 513 | local _DIRECTION= 514 | local _SEPARATOR=' ' 515 | local _LINE= 516 | local _INDEX=0 517 | [ "${3}" -eq '1' ] && _DIRECTION='-r' 518 | for _ITEM in ${_CONFIG_LIST}; do 519 | _TMPVALUE="$(FSspec_parse "${_ITEM}" "${_VARNAME}")" || return $? 520 | # append newline 521 | [ -n "${_LIST_RESULT}" ] && _LIST_RESULT="${_LIST_RESULT}"$'\n' 522 | # simply prepend the value at start, then space, then the config-item 523 | _LIST_RESULT="${_LIST_RESULT}${_TMPVALUE}${_SEPARATOR}${_ITEM}" 524 | done 525 | # sort the result 526 | _LIST_RESULT="$(echo -n "${_LIST_RESULT}" | LC_ALL=C sort ${_DIRECTION})" || return $? 527 | # loop line by line and print second field 528 | while read -r _LINE; do 529 | # prepend space 530 | [ "${_INDEX}" -gt 0 ] && echo -n ' ' 531 | # write result to STDOUT 532 | echo -n "$(echo -n "${_LINE}" | cut -d"${_SEPARATOR}" -f2)" || return $? 533 | _INDEX="$((_INDEX + 2))" 534 | done <<<"${_LIST_RESULT}" 535 | return 0 536 | } 537 | 538 | # FSspec_mountall() 539 | # mounts devices to prepare installation 540 | # also opens encrypted partitions 541 | # 542 | # arguments (required): 543 | # _CONFIG_LIST: a list of FSspec after encryption setup and mkfs 544 | # 545 | # exits: !=1 is an error 546 | # 547 | FSspec_mountall() { 548 | # check input 549 | check_num_args "${FUNCNAME}" 1 $# || return $? 550 | local _CONFIG_LIST="${1}" 551 | local _CONFIG_ITEM= 552 | local _PARTITION= 553 | local _MOUNTPOINT= 554 | local _FILESYSTEM= 555 | local _CRYPTTYPE= 556 | local _FORMAT= 557 | local _CRYPTNAME= 558 | local _PARTUUID= 559 | local _CRYPTKEY= 560 | local _PARTPATH= 561 | local _UUID= 562 | _UUID="$(uuidgen)" || return $? 563 | # check if mountpoint '/' exists 564 | if ! FSspec_list_haskeyvalue "${_CONFIG_LIST}" 'mountpoint' '/'; then 565 | echo "ERROR: Root partition (with mountpoint '/') not found." 1>&2 566 | return 1 567 | fi 568 | # sort by mountpoint 569 | _CONFIG_LIST="$(FSspec_sort "${_CONFIG_LIST}" 'mountpoint' 0)" || return $? 570 | for _CONFIG_ITEM in ${_CONFIG_LIST}; do 571 | _PARTITION="$(FSspec_parse "${_CONFIG_ITEM}" 'partition')" || return $? 572 | _MOUNTPOINT="$(FSspec_parse "${_CONFIG_ITEM}" 'mountpoint')" || return $? 573 | _FILESYSTEM="$(FSspec_parse "${_CONFIG_ITEM}" 'filesystem')" || return $? 574 | _FORMAT="$(FSspec_parse "${_CONFIG_ITEM}" 'format')" || return $? 575 | _CRYPTTYPE="$(FSspec_parse "${_CONFIG_ITEM}" 'crypttype')" || return $? 576 | _CRYPTNAME="$(FSspec_parse "${_CONFIG_ITEM}" 'cryptname')" || return $? 577 | _PARTUUID="$(FSspec_parse "${_CONFIG_ITEM}" 'partuuid')" || return $? 578 | _CRYPTKEY="$(FSspec_parse "${_CONFIG_ITEM}" 'cryptkey')" || return $? 579 | _PARTPATH="${_PARTITION}" 580 | # check format flag 581 | if [ "${_FORMAT}" -ne 0 ]; then 582 | echo "ERROR: Format flag for ${_PARTITION} should be 0 to mount, something is wrong!" 1>&2 583 | return 1 584 | fi 585 | # check partuuid 586 | if [ "${_PARTUUID}" != "$(blkid -s PARTUUID -o value "${_PARTITION}")" ]; then 587 | echo "error parsing config, partition '${_PARTITION}' does not have expected partuuid '${_PARTUUID}'" 1>&2 588 | return 1 589 | fi 590 | if [ "${_CRYPTTYPE}" != '' ]; then 591 | # use /dev/mapper 592 | _PARTPATH="/dev/mapper/${_CRYPTNAME}" 593 | # check if cryptsetup is already open 594 | if ! cryptsetup status "${_CRYPTNAME}" &>/dev/null; then 595 | # write key to temp file 596 | echo -n "${_CRYPTKEY}" > /tmp/"${_UUID}" || return $? 597 | case "${_CRYPTTYPE}" in 598 | 'swap') 599 | cryptsetup --batch-mode --cipher aes-xts-plain64:sha512 --key-size 512 -d /tmp/"${_UUID}" open --type plain "${_PARTITION}" "${_CRYPTNAME}" || return $? 600 | ;; 601 | 'luks2-gpg') 602 | # key is in base64 format 603 | base64 -d /tmp/"${_UUID}" > /tmp/"${_UUID}".asc 604 | gpg --decrypt /tmp/"${_UUID}".asc | cryptsetup --batch-mode open --type luks2 "${_PARTITION}" "${_CRYPTNAME}" || return $? 605 | # clean up 606 | rm /tmp/"${_UUID}".asc || return $? 607 | ;; 608 | 'luks2') 609 | cat /tmp/"${_UUID}" | cryptsetup --batch-mode open --type luks2 "${_PARTITION}" "${_CRYPTNAME}" || return $? 610 | ;; 611 | esac 612 | # clean up 613 | rm /tmp/"${_UUID}" || return $? 614 | fi 615 | fi 616 | # mount actions 617 | if [ "${_FILESYSTEM}" != 'swap' ]; then 618 | # check if already mounted 619 | if ! mount | grep -q -e "^${_PARTPATH} on $(echo "${DESTDIR}${_MOUNTPOINT}" | sed 's/\/$//') "; then 620 | # create our mount directory 621 | mkdir -p "${DESTDIR}${_MOUNTPOINT}" || return $? 622 | # normalize filesystem 623 | if [ "${_FILESYSTEM}" = "ext4-nojournal" ]; then 624 | _FILESYSTEM="ext4" 625 | elif [ "${_FILESYSTEM}" = "fat32" ]; then 626 | _FILESYSTEM="vfat" 627 | fi 628 | # mount the bad boy 629 | mount -t "${_FILESYSTEM}" "${_PARTPATH}" "${DESTDIR}${_MOUNTPOINT}" >>"${LOG}" 2>&1 || return $? 630 | fi 631 | else 632 | # check if already swapped on 633 | if ! swapon -s | grep -q -e "$(readlink -f "${_PARTPATH}")"; then 634 | # swapon the bad boy 1>&2 635 | swapon "${_PARTPATH}" >>"${LOG}" 2>&1 || return $? 636 | fi 637 | fi 638 | done 639 | } 640 | 641 | # FSspec_umountall() 642 | # umount all items and close cryptsetup 643 | # 644 | # returns 0 on success 645 | # anything else is a real error 646 | # 647 | # parameters (required): 648 | # _CONFIG_LIST: a list of FSspec 649 | # 650 | FSspec_umountall() { 651 | # check input 652 | check_num_args "${FUNCNAME}" 1 $# || return $? 653 | local _CONFIG_LIST="${1}" 654 | local _CONFIG_ITEM= 655 | local _PARTITIONS= 656 | # create list of partitions and call mount_umountall() 657 | for _CONFIG_ITEM in ${_CONFIG_LIST}; do 658 | _PARTITIONS="${_PARTITIONS} $(FSspec_parse "${_CONFIG_ITEM}" 'partition')" || return $? 659 | done 660 | if [ -n "${_PARTITIONS}" ]; then 661 | # trim first space 662 | mount_umountall "${_PARTITIONS:1}" || return $? 663 | fi 664 | return 0 665 | } 666 | 667 | 668 | ## END: utility functions## 669 | ############################# 670 | 671 | # simpy call function based on mode 672 | MODE="${1}" 673 | shift 674 | case "${MODE}" in 675 | 'add') 676 | "${SHAREDIR}"/FSspec_add "${@}" ;; 677 | 'create') 678 | FSspec_create "${@}" ;; 679 | 'del_keyvalue') 680 | FSspec_del_keyvalue "${@}" ;; 681 | 'edit') 682 | "${SHAREDIR}"/FSspec_edit "${@}" ;; 683 | 'listfind') 684 | FSspec_listfind "${@}" ;; 685 | 'list_haskeyvalue') 686 | FSspec_list_haskeyvalue "${@}" ;; 687 | 'merge') 688 | FSspec_merge "${@}" ;; 689 | 'parse') 690 | FSspec_parse "${@}" ;; 691 | 'setvalue') 692 | FSspec_setvalue "${@}" ;; 693 | 'sort') 694 | FSspec_sort "${@}" ;; 695 | 'mountall') 696 | FSspec_mountall "${@}" ;; 697 | 'umountall') 698 | FSspec_umountall "${@}" ;; 699 | *) 700 | echo "Unexpected mode '${MODE}' received, exiting ungracefully" 1>&2 701 | exit 1 702 | esac 703 | -------------------------------------------------------------------------------- /share/pentoo-installer/FSspec_add: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # FSspec_add() 6 | # user GUI to add a new FSspec 7 | # 8 | # parameters (required): 9 | # CONFIG_LIST: One string with 0 or more items of defined FSspec 10 | # Already configured partitions Need this to trigger setup of root/swap partition 11 | # 12 | # returns 0 on success 13 | # returns $ERROR_CANCEL=64 on user cancel 14 | # anything else is a real error 15 | # reason: show_dialog() needs a way to exit "Cancel" 16 | # 17 | # writes menus and noise to STDERR 18 | # 19 | # prints result to STDOUT 20 | 21 | # location of other scripts to source 22 | readonly SHAREDIR="$(dirname ${0})" || exit $? 23 | 24 | # source partitioning commons 25 | source "${SHAREDIR}"/partition_common.sh || exit $? 26 | 27 | ##################### 28 | ## begin execution ## 29 | 30 | # check input 31 | check_num_args "$(basename $0)" 1 $# || exit $? 32 | CONFIG_LIST="${1}" 33 | HAS_ROOT=0 34 | HAS_SWAP=0 35 | RETSUB= 36 | 37 | # properties of FSspec 38 | PARTITION= 39 | MOUNTPOINT= 40 | FILESYSTEM= 41 | 42 | # check for root/swap partition 43 | "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/' && HAS_ROOT=1 44 | "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'filesystem' 'swap' && HAS_SWAP=1 45 | # init root/swap handling 46 | if [ "${HAS_ROOT}" -ne 1 ]; then 47 | show_dialog --msgbox "You can now define the root partition (mountpoint '/')." 0 0 48 | MOUNTPOINT='/' 49 | # assume ext4 as default 50 | FILESYSTEM='ext4' 51 | fi 52 | # ask user for partition 53 | PARTITION="$(partition_selectpartition '_')" || exit $? 54 | # check if partition is already configured 55 | if "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'partition' "${PARTITION}"; then 56 | show_dialog --msgbox "ERROR: Partition ${PARTITION} is already configured!" 0 0 57 | exit "${ERROR_CANCEL}" 58 | fi 59 | if [ -z "${MOUNTPOINT}" ]; then 60 | show_dialog --yesno "Do you want to use ${PARTITION} as swap partition?" 0 0 61 | RETSUB=$? 62 | if [ "${RETSUB}" -eq 0 ]; then 63 | FILESYSTEM='swap' 64 | else 65 | # assume ext4 as default 66 | FILESYSTEM='ext4' 67 | fi 68 | fi 69 | if [ "${FILESYSTEM}" != 'swap' ]; then 70 | if [ -z "${MOUNTPOINT}" ]; then 71 | # ask for mountpoint 72 | MOUNTPOINT="$(show_dialog --inputbox "Enter the mountpoint for ${PARTITION}." 0 0 "${MOUNTPOINT}")" || exit $? 73 | # trim result 74 | MOUNTPOINT="$(echo "${MOUNTPOINT}" | awk '{gsub(/^ +| +$/,"")} {print $0}')" || exit $? 75 | # validate 76 | if [ -z "${MOUNTPOINT}" ]; then 77 | show_dialog --msgbox "ERROR: You have entered an empty mountpoint!" 0 0 78 | exit "${ERROR_CANCEL}" 79 | elif [ "${MOUNTPOINT:0:1}" != '/' ]; then 80 | show_dialog --msgbox "ERROR: A valid mountpoint begins with '/'!" 0 0 81 | exit "${ERROR_CANCEL}" 82 | # check if mountpoint is already configured 83 | elif "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' "${MOUNTPOINT}"; then 84 | show_dialog --msgbox "ERROR: Mountpoint ${MOUNTPOINT} is already configured!" 0 0 85 | exit "${ERROR_CANCEL}" 86 | fi 87 | # set ext4(-nojournal) for /boot 88 | [ "${MOUNTPOINT}" = '/boot' ] && FILESYSTEM='ext4' 89 | fi 90 | fi 91 | # everything ok, create new FSspec string 92 | # print result to STDOUT and exit 0 93 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec create \ 94 | "${PARTITION}" \ 95 | "${MOUNTPOINT}" \ 96 | "${FILESYSTEM}" \ 97 | "" \ 98 | "1")" || exit $? 99 | echo "${CONFIG_ITEM}" 100 | exit 0 101 | -------------------------------------------------------------------------------- /share/pentoo-installer/FSspec_edit: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # FSspec_edit 6 | # user GUI to edit an FSspec 7 | # 8 | # parameters (required): 9 | # CONFIG_ITEM: a FSspec 10 | # CONFIG_LIST: the list of all config items 11 | # 12 | # returns 0 on success 13 | # returns $ERROR_CANCEL=64 on user cancel 14 | # anything else is a real error 15 | # reason: show_dialog() needs a way to exit "Cancel" 16 | # 17 | # writes menus and noise to STDERR 18 | # 19 | # prints result to STDOUT 20 | # this is the new FSspec, if it's empty, then the FSspec was deleted 21 | 22 | # location of other scripts to source 23 | readonly SHAREDIR="$(dirname ${0})" || exit $? 24 | 25 | # source common variables, functions and error handling 26 | source "${SHAREDIR}"/common.sh || exit $? 27 | 28 | ######################################### 29 | ## START: dialog functions/definitions ## 30 | 31 | # FSspec_hasluks() 32 | # return 0 if file system is uspported with luks 33 | # parameters (required) 34 | # _CURRENT_FS: Current file system 35 | # 36 | # TODO: tell user which FS support luks 37 | FSspec_hasluks() { 38 | # check input 39 | check_num_args "${FUNCNAME}" 1 $# || return $? 40 | case "${1}" in 41 | 'ext3'|'ext4'|'reiserfs'|'btrfs') 42 | return 0 ;; 43 | esac 44 | return 1 45 | } 46 | 47 | # FSspec_getcrypttype() 48 | # asks user for enrcryption type of a partition and prints result to STDOUT 49 | # parameters (required) 50 | # _PARTITION: The partition 51 | # _FILESYSTEM: file system 52 | # _MOUNTPOINT: the mountpoint 53 | # _CURRENT_CRYPTTYPE: Current crypttype 54 | # 55 | # returns $ERROR_CANCEL=64 on user cancel 56 | # anything else is a real error 57 | # reason: show_dialog() needs a way to exit "Cancel" 58 | # 59 | FSspec_getcrypttype() { 60 | # check input 61 | check_num_args "${FUNCNAME}" 4 $# || return $? 62 | local _PARTITION="${1}" 63 | local _FILESYSTEM="${2}" 64 | local _MOUNTPOINT="${3}" 65 | local _CURRENT_CRYPTTYPE="${4}" 66 | local _CRYPTTYPE= 67 | local _MENU_ITEMS=() 68 | # construct menu 69 | if [ "${_FILESYSTEM}" = 'swap' ]; then 70 | _MENU_ITEMS+=("swap" "Encrypted swap partition") || return $? 71 | elif [ "${_MOUNTPOINT}" != '/boot' ]; then 72 | _MENU_ITEMS+=("luks2-gpg" "LUKS2 with a GPG encrypted key") || return $? 73 | # root partition must have gpg 74 | if [ "${_MOUNTPOINT}" != '/' ]; then 75 | _MENU_ITEMS+=("luks2" "LUKS2") || return $? 76 | fi 77 | fi 78 | _MENU_ITEMS+=("None" "No encryption") || return $? 79 | [ "${_CURRENT_CRYPTTYPE}" = '' ] && _CURRENT_CRYPTTYPE='None' 80 | # expand menu items array below 81 | _CRYPTTYPE="$(show_dialog --default-item "${_CURRENT_CRYPTTYPE}" --menu "Select the encryption type for ${_PARTITION} on ${_MOUNTPOINT}" \ 82 | 0 0 3 "${_MENU_ITEMS[@]}")" || return $? 83 | [ "${_CRYPTTYPE}" = 'None' ] && _CRYPTTYPE='' 84 | # everything ok, write to STDOUT and return 0 85 | echo "${_CRYPTTYPE}" 86 | return 0 87 | } 88 | 89 | # FSspec_getfilesystem() 90 | # asks user for filesystem and prints result to STDOUT 91 | # parameters (required) 92 | # _PARTITION: The partition 93 | # _CURRENT_FS: Current file system 94 | # 95 | # returns $ERROR_CANCEL=64 on user cancel 96 | # anything else is a real error 97 | # reason: show_dialog() needs a way to exit "Cancel" 98 | # 99 | FSspec_getfilesystem() { 100 | # check input 101 | check_num_args "${FUNCNAME}" 2 $# || return $? 102 | local _PARTITION="${1}" 103 | local _CURRENT_FS="${2}" 104 | local _FSTYPE= 105 | local _FSOPTS= 106 | # get available file systems 107 | _FSOPTS="$(get_supportedFS)" || return $? 108 | _FSOPTS="$(add_option_label "${_FSOPTS}" '-')" || return $? 109 | _FSTYPE="$(show_dialog --default-item "${_CURRENT_FS}" --menu "Select a filesystem for ${_PARTITION}" \ 110 | 0 0 6 ${_FSOPTS})" || return $? 111 | # everything ok, write to STDOUT and return 0 112 | echo "${_FSTYPE}" 113 | return 0 114 | } 115 | 116 | ## END: dialog functions/definitions ## 117 | ####################################### 118 | 119 | ##################### 120 | ## begin execution ## 121 | 122 | # check input 123 | check_num_args "$(basename $0)" 2 $# || exit $? 124 | CONFIG_ITEM="${1}" 125 | CONFIG_LIST="${2}" 126 | 127 | # properties of FSspec 128 | PARTITION= 129 | MOUNTPOINT= 130 | FILESYSTEM= 131 | CRYPTTYPE= 132 | FORMAT= 133 | 134 | SELECTION= 135 | # array holding menu items 136 | MENU_ITEMS=() 137 | NEWVAL= 138 | MESSAGE= 139 | RETSUB= 140 | 141 | while true; do 142 | # parse the item, also validates 143 | PARTITION="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'partition')" || exit $? 144 | MOUNTPOINT="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'mountpoint')" || exit $? 145 | FILESYSTEM="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'filesystem')" || exit $? 146 | CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'crypttype')" || exit $? 147 | FORMAT="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'format')" || exit $? 148 | # reset array holding menu items 149 | MENU_ITEMS=() 150 | # construct menu 151 | if [ "${FILESYSTEM}" != 'swap' ]; then 152 | MENU_ITEMS+=("mountpoint" "Change mountpoint, now: '${MOUNTPOINT}'") || exit $? 153 | MENU_ITEMS+=("filesystem" "Change file system, now: '${FILESYSTEM}'") || exit $? 154 | fi 155 | MENU_ITEMS+=("encryption" "Change encryption, now: '${CRYPTTYPE}'") || exit $? 156 | MENU_ITEMS+=("format" "Format and create file system, now: '$(get_yesno "${FORMAT}")'") || exit $? 157 | # Add other options: DONE 158 | MENU_ITEMS+=("DELETE" "Remove configuration, partition will no longer be used") || exit $? 159 | MENU_ITEMS+=("DONE" "Save changes") || exit $? 160 | # expand menu items array below 161 | SELECTION="$(show_dialog --menu "Changing setup of partition '${PARTITION}'.\nPlease select a property to change." \ 162 | 0 0 0 "${MENU_ITEMS[@]}")" || exit $? 163 | # evaluate answer 164 | case "${SELECTION}" in 165 | 'mountpoint') 166 | NEWVAL="$(show_dialog --inputbox "Enter the mountpoint for ${PARTITION}. Now: '${MOUNTPOINT}'." 0 0 "${MOUNTPOINT}")" 167 | RETSUB=$? 168 | if [ "${RETSUB}" -eq 0 ]; then 169 | # trim result 170 | NEWVAL="$(echo "${NEWVAL}" | awk '{gsub(/^ +| +$/,"")} {print $0}')" || exit $? 171 | # validate 172 | if [ -z "${NEWVAL}" ]; then 173 | show_dialog --msgbox "ERROR: You have entered an empty mountpoint!" 0 0 174 | elif [ "${NEWVAL:0:1}" != '/' ]; then 175 | show_dialog --msgbox "ERROR: A valid mountpoint begins with '/'!" 0 0 176 | elif [ "${NEWVAL}" = '/boot' ] && [ "${CRYPTTYPE}" != '' ]; then 177 | show_dialog --msgbox "ERROR: Mountpoint '/boot' cannot be encrypted!" 0 0 178 | else 179 | # change FSspec string 180 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'mountpoint' "${NEWVAL}")" || exit $? 181 | MOUNTPOINT="${NEWVAL}" 182 | fi 183 | fi 184 | ;; 185 | 'filesystem') 186 | # show dialog for filesystem 187 | NEWVAL="$(FSspec_getfilesystem "${PARTITION}" "${FILESYSTEM}")" 188 | RETSUB=$? 189 | if [ "${RETSUB}" -eq 0 ]; then 190 | if [ -z "${NEWVAL}" ]; then 191 | # should not be possible 192 | exit 1 193 | fi 194 | # check if encryption might be lost 195 | if [ "${CRYPTTYPE}" != '' ] && ! FSspec_hasluks "${NEWVAL}"; then 196 | show_dialog --yesno "New file system '${NEWVAL}' does not support encryption.\nDo you want to continue?" 0 0 197 | RETSUB=$? 198 | if [ "${RETSUB}" -eq 0 ]; then 199 | # change FSspec string 200 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'crypttype' '')" || exit $? 201 | CRYPTTYPE='' 202 | fi 203 | fi 204 | if [ "${RETSUB}" -eq 0 ]; then 205 | # change FSspec string 206 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'filesystem' "${NEWVAL}")" || exit $? 207 | FILESYSTEM="${NEWVAL}" 208 | fi 209 | fi 210 | ;; 211 | 'encryption') 212 | # check if file system supports encryption 213 | if [ "${FILESYSTEM}" != 'swap' ] && ! FSspec_hasluks "${FILESYSTEM}"; then 214 | show_dialog --msgbox "Error: Current file system '${FILESYSTEM}' does not support encryption.\nPlease select another file system." 0 0 215 | # for root partition, check if there is a separate /boot 216 | elif [ "${MOUNTPOINT}" = '/' ] && ! "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/boot'; then 217 | show_dialog --msgbox "Error: You must define a separate partition for mountpoint '/boot' to encrypt the root partition.\nPlease do this first!" 0 0 218 | # everything ok, let user edit the value 219 | else 220 | # show dialog for encryption types 221 | NEWVAL="$(FSspec_getcrypttype "${PARTITION}" "${FILESYSTEM}" "${MOUNTPOINT}" "${CRYPTTYPE}")" 222 | RETSUB=$? 223 | if [ "${RETSUB}" -eq 0 ]; then 224 | # change FSspec string 225 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'crypttype' "${NEWVAL}")" || exit $? 226 | CRYPTTYPE="${NEWVAL}" 227 | fi 228 | fi 229 | ;; 230 | 'format') 231 | # dialog for boolean value 232 | show_dialog --yesno "Formatting of ${PARTITION} is now '$(get_yesno "${FORMAT}")'.\nDo you want to change it?" 0 0 233 | RETSUB=$? 234 | if [ "${RETSUB}" -eq 0 ] && [ "${FORMAT}" -eq '0' ]; then 235 | # change FSspec string 236 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'format' '1')" || exit $? 237 | FORMAT=1 238 | elif [ "${RETSUB}" -eq 0 ]; then 239 | # change FSspec string 240 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'format' '0')" || exit $? 241 | FORMAT=0 242 | fi 243 | ;; 244 | 'DELETE') 245 | # Print empty sting 246 | # print result to STDOUT and exit 0 247 | echo '' 248 | exit 0 249 | ;; 250 | 'DONE') 251 | # everything ok, print result to STDOUT and exit 0 252 | echo "${CONFIG_ITEM}" 253 | exit 0 254 | ;; 255 | *) 256 | echo "ERROR: Unexpected response '${SELECTION}' in $(basename $0)" 1>&2 257 | exit 1 258 | ;; 259 | esac 260 | done 261 | -------------------------------------------------------------------------------- /share/pentoo-installer/bootloader_common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # to be sourced by other scripts 6 | 7 | # source common variables, functions and error handling 8 | source "${SHAREDIR}"/common.sh || exit $? 9 | 10 | ############################## 11 | ## START: define constants ## 12 | ## END: define constants ## 13 | ############################ 14 | 15 | ######################################## 16 | ## START: initialize global variables ## 17 | ## END: initialize global variables ## 18 | ###################################### 19 | 20 | ############################## 21 | ## START: utility functions ## 22 | 23 | # getkernelparams() 24 | # prints kernel params to STDOUT 25 | # 26 | # parameters (required) 27 | # _ROOTPART: root partition 28 | # _BOOTPART: boot partition 29 | # _CRYPTTYPE: encryption-type (should be '' or 'luks2-gpg') 30 | # _CRYPTNAME: cryptname of root partition 31 | # 32 | # returns 0 on success 33 | # anything else is a real error 34 | # 35 | getkernelparams() { 36 | # check input 37 | check_num_args "${FUNCNAME}" 4 $# || return $? 38 | local _ROOTPART="${1}" 39 | local _BOOTPART="${2}" 40 | local _CRYPTTYPE="${3}" 41 | local _CRYPTNAME="${4}" 42 | local _KERNEL_PARAMS= 43 | local _COMMON_PARAMS= 44 | _KERNEL_PARAMS="$(parse_kernel_cmdline)" || return $? 45 | # encrypted root partition 46 | _COMMON_PARAMS="console=tty1 net.ifnames=0 ro" 47 | if [ "${_CRYPTTYPE}" != '' ]; then 48 | _KERNEL_PARAMS="real_root=/dev/mapper/${_CRYPTNAME} dogpg crypt_root=${_ROOTPART} root_key=/${_CRYPTNAME}.gpg root_keydev=${_BOOTPART} ${_KERNEL_PARAMS} ${_COMMON_PARAMS}" 49 | else 50 | _KERNEL_PARAMS="real_root=${_ROOTPART} ${_KERNEL_PARAMS} ${_COMMON_PARAMS}" 51 | fi 52 | #wierd hack to disable amd memory encryption when nvidia is in use 53 | if [ "$(uname -i)" = "AuthenticAMD" ] && grep -q nvidia /proc/modules; then 54 | _KERNEL_PARAMS="${_KERNEL_PARAMS} mem_encrypt=off" 55 | fi 56 | # print result 57 | echo "${_KERNEL_PARAMS}" 58 | return 0 59 | } 60 | 61 | # getkernelversion() 62 | # outputs the kernel version 63 | # 64 | # parameters: none 65 | # outputs: kernel version on success 66 | # 67 | # returns: 0 on success 68 | # 1 on failure 69 | getkernelversion() { 70 | local _KERNVER= 71 | _KERNVER=$(ls "${DESTDIR}"/boot/kernel-genkernel-* | sed -e "s|kernel-genkernel||g" -e "s|${DESTDIR}/boot/||") \ 72 | || return 1 73 | echo "${_KERNVER}" 74 | } 75 | 76 | # parse_kernel_cmdline() 77 | # parse kernel cmdline (only video mode for now) 78 | # prints a string to STDOUT like 'video=whatever' 79 | parse_kernel_cmdline() { 80 | local _VAR= 81 | local _FIRST=0 82 | for _VAR in $(cat /proc/cmdline); do 83 | case "${_VAR}" in 84 | video=*) 85 | [ "${_FIRST}" -ne 0 ] && echo -n ' ' 86 | echo -n "${_VAR}" 87 | _FIRST=1 88 | ;; 89 | esac 90 | done 91 | } 92 | 93 | ## END: utility functions ## 94 | ############################ 95 | -------------------------------------------------------------------------------- /share/pentoo-installer/bootloader_grub2: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # bootloader_grub 6 | # installs Grub2 7 | # 8 | # parameters (required) 9 | # CONFIG_LIST: One string items of defined FSspec 10 | # 11 | # returns 0 on success 12 | # returns $ERROR_CANCEL=64 on user cancel 13 | # anything else is a real error 14 | # reason: show_dialog() needs a way to exit "Cancel" 15 | # 16 | # writes menus and noise to STDERR 17 | 18 | # location of other scripts to source 19 | readonly SHAREDIR="$(dirname ${0})" || exit $? 20 | 21 | # source bootloader commons 22 | source "${SHAREDIR}"/bootloader_common.sh || exit $? 23 | 24 | ######################################### 25 | ## START: dialog functions/definitions ## 26 | 27 | # confirm_overwrite_OSloader() 28 | # if target file exists, user is asked if he wants to overwrite it 29 | # 30 | # parameters (required) 31 | # _SOURCE: The path to the source file 32 | # _TARGET: The path to the target file 33 | # 34 | confirm_overwrite_OSloader() { 35 | # check input 36 | check_num_args "${FUNCNAME}" 2 $# || return $? 37 | local _SOURCE="$1" 38 | local _TARGET="$2" 39 | if [ ! -e "${_TARGET}" ] || \ 40 | show_dialog --defaultno --yesno "An OS loader already exists at the standardized file path:\n${_TARGET}\nSome UEFI implementations boot from that file.\nDo you want to overwrite it?" 0 0; then 41 | cp "${_SOURCE}" "${_TARGET}" || return $? 42 | fi 43 | return 0 44 | } 45 | 46 | # get_parent_disk() 47 | # Gets the parent disk of a partition, prints to STDOUT 48 | # 49 | # returns 0 on success 50 | # 51 | # parameters (required): 52 | # _PARTITION: the partition 53 | # 54 | get_parent_disk() { 55 | # check input 56 | check_num_args "${FUNCNAME}" 1 $# || return $? 57 | local _PARENT= 58 | # get parent (/dev/sda) 59 | _PARENT="$(lsblk -dnp -o PKNAME "${1}")" || return $? 60 | # check type='disk' 61 | if [ "$(lsblk -dnp -o TYPE "${_PARENT}")" != 'disk' ]; then 62 | echo "ERROR: Expected type=disk!" 1>&2 63 | return 1 64 | fi 65 | echo "${_PARENT}" 66 | return 0 67 | } 68 | 69 | # mapdev() 70 | # maps a partition to a grub device 71 | # 72 | # parameters (required) 73 | # _PARTITION: The partition 74 | # 75 | mapdev() { 76 | # check input 77 | check_num_args "${FUNCNAME}" 1 $# || return $? 78 | local _PARTITION="$1" 79 | local _DISK= 80 | #local _PNUM= 81 | #local _DISK_GRUB= 82 | # get parent (/dev/sda) 83 | _DISK="$(get_parent_disk "${_PARTITION}")" || return $? 84 | # /dev/sdaXY 85 | #_PNUM="${_PARTITION#"${_DISK}"}" 86 | # -1 (grub starts counting at 0), cut p off partition number if it exists 87 | #_PNUM=$((${_PNUM#p}-1)) || return $? 88 | #_DISK_GRUB="$(sed -r -e 's/[\(\)]//g' -e 's/[[:blank:]]+/ /g' "${DESTDIR}/boot/grub/device.map" | grep " ${_DISK}$" | cut -d' ' -f1)" || return $? 89 | if [ -n "${_DISK}" ]; then 90 | echo -n "${_DISK}" 91 | return 0 92 | else 93 | echo "ERROR: GRUB device not found properly" 1>&2 94 | return 1 95 | fi 96 | } 97 | 98 | # freeze xfs filesystems to enable grub installation on xfs filesystems 99 | fs_sync_helper() { 100 | return 101 | # I strongly suspect this isn't needed at all, so let's test 102 | # Based on quick research this was all needed due to an incompatibility between grub <0.97 and xfs 103 | # https://bugs.launchpad.net/ubuntu/+source/grub/+bug/8058 104 | sync 105 | if [ -x /usr/sbin/xfs_freeze ]; then 106 | for MOUNTPOINT_XFS in $(mount | grep " ${DESTDIR}" | grep ' type xfs ' | cut -d' ' -f3); do 107 | if [ "${1}" = "freeze" ]; then 108 | echo "INFO: Freezing XFS filesystem mounted at ${MOUNTPOINT_XFS}" 1>&2 109 | /usr/sbin/xfs_freeze -f "${MOUNTPOINT_XFS}" 2>/dev/null 110 | else 111 | echo "INFO: Un-freezing XFS filesystem mounted at ${MOUNTPOINT_XFS}" 1>&2 112 | /usr/sbin/xfs_freeze -u "${MOUNTPOINT_XFS}" 2>/dev/null 113 | fi 114 | done 115 | fi 116 | } 117 | 118 | ## END: dialog functions/definitions ## 119 | ####################################### 120 | 121 | ##################### 122 | ## begin execution ## 123 | 124 | # check input 125 | check_num_args "$(basename $0)" 1 $# || exit $? 126 | CONFIG_LIST="${1}" 127 | CONFIG_ITEM= 128 | #RET_SUB= 129 | 130 | # get root partition 131 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'mountpoint' '/')" || exit $? 132 | PART_ROOT="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'partition')" || exit $? 133 | ROOT_UUID="UUID=$(blkid -s UUID -o value ${PART_ROOT})" || exit $? 134 | # root partition encrypted? 135 | CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'crypttype')" || exit $? 136 | CRYPTNAME="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'cryptname')" || exit $? 137 | 138 | # look for a separately-mounted /boot partition 139 | if "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/boot'; then 140 | # get boot partition 141 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'mountpoint' '/boot')" || exit $? 142 | PART_BOOT="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'partition')" || exit $? 143 | BOOT_UUID="UUID=$(blkid -s UUID -o value ${PART_BOOT})" || exit $? 144 | #PART_GRUB="$(mapdev ${PART_BOOT})" || exit $? 145 | #SUBDIR= 146 | DISK_BOOT="$(get_parent_disk "${PART_BOOT}")" || exit $? 147 | else 148 | #PART_GRUB="$(mapdev ${PART_ROOT})" || exit $? 149 | #SUBDIR="/boot" 150 | DISK_BOOT="$(get_parent_disk "${PART_ROOT}")" || exit $? 151 | fi 152 | 153 | KERNEL_PARAMS= 154 | # get kernel version 155 | #KERNVER="$(getkernelversion)" || exit $? 156 | # get kernel params 157 | KERNEL_PARAMS="$(getkernelparams "${ROOT_UUID}" "${BOOT_UUID}" "${CRYPTTYPE}" "${CRYPTNAME}")" || exit $? 158 | 159 | #GRUBMENU="${DESTDIR}/boot/grub/grub.conf" 160 | GRUBCONFIG="${DESTDIR}/etc/default/grub" 161 | 162 | #setup /etc/default/grub 163 | #sed -i "/^# *GRUB_CMDLINE_LINUX_DEFAULT=/s/^# *//" "${GRUBCONFIG}" 164 | sed -i "s@#GRUB_CMDLINE_LINUX=\"\"@GRUB_CMDLINE_LINUX=\"${KERNEL_PARAMS}\"@" "${GRUBCONFIG}" || exit $? 165 | #add "resume=/dev/swappartition?" 166 | 167 | # set pentoo bootsplash 168 | # all 169 | sed -i 's/Gentoo/Pentoo/' "${GRUBCONFIG}" || exit $? 170 | # old 171 | if [ -f "${DESTDIR}"/boot/grub/pentoosplash.png ]; then 172 | sed -i 's/^#GRUB_BACKGROUND/GRUB_BACKGROUND/' "${GRUBCONFIG}" || exit $? 173 | sed -i 's/mybackground/pentoosplash/' "${GRUBCONFIG}" || exit $? 174 | fi 175 | # new 176 | if [ -f "${DESTDIR}"/usr/share/grub/themes/pentoo/pentoosplash.png ]; then 177 | sed -i 's/^#GRUB_THEME/GRUB_THEME/' "${GRUBCONFIG}" || exit $? 178 | sed -i 's/starfield/pentoo/' "${GRUBCONFIG}" || exit $? 179 | fi 180 | # for uefi set efifb for video 181 | if [ -d /sys/firmware/efi ]; then 182 | sed -i 's#video=\S* #video=efifb #' "${GRUBCONFIG}" || exit $? 183 | fi 184 | 185 | # inform user about target disk, partitions and such, last chance to abort ;) 186 | show_dialog --defaultno --yesno "GRUB bootloader will be installed to '${DISK_BOOT}'.\nPlease confirm this.\n\nYou will then be put into the editor to review the GRUB configuration file.\nInstallation will continue after you exit the editor." 0 0 || exit $? 187 | 188 | show_dialog --infobox "Filesystem is being prepared for bootloader. Please stand by..." 4 65 189 | 190 | # set system editor (if not already defined) 191 | chroot_mount || exit $? 192 | EDITOR="$(geteditor)" || exit $? 193 | # let user edit grub menu file (skipped for headless mode) 194 | if [ -z "${INSTALLER_HEADLESS:-}" ]; then 195 | "${EDITOR}" "${GRUBCONFIG}" || exit $? 196 | fi 197 | 198 | show_dialog --infobox "Grub bootloader is being installed and prepared for booting. Please stand by..." 4 70 199 | #maybe move the stat check a LOT earlier? 200 | if [ -d /sys/firmware/efi ]; then 201 | if mountpoint -q -- /sys/firmware/efi/efivars ; then 202 | efivars="1" 203 | if [ -w /sys/firmware/efi/efivars ]; then 204 | efiwriteable="1" 205 | else 206 | efiwriteable="0" 207 | mount -o remount,rw /sys/firmware/efi/efivars || exit $? 208 | fi 209 | else 210 | efivars="0" 211 | fi 212 | 213 | [ ! -d "${DESTDIR}"/boot/efi ] && mkdir -p "${DESTDIR}"/boot/efi 214 | #this check is super loose, since we actually are putting all of /boot in ESP for simplicity 215 | if [ "$(stat -f -c %T "${DESTDIR}"/boot/efi)" != "msdos" ]; then 216 | show_dialog --msgbox "/boot/efi *MUST* be formatted FAT, aborting." 0 0 217 | exit 1 218 | fi 219 | #run grub-install 220 | #copy shim into place 221 | #remove efi boot to grub 222 | #tell efi to boot shim (which boots grub) 223 | if [ -r "/sys/firmware/efi/fw_platform_size" ] && [ "$(cat /sys/firmware/efi/fw_platform_size)" = "64" ]; then 224 | fs_sync_helper freeze 225 | chroot "${DESTDIR}" /usr/sbin/grub-install -v --efi-directory=/boot --bootloader-id=Pentoo --themes=pentoo --target=x86_64-efi --recheck "${DISK_BOOT}" >/tmp/grub.log 2>&1 || exit $? 226 | fs_sync_helper unfreeze 227 | cp "${DESTDIR}"/usr/share/shim/BOOTX64.EFI "${DESTDIR}"/boot/efi/Pentoo/BOOTX64.EFI || exit $? 228 | cp "${DESTDIR}"/usr/share/shim/mmx64.efi "${DESTDIR}"/boot/efi/Pentoo/mmx64.efi || exit $? 229 | # mokmanager efi image is sometimes required in /boot/efi/boot 230 | mkdir -p "${DESTDIR}"/boot/efi/boot || exit $? 231 | cp "${DESTDIR}"/usr/share/shim/mmx64.efi "${DESTDIR}"/boot/efi/boot/mmx64.efi || exit $? 232 | if [ "${efivars}" = "1" ]; then 233 | #the kernel cannnot handle 32 bit userland and 64 bit efi well, so we can't do this 234 | if efibootmgr | grep -q Pentoo; then 235 | efibootmgr -B -b $(efibootmgr | grep Pentoo | awk -F'*' '{print $1}' | cut -b 5-8) || exit $? 236 | fi 237 | efibootmgr --create --disk "${DISK_BOOT}" --part ${PART_BOOT:(-1)} --loader '/EFI/Pentoo/BOOTX64.EFI' --label "Pentoo" --verbose || exit $? 238 | fi 239 | elif [ -r "/sys/firmware/efi/fw_platform_size" ] && [ "$(cat /sys/firmware/efi/fw_platform_size)" = "32" ]; then 240 | fs_sync_helper freeze 241 | chroot "${DESTDIR}" /usr/sbin/grub-install -v --efi-directory=/boot --bootloader-id=Pentoo --themes=pentoo --target=i386-efi --recheck "${DISK_BOOT}" >/tmp/grub.log 2>&1 || exit $? 242 | fs_sync_helper unfreeze 243 | cp "${DESTDIR}"/usr/share/shim/BOOTIA32.EFI "${DESTDIR}"/boot/efi/Pentoo/BOOTIA32.EFI || exit $? 244 | cp "${DESTDIR}"/usr/share/shim/mmia32.efi "${DESTDIR}"/boot/efi/Pentoo/mmia32.efi || exit $? 245 | # mokmanager efi image is sometimes required in /boot/efi/boot 246 | mkdir -p "${DESTDIR}"/boot/efi/boot || exit $? 247 | cp "${DESTDIR}"/usr/share/shim/mmia32.efi "${DESTDIR}"/boot/efi/boot/mmia32.efi || exit $? 248 | if [ "${efivars}" = "1" ]; then 249 | if efibootmgr | grep -q Pentoo; then 250 | efibootmgr -B -b $(efibootmgr | grep Pentoo | awk -F'*' '{print $1}' | cut -b 5-8) || exit $? 251 | fi 252 | efibootmgr --create --disk "${DISK_BOOT}" --part ${PART_BOOT:(-1)} --loader '/EFI/Pentoo/BOOTIA32.EFI' --label "Pentoo" --verbose || exit $? 253 | fi 254 | else 255 | fs_sync_helper freeze 256 | chroot "${DESTDIR}" /usr/sbin/grub-install -v --efi-directory=/boot --bootloader-id=Pentoo --themes=pentoo --recheck "${DISK_BOOT}" >/tmp/grub.log 2>&1 || exit $? 257 | fs_sync_helper unfreeze 258 | cp "${DESTDIR}"/usr/share/shim/BOOTX64.EFI "${DESTDIR}"/boot/efi/Pentoo/BOOTX64.EFI || exit $? 259 | cp "${DESTDIR}"/usr/share/shim/mmx64.efi "${DESTDIR}"/boot/efi/Pentoo/mmx64.efi || exit $? 260 | # mokmanager efi image is sometimes required in /boot/efi/boot 261 | mkdir -p "${DESTDIR}"/boot/efi/boot || exit $? 262 | cp "${DESTDIR}"/usr/share/shim/mmx64.efi "${DESTDIR}"/boot/efi/boot/mmx64.efi || exit $? 263 | if [ "${efivars}" = "1" ]; then 264 | if efibootmgr | grep -q Pentoo; then 265 | efibootmgr -B -b $(efibootmgr | grep Pentoo | awk -F'*' '{print $1}' | cut -b 5-8) || exit $? 266 | fi 267 | efibootmgr --create --disk "${DISK_BOOT}" --part ${PART_BOOT:(-1)} --loader '/EFI/Pentoo/BOOTX64.EFI' --label "Pentoo" --verbose || exit $? 268 | fi 269 | fi 270 | #so uefi implementations suck, like lots of them. So let's populate the fallback location too, you know, for fun (if my intel nuc needs this, then it's required) 271 | mkdir -p "${DESTDIR}"/boot/efi/boot || exit $? 272 | if [ -f "${DESTDIR}"/boot/efi/Pentoo/grubx64.efi ]; then 273 | cp "${DESTDIR}"/boot/efi/Pentoo/grubx64.efi "${DESTDIR}"/boot/efi/boot/GRUBX64.EFI || exit $? 274 | fi 275 | if [ -f "${DESTDIR}"/boot/efi/Pentoo/grubia32.efi ]; then 276 | cp "${DESTDIR}"/boot/efi/Pentoo/grubia32.efi "${DESTDIR}"/boot/efi/boot/GRUBIA32.EFI || exit $? 277 | fi 278 | #add shim for secure boot to the fallback location 279 | if [ -r "/sys/firmware/efi/fw_platform_size" ] && [ "$(cat /sys/firmware/efi/fw_platform_size)" = "64" ]; then 280 | confirm_overwrite_OSloader "${DESTDIR}"/usr/share/shim/BOOTX64.EFI "${DESTDIR}"/boot/efi/boot/BOOTX64.EFI || exit $? 281 | elif [ -r "/sys/firmware/efi/fw_platform_size" ] && [ "$(cat /sys/firmware/efi/fw_platform_size)" = "32" ]; then 282 | confirm_overwrite_OSloader "${DESTDIR}"/usr/share/shim/BOOTIA32.EFI "${DESTDIR}"/boot/efi/boot/BOOTIA32.EFI || exit $? 283 | else 284 | confirm_overwrite_OSloader "${DESTDIR}"/usr/share/shim/BOOTX64.EFI "${DESTDIR}"/boot/efi/boot/BOOTX64.EFI || exit $? 285 | fi 286 | #clearing the mok password forces the user to set one at boot 287 | if [ "${efivars}" = "1" ]; then 288 | mokutil --clear-password || true 289 | chroot "${DESTDIR}" emerge --noreplace sys-boot/mokutil --nodeps || exit $? 290 | fi 291 | if [ "${efivars}" = "1" ] && [ "${efiwriteable}" = "0" ]; then 292 | mount -o remount,ro /sys/firmware/efi/efivars || exit $? 293 | fi 294 | chroot "${DESTDIR}" emerge --noreplace sys-boot/shim --nodeps || exit $? 295 | else 296 | fs_sync_helper freeze 297 | # without --targets grub-install finds /sys/device-tree and gets confused that it's an ieee1275 system 298 | # i386-pc is the target for all legacy boot systems 299 | chroot "${DESTDIR}" /usr/sbin/grub-install -v --themes=pentoo --targets=i386-pc --recheck "${DISK_BOOT}" >/tmp/grub.log 2>&1 || exit $? 300 | fs_sync_helper unfreeze 301 | fi 302 | cat "${DESTDIR}"/tmp/grub.log >>"${LOG}" 303 | #okay so wow, this is ugly 304 | #os-prober sucks, and to handle lvm volumes it needs lvmetad running 305 | #if it's not running, then it has to time out on a bunch of things like /dev/loop0 and /dev/ram0 which takes forever 306 | #easiest solution, run lvmetad 307 | show_dialog --infobox "Starting lvmetad to appease os-prober. Please stand by..." 4 70 308 | /etc/init.d/lvmetad start 309 | rm -rf "${DESTDIR}/run/*" 310 | mount --make-shared /run 311 | mount --rbind --make-rslave /run "${DESTDIR}/run" 312 | show_dialog --infobox "Grub bootloader is being configured for booting. Please stand by..." 4 70 313 | chroot "${DESTDIR}" /usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg || exit $? 314 | umount -R "${DESTDIR}/run" 315 | show_dialog --infobox "Stopping lvmetad, no longer needed. Please stand by..." 4 70 316 | /etc/init.d/lvmetad stop 317 | 318 | chroot "${DESTDIR}" emerge --noreplace sys-boot/grub:2 --nodeps || exit $? 319 | 320 | sync 321 | chroot_umount || exit $? 322 | 323 | if grep -q 'Error [0-9]*: ' "${DESTDIR}"/tmp/grub.log; then 324 | show_dialog --msgbox "Error installing GRUB. (see ${LOG} for output)" 0 0 325 | exit 1 326 | fi 327 | 328 | show_dialog --msgbox "GRUB was successfully installed." 0 0 329 | exit 0 330 | -------------------------------------------------------------------------------- /share/pentoo-installer/bootloader_mainmenu: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # bootloader_mainmenu 6 | # main menu for bootloader installation 7 | # 8 | # parameters (required) 9 | # CONFIG_LIST: One string items of defined FSspec 10 | # 11 | # returns 0 on success 12 | # returns $ERROR_CANCEL=64 on user cancel 13 | # anything else is a real error 14 | # reason: show_dialog() needs a way to exit "Cancel" 15 | # 16 | # writes menus and noise to STDERR 17 | 18 | # location of other scripts to source 19 | readonly SHAREDIR="$(dirname ${0})" || exit $? 20 | 21 | # source common variables, functions and error handling 22 | source "${SHAREDIR}"/common.sh || exit $? 23 | 24 | ######################################### 25 | ## START: dialog functions/definitions ## 26 | 27 | ## END: dialog functions/definitions ## 28 | ####################################### 29 | 30 | ##################### 31 | ## begin execution ## 32 | 33 | # check input 34 | check_num_args "$(basename $0)" 1 $# || exit $? 35 | CONFIG_LIST="${1}" 36 | SELECTION= 37 | RETSUB= 38 | 39 | # mount everything, including cryptsetup 40 | "${SHAREDIR}"/FSspec mountall "${CONFIG_LIST}" || exit $? 41 | 42 | 43 | if [ -d /sys/firmware/efi ]; then 44 | SELECTION="$(show_dialog --menu "Which bootloader would you like to use? Grub2 is the Pentoo default." \ 45 | 0 0 4 \ 46 | "GRUB2-UEFI" "Use GRUB2 and UEFI (default)" \ 47 | "UEFI" "Boot kernel directly by UEFI (unsupported)" \ 48 | "None" "Warning: you must install your own bootloader!")" \ 49 | || exit $? 50 | else 51 | SELECTION="$(show_dialog --menu "Which bootloader would you like to use? Grub2 is the Pentoo default." \ 52 | 0 0 4 \ 53 | "GRUB2" "Use grub2 in legacy bios mode (default)" \ 54 | "None" "Warning: you must install your own bootloader!")" \ 55 | || exit $? 56 | fi 57 | case "${SELECTION}" in 58 | "GRUB2") 59 | "${SHAREDIR}"/bootloader_grub2 "${CONFIG_LIST}" || exit $? 60 | ;; 61 | "GRUB2-UEFI") 62 | "${SHAREDIR}"/bootloader_grub2 "${CONFIG_LIST}" || exit $? 63 | ;; 64 | "UEFI") 65 | "${SHAREDIR}"/bootloader_uefi "${CONFIG_LIST}" || exit $? 66 | ;; 67 | "None") 68 | # TODO: Give user info about kernel params and such 69 | ;; 70 | esac 71 | 72 | exit 0 73 | -------------------------------------------------------------------------------- /share/pentoo-installer/bootloader_uefi: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # bootloader_uefi 6 | # writes kernel to UEFI as new boot option 7 | # 8 | # parameters (required) 9 | # CONFIG_LIST: One string items of defined FSspec 10 | # 11 | # returns 0 on success 12 | # returns: 1 on failure 13 | # 14 | # writes menus and noise to STDERR 15 | 16 | # location of other scripts to source 17 | readonly SHAREDIR="$(dirname ${0})" || exit $? 18 | 19 | # source bootloader commons 20 | source "${SHAREDIR}"/bootloader_common.sh || exit $? 21 | 22 | ######################################### 23 | ## START: dialog functions/definitions ## 24 | 25 | ## END: dialog functions/definitions ## 26 | ####################################### 27 | 28 | ##################### 29 | ## begin execution ## 30 | 31 | # check input 32 | check_num_args "$(basename $0)" 1 $# || exit $? 33 | CONFIG_LIST="${1}" 34 | 35 | echo dump CONFIG_LIST="'${CONFIG_LIST}'" 1>&2 36 | 37 | modprobe efivars 38 | # check if booted through UEFI 39 | efibootmgr -v 2>/dev/null 1>&2 40 | if [ $? -ne 0 ]; then 41 | show_dialog --msgbox "Error: Couldn't read from UEFI. Did you boot through UEFI?" 0 0 42 | exit 1 43 | fi 44 | 45 | # mount everything, including cryptsetup 46 | "${SHAREDIR}"/FSspec mountall "${CONFIG_LIST}" || exit $? 47 | 48 | # get kernel version 49 | KERNVER=$(getkernelversion) || exit $? 50 | 51 | # kernelpath: path to kernel, relative to partition root 52 | KERNELPATH="/boot/kernel-genkernel${KERNVER}" 53 | # initrdpath: path to initrd 54 | INITRDPATH="/boot/initramfs-genkernel${KERNVER}" 55 | 56 | # get root partition 57 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'mountpoint' '/')" || exit $? 58 | ROOT_PART="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'partition')" || exit $? 59 | # root partition encrypted? 60 | ROOT_CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'crypttype')" || exit $? 61 | 62 | # check for separate /boot partition 63 | BOOT_PART= 64 | if "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/boot'; then 65 | # get boot partition 66 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'mountpoint' '/boot')" || exit $? 67 | BOOT_PART="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'partition')" || exit $? 68 | # fix paths 69 | KERNELPATH="${KERNELPATH#/boot}" 70 | INITRDPATH="${INITRDPATH#/boot}" 71 | fi 72 | 73 | # kernel path with \\ instead of / 74 | KERNELPATH=${KERNELPATH//\//\\\\} 75 | # initrd path with \ instead of / 76 | INITRDPATH=${INITRDPATH//\//\\} 77 | 78 | # get kernel params 79 | KERNEL_PARAMS="$(getkernelparams "${ROOTPART}" "${BOOTDEV}" "${CRYPTTYPE}")" || exit $? 80 | 81 | # kernelpart= 82 | # # kernelpart: kernel partition, ex. /dev/sda2 83 | # kernelpart="$(show_dialog --menu "Select the partition with the kernel (/boot)" 21 50 13 NONE - ${PARTS})" || exit $? 84 | # PARTS="$(echo ${PARTS} | sed -e "s#${kernelpart}\ _##g")" 85 | # [ "${kernelpart}" = "NONE" ] && return 1 86 | 87 | # kernelpart as disk and trailing part-number 88 | local kernelpartnu=$(expr match "${kernelpart}" '.*\([1-9][0-9]*\)') 89 | local kernelpartdisk=${kernelpart:0: -${#kernelpartnu}} 90 | # write to UEFI 91 | echo "${KERNEL_PARAMS} initrd=${initrdpath}" | \ 92 | iconv -f ascii -t ucs2 | \ 93 | efibootmgr --create --gpt \ 94 | --disk "${kernelpartdisk}" --part "${kernelpartnu}" \ 95 | --label "Pentoo" \ 96 | --loader "${kernelpath}" \ 97 | --append-binary-args - 98 | if [ $? -ne 0 ]; then 99 | show_dialog --msgbox "Error: Couldn't write to UEFI!" 0 0 100 | return 1 101 | fi 102 | 103 | chroot "${DESTDIR}" emerge --noreplace sys-boot/efibootmgr --nodeps 104 | if equery -q list sys-boot/grub:2 1>/dev/null; then 105 | chroot "${DESTDIR}" emerge --rage-clean sys-boot/grub:2 || exit $? 106 | fi 107 | 108 | show_dialog --msgbox "Success: Direct UEFI booting installed!" 0 0 109 | 110 | exit 0 111 | -------------------------------------------------------------------------------- /share/pentoo-installer/common.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # to be sourced by other scripts 6 | 7 | ############################## 8 | ## START: define constants ## 9 | readonly DESTDIR="/mnt/gentoo" 10 | # This error code will be used when the user cancels a process 11 | # dialog and Xdialog use 1 for cancel, Xdialog returns 255 upon closing of the box 12 | readonly ERROR_CANCEL=64 13 | readonly ISNUMBER='^[0-9]+$' 14 | # use the first VT not dedicated to a running console 15 | readonly LOG="/tmp/pentoo-installer-callbacks.log" 16 | readonly TITLE="Pentoo Installation" 17 | ## END: define constants ## 18 | ############################ 19 | 20 | ######################################## 21 | ## START: initialize global variables ## 22 | ## END: initialize global variables ## 23 | ###################################### 24 | 25 | # source error handling/functions 26 | source "${SHAREDIR}"/error.sh || exit $? 27 | 28 | ############################## 29 | ## START: utility functions ## 30 | 31 | # add_option_label() 32 | # Adds dummy labels to a list of strings, so it can be used by a --menu dialog 33 | # 34 | # returns 0 on success 35 | # 36 | # parameters (required): 37 | # list: space delimited list 38 | # label: the string to add as label 39 | # 40 | add_option_label() { 41 | # check input 42 | check_num_args "${FUNCNAME}" 2 $# || return $? 43 | local _ITEM= 44 | for _ITEM in ${1}; do 45 | echo "${_ITEM} ${2}" 46 | done 47 | return 0 48 | } 49 | 50 | # catch_menuerror() 51 | # catch errors from sub-script/functions 52 | # 53 | # returns 0 when an error was given 54 | # otherwise returns 1 55 | # 56 | # parameters (required): 57 | # _FUNCNAME: name of calling function/script 58 | # _SELECTION: which menu selection caused the error 59 | # _RETSUB: the return of the sub-function/script 60 | # 61 | # usage example: 62 | # if [ ! catch_menuerror "$(basename $0)" "${NEWSELECTION}" "${RETSUB}" ]; then 63 | # do_OK_action 64 | # fi 65 | catch_menuerror() { 66 | # check input 67 | check_num_args "${FUNCNAME}" 3 $# || return $? 68 | local _FUNCNAME="${1}" 69 | local _SELECTION="${2}" 70 | local _RETSUB="${3}" 71 | # catch errors from sub-script/functions 72 | if [ "${_RETSUB}" -ne 0 ]; then 73 | # received CANCEL 74 | if [ "${_RETSUB}" -eq "${ERROR_CANCEL}" ]; then 75 | echo "INFO: Received CANCEL after selection of '${_SELECTION}' in $(basename $0)" 1>&2 76 | # received other ERROR 77 | else 78 | echo "WARNING: Received ERROR '${_RETSUB}' after selection of '${_SELECTION}' in ${_FUNCNAME}" 1>&2 79 | # inform user 80 | show_dialog --msgbox "WARNING: The last step returned an error!" 0 0 81 | # exit completly on error in headless mode 82 | if [ -n "${INSTALLER_HEADLESS:-}" ]; then 83 | exit 1 84 | fi 85 | fi 86 | return 0 87 | fi 88 | # no error in sub-script 89 | return 1 90 | } 91 | 92 | # chroot_mount() 93 | # prepares target system as a chroot 94 | # 95 | chroot_mount() { 96 | # do a clean chroot-umount 97 | chroot_umount || return $? 98 | if [ ! -e "${DESTDIR}/sys" ]; then 99 | mkdir "${DESTDIR}/sys" || return $? 100 | fi 101 | if [ ! -e "${DESTDIR}/proc" ]; then 102 | mkdir "${DESTDIR}/proc" || return $? 103 | fi 104 | if [ ! -e "${DESTDIR}/dev" ]; then 105 | mkdir "${DESTDIR}/dev" || return $? 106 | fi 107 | #mount -t sysfs sysfs "${DESTDIR}/sys" || return $? 108 | #mount -t proc proc "${DESTDIR}/proc" || return $? 109 | for i in dev proc sys; do 110 | mount --make-shared /${i} || return $? 111 | mount --rbind --make-rslave /${i} "${DESTDIR}/${i}" || return $? 112 | done 113 | return 0 114 | } 115 | 116 | # chroot_umount() 117 | # tears down chroot in target system 118 | # 119 | chroot_umount() { 120 | sleep 1 121 | if mount | grep -q "${DESTDIR}/proc "; then 122 | umount -R ${DESTDIR}/proc || return $? 123 | fi 124 | if mount | grep -q "${DESTDIR}/sys "; then 125 | umount -R ${DESTDIR}/sys || return $? 126 | fi 127 | if mount | grep -q "${DESTDIR}/dev "; then 128 | umount -R ${DESTDIR}/dev || return $? 129 | fi 130 | return 0 131 | } 132 | 133 | # check_num_args() 134 | # simple check for required number of input arguments of calling function 135 | # 136 | # returns 0 on success 137 | # anything else is a real error 138 | # parameters: 139 | # required: 3 140 | # _FUNCNAME: name of calling function 141 | # _REQARGS: number of required args 142 | # _NUMARGS: number of received args 143 | # 144 | # example call for 3 required arguments: 145 | # check_num_args "${FUNCNAME}" 3 $# || return $? 146 | check_num_args() { 147 | # simple check number of input arguments of calling function 148 | if [ "${2}" -ne "${3}" ]; then 149 | echo "${1} takes exactly ${2} arguments but received ${3}." 1>&2 150 | echo "Returning error 1" 1>&2 151 | return 1 152 | fi 153 | return 0 154 | } 155 | 156 | # get_supportedFS() 157 | # prints a list of supported file systems to STDOUT 158 | # 159 | # returns 0 on success 160 | # anything else is a real error 161 | # 162 | get_supportedFS() { 163 | echo -n 'ext4 ext4-nojournal' 164 | [ "$(which mkreiserfs 2>/dev/null)" ] && echo -n ' reiserfs' 165 | [ "$(which btrfs 2>/dev/null)" ] && echo -n ' btrfs' 166 | [ "$(which mkfs.xfs 2>/dev/null)" ] && echo -n ' xfs' 167 | [ "$(which mkfs.jfs 2>/dev/null)" ] && echo -n ' jfs' 168 | [ "$(which mkfs.vfat 2>/dev/null)" ] && echo -n ' vfat' 169 | [ "$(which mkfs.fat 2>/dev/null)" ] && echo -n ' fat32' 170 | [ "$(which mkfs.f2fs 2>/dev/null)" ] && echo -n ' f2fs' 171 | return 0 172 | } 173 | 174 | # get_yesno() 175 | # convert 0|1 to yes|no 176 | # 177 | # returns 0 on success 178 | # 179 | # parameters (required): 180 | # input: 0 or 1 181 | # 182 | get_yesno() { 183 | # check input 184 | check_num_args "${FUNCNAME}" 1 $# || return $? 185 | case "${1}" in 186 | 0) echo 'no' ;; 187 | 1) echo 'yes' ;; 188 | *) echo 'ERROR: Not a boolean value of [0|1].' 1>&2 189 | return 1 ;; 190 | esac 191 | return 0 192 | } 193 | 194 | # mount_umountall() 195 | # 1) umount -R $DESTDIR to prepare installation 196 | # 2) swaps off devices 197 | # 3) cleans up cryptsetup 198 | # does a dry run and asks user for 3 199 | # 200 | # arguments (required): 201 | # _DISCLIST: List of involved discs or partitions 202 | # 203 | # exits: !=0 is an error 204 | # 205 | mount_umountall() { 206 | # check input 207 | check_num_args "${FUNCNAME}" 1 $# || return $? 208 | local _DISCLIST="${1}" 209 | local _DISC= 210 | local _UMOUNTLIST= 211 | local _NAME= 212 | local _FSTYPE= 213 | local _MOUNTPOINT= 214 | local _CRYPTCLOSE=() 215 | local _LINE= 216 | # umount /mnt/gentoo and below 217 | # this is the only umount, anything mounted outside is the users problem 218 | # umount -R "${DESTDIR}" 2>/dev/null 219 | chroot_umount 220 | if lsblk -o MOUNTPOINT | grep -Eq '^/mnt/gentoo(/.*)?'; then 221 | umount `lsblk -o MOUNTPOINT | grep -E '^/mnt/gentoo(/.*)?' | LC_ALL=C sort -r | tr '\n' ' '` || return $? 222 | fi 223 | # do a first run, swapoff, check mountpoints and collect cryptsetup stuff 224 | for _DISC in ${_DISCLIST}; do 225 | _UMOUNTLIST="$(lsblk -lnp -o NAME,FSTYPE,MOUNTPOINT "${_DISC}")" || return $? 226 | while read -r _LINE; do 227 | _NAME=$(echo ${_LINE} | awk '{print $1}') 228 | # FSTYPE is only helpful for luks devices, not swap 229 | _FSTYPE=$(echo "${_LINE}" | awk '{print $2}') 230 | _MOUNTPOINT=$(echo "${_LINE}" | awk '{print $3}') 231 | # swapped on partition 232 | if [ "${_FSTYPE}" = 'swap' ] && [ "${_MOUNTPOINT}" = '[SWAP]' ]; then 233 | swapoff "${_NAME}" || return $? 234 | sleep 1 235 | # throw error on any other mountpoint, aka outside $DESTDIR 236 | elif [ -n "${_MOUNTPOINT}" ]; then 237 | echo "ERROR: Unexpected mountpoint '${_MOUNTPOINT}' for '${_NAME}'." 1>&2 238 | return 1 239 | fi 240 | # check for open cryptsetup 241 | # only childs, not the target partition itself 242 | if [ "${_NAME}" != "${_DISC}" ] && cryptsetup status "${_NAME}" &>/dev/null; then 243 | _CRYPTCLOSE+=("${_NAME}") 244 | fi 245 | done <<<"${_UMOUNTLIST}" 246 | done 247 | # cryptsetup open anywhere? 248 | if [ "${#_CRYPTCLOSE[@]}" -gt 0 ]; then 249 | # TODO: how is the correct term for an open cryptsetup thingy? ;) 250 | show_dialog --defaultno --yesno "Cryptsetup is using the names below. Do you want to close them?\n$(echo "${_CRYPTCLOSE[@]}" | tr ' ' '\n')" 0 0 || return "${ERROR_CANCEL}" 251 | for _NAME in ${_CRYPTCLOSE[@]}; do 252 | cryptsetup close "${_NAME}" || return $? 253 | done 254 | fi 255 | return 0 256 | } 257 | 258 | # seteditor() 259 | # sets a system editor in chroot environment 260 | # chroot must be prepared outside this function! 261 | # 262 | # parameters (none) 263 | # 264 | # returns $ERROR_CANCEL=64 on user cancel 265 | # anything else is a real error 266 | # reason: show_dialog() needs a way to exit "Cancel" 267 | # 268 | seteditor(){ 269 | # check input 270 | check_num_args "${FUNCNAME}" 0 $# || return $? 271 | local _EDITOR= 272 | local _MENU_ITEMS=() 273 | local _RET_SUB= 274 | # parse the output of 'eselect editor list' so it can be used as menu options 275 | _MENU_ITEMS=("$(chroot "${DESTDIR}" eselect editor list | tail -n +2 | grep -v '\(free form\)' | sed -r 's/[[:space:]]+\*[[:space:]]*$//' | sed -r -e 's/^[[:space:]]*//g' -e "s/\[([[:digit:]]+)\][[:space:]]+/\1 /" | tr '\n' ' ')") || return $? 276 | # ask user for editor 277 | _EDITOR="$(show_dialog --menu "Select a text editor to use (nano is easier)" \ 278 | 0 0 0 ${_MENU_ITEMS[@]})" \ 279 | || return $? 280 | # set new editor 281 | chroot ${DESTDIR} /bin/bash <&2 || exit $? 283 | source /etc/profile || exit $? 284 | EOF 285 | _RET_SUB=$? 286 | [ "${_RET_SUB}" -ne 0 ] && return "${_RET_SUB}" 287 | # read new editor 288 | _EDITOR="$(chroot "${DESTDIR}" eselect editor show | tail -n +2 | sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g')" || return $? 289 | # print editor to STDOUT 290 | echo "${_EDITOR}" 291 | return 0 292 | } 293 | 294 | # geteditor() 295 | # get system editor from chroot, prints to SDTOUT 296 | # if not set: asks user to choose one 297 | # chroot must be prepared outside this function! 298 | # 299 | # parameters (none) 300 | # 301 | # returns $ERROR_CANCEL=64 on user cancel 302 | # anything else is a real error 303 | # reason: show_dialog() needs a way to exit "Cancel" 304 | # 305 | geteditor(){ 306 | # check input 307 | check_num_args "${FUNCNAME}" 0 $# || return $? 308 | local _EDITOR= 309 | # read current editor 310 | _EDITOR="$(chroot "${DESTDIR}" eselect editor show | tail -n +2 | sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*$//g' -e 's/[[:space:]]*$//g')" || return $? 311 | # check if not set 312 | if [ "${_EDITOR}" = '(none)' ]; then 313 | _EDITOR="$(seteditor)" || return $? 314 | fi 315 | # print editor to STDOUT 316 | echo "${_EDITOR}" 317 | return 0 318 | } 319 | 320 | # get_dialog() 321 | # prints used dialog programm: 'dialog' or 'Xdialog' 322 | # 323 | get_dialog() { 324 | # let's support Xdialog for the fun of it 325 | #if [ ! $(type "Xdialog" &> /dev/null) ] && [ -n "${DISPLAY}" ]; then 326 | # echo 'Xdialog' 327 | #else 328 | echo 'dialog' 329 | #fi 330 | return 0 331 | } 332 | 333 | # show_dialog() 334 | # uses dialogSTDOUT 335 | # an el-cheapo dialog wrapper 336 | # parameters: see dialog(1) and Xdialog(1 337 | # usage: MYVAR="$(show_dialog .......)" 338 | # returns: 339 | # - 0 for Ok, result is written to STDOUT 340 | # - 64 when user clicks cancel or closes the box 341 | # - anything else is a real error 342 | # 343 | show_dialog() { 344 | # this script supports dialog and Xdialog but writes result to STDOUT 345 | # returns 64 if user cancels or closes the box! 346 | # detect auto-width and auto-height 347 | local _ARGUMENTS=() 348 | local _HEIGHT= 349 | local _WIDTH= 350 | local _BOXOPTION_INDEX= 351 | local _INDEX=0 352 | local _WHICHDIALOG= 353 | local _ANSWER= 354 | local _DIALOGRETURN= 355 | local _XDIALOG_AUTOSIZE_PERCENTAGE=33 356 | local _DEFAULTITEM= 357 | local _DEFAULTVALUE= 358 | local _DIALOGBOX= 359 | # copy array of arguments so we can write to it 360 | # also prepend our own arguments 361 | # add timeout for headless mode 362 | if [ -n "${INSTALLER_HEADLESS:-}" ]; then 363 | _ARGUMENTS+=('--timeout' '3'); 364 | fi 365 | _ARGUMENTS+=( '--backtitle' "${TITLE}" '--aspect' '15' "$@") || return $? 366 | # decide which dialog to use 367 | _WHICHDIALOG="$(get_dialog)" 368 | 369 | # loop arguments and search for options 370 | while [ "${_INDEX}" -lt "${#_ARGUMENTS[@]}" ]; do 371 | # get box type 372 | case "${_ARGUMENTS[$_INDEX]}" in 373 | '--buildlist' | '--calendar' | '--checklist' | '--dselect' | '--editbox' | '--form' | '--fselect' | '--gauge' | '--infobox' | '--inputbox' | '--inputmenu' | '--menu' | '--mixedform' | '--mixedgauge' | '--msgbox' | '--passwordbox' | '--passwordform' | '--pause' | '--prgbox' | '--programbox' | '--progressbox' | '--radiolist' | '--rangebox' | '--tailbox' | '--tailboxbg' | '--textbox' | '--timebox' | '--treeview' | '--yesno') 374 | _DIALOGBOX="${_ARGUMENTS[$_INDEX]}" 375 | ;; 376 | esac 377 | 378 | # for Xdialog: autosize does not work well with a title, use percentage of max-size 379 | if [ "${_WHICHDIALOG}" = 'Xdialog' ]; then 380 | # search for the box option 381 | # also swap --title and --backtitle 382 | case "${_ARGUMENTS[$_INDEX]}" in 383 | # all of these have the format: -- text height width 384 | '--calendar' | '--checklist' | '--dselect' | '--editbox' | '--form' | '--fselect' | '--gauge' | '--infobox' | '--inputbox' | '--inputmenu' | '--menu' | '--mixedform' | '--mixedgauge' | '--msgbox' | '--passwordbox' | '--passwordform' | '--pause' | '--progressbox' | '--radiolist' | '--tailbox' | '--tailboxbg' | '--textbox' | '--timebox' | '--yesno') 385 | # prevent multiple box options 386 | [ -n "${_BOXOPTION_INDEX}" ] && return 1 387 | _BOXOPTION_INDEX="${_INDEX}" 388 | ;; 389 | # swap title and backtitle for Xdialog 390 | '--title') 391 | _ARGUMENTS[${_INDEX}]='--backtitle' 392 | ;; 393 | # swap title and backtitle for Xdialog 394 | '--backtitle') 395 | _ARGUMENTS[${_INDEX}]='--title' 396 | ;; 397 | *) ;; 398 | esac 399 | fi 400 | # store default item for menu 401 | if [ "${_ARGUMENTS[$_INDEX]}" == '--default-item' ]; then 402 | _DEFAULTITEM="${_ARGUMENTS[$((_INDEX+1))]}" || exit $? 403 | # suppress defaultno in yesno dialog (headless mode only) 404 | elif [ -n "${INSTALLER_HEADLESS:-}" ] && [ "${_ARGUMENTS[$_INDEX]}" == '--defaultno' ]; then 405 | _ARGUMENTS[$_INDEX]='--nocancel' 406 | elif [ "${_ARGUMENTS[$_INDEX]}" == '--inputbox' ]; then 407 | if [ "$((${_INDEX}+4))" -lt "${#_ARGUMENTS[@]}" ]; then 408 | _DEFAULTVALUE="${_ARGUMENTS[$((_INDEX+4))]}" || exit $? 409 | fi 410 | elif [ "${_ARGUMENTS[$_INDEX]}" == '--menu' ]; then 411 | if [ "$((${_INDEX}+4))" -ge "${#_ARGUMENTS[@]}" ]; then 412 | echo "ERROR: cannot find the first menu item'. Exiting with an error!" 1>&2 413 | return 1 414 | fi 415 | _DEFAULTVALUE="${_ARGUMENTS[$((_INDEX+5))]}" || exit $? 416 | fi 417 | _INDEX="$((_INDEX+1))" || return $? 418 | done 419 | 420 | # for Xdialog: autosize does not work well with a title, use percentage of max-size 421 | if [ "${_WHICHDIALOG}" = 'Xdialog' ]; then 422 | # check if box option was found 423 | if [ -z "${_BOXOPTION_INDEX}" ]; then 424 | echo "ERROR: Cannot find box option. Exiting with an error!" 1>&2 425 | return 1 426 | fi 427 | if [ "$((${_BOXOPTION_INDEX}+3))" -ge "${#_ARGUMENTS[@]}" ]; then 428 | echo "ERROR: cannot find height and width for box option '"${_ARGUMENTS[${_BOXOPTION_INDEX}]}"'. Exiting with an error!" 1>&2 429 | return 1 430 | fi 431 | # only fix width/height for these box options 432 | case "${_ARGUMENTS[${_BOXOPTION_INDEX}]}" in 433 | '--menu' | '--gauge') 434 | _HEIGHT="${_ARGUMENTS[$((_BOXOPTION_INDEX+2))]}" || return $? 435 | _WIDTH="${_ARGUMENTS[$((_BOXOPTION_INDEX+3))]}" || return $? 436 | # check if width/height were found 437 | if [ -z "${_HEIGHT}" ] || [ -z "${_WIDTH}" ]; then 438 | echo "ERROR: Did not find box option with height/width. Exiting with an error" 1>&2 439 | return 1 440 | fi 441 | # use defined percentage of max-size 442 | if [ "${_HEIGHT}" -eq 0 ] && [ "${_WIDTH}" -eq 0 ]; then 443 | _HEIGHT=$("${_WHICHDIALOG}" --print-maxsize 2>&1 | tr -d ',' | cut -d ' ' -f2) || return $? 444 | _WIDTH=$("${_WHICHDIALOG}" --print-maxsize 2>&1 | tr -d ',' | cut -d ' ' -f3) || return $? 445 | _HEIGHT=$((${_HEIGHT} * ${_XDIALOG_AUTOSIZE_PERCENTAGE} / 100)) || return $? 446 | _WIDTH=$((${_WIDTH} * ${_XDIALOG_AUTOSIZE_PERCENTAGE} / 100)) || return $? 447 | # write new values to copy of arguments array 448 | _ARGUMENTS[$((_BOXOPTION_INDEX+2))]="${_HEIGHT}" || return $? 449 | _ARGUMENTS[$((_BOXOPTION_INDEX+3))]="${_WIDTH}" || return $? 450 | fi 451 | ;; 452 | *) ;; 453 | esac 454 | fi 455 | 456 | #not sure how this redirection will work for Xdialog, but for now this makes catching logs perfect 457 | _ANSWER=$("${_WHICHDIALOG}" "${_ARGUMENTS[@]}" 2>&1 >/dev/tty) 458 | _DIALOGRETURN=$? 459 | # check for timeout return when running headless 460 | if [ -n "${INSTALLER_HEADLESS:-}" ] && [ "${_DIALOGRETURN}" -eq "255" ]; then 461 | _DIALOGRETURN=0 462 | # return default selection for --menu 463 | if [ -n "${_DEFAULTITEM}" ]; then 464 | _ANSWER="${_DEFAULTITEM}" 465 | elif [ -n "${_DEFAULTVALUE}" ]; then 466 | _ANSWER="${_DEFAULTVALUE}" 467 | elif [ "${_DIALOGBOX}" == '--calendar' ]; then 468 | _ANSWER="$(date +'%d/%m/%Y')" || exit $? 469 | elif [ "${_DIALOGBOX}" == '--timebox' ]; then 470 | _ANSWER="$(date +'%T')" || exit $? 471 | # inputbox without default value, catch timeout 472 | elif [ "${_DIALOGBOX}" == '--inputbox' ]; then 473 | if [ "${_ANSWER}" == $'\ntimeout' ]; then 474 | echo "Error: input box in headless mode without default returned timeout" 1>&2 475 | exit 1 476 | fi 477 | fi 478 | # check if user clicked cancel or closed the box 479 | elif [ "${_DIALOGRETURN}" -eq "1" ] || [ "${_DIALOGRETURN}" -eq "255" ]; then 480 | return ${ERROR_CANCEL} 481 | elif [ "${_DIALOGRETURN}" -ne "0" ]; then 482 | return "${_DIALOGRETURN}" 483 | fi 484 | # no error or cancel, echo to STDOUT 485 | echo -n "${_ANSWER}" 486 | return 0 487 | } 488 | 489 | # show_dialog_rsync() 490 | # runs rsync, displays output as gauge dialog 491 | # tee's log to "${LOG}" 492 | # options to rsync should include '--progress' or the gauge will not move ;) 493 | # 494 | # parameters (required): 495 | # _OPTIONS: options for rsync 496 | # _SOURCE: source for rsync 497 | # _DESTINATION: destination for rsync 498 | # _MSG: message for gauge dialog 499 | # 500 | # returns $ERROR_CANCEL=64 on user cancel 501 | # anything else is a real error 502 | # reason: show_dialog() needs a way to exit "Cancel" 503 | # 504 | show_dialog_rsync() { 505 | # check input 506 | check_num_args "${FUNCNAME}" 4 $# || return $? 507 | local _OPTIONS="${1}" 508 | local _SOURCE="${2}" 509 | local _DESTINATION="${3}" 510 | local _MSG="${4}" 511 | rsync ${_OPTIONS} ${_SOURCE} ${_DESTINATION} 2>&1 \ 512 | | tee "${LOG}" \ 513 | | awk -f "${SHAREDIR}"/rsync.awk \ 514 | | sed --unbuffered 's/\([0-9]*\).*/\1/' \ 515 | | show_dialog --gauge "${_MSG}" 0 0 516 | _RET_SUB=$? 517 | if [ "${_RET_SUB}" -ne 0 ]; then 518 | show_dialog --msgbox "Failed to rsync '${_DESTINATION}'. See the log output for more information" 0 0 519 | return "${_RET_SUB}" 520 | fi 521 | return 0 522 | } 523 | 524 | ## END: utility functions ## 525 | ############################ 526 | -------------------------------------------------------------------------------- /share/pentoo-installer/config-samples/config.bios.msdos.json: -------------------------------------------------------------------------------- 1 | { 2 | "#": "optional (utc or localtime)", 3 | "hwclock": "utc", 4 | 5 | "#": "optional", 6 | "timezone": "Europe/Zurich", 7 | 8 | "#": "required", 9 | "disks":[ 10 | { 11 | "#": "required", 12 | "device": "/dev/sda", 13 | 14 | "#": "optional: will only be applied when set and different from current (msdos/gpt)", 15 | "#": "requires wipe=true", 16 | "partition-table": "msdos", 17 | 18 | "#": "optional default=false", 19 | "wipe": true, 20 | 21 | "#": "required", 22 | "partitions": [ 23 | { 24 | "#": "semi-required: either 'create' or 'existing' must be present", 25 | "create": { 26 | "#": "optional (default=primary) for msdos: primary/extended/logical", 27 | "#": "list extended before logical and only one extended per disk!", 28 | "partition-type": "primary", 29 | 30 | "#": "required", 31 | "start": "1", 32 | 33 | "#": "anything that parted understands", 34 | "end": "129M", 35 | 36 | "#": "optional", 37 | "flags": { 38 | "#": "anything that parted understands", 39 | "boot": "on" 40 | } 41 | }, 42 | 43 | "#": "semi-required: either 'create' or 'existing' must be present", 44 | "#": "below key is prepended with '#', since it's just an example!", 45 | "#existing": { 46 | "#": "required", 47 | "device": "/dev/sda1", 48 | 49 | "#": "optional, default=false", 50 | "format": false 51 | }, 52 | 53 | "#": "required: must be empty for swap", 54 | "#": "ignored for msdos logical partitions", 55 | "mountpoint": "/boot", 56 | 57 | "#": "optional, default='' (one of: 'swap', 'luks2', 'luks2-gpg', '')", 58 | "crypttype": "", 59 | 60 | "#": "required", 61 | "#": "ignored for msdos logical partitions", 62 | "filesystem": "ext4-nojournal", 63 | 64 | "#": "optional (default=false): maximise into free space", 65 | "want_maximised": true 66 | }, 67 | { 68 | "create": { 69 | "start": "129M", 70 | "end": "1281M" 71 | }, 72 | "mountpoint": "", 73 | "filesystem": "swap", 74 | "want_maximised": true 75 | }, 76 | { 77 | "create": { 78 | "start": "1281M", 79 | "end": "54G" 80 | }, 81 | "mountpoint": "/", 82 | "filesystem": "ext4", 83 | "want_maximised": true 84 | }, 85 | { 86 | "create": { 87 | "partition-type": "extended", 88 | "start": "54G", 89 | "end": "64G" 90 | }, 91 | "want_maximised": true 92 | }, 93 | { 94 | "create": { 95 | "partition-type": "logical", 96 | "start": "54G", 97 | "end": "60G" 98 | }, 99 | "mountpoint": "/mnt/logical1", 100 | "filesystem": "ext4", 101 | "want_maximised": true 102 | }, 103 | { 104 | "create": { 105 | "partition-type": "logical", 106 | "start": "60G", 107 | "end": "64G" 108 | }, 109 | "mountpoint": "/mnt/logical2", 110 | "filesystem": "ext4", 111 | "want_maximised": true 112 | } 113 | ] 114 | } 115 | ] 116 | } 117 | -------------------------------------------------------------------------------- /share/pentoo-installer/config-samples/config.bios.msdos.withexisting.json: -------------------------------------------------------------------------------- 1 | { 2 | "#": "optional (utc or localtime)", 3 | "hwclock": "utc", 4 | 5 | "#": "optional", 6 | "timezone": "Europe/Zurich", 7 | 8 | "#": "required", 9 | "disks":[ 10 | { 11 | "#": "required", 12 | "device": "/dev/sda", 13 | "#": "optional: will only be applied when set and different from current (msdos/gpt)", 14 | "#": "requires wipe=true", 15 | "partition-table": "msdos", 16 | "#": "optional default=false", 17 | "wipe": false, 18 | "#": "required", 19 | "partitions": [ 20 | { 21 | "#": "semi-required: either 'create' or 'existing' must be present", 22 | "create": { 23 | "#": "optional (default=primary) for msdos: primary/extended/logical", 24 | "#": "list extended before logical and only one extended per disk!", 25 | "partition-type": "primary", 26 | "#": "required", 27 | "start": "1", 28 | "#": "anything that parted understands", 29 | "end": "129M", 30 | "#": "optional", 31 | "flags": { 32 | "#": "anything that parted understands", 33 | "boot": "on" 34 | } 35 | 36 | }, 37 | 38 | "#": "semi-required: either 'create' or 'existing' must be present", 39 | "#": "below key is prepended with '#', since it's just an example!", 40 | "#existing": { 41 | "#": "required", 42 | "device": "/dev/sda1", 43 | "#": "optional, default=false", 44 | "format": false 45 | }, 46 | 47 | "#": "required: must be empty for swap", 48 | "#": "ignored for msdos logical partitions", 49 | "mountpoint": "/boot", 50 | "#": "optional, default='' (one of: 'swap', 'luks2', 'luks2-gpg', '')", 51 | "crypttype": "", 52 | "#": "required", 53 | "#": "ignored for msdos logical partitions", 54 | "filesystem": "ext4-nojournal", 55 | "#": "optional (default=false): maximise into free space", 56 | "want_maximised": true 57 | }, 58 | { 59 | "create": { 60 | "start": "129M", 61 | "end": "1281M" 62 | }, 63 | "mountpoint": "", 64 | "filesystem": "swap", 65 | "want_maximised": true 66 | }, 67 | { 68 | "create": { 69 | "start": "1281M", 70 | "end": "54G" 71 | }, 72 | "mountpoint": "/", 73 | "filesystem": "ext4", 74 | "want_maximised": true 75 | }, 76 | { 77 | "existing": { 78 | "device": "/dev/sda5", 79 | "format": true 80 | }, 81 | "mountpoint": "/mnt/logical1", 82 | "filesystem": "ext4", 83 | "want_maximised": true 84 | }, 85 | { 86 | "create": { 87 | "partition-type": "logical", 88 | "start": "60G", 89 | "end": "64G" 90 | }, 91 | "mountpoint": "/mnt/logical2", 92 | "filesystem": "ext4", 93 | "want_maximised": true 94 | } 95 | 96 | ] 97 | } 98 | ] 99 | } 100 | -------------------------------------------------------------------------------- /share/pentoo-installer/config-samples/config.efi.gpt.json: -------------------------------------------------------------------------------- 1 | { 2 | "#": "optional (utc or localtime)", 3 | "hwclock": "utc", 4 | 5 | "#": "optional", 6 | "timezone": "Europe/Zurich", 7 | 8 | "#": "required", 9 | "disks":[ 10 | { 11 | "#": "required", 12 | "device": "/dev/sda", 13 | 14 | "#": "optional: will only be applied when set and different from current (msdos/gpt)", 15 | "#": "requires wipe=true", 16 | "partition-table": "gpt", 17 | 18 | "#": "optional default=false", 19 | "wipe": true, 20 | 21 | "#": "required", 22 | "partitions": [ 23 | { 24 | "#": "semi-required: either 'create' or 'existing' must be present", 25 | "create": { 26 | "#": "optional (default=primary) for msdos: primary/extended/logical", 27 | "#": "list extended before logical and only one extended per disk!", 28 | "partition-type": "primary", 29 | 30 | "#": "required", 31 | "start": "1", 32 | 33 | "#": "anything that parted understands", 34 | "end": "551M", 35 | 36 | "#": "optional, ignored for msdos", 37 | "label": "boot", 38 | 39 | "#": "optional", 40 | "flags": { 41 | "#": "anything that parted understands", 42 | "boot": "on" 43 | } 44 | }, 45 | 46 | "#": "semi-required: either 'create' or 'existing' must be present", 47 | "#": "below key is prepended with '#', since it's just an example!", 48 | "#existing": { 49 | "#": "required", 50 | "device": "/dev/sda1", 51 | 52 | "#": "optional, default=false", 53 | "format": false 54 | }, 55 | 56 | "#": "required: must be empty for swap", 57 | "mountpoint": "/boot", 58 | 59 | "#": "optional, default='' (one of: 'swap', 'luks2', 'luks2-gpg', '')", 60 | "crypttype": "", 61 | 62 | "#": "required", 63 | "filesystem": "fat32", 64 | 65 | "#": "optional (default=false): maximise into free space", 66 | "want_maximised": true 67 | }, 68 | { 69 | "create": { 70 | "start": "551M", 71 | "end": "1575M", 72 | "label": "swap" 73 | }, 74 | "mountpoint": "", 75 | "filesystem": "swap", 76 | "want_maximised": true 77 | }, 78 | { 79 | "create": { 80 | "start": "1575M", 81 | "end": "54G", 82 | "label": "root" 83 | }, 84 | "mountpoint": "/", 85 | "filesystem": "ext4", 86 | "want_maximised": true 87 | }, 88 | { 89 | "create": { 90 | "start": "54G", 91 | "end": "60G", 92 | "label": "test1" 93 | }, 94 | "mountpoint": "/mnt/test1", 95 | "filesystem": "ext4", 96 | "want_maximised": true 97 | }, 98 | { 99 | "create": { 100 | "start": "60G", 101 | "end": "64G", 102 | "label": "test2" 103 | }, 104 | "mountpoint": "/mnt/test2", 105 | "filesystem": "ext4", 106 | "want_maximised": true 107 | } 108 | ] 109 | } 110 | ] 111 | } 112 | -------------------------------------------------------------------------------- /share/pentoo-installer/config-samples/config.efi.msdos.json: -------------------------------------------------------------------------------- 1 | { 2 | "#": "optional (utc or localtime)", 3 | "hwclock": "utc", 4 | 5 | "#": "optional", 6 | "timezone": "Europe/Zurich", 7 | 8 | "#": "required", 9 | "disks":[ 10 | { 11 | "#": "required", 12 | "device": "/dev/sda", 13 | 14 | "#": "optional: will only be applied when set and different from current (msdos/gpt)", 15 | "#": "requires wipe=true", 16 | "partition-table": "msdos", 17 | 18 | "#": "optional default=false", 19 | "wipe": true, 20 | 21 | "#": "required", 22 | "partitions": [ 23 | { 24 | "#": "semi-required: either 'create' or 'existing' must be present", 25 | "create": { 26 | "#": "optional (default=primary) for msdos: primary/extended/logical", 27 | "#": "list extended before logical and only one extended per disk!", 28 | "partition-type": "primary", 29 | 30 | "#": "required", 31 | "start": "1", 32 | 33 | "#": "anything that parted understands", 34 | "end": "551M", 35 | 36 | "#": "optional", 37 | "flags": { 38 | "#": "anything that parted understands", 39 | "boot": "on" 40 | } 41 | }, 42 | 43 | "#": "semi-required: either 'create' or 'existing' must be present", 44 | "#": "below key is prepended with '#', since it's just an example!", 45 | "#existing": { 46 | "#": "required", 47 | "device": "/dev/sda1", 48 | 49 | "#": "optional, default=false", 50 | "format": false 51 | }, 52 | 53 | "#": "required: must be empty for swap", 54 | "#": "ignored for msdos logical partitions", 55 | "mountpoint": "/boot", 56 | 57 | "#": "optional, default='' (one of: 'swap', 'luks2', 'luks2-gpg', '')", 58 | "crypttype": "", 59 | 60 | "#": "required", 61 | "#": "ignored for msdos logical partitions", 62 | "filesystem": "fat32", 63 | 64 | "#": "optional (default=false): maximise into free space", 65 | "want_maximised": true 66 | }, 67 | { 68 | "create": { 69 | "start": "551M", 70 | "end": "1575M" 71 | }, 72 | "mountpoint": "", 73 | "filesystem": "swap", 74 | "want_maximised": true 75 | }, 76 | { 77 | "create": { 78 | "start": "1575M", 79 | "end": "54G" 80 | }, 81 | "mountpoint": "/", 82 | "filesystem": "ext4", 83 | "want_maximised": true 84 | }, 85 | { 86 | "create": { 87 | "partition-type": "extended", 88 | "start": "54G", 89 | "end": "64G" 90 | }, 91 | "want_maximised": true 92 | }, 93 | { 94 | "create": { 95 | "partition-type": "logical", 96 | "start": "54G", 97 | "end": "60G" 98 | }, 99 | "mountpoint": "/mnt/test1", 100 | "filesystem": "ext4", 101 | "want_maximised": true 102 | }, 103 | { 104 | "create": { 105 | "partition-type": "logical", 106 | "start": "60G", 107 | "end": "64G" 108 | }, 109 | "mountpoint": "/mnt/test2", 110 | "filesystem": "ext4", 111 | "want_maximised": true 112 | } 113 | ] 114 | } 115 | ] 116 | } 117 | -------------------------------------------------------------------------------- /share/pentoo-installer/configure_system: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # configure_system 6 | # gives user choices to further edit target system 7 | # 8 | # parameters (required) 9 | # CONFIG_LIST: One string items of defined FSspec 10 | # 11 | # returns 0 on success 12 | # returns $ERROR_CANCEL=64 on user cancel 13 | # anything else is a real error 14 | # reason: show_dialog() needs a way to exit "Cancel" 15 | # 16 | # writes menus and noise to STDERR 17 | 18 | # location of other scripts to source 19 | readonly SHAREDIR="$(dirname ${0})" || exit $? 20 | 21 | # source common variables, functions and error handling 22 | source "${SHAREDIR}"/common.sh || exit $? 23 | 24 | ######################################### 25 | ## START: dialog functions/definitions ## 26 | 27 | # setbootopts() 28 | # sets boot time services 29 | # chroot must be prepared outside this function! 30 | # 31 | # parameters (none) 32 | setbootopts() { 33 | while true; do 34 | local _MENU_ITEMS=() 35 | if chroot "${DESTDIR}" rc-update show | grep NetworkManager | grep -q default; then 36 | _MENU_ITEMS+=("BootQuiet" "NetworkManager is currently enabled at boot, disable NetworkManager?") 37 | else 38 | _MENU_ITEMS+=("BootNet" "NetworkManager is currently disabled at boot, enable NetworkManager?") 39 | fi 40 | if chroot "${DESTDIR}" rc-update show | grep bluetooth | grep -q default; then 41 | _MENU_ITEMS+=("BootNoBluetooth" "Bluetooth is currently enabled at boot, disable bluetooth?") 42 | else 43 | _MENU_ITEMS+=("BootBluetooth" "Bluetooth is currently disabled at boot, enable bluetooth?") 44 | fi 45 | if chroot "${DESTDIR}" rc-update show | grep display-manager | grep -q default; then 46 | _MENU_ITEMS+=("BootConsole" "Currently booting to X (display-manager/slim), switch to console for login?") 47 | elif chroot "${DESTDIR}" rc-update show | grep xdm | grep -q default; then 48 | _MENU_ITEMS+=("BootConsole" "Currently booting to X (xdm/slim), switch to console for login?") 49 | else 50 | _MENU_ITEMS+=("BootX" "Currently booting to console, switch to X for login (display-manager/slim)?") 51 | fi 52 | _MENU_ITEMS+=("DONE" "Return to Configuration Menu" ) 53 | 54 | # expand menu items array below 55 | NEWSELECTION="$(show_dialog --menu 'Boot services' \ 56 | 0 0 0 "${_MENU_ITEMS[@]}")" || exit $? 57 | # call subscript by selected item 58 | case "${NEWSELECTION}" in 59 | # Return to main menu 60 | "DONE") 61 | return 0 62 | ;; 63 | "BootQuiet") 64 | chroot "${DESTDIR}" rc-update del NetworkManager default 65 | ;; 66 | "BootNet") 67 | chroot "${DESTDIR}" rc-update add NetworkManager default 68 | ;; 69 | "BootNoBluetooth") 70 | chroot "${DESTDIR}" rc-update del bluetooth default 71 | ;; 72 | "BootBluetooth") 73 | chroot "${DESTDIR}" rc-update add bluetooth default 74 | ;; 75 | "BootConsole") 76 | if [ -x "${DESTDIR}/etc/init.d/display-manager" ]; then 77 | chroot "${DESTDIR}" rc-update del display-manager default 78 | elif [ -x "${DESTDIR}/etc/init.d/xdm" ]; then 79 | chroot "${DESTDIR}" rc-update del xdm default 80 | fi 81 | ;; 82 | "BootX") 83 | if [ -x "${DESTDIR}/etc/init.d/display-manager" ]; then 84 | chroot "${DESTDIR}" rc-update add display-manager default 85 | elif [ -x "${DESTDIR}/etc/init.d/xdm" ]; then 86 | chroot "${DESTDIR}" rc-update add xdm default 87 | fi 88 | ;; 89 | esac 90 | done 91 | } 92 | 93 | # setpassword() 94 | # sets password for a user 95 | # chroot must be prepared outside this function! 96 | # 97 | # parameters (required) 98 | # _USERNAME: Name of the user 99 | # 100 | # returns $ERROR_CANCEL=64 on user cancel 101 | # anything else is a real error 102 | # reason: show_dialog() needs a way to exit "Cancel" 103 | # 104 | setpassword(){ 105 | # check input 106 | check_num_args "${FUNCNAME}" 1 $# || return $? 107 | local _USERNAME="${1}" 108 | local _PASSWORD="jimmy" 109 | local _PASSWORD2="sally" 110 | local _FIRST_TRY="true" 111 | local _RET_SUB= 112 | until [ "${_PASSWORD}" == "${_PASSWORD2}" ]; do 113 | if [ "${_FIRST_TRY}" != "true" ]; then 114 | show_dialog --msgbox "Passwords do not match, unable to set password. Please try again." 7 30 115 | fi 116 | _PASSWORD="$(show_dialog --clear --insecure --passwordbox "Enter a password for user '${_USERNAME}'" 17 70)" || return $? 117 | _PASSWORD2="$(show_dialog --clear --insecure --passwordbox "Confirm password for user '${_USERNAME}'" 17 70)" || return $? 118 | _FIRST_TRY="false" 119 | done 120 | chroot "${DESTDIR}" /bin/bash < /dev/null 190 | # capture sub script exit 191 | RETSUB=$? 192 | ;; 193 | "Set-Username") 194 | # find username with UID=1000 195 | OLD_USERNAME="$(chroot "${DESTDIR}" id --name --user --zero 1000)" 196 | USERNAME="$(show_dialog --inputbox "Enter a username" 17 70)" \ 197 | && chroot "${DESTDIR}" usermod -l ${USERNAME} "${OLD_USERNAME}" >> ${LOG} \ 198 | && chroot "${DESTDIR}" usermod -d /home/${USERNAME} -m ${USERNAME} >> ${LOG} \ 199 | && chroot "${DESTDIR}" groupmod --new-name "${USERNAME}" "${OLD_USERNAME}" >> ${LOG} \ 200 | && setpassword "${USERNAME}" 2> /dev/null 201 | RETSUB=$? 202 | if [ "${RETSUB}" = 0 ]; then 203 | [ -w "${DESTDIR}/home/${USERNAME}/.config/gtk-3.0/bookmarks" ] && sed -i "s#/home/${OLD_USERNAME}#/home/${USERNAME}#" "${DESTDIR}/home/${USERNAME}/.config/gtk-3.0/bookmarks" 204 | [ -d "${DESTDIR}/home/${USERNAME}/.config/xfce4/desktop/" ] && find "${DESTDIR}/home/${USERNAME}/.config/xfce4/desktop/" -name "icons.*.rc" -print0 | xargs -0 -I {} -P 0 sed -i -e "s#/home/${OLD_USERNAME}#/home/${USERNAME}#" {} 205 | [ -d "${DESTDIR}/home/${USERNAME}/.config/xfce4/xfconf/xfce-perchannel-xml/" ] && find "${DESTDIR}/home/${USERNAME}/.config/xfce4/xfconf/xfce-perchannel-xml/" -name "*.xml" -print0 | xargs -0 -I {} -P 0 sed -i "s#/home/${OLD_USERNAME}#/home/${USERNAME}#" {} 206 | fi 207 | ;; 208 | "Change-Hostname") 209 | HOSTNAME="$(show_dialog --inputbox "Enter a hostname" 17 70)" \ 210 | && chroot "${DESTDIR}" sed -i "/hostname/I s#\"\([^\"]*\)#\"${HOSTNAME}#" /etc/conf.d/hostname \ 211 | && chroot "${DESTDIR}" sed -i "/#/! s#localhost\(.*\)#localhost ${HOSTNAME}#" /etc/hosts 212 | RETSUB=$? 213 | ;; 214 | # add user 215 | "add-user") 216 | # 1. ask for user name 217 | # 2. set up user 218 | # 3. set password for user 219 | # 4. copy root profile 220 | # run rsync with nice dialog 221 | USERNAME="$(show_dialog --inputbox "Enter a username" 17 70)" \ 222 | && chroot "${DESTDIR}" useradd -m -G android,audio,cdrom,cdrw,kismet,pcscd,plugdev,portage,usb,users,uucp,video,wheel,wireshark ${USERNAME} \ 223 | && setpassword "${USERNAME}" 2> /dev/null \ 224 | && show_dialog_rsync '-r --progress --exclude=.svn --exclude=.subversion' \ 225 | "${DESTDIR}"'/root/.[!.]*' \ 226 | "${DESTDIR}/home/${USERNAME}/" \ 227 | "Syncing ${DESTDIR}/home/${USERNAME}/ ..." \ 228 | && chroot "${DESTDIR}" chown -R "${USERNAME}":"${USERNAME}" "/home/${USERNAME}" >>"${LOG}" 229 | RETSUB=$? 230 | ;; 231 | # locales 232 | "/etc/locale.gen") 233 | chroot "${DESTDIR}" "${EDITOR}" "${NEWSELECTION}" \ 234 | && chroot "${DESTDIR}" locale-gen 1>&2 235 | RETSUB=$? 236 | ;; 237 | #regular file 238 | *) 239 | chroot "${DESTDIR}" "${EDITOR}" "${NEWSELECTION}" 240 | RETSUB=$? 241 | ;; 242 | esac 243 | sync || exit $? 244 | # handle errors from sub-script/functions using a common utility function 245 | catch_menuerror "$(basename $0)" "${NEWSELECTION}" "${RETSUB}" 246 | done 247 | 248 | chroot_umount || exit $? 249 | 250 | exit 0 251 | -------------------------------------------------------------------------------- /share/pentoo-installer/copy_distro: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # copy_distro 6 | # Copies the distro from squashfs plus uses rsync 7 | # 8 | # parameters (required) 9 | # CONFIG_LIST: One string with items of defined FSspec 10 | # 11 | # returns 0 on success 12 | # returns $ERROR_CANCEL=64 on user cancel 13 | # anything else is a real error 14 | # reason: show_dialog() needs a way to exit "Cancel" 15 | # 16 | # writes menus and noise to STDERR 17 | 18 | # location of other scripts to source 19 | readonly SHAREDIR="$(dirname ${0})" || exit $? 20 | 21 | # source common variables, functions and error handling 22 | source "${SHAREDIR}"/common.sh || exit $? 23 | 24 | ######################################### 25 | ## START: dialog functions/definitions ## 26 | 27 | # auto_dmcrypt() 28 | # copy dmcrypt and keys to partitions 29 | # 30 | # parameters (required) 31 | # CONFIG_LIST: One string with items of defined FSspec 32 | # 33 | auto_dmcrypt() { 34 | # check input 35 | check_num_args "${FUNCNAME}" 1 $# || return $? 36 | local _CONF_LIST="${1}" 37 | local _ITEM= 38 | # properties of FSspec 39 | local _PARTITION= 40 | local _MOUNTPOINT= 41 | local _CRYPTTYPE= 42 | local _CRYPTNAME= 43 | local _CRYPTKEY= 44 | local _FSTAB_ITEM= 45 | local _DO_RCUPDATE=0 46 | local _RET_SUB= 47 | # sort by partition 48 | _CONF_LIST="$("${SHAREDIR}"/FSspec sort "${_CONF_LIST}" 'partition' 0)" || return $? 49 | # START: write all keys to /etc/keys and only swap partitions to /etc/conf.d/dmcrypt 50 | # swap partitions sould come first in /etc/conf.d/dmcrypt 51 | for _ITEM in ${_CONF_LIST}; do 52 | _PARTITION="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'partition')" || exit $? 53 | _MOUNTPOINT="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'mountpoint')" || exit $? 54 | _CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'crypttype')" || exit $? 55 | _CRYPTNAME="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'cryptname')" || exit $? 56 | _CRYPTKEY="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'cryptkey')" || exit $? 57 | if [ "${_CRYPTTYPE}" != '' ]; then 58 | # write all crypt-keys (except root- and swap-partitions) 59 | if [ "${_CRYPTTYPE}" != 'swap' ] && [ "${_MOUNTPOINT}" != '/' ]; then 60 | mkdir -p "${DESTDIR}/etc/keys/" || return $? 61 | case "${_CRYPTTYPE}" in 62 | 'luks2-gpg') 63 | # key is in base64 format 64 | echo -n "${_CRYPTKEY}" | base64 -d >"${DESTDIR}/etc/keys/${_CRYPTNAME}" || return $? 65 | ;; 66 | 'luks2') 67 | echo -n "${_CRYPTKEY}" >"${DESTDIR}/etc/keys/${_CRYPTNAME}" || return $? 68 | ;; 69 | esac 70 | # write key for root-partition 71 | elif [ "${_MOUNTPOINT}" = '/' ]; then 72 | case "${_CRYPTTYPE}" in 73 | 'luks2-gpg') 74 | # key is in base64 format 75 | echo "${_CRYPTKEY}" | base64 -d >"${DESTDIR}/boot/${_CRYPTNAME}.gpg" || return $? 76 | ;; 77 | 'luks2') 78 | # Info: this should not be possible for root partition and actually is disabled in the menu 79 | echo "${_CRYPTKEY}" >"${DESTDIR}/boot/${_CRYPTNAME}.key" || return $? 80 | ;; 81 | esac 82 | fi 83 | # add to /etc/conf.d/dmcrypt if swap 84 | if [ "${_CRYPTTYPE}" = 'swap' ]; then 85 | _DO_RCUPDATE=1 86 | echo ''>>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 87 | echo "swap=${_CRYPTNAME}">>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 88 | echo "source='${_PARTITION}'">>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 89 | fi 90 | fi 91 | done 92 | # END: write all keys to /etc/keys and only swap partitions to /etc/conf.d/dmcrypt 93 | # START: write non-swap partitions to /etc/conf.d/dmcrypt 94 | for _ITEM in ${_CONF_LIST}; do 95 | _PARTITION="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'partition')" || exit $? 96 | _MOUNTPOINT="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'mountpoint')" || exit $? 97 | _CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'crypttype')" || exit $? 98 | _CRYPTNAME="$("${SHAREDIR}"/FSspec parse "${_ITEM}" 'cryptname')" || exit $? 99 | if [ "${_CRYPTTYPE}" != '' ]; then 100 | # add to /etc/conf.d/dmcrypt if non-swap and not root-partition 101 | if [ "${_CRYPTTYPE}" != 'swap' ] && [ "${_MOUNTPOINT}" != '/' ]; then 102 | _DO_RCUPDATE=1 103 | echo ''>>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 104 | echo "target=${_CRYPTNAME}">>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 105 | echo "source='${_PARTITION}'">>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 106 | case "${_CRYPTTYPE}" in 107 | 'luks2-gpg') 108 | echo "key='/etc/keys/${_CRYPTNAME}:gpg'">>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 109 | ;; 110 | 'luks2') 111 | echo "key='/etc/keys/${_CRYPTNAME}'">>"${DESTDIR}/etc/conf.d/dmcrypt" || return $? 112 | ;; 113 | esac 114 | fi 115 | fi 116 | done 117 | # run rc-update, chroot must be mounted outside this function! 118 | if [ "${_DO_RCUPDATE}" -eq 1 ]; then 119 | chroot "${DESTDIR}" /bin/bash <> "${DESTDIR}/etc/fstab" || return $? 218 | else 219 | echo "#${_PARTITION}" >> "${DESTDIR}/etc/fstab" || return $? 220 | fi 221 | echo "${_FSTAB_ITEM}" >> "${DESTDIR}/etc/fstab" || return $? 222 | # END: fstab setup 223 | done 224 | return 0 225 | } 226 | 227 | ## END: dialog functions/definitions ## 228 | ####################################### 229 | 230 | ##################### 231 | ## begin execution ## 232 | 233 | # check input 234 | check_num_args "$(basename $0)" 1 $# || exit $? 235 | CONFIG_LIST="${1}" 236 | RET_SUB= 237 | MODULE= 238 | 239 | # mount everything, including cryptsetup 240 | "${SHAREDIR}"/FSspec mountall "${CONFIG_LIST}" || exit $? 241 | 242 | "${SHAREDIR}"/gauge_unsquashfs '/mnt/cdrom/image.squashfs' "${DESTDIR}" "Uncompressing base system" || exit $? 243 | 244 | # squashfs files created by flushchanges are ignored - they may contain whiteout files! 245 | # filenames used by flushchanges (old/new syntax): z_changes-* zz_changes-* 246 | for MODULE in $(ls -1 --color=never /mnt/cdrom/modules/*.lzm | grep -v -e '/z_' -e '/zz_'); do 247 | "${SHAREDIR}"/gauge_unsquashfs "${MODULE}" "${DESTDIR}" "Uncompressing ${MODULE%.lzm}" || exit $? 248 | done 249 | # Unconditionally rsync the minimum we expect for a working system 250 | show_dialog_rsync '-av --progress' \ 251 | '/etc/' "${DESTDIR}/etc" "Syncing /etc ..." || exit $? 252 | #firmware may have been installed at boot and we want to keep it 253 | show_dialog_rsync '-av --progress' \ 254 | '/lib/firmware/' "${DESTDIR}/lib/firmware" "Syncing /lib/firmware ..." || exit $? 255 | show_dialog_rsync '-av --progress --exclude=/root/.bashrc' \ 256 | '/root/' "${DESTDIR}/root" "Syncing /root ..." || exit $? 257 | show_dialog_rsync '-av --progress --exclude=/home/pentoo/.bashrc' \ 258 | '/home/pentoo/' "${DESTDIR}/home/pentoo" "Syncing /home/pentoo ..." || exit $? 259 | show_dialog_rsync '-av --progress' \ 260 | "/lib/modules/" "${DESTDIR}/lib/modules" "Syncing kernel modules ..." || exit $? 261 | show_dialog_rsync '-av --progress' \ 262 | "/var/lib/portage/" "${DESTDIR}/var/lib/portage" "Syncing portage information ..." || exit $? 263 | show_dialog_rsync '-av --progress' \ 264 | "/var/log/" "${DESTDIR}/var/log" "Syncing logs ..." || exit $? 265 | if [ -d "/mnt/overlay/.upper/var/lib/NetworkManager" ]; then 266 | show_dialog_rsync '-av --progress' \ 267 | "/var/lib/NetworkManager" "${DESTDIR}/var/lib/" "Syncing NetworkManager config ..." || exit $? 268 | fi 269 | if [ -d "/mnt/overlay/.upper/var/lib/gentoo/news" ]; then 270 | show_dialog_rsync '-av --progress' \ 271 | "/var/lib/gentoo/news" "${DESTDIR}/var/lib/gentoo/" "Syncing Gentoo News ..." || exit $? 272 | fi 273 | if [ -d "/mnt/overlay/.upper/var/lib/dhcpcd" ]; then 274 | show_dialog_rsync '-av --progress' \ 275 | "/var/lib/dhcpcd" "${DESTDIR}/var/lib/" "Syncing dhcpcd config ..." || exit $? 276 | fi 277 | if [ -d "/mnt/overlay/.upper/usr/portage" ]; then 278 | show_dialog_rsync '-av --progress' \ 279 | "/usr/portage/" "${DESTDIR}/usr/portage" "Syncing gentoo portage tree ..." || exit $? 280 | fi 281 | #old repo location 282 | if [ -d "/mnt/overlay/.upper/var/lib/layman" ]; then 283 | show_dialog_rsync '-av --progress' \ 284 | "/var/lib/layman/" "${DESTDIR}/var/lib/layman" "Syncing pentoo overlay ..." || exit $? 285 | fi 286 | #new repo location 287 | if [ -d "/mnt/overlay/.upper/var/db/repos" ]; then 288 | show_dialog_rsync '-av --progress' \ 289 | "/var/db/repos/" "${DESTDIR}/var/db/repos" "Syncing pentoo overlay ..." || exit $? 290 | fi 291 | 292 | # check if we need to prompt user about syncing more things 293 | unsyncd="" 294 | tmp_unsyncd="" 295 | for i in $(ls -1 /mnt/overlay/.upper); do 296 | [ "${i}" = "root" ] && continue 297 | [ "${i}" = "etc" ] && continue 298 | [ "${i}" = "mnt" ] && continue 299 | [ "${i}" = "proc" ] && continue 300 | [ "${i}" = "dev" ] && continue 301 | [ "${i}" = "sys" ] && continue 302 | [ "${i}" = "run" ] && continue 303 | [ "${i}" = "newroot" ] && continue 304 | [ "${i}" = "tmp" ] && continue 305 | if [ "${i}" = "var" ]; then 306 | tmp_unsyncd=$(du -sh --exclude=cache --exclude=tmp --exclude=run --exclude=log --exclude=db/pkg/pentoo/pentoo-installer-* --exclude=lib/portage --exclude=lib/blueman/network.state --exclude=lib/misc/random-seed --exclude=lib/NetworkManager --exclude=lib/gentoo/news --exclude=lib/dhcpcd --exclude=lib/syslog-ng/syslog-ng.persist --exclude=lib/layman "/mnt/overlay/.upper/${i}" 2> /dev/null | grep -v -E '^0|^4\.0K') 307 | elif [ "${i}" = "home" ]; then 308 | tmp_unsyncd=$(du -sh --exclude=home/pentoo "/mnt/overlay/.upper/${i}" 2> /dev/null | grep -v -E '^0|^4\.0K') 309 | elif [ "${i}" = "lib" ] || [ "${i}" = "lib64" ]; then 310 | tmp_unsyncd=$(du -sh --exclude=modules --exclude=rc/console/unicode "/mnt/overlay/.upper/${i}" 2> /dev/null | grep -v -E '^0|^4\.0K') 311 | elif [ "${i}" = "sbin" ]; then 312 | tmp_unsyncd=$(du -sh --exclude=pentoo-installer "/mnt/overlay/.upper/${i}" 2> /dev/null | grep -v -E '^0|^4\.0K') 313 | elif [ "${i}" = "usr" ]; then 314 | tmp_unsyncd=$(du -sh --exclude=share/applications/pentoo-installer.desktop --exclude=share/applications/sudo-pentoo-installer.desktop --exclude=share/pentoo-installer --exclude=portage "/mnt/overlay/.upper/${i}" 2> /dev/null | grep -v -E '^0|^4\.0K') 315 | else 316 | tmp_unsyncd=$(du -sh "/mnt/overlay/.upper/${i}" 2> /dev/null | grep -v -E '^0|^4\.0K') 317 | fi 318 | if [ -n "${tmp_unsyncd}" ]; then 319 | unsyncd="${unsyncd}${tmp_unsyncd/\mnt\/overlay\/.upper\//}\n" 320 | fi 321 | done 322 | 323 | if [ -n "${unsyncd}" ]; then 324 | show_dialog --defaultno --yesno "The following unsynced changes to the running livecd have been detected:\n${unsyncd}\nWould you like to sync unsaved changes to your new install? (It is safe to say no here if no changes to the running livecd were intended.)" 0 0 325 | RET_SUB=$? 326 | 327 | # run rsync with nice dialog 328 | if [ "${RET_SUB}" = "0" ]; then 329 | show_dialog_rsync '-av --progress --exclude=/mnt --exclude=/proc --exclude=/dev --exclude=/sys --exclude=/run --exclude=/newroot --exclude=/tmp --exclude=/var/tmp --exclude=/var/run --exclude=/var/lock' \ 330 | '/*' "${DESTDIR}/" "Syncing / ..." || exit $? 331 | fi 332 | fi 333 | 334 | # pre-configure systems, these steps should happen only once 335 | # must mount chroot so pre/post installs don't fail out 336 | chroot_mount || exit $? 337 | 338 | show_dialog --infobox "Removing livecd only packages and configs from install..." 3 70 339 | 340 | # remove livecd stuff 341 | sed -i '/bindist livecd/d' "${DESTDIR}"/etc/portage/make.conf 342 | chroot "${DESTDIR}" emerge --rage-clean app-misc/livecd-tools pentoo/pentoo-livecd pentoo/pentoo-installer app-admin/pwgen sys-apps/hwsetup sys-apps/hwdata-gentoo x11-misc/mkxf86config net-dialup/mingetty wmctrl 343 | rm -f "${DESTDIR}/home/pentoo/Desktop/networkmanager.desktop" 344 | rm -f "${DESTDIR}/home/pentoo/Desktop/pentoo-installer.desktop" 345 | rm -f "${DESTDIR}/home/pentoo/Desktop/toggle_hidpi.desktop" 346 | 347 | #mark open-vm-tools to keep if we are on a vm 348 | if [ -n "${vm:-}" ] && [ -n "${vm_from:-}" ]; then 349 | printf "Detecting ${vm} using ${vm_from}, marking open-vm-tools required.\n" 350 | chroot "${DESTDIR}" emerge --noreplace app-emulation/open-vm-tools --nodeps || exit $? 351 | fi 352 | #broadcom firmwares 353 | for chip in b43 b43legacy; do 354 | if portageq has_version / sys-firmware/${chip}-firmware; then 355 | chroot "${DESTDIR}" emerge --noreplace sys-firmware/${chip}-firmware --nodeps || exit $? 356 | fi 357 | done 358 | 359 | #prevent livecd bashrc from being on install 360 | rm -f "${DESTDIR}"/root/.bashrc 361 | [ -w "${DESTDIR}"/home/pentoo/.bashrc ] && rm -f "${DESTDIR}"/home/pentoo/.bashrc 362 | 363 | mknod -m666 "${DESTDIR}"/dev/zero c 1 5 364 | mknod -m666 "${DESTDIR}"/dev/null c 1 3 365 | mknod -m600 "${DESTDIR}"/dev/console c 5 1 366 | mkdir -m755 "${DESTDIR}"/media/{cd,dvd,fl} 367 | 368 | #restore stock bashrc 369 | chroot "${DESTDIR}" /bin/bash < /dev/null 2>&1 395 | EOF 396 | RET_SUB=$? 397 | [ "${RET_SUB}" -ne 0 ] && exit "${RET_SUB}" 398 | # ensure that the disk is synced 399 | sync || exit $? 400 | 401 | # automagic time! 402 | # any automatic configuration should go here 403 | show_dialog --infobox "Writing base configuration..." 3 40 404 | auto_fstab "${CONFIG_LIST}" || exit $? 405 | auto_dmcrypt "${CONFIG_LIST}" || exit $? 406 | 407 | # don't need chroot anymore 408 | chroot_umount || exit $? 409 | 410 | exit 0 411 | -------------------------------------------------------------------------------- /share/pentoo-installer/error.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # to be sourced by other scripts 6 | 7 | #################################### 8 | ## START: error handling settings ## 9 | 10 | # These are not without drawbacks! 11 | set -o pipefail # trace ERR through pipes 12 | set -o errtrace # trace ERR through 'time command' and other functions 13 | set -o nounset # set -u : exit the script if you try to use an uninitialised variable 14 | # this is really 'tricky' thus diabled 15 | # at least causes problem with show_dialog() and user-cancel 16 | # set -o errexit # set -e : exit the script if any statement returns a non-true return value 17 | 18 | ## END: error handling settings ## 19 | ################################## 20 | 21 | ##################################### 22 | ## START: error handling functions ## 23 | 24 | # error_exit() 25 | # This function is used to cleanly exit any script. It does this displaying a 26 | # given error message, and exiting with an error code. 27 | # parameters: 28 | # 29 | error_exit() { 30 | echo 31 | echo "${@}" 32 | exit 1 33 | } 34 | 35 | # Trap the killer signals so that we can exit with a good message. 36 | # TODO: dump remove the basename below 37 | trap 'error_exit ''"$(basename $0)" Received signal SIGHUP''' SIGHUP 38 | trap 'error_exit ''"$(basename $0)" Received signal SIGINT''' SIGINT 39 | trap 'error_exit ''"$(basename $0)" Received signal SIGTERM''' SIGTERM 40 | 41 | # Alias the function so that it will print a message with the following format: 42 | # prog-name(@line#): message 43 | # We have to explicitly allow aliases, we do this because they make calling the 44 | # function much easier. 45 | shopt -s expand_aliases 46 | alias die='error_exit "Error ${0}(@`echo $(( ${LINENO} - 1 ))`):"' 47 | 48 | ## END: error handling functions ## 49 | ################################### 50 | -------------------------------------------------------------------------------- /share/pentoo-installer/gauge_unsquashfs: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # this script is released under the gnu general public license 3.0 3 | # check the copying file included with this distribution 4 | 5 | # gauge_unsquashfs 6 | # runs unsquashfs, displays output as gauge dialog 7 | # originally taken from manjaro 8 | # 9 | # parameters (required) 10 | # source: source for unsquashfs 11 | # destination: destination for unsquashfs 12 | # msg: message to show 13 | # 14 | # returns 0 on success 15 | # returns $error_cancel=64 on user cancel 16 | # anything else is a real error 17 | # reason: show_dialog() needs a way to exit "cancel" 18 | # 19 | # writes menus and noise to stderr 20 | 21 | # TODO: 22 | # find a better solution to remove background process then `killall unsquashfs` 23 | 24 | # TODO: 25 | # find a way to pipe output of unsquashfs so background process and temp files are not needed 26 | # somehow piping through awk/sed results in strange delays/buffering which is not shown when tee-ing to /dev/tty8 before 27 | # rant end ;) 28 | 29 | # location of other scripts to source 30 | readonly SHAREDIR="$(dirname ${0})" || exit $? 31 | 32 | # source common variables, functions and error handling 33 | source "${SHAREDIR}"/common.sh || exit $? 34 | 35 | #we export RAMSIZE from pentoo-installer, so hopefully we can use it here 36 | if [ "${RAMSIZE}" -le "1500" ]; then 37 | procarg="-p 1" 38 | else 39 | procarg="" 40 | fi 41 | 42 | # Trap the killer signals so that we can kill child background processes 43 | trap 'killall unsquashfs;' SIGHUP 44 | # unsquashfs ignores SIGINT ... 45 | trap 'killall unsquashfs;' SIGINT 46 | trap 'killall unsquashfs;' SIGTERM 47 | 48 | ##################### 49 | ## begin execution ## 50 | 51 | # check input 52 | check_num_args "$(basename $0)" 3 $# || exit $? 53 | SOURCE="${1}" 54 | DESTINATION="${2}" 55 | MSG="${3}" 56 | LINE= 57 | BLOCKS= 58 | PERCENT= 59 | PERCENTTEMP= 60 | RETGAUGE= 61 | # all unsquashfs output goes to /tmp/unsquashfs.log, which we tail 62 | # into a dialog 63 | touch /tmp/setup-unsquashfs-running 64 | #set the return code to failure so if things race we catch the failure 65 | echo 1 > /tmp/.unsquashfs-retcode 66 | 67 | # start background process 68 | ( 69 | echo "unsquashing $(basename $1) ..." > /tmp/unsquashfs.log; \ 70 | echo >> /tmp/unsquashfs.log; \ 71 | # unsquash and output to file used for gauge dialog 72 | # also write filtered output to $LOG 73 | unsquashfs ${procarg} -f -d "${DESTINATION}" "${SOURCE}" 2>&1 \ 74 | | tee -a /tmp/unsquashfs.log \ 75 | | tr '\r' '\n' | grep -Ev '[[:blank:]][0-9]+/[0-9]+[[:blank:]]+[0-9]+\%$' >>"${LOG}" 76 | echo $? > /tmp/.unsquashfs-retcode 77 | echo >> /tmp/unsquashfs.log 78 | rm -f /tmp/setup-unsquashfs-running 79 | ) & 80 | 81 | sleep 1 82 | 83 | # read output of unsquashfs every x second and keep piping result to the gauge dialog 84 | ( 85 | PERCENT=0 86 | while [ -e /tmp/setup-unsquashfs-running ]; do 87 | # sleep 1 88 | sleep 0.5 89 | LINE="$(tail -n1 /tmp/unsquashfs.log)" || exit $? 90 | PERCENTTEMP="$(echo "${LINE}" | sed -r 's/^.*[[:space:]]([0-9]+)%$/\1/')" || exit $? 91 | if [[ ${PERCENTTEMP} =~ ${ISNUMBER} ]]; then 92 | PERCENT="${PERCENTTEMP}" 93 | BLOCKS="$(echo "${LINE}" | sed -r 's#^.*[[:space:]]+([0-9]+)/([0-9]+)[[:space:]]+.*$#\1 of \2 blocks#')" || exit $? 94 | echo "${PERCENT}" 95 | echo "XXX" 96 | echo "${MSG}" 97 | echo " => " 98 | echo "${BLOCKS}" 99 | echo "XXX" 100 | else 101 | echo "XXX" 102 | echo "${MSG}" 103 | echo " => " 104 | if [[ "${PERCENTTEMP}" =~ "ailed" ]]; then 105 | echo "Progress Indicator Frozen at ${PERCENT} % (${PERCENTTEMP})" 106 | rm /tmp/setup-unsquashfs-running 107 | sleep 4.5 108 | else 109 | echo "Progress Indicator Frozen at ${PERCENT} % (but no errors seen)" 110 | fi 111 | echo "XXX" 112 | fi 113 | done 114 | ) | 115 | # prepend dummy values for auto-sizing of dialog 116 | show_dialog --gauge "${MSG} => ......... of ......... blocks" 0 0 0 117 | RETGAUGE=$? 118 | if [ "${RETGAUGE}" -ne 0 ]; then 119 | echo "User cancelled unsquashfs by exiting gauge dialog." 1>&2 120 | killall unsquashfs 121 | exit "${RETGAUGE}" 122 | fi 123 | # check success 124 | while [ -e /tmp/setup-unsquashfs-running ]; do 125 | echo "Won the race, night night (This should have been impossible)" 1>&2 126 | sleep 1 127 | done 128 | if ! [ -f /tmp/.unsquashfs-retcode ]; then 129 | echo "This shouldn't be possible, /tmp/.unsquashfs-retcode is missing" 1>&2 130 | fi 131 | # alert the user to fatal errors 132 | #make sure we have a retcode 133 | if [ -z "$(cat /tmp/.unsquashfs-retcode)" ]; then 134 | killall unsquashfs 135 | if [ -n "${PERCENTTEMP}" ] && [[ "${PERCENTTEMP}" =~ "ailed" ]]; then 136 | show_dialog --title "Error unsquashing, possible error:" --exit-label \ 137 | "OK" --textbox "${PERCENTTEMP}" 18 70 138 | else 139 | show_dialog --title "Error unsquashing, no return code" --exit-label \ 140 | "OK" --textbox "/tmp/unsquashfs.log" 18 70 141 | fi 142 | exit 1 143 | fi 144 | #make sure the retcode is a number 145 | if ! [[ $(cat /tmp/.unsquashfs-retcode) =~ ${ISNUMBER} ]]; then 146 | killall unsquashfs 147 | show_dialog --title "Error unsquashing, code '$(cat /tmp/.unsquashfs-retcode)'" --exit-label \ 148 | "OK" --textbox "/tmp/unsquashfs.log" 18 70 149 | exit 1 150 | fi 151 | #make sure the retcode is 0 152 | if [ $(cat /tmp/.unsquashfs-retcode) -ne 0 ]; then 153 | killall unsquashfs 154 | show_dialog --title "Error unsquashing, code '$(cat /tmp/.unsquashfs-retcode)'" --exit-label \ 155 | "OK" --textbox "/tmp/unsquashfs.log" 18 70 156 | exit 1 157 | fi 158 | # save unsquashfs.log 159 | mv "/tmp/unsquashfs.log" "/tmp/unsquashfs-$(basename "${SOURCE}").log" || exit $? 160 | exit 0 161 | -------------------------------------------------------------------------------- /share/pentoo-installer/partition_autoconfig: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # partition_autoconfig 6 | # apply preconfigured partition layout 7 | # parameters: none 8 | # 9 | # returns $ERROR_CANCEL=64 on user cancel 10 | # anything else is a real error 11 | # reason: show_dialog() needs a way to exit "Cancel" 12 | # 13 | # writes menus and noise to STDERR 14 | # 15 | # prints result to STDOUT 16 | 17 | # location of other scripts to source 18 | readonly SHAREDIR="$(dirname ${0})" || exit $? 19 | 20 | # source partitioning commons 21 | source "${SHAREDIR}"/partition_common.sh || exit $? 22 | 23 | ######################################### 24 | ## START: dialog functions/definitions ## 25 | 26 | # autoconfig_createpartition() 27 | # creates a partition 28 | # 29 | # returns 0 on success 30 | # 31 | # prints new JSON to STDOUT 32 | # 33 | # parameters (required): 34 | # disk: json 35 | # partnum: index in partition array 36 | # 37 | autoconfig_createpartition() { 38 | # check input 39 | check_num_args "${FUNCNAME}" 2 $# || return $? 40 | local disk="${1}" 41 | local partnum="${2}" 42 | local diskblock="$(echo "${disk}" | jq -jr '."device"')" || return $? 43 | local parttable="$(autoconfig_getpartitiontable "${disk}")" || return $? 44 | local part="$(echo "${disk}" | jq -j ".partitions["${partnum}"]")" || return $? 45 | local parttype="$(echo "$part" | jq -jr '.create."partition-type" // empty')" || return $? 46 | local label="$(echo "$part" | jq -jr '.create.label // empty')" || return $? 47 | local start="$(echo "$part" | jq -jr '.create.start')" || return $? 48 | local end="$(echo "$part" | jq -jr '.create.end')" || return $? 49 | local before="$(parted --script "${diskblock}" print | sed -e '/^$/d' -e '1,/^Number/d' | awk '{print $1}' | LC_ALL=C sort)" || return $? 50 | local beforeDevices="$(blkid -o device | LC_ALL=C sort)" || return $? 51 | local after= 52 | local afterDevices= 53 | local newDevice= 54 | local index= 55 | local flags= 56 | local flagkey= 57 | local flagvalue= 58 | case "${parttable}" in 59 | gpt) 60 | parted -a optimal --script "${diskblock}" mkpart "${label}" ext4 $start $end || return $? 61 | ;; 62 | msdos) 63 | # default to primary 64 | if [ -z "${parttype}" ]; then 65 | parttype=primary 66 | fi 67 | case "${parttype}" in 68 | primary|logical) 69 | parted -a optimal --script "${diskblock}" mkpart "${parttype}" ext4 $start $end || return $? 70 | ;; 71 | extended) 72 | parted -a optimal --script "${diskblock}" mkpart "${parttype}" $start $end || return $? 73 | ;; 74 | *) echo "ERROR: Unknown partition type '${parttype}'." 1>&2 75 | return 1 ;; 76 | esac 77 | ;; 78 | *) echo "ERROR: Unknown partition table '${parttable}'." 1>&2 79 | return 1 ;; 80 | esac 81 | after="$(parted --script "${diskblock}" print | sed -e '/^$/d' -e '1,/^Number/d' | awk '{print $1}' | LC_ALL=C sort)" || return $? 82 | afterDevices="$(blkid -o device | LC_ALL=C sort)" || return $? 83 | index="$(join -v 2 <(echo "${before}") <(echo "${after}"))" || return $? 84 | newDevice="$(join -v 2 <(echo "${beforeDevices}") <(echo "${afterDevices}"))" || return $? 85 | echo "newDevice='${newDevice}'" 1>&2 || return $? 86 | # flags is set 87 | if echo "${part}" | jq -e ".create.flags" 1>/dev/null; then 88 | flags="$(echo "${part}" | jq -j ".create.flags")" || return $? 89 | for flagkey in $(echo "${flags}" | jq -r 'keys | .[]'); do 90 | flagvalue="$(echo "${part}" | jq -j ".flags.${flagkey}")" || return $? 91 | parted --script "${diskblock}" set "${index}" "${flagkey}" || return $? 92 | done 93 | fi 94 | # modify json to return new object 95 | # add existing object 96 | disk="$(echo "${disk}" | jq -e ".partitions[${partnum}].existing = {\"device\":\"${newDevice}\"}")" 97 | # remove create object 98 | disk="$(echo "${disk}" | jq -e "del(.partitions[${partnum}].create)")" 99 | if [ "${parttype}" == 'extended' ]; then 100 | # add extended=true 101 | disk="$(echo "${disk}" | jq -e ".partitions[${partnum}].existing.extended = true")" 102 | else 103 | # set format = true 104 | disk="$(echo "${disk}" | jq -e ".partitions[${partnum}].existing.format = true")" 105 | fi 106 | # print new json 107 | echo "${disk}" 108 | return 0 109 | } 110 | 111 | # autoconfig_printpartition() 112 | # prints partition 113 | # 114 | # returns 0 on success 115 | # 116 | # parameters (required): 117 | # disk: json 118 | # partnum: index in partition array 119 | # 120 | autoconfig_printpartition() { 121 | # check input 122 | check_num_args "${FUNCNAME}" 2 $# || return $? 123 | local disk="${1}" 124 | local partnum="${2}" 125 | local part="$(echo "${disk}" | jq -j ".partitions["${partnum}"]")" || return $? 126 | # don't print/use msdos extended partitions 127 | if !(echo "${part}" | jq -e ".existing.extended" 1>/dev/null); then 128 | local partblock="$(echo "${part}" | jq -jr '.existing.device')" || return $? 129 | local mountpoint="$(echo "${part}" | jq -jr '."mountpoint"')" || return $? 130 | local filesystem="$(echo "${part}" | jq -jr '.filesystem')" || return $? 131 | local crypttype="$(echo "${part}" | jq -jr '.crypttype // empty')" || return $? 132 | local format=0 133 | # format is set 134 | if echo "${part}" | jq -e ".existing.format" 1>/dev/null; then 135 | format=1 136 | fi 137 | # validate 138 | "${SHAREDIR}"/FSspec create "${partblock}" "${mountpoint}" "${filesystem}" "${crypttype}" "${format}" 1>/dev/null || return $? 139 | local fsspec="$("${SHAREDIR}"/FSspec create "${partblock}" "${mountpoint}" "${filesystem}" "${crypttype}" "${format}")" || return $? 140 | echo -n "${fsspec}" 141 | fi 142 | } 143 | 144 | # autoconfig_getpartitionindex() 145 | # prints partition index 146 | # 147 | # returns 0 on success 148 | # 149 | # parameters (required): 150 | # disk: json 151 | # partnum: index in partition array 152 | # 153 | # 154 | autoconfig_getpartitionindex() { 155 | # check input 156 | check_num_args "${FUNCNAME}" 2 $# || return $? 157 | local disk="${1}" 158 | local partnum="${2}" 159 | local diskblock="$(echo "${disk}" | jq -jr '."device"')" || return $? 160 | local parttable="$(autoconfig_getpartitiontable "${disk}")" || return $? 161 | local part="$(echo "${disk}" | jq -j ".partitions["${partnum}"]")" || return $? 162 | local partblock="$(echo "${part}" | jq -jr '."device"')" || return $? 163 | local partshort="$(basename "${partblock}")" || return $? 164 | local maxpart="$(lsblk -J /dev/sda | jq -j '..|.children? // empty | length')" || return $? 165 | local partnum 166 | local partname= 167 | for (( partnum=0; partnum<${maxpart}; partnum++ )); do 168 | partname="$(lsblk -J /dev/sda | jq -jr "..|.children? // empty | .[$partnum].name")" || return $? 169 | if [ "${partname}" == "${partshort}" ]; then 170 | echo -n "$((partnum + 1))"; return $? 171 | fi 172 | done 173 | return 1 174 | } 175 | 176 | # autoconfig_getpartitiontable() 177 | # prints partition table 178 | # either from config file or current 179 | # 180 | # returns 0 on success 181 | # 182 | # parameters (required): 183 | # disk: json 184 | # 185 | autoconfig_getpartitiontable() { 186 | # check input 187 | check_num_args "${FUNCNAME}" 1 $# || return $? 188 | local disk="${1}" 189 | # partition table is set 190 | if echo "${disk}" | jq -e '."partition-table"' 1>/dev/null; then 191 | echo "${disk}" | jq -jr '."partition-table"'; return $? 192 | else 193 | parted --script "${disk}" print | sed -En 's#^Partition Table: (.*)#\1#p'; return $? 194 | fi 195 | } 196 | 197 | ## END: dialog functions/definitions ## 198 | ####################################### 199 | 200 | ##################### 201 | ## begin execution ## 202 | 203 | # remove comments 204 | CONF_FULL="$(cat "${INSTALLER_CONFIGFILE}" | jq 'del(..|.["#"]?)')" || exit $? 205 | # get array of disks with partitions 206 | CONF_DISKS="$(echo "${CONF_FULL}" | jq '..|.disks? // empty')" || exit $? 207 | 208 | LEN_DISKS="$(echo "${CONF_DISKS}" | jq -j 'length')" || exit $? 209 | 210 | # loop disks 211 | DISKNUM= 212 | PARTNUM= 213 | for (( DISKNUM=0; DISKNUM<${LEN_DISKS}; DISKNUM++ )); do 214 | DISK="$(echo "${CONF_DISKS}" | jq ".[${DISKNUM}]")" || exit $? 215 | DISK_BLOCK="$(echo "${DISK}" | jq -jr '."device"')" || exit $? 216 | # wipe is set 217 | if echo "${DISK}" | jq -e '.wipe' 1>/dev/null; then 218 | PARTTABLE="$(autoconfig_getpartitiontable "${DISK}")" || exit $? 219 | # set partition table 220 | parted --script "${DISK_BLOCK}" mklabel "${PARTTABLE}" || exit $? 221 | fi 222 | # loop partitions to create them 223 | LEN_PARTS="$(echo "${DISK}" | jq -j '.partitions | length')" || exit $? 224 | for (( PARTNUM=0; PARTNUM<${LEN_PARTS}; PARTNUM++ )); do 225 | CREATEPART=1 226 | USEPART=1 227 | # check if create is set 228 | if echo "${DISK}" | jq -e ".partitions[${PARTNUM}].create" 1>/dev/null; then 229 | CREATEPART=0 230 | fi 231 | # check if existing is set 232 | if echo "${DISK}" | jq -e ".partitions[${PARTNUM}].existing" 1>/dev/null; then 233 | USEPART=0 234 | fi 235 | # safety check 236 | if [ $((CREATEPART+USEPART)) -ne 1 ]; then 237 | echo "ERROR: Either 'create' or 'existing' must be used, not both." 1>&2 238 | exit 1 239 | fi 240 | if [ $CREATEPART -eq 0 ]; then 241 | DISK="$(autoconfig_createpartition "${DISK}" "${PARTNUM}")" || exit $? 242 | # replace in parent json 243 | CONF_DISKS="$(echo "${CONF_DISKS}" | jq ".[${DISKNUM}] = ${DISK}")" || exit $? 244 | fi 245 | done 246 | # loop partitions to maximise them 247 | for (( PARTNUM=0; PARTNUM<${LEN_PARTS}; PARTNUM++ )); do 248 | # want_maximised is set 249 | if echo "${DISK}" | jq -e ".partitions[${PARTNUM}].want_maximised" 1>/dev/null; then 250 | PARTINDEX="$(autoconfig_getpartitionindex "${DISK}" "${PARTNUM}")" 251 | if growpart -N "${DISK_BLOCK}" "${PARTINDEX}" 1>&2; then 252 | growpart "${DISK_BLOCK}" "${PARTINDEX}" 1>&2 || exit $? 253 | fi 254 | fi 255 | done 256 | done 257 | 258 | # print output 259 | # loop disks 260 | for (( DISKNUM=0; DISKNUM<${LEN_DISKS}; DISKNUM++ )); do 261 | DISK="$(echo "${CONF_DISKS}" | jq ".[${DISKNUM}]")" || exit $? 262 | # loop partitions 263 | LEN_PARTS="$(echo "${DISK}" | jq -j '.partitions | length')" || exit $? 264 | for (( PARTNUM=0; PARTNUM<${LEN_PARTS}; PARTNUM++ )); do 265 | if [ $DISKNUM -gt 0 ] || [ $PARTNUM -gt 0 ];then 266 | echo -n ' ' 267 | fi 268 | autoconfig_printpartition "${DISK}" "${PARTNUM}" || exit $? 269 | done 270 | done 271 | echo 272 | -------------------------------------------------------------------------------- /share/pentoo-installer/partition_autoprepare: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # partition_autoprepare 6 | # apply preconfigured partition layout 7 | # parameters: none 8 | # 9 | # returns $ERROR_CANCEL=64 on user cancel 10 | # anything else is a real error 11 | # reason: show_dialog() needs a way to exit "Cancel" 12 | # 13 | # writes menus and noise to STDERR 14 | # 15 | # prints result to STDOUT 16 | 17 | # location of other scripts to source 18 | readonly SHAREDIR="$(dirname ${0})" || exit $? 19 | 20 | # source partitioning commons 21 | source "${SHAREDIR}"/partition_common.sh || exit $? 22 | 23 | ######################################### 24 | ## START: dialog functions/definitions ## 25 | 26 | # printk() 27 | # parameters (required) 28 | # on|off 29 | # 30 | printk() { 31 | # check input 32 | check_num_args "${FUNCNAME}" 1 $# || return $? 33 | case $1 in 34 | "on") echo 4 >/proc/sys/kernel/printk || return $? ;; 35 | "off") echo 0 >/proc/sys/kernel/printk || return $? ;; 36 | *) return 1 ;; 37 | esac 38 | return 0 39 | } 40 | 41 | # partition_getpartitionsize() 42 | # asks user for size and prints result to STDOUT 43 | # 44 | # parameters (required) 45 | # _MOUNTPOINT: Mountpoint of the partition 46 | # _DISC_SIZE: Remaining space on disc in MiB 47 | # _MIN_SIZE: Minimal size in MiB 48 | # _SUGGESTED_SIZE: Suggested size in MiB 49 | # 50 | # returns $ERROR_CANCEL=64 on user cancel 51 | # anything else is a real error 52 | # reason: show_dialog() needs a way to exit "Cancel" 53 | # 54 | partition_getpartitionsize() { 55 | # check input 56 | check_num_args "${FUNCNAME}" 4 $# || return $? 57 | local _MOUNTPOINT="$1" 58 | local _DISC_SIZE="$2" 59 | local _MIN_SIZE="$3" 60 | local _SUGGESTED_SIZE="$4" 61 | local _PART_SIZE= 62 | while true; do 63 | _PART_SIZE="$(show_dialog --inputbox "Enter the size (MiB) of your ${_MOUNTPOINT} partition. Minimum value is ${_MIN_SIZE} MiB\n\nDisk space left: ${_DISC_SIZE} MiB" \ 64 | 0 0 "${_SUGGESTED_SIZE}")" || return $? 65 | if ! [[ ${_PART_SIZE} =~ ${ISNUMBER} ]]; then 66 | show_dialog --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0 67 | elif [ "${_PART_SIZE}" -ge "${_DISC_SIZE}" -o "${_PART_SIZE}" -eq "${_DISC_SIZE}" ]; then 68 | show_dialog --msgbox "ERROR: You have entered a too large size, please enter again." 0 0 69 | elif [ "${_PART_SIZE}" -eq "0" -o "${_PART_SIZE}" -lt "${_MIN_SIZE}" ]; then 70 | show_dialog --msgbox "ERROR: You have entered a too small size, please enter again." 0 0 71 | else 72 | # everyhing ok, print ot STDOUT and return 73 | echo "${_PART_SIZE}" 74 | return $? 75 | fi 76 | done 77 | return 0 78 | } 79 | 80 | ## END: dialog functions/definitions ## 81 | ####################################### 82 | 83 | ##################### 84 | ## begin execution ## 85 | 86 | BOOT_PART_SIZE="" 87 | DISC="" 88 | CURRENT_PARTITIONTABLE= 89 | DISC_SIZE="" 90 | ROOT_PART_SET="" 91 | SUGGESTED_SWAP_SIZE="" 92 | SWAP_PART_SIZE="" 93 | FSSPEC="" 94 | 95 | # let user select a disc 96 | DISC=$(partition_selectdisk) || exit $? 97 | # disk size in MiB 98 | DISC_SIZE=$(($(partition_getdisccapacity ${DISC}) / 2**20)) || exit $? 99 | # boot partition size (M) 100 | BOOT_PART_SIZE=$(partition_getpartitionsize "/boot" "${DISC_SIZE}" 128 512) || exit $? 101 | # calc remaining disk size 102 | DISC_SIZE=$((${DISC_SIZE}-${BOOT_PART_SIZE})) || exit $? 103 | # swap partition size 104 | SUGGESTED_SWAP_SIZE=$(awk '/MemTotal/ {printf( "%.0f\n", int ( $2 / 1024 ) + 1)}' /proc/meminfo) || exit $? 105 | #the line above is confusing mceditor. Close it: ' 106 | SWAP_PART_SIZE=$(partition_getpartitionsize "swap" "${DISC_SIZE}" 1 "${SUGGESTED_SWAP_SIZE}") || exit $? 107 | # calc remaining disk size 108 | DISC_SIZE=$((${DISC_SIZE}-${SWAP_PART_SIZE})) || exit $? 109 | # root partition size info 110 | if [ "${DISC_SIZE}" -lt "20000" ]; then 111 | show_dialog --msgbox "Pentoo requires at least 20GB for / and you don't have that much left, aborting partitioning" 0 0 112 | exit "${ERROR_CANCEL}" 113 | elif [ "${DISC_SIZE}" -lt "43000" ]; then 114 | show_dialog --msgbox "Pentoo *suggests* using at least 43GB for your / partition but you don't have that much left. You have been warned." 0 0 115 | fi 116 | show_dialog --msgbox "${DISC_SIZE} MiB will be used for your / partition." 0 0 117 | show_dialog --defaultno --yesno "${DISC} will be COMPLETELY ERASED! Are you absolutely sure?" \ 118 | 0 0 || exit "${ERROR_CANCEL}" 119 | #blow away partition table (this negates the check for partition table type below) 120 | dd if=/dev/zero of="${DISC}" bs=512 count=1 conv=notrunc 121 | parted "${DISC}" --script -- mklabel 'msdos' || exit $? 122 | # Check current partition layout 123 | #CURRENT_PARTITIONTABLE='unknown' 124 | # this can fail, for ex. on a virgin HD with no partition table 125 | #CURRENT_PARTITIONTABLE=$(parted "${DISC}" print -s 2>/dev/null | sed -nr 's/^Partition Table:\s(.*)/\1/p') 126 | #if [ "${CURRENT_PARTITIONTABLE}" != 'msdos' ]; then 127 | # show_dialog --defaultno --yesno "${DISC} currently has a '${CURRENT_PARTITIONTABLE}' partition layout.\nThis will be changed to 'msdos'!\nAre you absolutely sure?" 0 0 \ 128 | # || exit "${ERROR_CANCEL}" 129 | # parted -s "${DISC}" mklabel 'msdos' || exit $? 130 | #fi 131 | # umount and swapoff all partitions of the disc 132 | mount_umountall "${DISC}" || exit $? 133 | # prepare fdisk input 134 | # boot partition 135 | #${BOOT_PART_SIZE}" 136 | # swap partition 137 | #${SWAP_PART_SIZE}" 138 | # root partition 139 | #all the rest 140 | # invoke fdisk 141 | printk off || exit $? 142 | show_dialog --infobox "Partitioning ${DISC}" 0 0 143 | sync 144 | # run fdisk with prepared input (-c and -u are intentionally redundantly redundant "just in case") 145 | # 'a' toggles bootable (which isn't set by default) 146 | fdisk -c -u ${DISC} >>"${LOG}" 2>&1 </proc/sys/kernel/printk || return $? ;; 35 | "off") echo 0 >/proc/sys/kernel/printk || return $? ;; 36 | *) return 1 ;; 37 | esac 38 | return 0 39 | } 40 | 41 | # partition_getpartitionsize() 42 | # asks user for size and prints result to STDOUT 43 | # 44 | # parameters (required) 45 | # _MOUNTPOINT: Mountpoint of the partition 46 | # _DISC_SIZE: Remaining space on disc in MiB 47 | # _MIN_SIZE: Minimal size in MiB 48 | # _SUGGESTED_SIZE: Suggested size in MiB 49 | # 50 | # returns $ERROR_CANCEL=64 on user cancel 51 | # anything else is a real error 52 | # reason: show_dialog() needs a way to exit "Cancel" 53 | # 54 | partition_getpartitionsize() { 55 | # check input 56 | check_num_args "${FUNCNAME}" 4 $# || return $? 57 | local _MOUNTPOINT="$1" 58 | local _DISC_SIZE="$2" 59 | local _MIN_SIZE="$3" 60 | local _SUGGESTED_SIZE="$4" 61 | local _PART_SIZE= 62 | while true; do 63 | _PART_SIZE="$(show_dialog --inputbox "Enter the size (MiB) of your ${_MOUNTPOINT} partition. Minimum value is ${_MIN_SIZE} MiB\n\nDisk space left: ${_DISC_SIZE} MiB" \ 64 | 0 0 "${_SUGGESTED_SIZE}")" || return $? 65 | if ! [[ ${_PART_SIZE} =~ ${ISNUMBER} ]]; then 66 | show_dialog --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0 67 | elif [ "${_PART_SIZE}" -ge "${_DISC_SIZE}" -o "${_PART_SIZE}" -eq "${_DISC_SIZE}" ]; then 68 | show_dialog --msgbox "ERROR: You have entered a too large size, please enter again." 0 0 69 | elif [ "${_PART_SIZE}" -eq "0" -o "${_PART_SIZE}" -lt "${_MIN_SIZE}" ]; then 70 | show_dialog --msgbox "ERROR: You have entered a too small size, please enter again." 0 0 71 | else 72 | # everything ok, print ot STDOUT and return 73 | echo "${_PART_SIZE}" 74 | return $? 75 | fi 76 | done 77 | return 0 78 | } 79 | 80 | ## END: dialog functions/definitions ## 81 | ####################################### 82 | 83 | ##################### 84 | ## begin execution ## 85 | 86 | BOOT_PART_SIZE="" 87 | DISC="" 88 | CURRENT_PARTITIONTABLE= 89 | DISC_SIZE="" 90 | ROOT_PART_SET="" 91 | SUGGESTED_SWAP_SIZE="" 92 | SWAP_PART_SIZE="" 93 | FSSPEC="" 94 | 95 | # let user select a disc 96 | DISC=$(partition_selectdisk) || exit $? 97 | # disk size in MiB 98 | DISC_SIZE=$(($(partition_getdisccapacity ${DISC}) / 2**20)) || exit $? 99 | # boot partition size 100 | BOOT_PART_SIZE=$(partition_getpartitionsize "/boot" "${DISC_SIZE}" 550 550) || exit $? 101 | # calc remaining disk size 102 | DISC_SIZE=$((${DISC_SIZE}-${BOOT_PART_SIZE})) || exit $? 103 | # swap partition size 104 | SUGGESTED_SWAP_SIZE=$(awk '/MemTotal/ {printf( "%.0f\n", int ( $2 / 1024 ) + 1)}' /proc/meminfo) || exit $? 105 | #the line above is confusing mceditor. Close it: ' 106 | SWAP_PART_SIZE=$(partition_getpartitionsize "swap" "${DISC_SIZE}" 1 "${SUGGESTED_SWAP_SIZE}") || exit $? 107 | # calc remaining disk size 108 | DISC_SIZE=$((${DISC_SIZE}-${SWAP_PART_SIZE})) || exit $? 109 | # root partition size info 110 | if [ "${DISC_SIZE}" -lt "20000" ]; then 111 | show_dialog --msgbox "Pentoo requires at least 20GB for / and you don't have that much left, aborting partitioning" 0 0 112 | exit "${ERROR_CANCEL}" 113 | elif [ "${DISC_SIZE}" -lt "43000" ]; then 114 | show_dialog --msgbox "Pentoo *suggests* using at least 43GB for your / partition but you don't have that much left. You have been warned." 0 0 115 | fi 116 | show_dialog --msgbox "${DISC_SIZE} MiB will be used for your / partition." 0 0 117 | show_dialog --defaultno --yesno "${DISC} will be COMPLETELY ERASED! Are you absolutely sure?" \ 118 | 0 0 || exit "${ERROR_CANCEL}" 119 | #blow away partition table (this negates the check for partition table type below) 120 | dd if=/dev/zero of="${DISC}" bs=5M count=1 conv=notrunc 121 | #parted "${DISC}" --script -- mklabel gpt || exit $? 122 | # Check current partition layout 123 | #CURRENT_PARTITIONTABLE='unknown' 124 | # this can fail, for ex. on a virgin HD with no partition table 125 | #CURRENT_PARTITIONTABLE=$(parted "${DISC}" print -s 2>/dev/null | sed -nr 's/^Partition Table:\s(.*)/\1/p') 126 | #if [ "${CURRENT_PARTITIONTABLE}" != 'msdos' ]; then 127 | # show_dialog --defaultno --yesno "${DISC} currently has a '${CURRENT_PARTITIONTABLE}' partition layout.\nThis will be changed to 'msdos'!\nAre you absolutely sure?" 0 0 \ 128 | # || exit "${ERROR_CANCEL}" 129 | # parted -s "${DISC}" mklabel 'msdos' || exit $? 130 | #fi 131 | # umount and swapoff all partitions of the disc 132 | mount_umountall "${DISC}" || exit $? 133 | # prepare fdisk input 134 | # boot partition 135 | #${BOOT_PART_SIZE}" 136 | # swap partition 137 | #${SWAP_PART_SIZE}" 138 | # root partition 139 | #all the rest 140 | # invoke fdisk 141 | printk off || exit $? 142 | show_dialog --infobox "Partitioning ${DISC}" 0 0 143 | sync 144 | # run fdisk with prepared input (-c and -u are intentionally redundantly redundant "just in case") 145 | # 'a' toggles bootable (which isn't set by default) 146 | fdisk -c -u ${DISC} >>"${LOG}" 2>&1 </dev/null | grep -q "${_PART}" \ 108 | && ! file -s /dev/"${_PART}" | grep -qi lvm2 \ 109 | && ( \ 110 | ! fdisk -l /dev/"${_PART}" | grep "Disklabel type:" | grep -q 'msdos' \ 111 | || ! fdisk -l /dev/"${_DISC}" | grep "^/dev/${_PART}[[:space:]]" | sed 's/ \* / /' | awk '{print $5}' | grep -q 5 \ 112 | ) \ 113 | ; then 114 | if [ -d "${_PARTPATH}" ]; then 115 | _LIST_RESULT+="/dev/${_PART}\n" 116 | fi 117 | fi 118 | done 119 | done 120 | # include any mapped devices 121 | for _DEVPATH in $(ls /dev/mapper 2>/dev/null | grep -v control); do 122 | _LIST_RESULT+="/dev/mapper/${_DEVPATH}\n" 123 | done 124 | # include any raid md devices 125 | for _DEVPATH in $(ls -d /dev/md* | grep '[0-9]' 2>/dev/null); do 126 | if cat /proc/mdstat | grep -qw $(echo ${_DEVPATH} | sed -e 's|/dev/||g'); then 127 | _LIST_RESULT+="${_DEVPATH}\n" 128 | fi 129 | done 130 | # include cciss controllers 131 | if [ -d /dev/cciss ] ; then 132 | for _DEV in $(ls /dev/cciss | egrep 'p'); do 133 | _LIST_RESULT+="/dev/cciss/${_DEV}\n" 134 | done 135 | fi 136 | # include Smart 2 controllers 137 | if [ -d /dev/ida ] ; then 138 | for _DEV in $(ls /dev/ida | egrep 'p'); do 139 | _LIST_RESULT+="/dev/ida/${_DEV}\n" 140 | done 141 | fi 142 | #emmc 143 | for _DEVPATH in $(ls /dev/mmcblk* | egrep 'p'); do 144 | _LIST_RESULT+="${_DEVPATH}\n" 145 | done 146 | #NVMe 147 | for _DEVPATH in $(ls /dev/nvme* | egrep 'p'); do 148 | _LIST_RESULT+="${_DEVPATH}\n" 149 | done 150 | echo -e "${_LIST_RESULT}" | LC_ALL=C sort -u 151 | return 0 152 | } 153 | # end of partition_findpartitions() 154 | 155 | # partition_getdisccapacity() 156 | # 157 | # parameters: device file 158 | # outputs: disc capacity in bytes 159 | partition_getdisccapacity() { 160 | # check input 161 | check_num_args "${FUNCNAME}" 1 $# || return $? 162 | fdisk -l "${1}" | awk '/^Disk .*bytes/ { print $5 }' || echo 0 163 | return 0 164 | } 165 | 166 | # partition_getdisccapacity_formatted() 167 | # outputs formatted disc capacity 168 | # Example: 169 | # 625000 MiB (610 GiB) 170 | # 171 | # parameters: device file 172 | # 173 | partition_getdisccapacity_formatted() { 174 | # check input 175 | check_num_args "${FUNCNAME}" 1 $# || return $? 176 | local _DISC_SIZE="" 177 | _DISC_SIZE=$(partition_getdisccapacity "${1}") || return $? 178 | _DISC_SIZE="$((_DISC_SIZE / 2**20)) MiB ($((_DISC_SIZE / 2**30)) GiB)" || return $? 179 | echo -n "${_DISC_SIZE}" 180 | return 0 181 | } 182 | 183 | # partition_selectdisk() 184 | # displays disks so user can select one 185 | # prints disk to STDOUT 186 | # 187 | # exits: !=1 is an error 188 | # 189 | partition_selectdisk() { 190 | local _DISC= 191 | local _DISCS= 192 | local _MENU_ITEMS=() 193 | _DISCS="$(partition_finddisks)" || return $? 194 | for _DISC in ${_DISCS}; do 195 | # add disc and description to array 196 | _MENU_ITEMS+=("${_DISC}" "$(partition_getdisccapacity_formatted "${_DISC}")") \ 197 | || return $? 198 | done 199 | _MENU_ITEMS+=('OTHER' '-') 200 | # expand array below 201 | _DISC="$(show_dialog --menu "Select the disk you want to use" \ 202 | 0 0 7 "${_MENU_ITEMS[@]}")" \ 203 | || return $? 204 | if [ "${_DISC}" = "OTHER" ]; then 205 | _DISC="$(show_dialog --inputbox "Enter the full path to the device you wish to use" \ 206 | 0 0 "/dev/sda")" || return $? 207 | # validate _DISC 208 | if [ ! -b "${_DISC}" ] \ 209 | || ! lsblk -dn -o TYPE "${_DISC}" | grep -q disk; then 210 | show_dialog --msgbox "Device '${_DISC}' is not valid" 0 0 211 | return "${ERROR_CANCEL}" 212 | fi 213 | fi 214 | # everything ok, print result to STDOUT 215 | echo "${_DISC}" 216 | return 0 217 | } 218 | 219 | # partition_selectpartition() 220 | # displays partitions so user can select one 221 | # prints partition to STDOUT 222 | # 223 | # exits: !=1 is an error 224 | # 225 | partition_selectpartition() { 226 | local _PART= 227 | local _PARTS= 228 | local _DISC= 229 | local _DISCS= 230 | local _MSG= 231 | _DISCS="$(partition_finddisks)" || return $? 232 | # compose dialog message 233 | _MSG="Available Disks:\n" 234 | for _DISC in ${_DISCS}; do 235 | # add disc and description to message 236 | _MSG="${_MSG}\n${_DISC} $(partition_getdisccapacity_formatted "${_DISC}")" \ 237 | || return $? 238 | done 239 | _MSG="${_MSG}\n\nSelect the partition you want to use" 240 | _PARTS="$(partition_findpartitions)" || return $? 241 | _PARTS="$(add_option_label "${_PARTS}" '-')" || return $? 242 | _PARTS="${_PARTS} OTHER -" 243 | _PART="$(show_dialog --menu "${_MSG}" \ 244 | 0 0 7 ${_PARTS})" \ 245 | || return $? 246 | if [ "${_PART}" = "OTHER" ]; then 247 | _PART="$(show_dialog --inputbox "Enter the full path to the device you wish to use" \ 248 | 0 0 "/dev/sda1")" || return $? 249 | # validate _PART 250 | if [ ! -b "${_PART}" ] \ 251 | || ! lsblk -dn -o TYPE "${_PART}" | grep -q part; then 252 | show_dialog --msgbox "Partition '${_PART}' is not valid" 0 0 253 | return "${ERROR_CANCEL}" 254 | fi 255 | fi 256 | # everything ok, print result to STDOUT 257 | echo "${_PART}" 258 | return 0 259 | } 260 | 261 | ## END: utility functions ## 262 | ############################ 263 | -------------------------------------------------------------------------------- /share/pentoo-installer/partition_configurations: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # partition_configurations 6 | # display configure mountpoints and filesystems 7 | # lets user add new ones or delete existing ones 8 | # parameters (required) 9 | # CONFIG_LIST: One string with 0 or more items of defined FSspec 10 | # 11 | # returns 0 on success 12 | # returns $ERROR_CANCEL=64 on user cancel 13 | # anything else is a real error 14 | # reason: show_dialog() needs a way to exit "Cancel" 15 | # 16 | # writes menus and noise to STDERR 17 | # 18 | # prints result to STDOUT 19 | 20 | # location of other scripts to source 21 | readonly SHAREDIR="$(dirname ${0})" || exit $? 22 | 23 | # source partitioning commons 24 | source "${SHAREDIR}"/partition_common.sh || exit $? 25 | 26 | ######################################### 27 | ## START: dialog functions/definitions ## 28 | 29 | # partition_getlistmaxlength() 30 | # loops string list and prints length of longest item 31 | # parameters (required) 32 | # _LIST: The list 33 | partition_getlistmaxlength() { 34 | # check input 35 | check_num_args "${FUNCNAME}" 1 $# || return $? 36 | local _LIST="${1}" 37 | local _ITEM= 38 | local _MAX=0 39 | for _ITEM in ${_LIST}; do 40 | [ "${_MAX}" -lt "${#_ITEM}" ] && _MAX="${#_ITEM}" 41 | done 42 | echo "${_MAX}" 43 | return 0 44 | } 45 | 46 | ## END: dialog functions/definitions ## 47 | ####################################### 48 | 49 | ##################### 50 | ## begin execution ## 51 | 52 | # check input 53 | check_num_args "$(basename $0)" 1 $# || exit $? 54 | CONFIG_LIST="${1}" 55 | RETSUB= 56 | 57 | while true; do 58 | # array holding menu items 59 | MENU_ITEMS=() 60 | MENU_STRING= 61 | # arrays of item settings 62 | PARTITIONS=() 63 | MOUNTPOINTS=() 64 | FILESYSTEMS=() 65 | CRYPTTYPES=() 66 | FORMATS=() 67 | # other vars 68 | TMP_ITEM= 69 | TMPSTRING= 70 | MAXLEN= 71 | SELECTION= 72 | # parse input 73 | # loop input/config items, add each sub-var to an array for the menu 74 | for TMP_ITEM in ${CONFIG_LIST}; do 75 | # parse the item, also validates 76 | # add each item to the corresponding array 77 | PARTITIONS+=("$("${SHAREDIR}"/FSspec parse "${TMP_ITEM}" 'partition')") || exit $? 78 | MOUNTPOINTS+=("$("${SHAREDIR}"/FSspec parse "${TMP_ITEM}" 'mountpoint')") || exit $? 79 | FILESYSTEMS+=("$("${SHAREDIR}"/FSspec parse "${TMP_ITEM}" 'filesystem')") || exit $? 80 | CRYPTTYPES+=("$("${SHAREDIR}"/FSspec parse "${TMP_ITEM}" 'crypttype')") || exit $? 81 | FORMATS+=("$(get_yesno "$("${SHAREDIR}"/FSspec parse "${TMP_ITEM}" 'format')")") || exit $? 82 | done 83 | # ### START: UGLY CODE BLOCK ### 84 | # ### This just creates formatted/padded labels for the menu options 85 | # ### menu keys will be the partitions, like '/dev/sda1' 86 | # ### 87 | # loop input/config items, create formatted/padded strings for the menu 88 | if [ "${#PARTITIONS[@]}" -gt 0 ]; then 89 | 90 | # loop partitions and init menu items array 91 | TMP_ITEM=0 92 | while [ "${TMP_ITEM}" -lt "${#PARTITIONS[@]}" ]; do 93 | # add to menu items 94 | MENU_ITEMS+=("${PARTITIONS[$TMP_ITEM]}" "") || exit $? 95 | # increment for next partition 96 | TMP_ITEM=$((TMP_ITEM+1)) 97 | done 98 | 99 | # construct formatted string 100 | # padd all strings 101 | # mountpoint 102 | MAXLEN=$(partition_getlistmaxlength "$(echo ${MOUNTPOINTS[@]})") || exit $? 103 | TMP_ITEM=0 104 | while [ "${TMP_ITEM}" -lt "${#PARTITIONS[@]}" ]; do 105 | TMPSTRING="${MOUNTPOINTS[$TMP_ITEM]}" || exit $? 106 | # append spaces so all items have same length + 4 for padding 107 | TMPSTRING="${TMPSTRING}$(printf ' %.0s' $(eval echo {1..$((MAXLEN+4-${#TMPSTRING}))}))" || exit $? 108 | # store in menu items array 109 | MENU_ITEMS[$((TMP_ITEM * 2 + 1))]+="mountpoint=${TMPSTRING}" || exit $? 110 | # increment for next partition 111 | TMP_ITEM=$((TMP_ITEM+1)) 112 | done 113 | 114 | # filesystem 115 | MAXLEN=$(partition_getlistmaxlength "$(echo ${FILESYSTEMS[@]})") || exit $? 116 | TMP_ITEM=0 117 | while [ "${TMP_ITEM}" -lt "${#PARTITIONS[@]}" ]; do 118 | TMPSTRING="${FILESYSTEMS[$TMP_ITEM]}" || exit $? 119 | # append spaces so all items have same length + 4 for padding 120 | TMPSTRING="${TMPSTRING}$(printf ' %.0s' $(eval echo {1..$((MAXLEN+4-${#TMPSTRING}))}))" || exit $? 121 | # store in menu items array 122 | MENU_ITEMS[$((TMP_ITEM * 2 + 1))]+="filesystem=${TMPSTRING}" || exit $? 123 | # increment for next partition 124 | TMP_ITEM=$((TMP_ITEM+1)) 125 | done 126 | 127 | # crypttypes 128 | MAXLEN=$(partition_getlistmaxlength "$(echo ${CRYPTTYPES[@]})") || exit $? 129 | TMP_ITEM=0 130 | while [ "${TMP_ITEM}" -lt "${#PARTITIONS[@]}" ]; do 131 | TMPSTRING="${CRYPTTYPES[$TMP_ITEM]}" || exit $? 132 | # append spaces so all items have same length + 4 for padding 133 | TMPSTRING="${TMPSTRING}$(printf ' %.0s' $(eval echo {1..$((MAXLEN+4-${#TMPSTRING}))}))" || exit $? 134 | # store in menu items array 135 | MENU_ITEMS[$((TMP_ITEM * 2 + 1))]+="encryption=${TMPSTRING}" || exit $? 136 | # increment for next partition 137 | TMP_ITEM=$((TMP_ITEM+1)) 138 | done 139 | 140 | # format 141 | MENU_STRING="${MENU_STRING}format=" 142 | MAXLEN=$(partition_getlistmaxlength "$(echo ${FORMATS[@]})") || exit $? 143 | TMP_ITEM=0 144 | while [ "${TMP_ITEM}" -lt "${#PARTITIONS[@]}" ]; do 145 | TMPSTRING="${FORMATS[$TMP_ITEM]}" || exit $? 146 | # append spaces so all items have same length + 4 for padding 147 | TMPSTRING="${TMPSTRING}$(printf ' %.0s' $(eval echo {1..$((MAXLEN+4-${#TMPSTRING}))}))" || exit $? 148 | # store in menu items array 149 | MENU_ITEMS[$((TMP_ITEM * 2 + 1))]+="format=${TMPSTRING}" || exit $? 150 | # increment for next partition 151 | TMP_ITEM=$((TMP_ITEM+1)) 152 | done 153 | 154 | fi 155 | # ### 156 | # ### END: UGLY CODE BLOCK ### 157 | # Add other options: ADD, DONE 158 | MENU_ITEMS+=("ADD" "Add another partition") || exit $? 159 | MENU_ITEMS+=("DONE" "Save changes") || exit $? 160 | # expand menu items array below 161 | SELECTION=$(show_dialog --menu "Please select partitions to edit or add a new partition." \ 162 | 0 0 0 "${MENU_ITEMS[@]}") || exit $? 163 | # evaluate answer 164 | case "${SELECTION}" in 165 | 'ADD') 166 | TMP_ITEM="$("${SHAREDIR}"/FSspec add "${CONFIG_LIST}")" 167 | RETSUB=$? 168 | if [ "${RETSUB}" -eq 0 ]; then 169 | # merge/check config list 170 | CONFIG_LIST="$("${SHAREDIR}"/FSspec merge "${CONFIG_LIST}" "${TMP_ITEM}")" || exit $? 171 | fi 172 | ;; 173 | 'DONE') 174 | # print result to STDOUT 175 | echo "${CONFIG_LIST}" 176 | exit 0 177 | ;; 178 | *) 179 | # find config of selected item 180 | TMP_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'partition' "${SELECTION}")" || exit $? 181 | # open submenu 182 | TMP_ITEM="$("${SHAREDIR}"/FSspec edit "${TMP_ITEM}" "${CONFIG_LIST}")" 183 | RETSUB=$? 184 | if [ "${RETSUB}" -eq 0 ]; then 185 | # item was removed 186 | if [ -z "${TMP_ITEM}" ]; then 187 | # delete item from config list 188 | CONFIG_LIST="$("${SHAREDIR}"/FSspec del_keyvalue "${CONFIG_LIST}" 'partition' "${SELECTION}")" || exit $? 189 | else 190 | # merge/check config list 191 | CONFIG_LIST="$("${SHAREDIR}"/FSspec merge "${CONFIG_LIST}" "${TMP_ITEM}")" || exit $? 192 | fi 193 | fi 194 | ;; 195 | esac 196 | # handle errors from sub-script/functions using a common utility function 197 | catch_menuerror "$(basename $0)" "${SELECTION}" "${RETSUB}" 198 | done 199 | -------------------------------------------------------------------------------- /share/pentoo-installer/partition_finalise: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # partition_finalise 6 | # Creates filesystem, also with encryption, mounts the partitions 7 | # parameters (required) 8 | # CONFIG_LIST: One string items of defined FSspec 9 | # 10 | # returns 0 on success 11 | # returns $ERROR_CANCEL=64 on user cancel 12 | # anything else is a real error 13 | # reason: show_dialog() needs a way to exit "Cancel" 14 | # 15 | # writes menus and noise to STDERR 16 | 17 | # location of other scripts to source 18 | readonly SHAREDIR="$(dirname ${0})" || exit $? 19 | 20 | # source partitioning commons 21 | source "${SHAREDIR}"/partition_common.sh || exit $? 22 | 23 | ######################################### 24 | ## START: dialog functions/definitions ## 25 | 26 | # partition_crypt_setup() 27 | # Generate a key, optionnaly encrypt it with gpg 28 | # format a luks or swap partition. Cipher and hash chosen arbitrarily 29 | # uses cryptsetup 30 | # writes the key to STDOUT, in base64 form for gpg 31 | # 32 | # parameters (required) 33 | # _PARTITION: The partition to encrypt 34 | # _CRYPTNAME: name used by cryptsetup 35 | # _CRYPTTYPE: one of: 'swap', 'luks2', 'luks2-gpg' 36 | # 37 | # return !=0 on failure (including user abort with ERROR_CANCEL=64) 38 | # 39 | partition_crypt_setup() { 40 | # check input 41 | check_num_args "${FUNCNAME}" 3 $# || return $? 42 | local _PARTITION="${1}" 43 | local _CRYPTNAME="${2}" 44 | local _CRYPTTYPE="${3}" 45 | local _UUID= 46 | # use uuid as temp file name 47 | _UUID="$(uuidgen)" || return $? 48 | case "${_CRYPTTYPE}" in 49 | 'swap') 50 | # TODO swap key is shorter then before with -d /dev/urandom and 51 | # Maximum keyfile size: 8192kB 52 | head -c60 /dev/urandom | base64 | head -n1 | tr -d '\n' > /tmp/"${_UUID}" || return $? 53 | cryptsetup --batch-mode --cipher aes-xts-plain64:sha512 --key-size 512 -d /tmp/"${_UUID}" open --type plain "${_PARTITION}" "${_CRYPTNAME}" || return $? 54 | # print to STDOUT 55 | cat /tmp/"${_UUID}" || return $? 56 | # clean up 57 | rm /tmp/"${_UUID}" || return $? 58 | ;; 59 | 'luks2-gpg') 60 | show_dialog --infobox "Now generating a GPG-encrypted luks key for ${_PARTITION}" 0 0 61 | head -c60 /dev/urandom | base64 | head -n1 | tr -d '\n' > /tmp/"${_UUID}" || return $? 62 | gpg --symmetric --cipher-algo aes256 --armor /tmp/"${_UUID}" || return $? 63 | gpg --decrypt /tmp/"${_UUID}".asc | cryptsetup --batch-mode --type luks2 --hash sha512 --cipher aes-xts-plain64 --iter-time 3000 --key-size 512 --pbkdf argon2id --use-random luksFormat --align-payload=4096 "${_PARTITION}" || return $? 64 | # TODO, is this needed? Seems not 65 | # show_dialog --msgbox "Please enter the GPG key for ${_PARTITION} (last time :-)" 0 0 || return $? 66 | gpg --decrypt /tmp/"${_UUID}".asc | cryptsetup --batch-mode open --type luks2 "${_PARTITION}" "${_CRYPTNAME}" || return $? 67 | # print to STDOUT 68 | cat /tmp/"${_UUID}".asc | base64 -w0 || return $? 69 | # clean up 70 | rm /tmp/"${_UUID}".asc || return $? 71 | rm /tmp/"${_UUID}" || return $? 72 | ;; 73 | 'luks2') 74 | head -c60 /dev/urandom | base64 | head -n1 | tr -d '\n' > /tmp/"${_UUID}" || return $? 75 | cat /tmp/"${_UUID}" | cryptsetup --batch-mode --type luks2 --hash sha512 --cipher aes-xts-plain64 --iter-time 3000 --key-size 512 --pbkdf argon2id --use-random luksFormat --align-payload=4096 "${_PARTITION}" || return $? 76 | cat /tmp/"${_UUID}" | cryptsetup --batch-mode open --type luks2 "${_PARTITION}" "${_CRYPTNAME}" || return $? 77 | # print to STDOUT 78 | cat /tmp/"${_UUID}" || return $? 79 | # clean up 80 | rm /tmp/"${_UUID}" || return $? 81 | ;; 82 | *) 83 | echo "ERROR: Unexpected input '${_CRYPTTYPE}' in '${FUNCNAME}'" 1>&2 84 | return 1 85 | ;; 86 | esac 87 | return 0 88 | } 89 | 90 | ## END: dialog functions/definitions ## 91 | ####################################### 92 | 93 | ##################### 94 | ## begin execution ## 95 | 96 | # check input 97 | check_num_args "$(basename $0)" 1 $# || exit $? 98 | CONFIG_LIST="${1}" 99 | # sort by mountpoint 100 | CONFIG_LIST="$("${SHAREDIR}"/FSspec sort "${CONFIG_LIST}" 'mountpoint' 0)" || exit $? 101 | CONFIG_ARRAY=(${CONFIG_LIST}) || exit $? 102 | CONFIG_INDEX=0 103 | 104 | # validate config 105 | # check if mountpoint '/' exists 106 | if ! "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/'; then 107 | show_dialog --msgbox "Error: Root partition (with mountpoint '/') not found.\nPlease re-configure the partitions!" 0 0 108 | exit "${ERROR_CANCEL}" 109 | fi 110 | # validate root partition 111 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'mountpoint' '/')" || exit $? 112 | CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'crypttype')" || exit $? 113 | # root partition encrypted, requires /boot 114 | # check if mountpoint '/boot' exists 115 | if [ "${CRYPTTYPE}" != '' ] && ! "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/boot'; then 116 | show_dialog --msgbox "Error: Encrypted root partition requires a separate, non-encrypted partition for /boot.\nPlease re-configure the partitions!" 0 0 117 | exit "${ERROR_CANCEL}" 118 | fi 119 | # check if mountpoint '/boot' is not encrypted 120 | if "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/boot'; then 121 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec listfind "${CONFIG_LIST}" 'mountpoint' '/boot')" || exit $? 122 | CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'crypttype')" || exit $? 123 | if [ "${CRYPTTYPE}" != '' ]; then 124 | show_dialog --msgbox "Error: /boot cannot be encrypted.\nPlease re-configure the partitions!" 0 0 125 | exit "${ERROR_CANCEL}" 126 | fi 127 | fi 128 | 129 | # cleanup mounts 130 | "${SHAREDIR}"/FSspec umountall "${CONFIG_LIST}" || exit $? 131 | 132 | while [ "${CONFIG_INDEX}" -lt "${#CONFIG_ARRAY[@]}" ]; do 133 | CONFIG_ITEM="${CONFIG_ARRAY[${CONFIG_INDEX}]}" || exit $? 134 | PARTITION="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'partition')" || exit $? 135 | MOUNTPOINT="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'mountpoint')" || exit $? 136 | FILESYSTEM="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'filesystem')" || exit $? 137 | CRYPTTYPE="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'crypttype')" || exit $? 138 | FORMAT="$("${SHAREDIR}"/FSspec parse "${CONFIG_ITEM}" 'format')" || exit $? 139 | CRYPTNAME= 140 | CRYPTKEY= 141 | PARTPATH="${PARTITION}" 142 | # encrypted 143 | if [ "${CRYPTTYPE}" != '' ]; then 144 | # define cryptname 145 | if [ "${MOUNTPOINT}" != '/' ]; then 146 | CRYPTNAME="luks_$(basename "${PARTITION}")" || exit $? 147 | else 148 | CRYPTNAME='root' 149 | fi 150 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'cryptname' "${CRYPTNAME}")" || exit $? 151 | # create crypt-key and use cryptsetup 152 | CRYPTKEY="$(partition_crypt_setup "${PARTITION}" "${CRYPTNAME}" "${CRYPTTYPE}")" || exit $? 153 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'cryptkey' "${CRYPTKEY}")" || exit $? 154 | PARTPATH="/dev/mapper/${CRYPTNAME}" 155 | fi 156 | sync 157 | # format partition 158 | if [ "${FORMAT}" -eq 1 ]; then 159 | case ${FILESYSTEM} in 160 | btrfs) 161 | if lsblk -nP -oSIZE ${PARTPATH} | grep -q 'G'; then 162 | mkfs.btrfs -f ${PARTPATH} >>"${LOG}" 2>&1 || exit $? 163 | else 164 | #if the user selects btrfs for a small partition, eg /boot, --mixed mode is desired by no longer default 165 | mkfs.btrfs --mixed -f ${PARTPATH} >>"${LOG}" 2>&1 || exit $? 166 | fi 167 | ;; 168 | xfs) mkfs.xfs -f ${PARTPATH} >>"${LOG}" 2>&1 || exit $? ;; 169 | jfs) mkfs.jfs -q ${PARTPATH} >>"${LOG}" 2>&1 || exit $? ;; 170 | reiserfs) mkreiserfs -f ${PARTPATH} >>"${LOG}" 2>&1 || exit $?;; 171 | # Pulling out ext2 and ext3 since no sane person wants this 172 | #ext2) mke2fs "${PARTPATH}" -F >>"${LOG}" 2>&1 || exit $? ;; 173 | #ext3) mke2fs -j ${PARTPATH} -F >>"${LOG}" 2>&1 || exit $? ;; 174 | ext4) mke2fs -t ext4 ${PARTPATH} -F >>"${LOG}" 2>&1 || exit $? ;; 175 | ext4-nojournal) mke2fs -F -t ext4 -O ^has_journal ${PARTPATH} -F >>"${LOG}" 2>&1 || exit $? ;; 176 | vfat) mkfs.vfat ${PARTPATH} >>"${LOG}" 2>&1 || exit $? ;; 177 | fat32) mkfs.fat -F32 -n Pentoo ${PARTPATH} >>"${LOG}" 2>&1 || exit $? ;; 178 | f2fs) mkfs.f2fs -f ${PARTPATH} >>"${LOG}" 2>&1 || exit $? ;; 179 | # swap 180 | swap) mkswap ${PARTPATH} >>"${LOG}" 2>&1 || exit $? ;; 181 | *) 182 | echo "ERROR: Unexpected file sytem '${FILESYSTEM}' for '${PARTITION}'" 1>&2 183 | exit 1 ;; 184 | esac 185 | FORMAT='0' 186 | CONFIG_ITEM="$("${SHAREDIR}"/FSspec setvalue "${CONFIG_ITEM}" 'format' "${FORMAT}")" || exit $? 187 | sync 188 | fi 189 | # mount actions 190 | if [ "${FILESYSTEM}" != 'swap' ]; then 191 | # create our mount directory 192 | mkdir -p "${DESTDIR}${MOUNTPOINT}" || exit $? 193 | # normalize filesystem 194 | if [ "${FILESYSTEM}" = "ext4-nojournal" ]; then 195 | FILESYSTEM="ext4" 196 | elif [ "${FILESYSTEM}" = "fat32" ]; then 197 | FILESYSTEM="vfat" 198 | fi 199 | # mount the bad boy 200 | mount -t "${FILESYSTEM}" "${PARTPATH}" "${DESTDIR}${MOUNTPOINT}" >>"${LOG}" 2>&1 || exit $? 201 | else 202 | swapon ${PARTPATH} >>"${LOG}" 2>&1 || exit $? 203 | fi 204 | # write FSspec back to array 205 | CONFIG_ARRAY[${CONFIG_INDEX}]="${CONFIG_ITEM}" || exit $? 206 | # increment array index 207 | CONFIG_INDEX="$((CONFIG_INDEX+1))" || exit $? 208 | done 209 | 210 | # rewrite list from array 211 | CONFIG_LIST="${CONFIG_ARRAY[@]}" 212 | # default sort by partition again 213 | CONFIG_LIST="$("${SHAREDIR}"/FSspec sort "${CONFIG_LIST}" 'partition' 0)" || exit $? 214 | 215 | # everything ok, write new config to STDOUT 216 | echo -n "${CONFIG_LIST}" || exit $? 217 | 218 | exit 0 219 | -------------------------------------------------------------------------------- /share/pentoo-installer/partition_mainmenu: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # partition_mainmenu 6 | # first menu for partitioning. Auto-partition or manually? 7 | # parameters: none 8 | # 9 | # returns $ERROR_CANCEL=64 on user cancel 10 | # anything else is a real error 11 | # reason: show_dialog() needs a way to exit "Cancel" 12 | # 13 | # writes menus and noise to STDERR 14 | 15 | # location of other scripts to source 16 | readonly SHAREDIR="$(dirname ${0})" || exit $? 17 | 18 | # source common variables, functions and error handling 19 | source "${SHAREDIR}"/common.sh || exit $? 20 | 21 | ##################### 22 | ## begin execution ## 23 | 24 | NEWSELECTION= 25 | SELECTION='0' 26 | RETSUB= 27 | MENU_ITEMS= 28 | MAXSELECTION="0" 29 | 30 | # CONFIG_LIST: One string with 0 or more items of defined FSspec: 31 | CONFIG_LIST= 32 | CONFIG_LIST_NEW= 33 | 34 | # run from config-file 35 | if [ -n "${INSTALLER_CONFIGFILE:-}" ]; then 36 | CONFIG_LIST="$("${SHAREDIR}"/partition_autoconfig)" || exit $? 37 | SELECTION='3' 38 | fi 39 | 40 | while true; do 41 | # define menu items 42 | MENU_ITEMS=("0" "Guided Partitioning (erases the ENTIRE hard drive)" \ 43 | "1" "Manually partition whole drives (advanced users only)" \ 44 | "2" "Fine-tune partition setup (add, edit, encrypt, preserve existing layout)" 45 | ) 46 | # check if root partition is defined 47 | if "${SHAREDIR}"/FSspec list_haskeyvalue "${CONFIG_LIST}" 'mountpoint' '/'; then 48 | MENU_ITEMS+=("3" "Finish partition setup and format partitions") 49 | else 50 | [ "${MAXSELECTION}" -ge 3 ] && MAXSELECTION=2 51 | fi 52 | 53 | # expand menu items array below 54 | NEWSELECTION="$(show_dialog --default-item "${SELECTION}" --menu "Prepare Hard Drive" \ 55 | 0 0 0 "${MENU_ITEMS[@]}")" || exit $? 56 | # call subscript by selected item 57 | case "${NEWSELECTION}" in 58 | # autoprepare 59 | "0") 60 | if [ -d /sys/firmware/efi ]; then 61 | CONFIG_LIST_NEW="$("${SHAREDIR}"/partition_autoprepare_uefi)" 62 | else 63 | CONFIG_LIST_NEW="$("${SHAREDIR}"/partition_autoprepare)" 64 | fi 65 | # capture sub script exit 66 | RETSUB=$? 67 | if [ "${RETSUB}" -eq 0 ]; then 68 | # merge old config with new one 69 | CONFIG_LIST="$("${SHAREDIR}"/FSspec merge "${CONFIG_LIST}" "${CONFIG_LIST_NEW}")" || exit $? 70 | fi 71 | ;; 72 | # manual setup 73 | "1") 74 | CONFIG_LIST_NEW="$("${SHAREDIR}"/partition_manual)" 75 | # capture sub script exit 76 | RETSUB=$? 77 | if [ "${RETSUB}" -eq 0 ]; then 78 | # nothing to merge, but remove inexistent devices 79 | CONFIG_LIST="$("${SHAREDIR}"/FSspec merge "${CONFIG_LIST}" "${CONFIG_LIST_NEW}")" || exit $? 80 | fi 81 | ;; 82 | # change configurations (filesystems, mountpoint, encryption, etc.) 83 | "2") 84 | CONFIG_LIST_NEW="$("${SHAREDIR}"/partition_configurations "${CONFIG_LIST}")" 85 | # capture sub script exit 86 | RETSUB=$? 87 | if [ "${RETSUB}" -eq 0 ]; then 88 | # use result as new config list 89 | CONFIG_LIST="${CONFIG_LIST_NEW}" 90 | fi 91 | ;; 92 | # Create filesystems, then exit this menu 93 | "3") 94 | # prints new configs to STDOUT on success 95 | show_dialog --infobox "Partitioning and formatting drives..." 3 45 96 | "${SHAREDIR}"/partition_finalise "${CONFIG_LIST}" 97 | # capture sub script exit 98 | RETSUB=$? 99 | if [ "${RETSUB}" -eq 0 ]; then 100 | exit "${RETSUB}" 101 | fi 102 | ;; 103 | 104 | *) 105 | echo "ERROR: Unexpected response '${NEWSELECTION}' in $(basename $0)" 1>&2 106 | exit 1 107 | ;; 108 | esac 109 | # handle errors from sub-script/functions using a common utility function 110 | if ! catch_menuerror "$(basename $0)" "${NEWSELECTION}" "${RETSUB}"; then 111 | # everything ok, increase selection for next menu item 112 | if [ "${SELECTION}" -eq 0 ]; then 113 | if [ -n "${INSTALLER_HEADLESS:-}" ]; then 114 | # jump from auto-prepare directly to create-FS and exit (headless mode) 115 | SELECTION=3 116 | else 117 | # jump from auto-prepare directly to mountpoints 118 | SELECTION=2 119 | fi 120 | else 121 | SELECTION="$((NEWSELECTION+1))" || exit $? 122 | fi 123 | if [ "${MAXSELECTION}" -lt "${SELECTION}" ]; then 124 | MAXSELECTION="${SELECTION}" 125 | fi 126 | fi 127 | done 128 | -------------------------------------------------------------------------------- /share/pentoo-installer/partition_manual: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # partition_manual 6 | # manually partition disk 7 | # parameters: none 8 | # 9 | # returns $ERROR_CANCEL=64 on user cancel 10 | # anything else is a real error 11 | # reason: show_dialog() needs a way to exit "Cancel" 12 | # 13 | # writes menus and noise to STDERR 14 | 15 | # location of other scripts to source 16 | readonly SHAREDIR="$(dirname ${0})" || exit $? 17 | 18 | # source partitioning commons 19 | source "${SHAREDIR}"/partition_common.sh || exit $? 20 | 21 | ######################################### 22 | ## START: dialog functions/definitions ## 23 | 24 | # partition_setpartitionlabel() 25 | # select and write partition layout 26 | # writes suggested editor to STDOUT 27 | # parameters (required) 28 | # _DISC: The disk to use 29 | # 30 | # returns 0 on success 31 | # returns $ERROR_CANCEL=64 on user cancel 32 | # anything else is a real error 33 | # reason: show_dialog() needs a way to exit "Cancel" 34 | # 35 | partition_setpartitionlabel() { 36 | # check input 37 | check_num_args "${FUNCNAME}" 1 $# || return $? 38 | local _CPT= 39 | local _DISC="$1" 40 | local _PT= 41 | local _PARTITIONEDITOR= 42 | # Read current partition layout 43 | _CPT='unknown' 44 | # ignore if this fails 45 | _CPT=$(parted $1 print -s 2>/dev/null | sed -nr 's/^Partition Table:\s(.*)/\1/p') 46 | _PT=$(show_dialog --menu "Select a partition table to use" 0 0 3 \ 47 | "msdos" "msdos (default)" \ 48 | "gpt" "gpt") || return $? 49 | case "$_PT" in 50 | "msdos") 51 | _PARTITIONEDITOR="cfdisk" ;; 52 | "gpt") 53 | _PARTITIONEDITOR="cgdisk" ;; 54 | *) return 1 ;; 55 | esac 56 | # Check current partition layout 57 | if [ "${_PT}" != "${_CPT}" ]; then 58 | show_dialog --defaultno --yesno "${_DISC} will be COMPLETELY ERASED! Are you absolutely sure?" 0 0 \ 59 | || return $? 60 | parted -s "${_DISC}" mklabel "${_PT}" || return $? 61 | sync 62 | fi 63 | # print partition editor to STDOUT 64 | echo "${_PARTITIONEDITOR}" 65 | return 0 66 | } 67 | 68 | ## END: dialog functions/definitions ## 69 | ####################################### 70 | 71 | ##################### 72 | ## begin execution ## 73 | 74 | DISC= 75 | MESSAGE= 76 | PARTITIONEDITOR= 77 | RET= 78 | 79 | # let user select a disc 80 | DISC=$(partition_selectdisk) || exit $? 81 | # umount and swapoff all partitions of the disc 82 | mount_umountall "${DISC}" || exit $? 83 | # Set partition layout and get partition editor PARTITIONEDITOR 84 | PARTITIONEDITOR=$(partition_setpartitionlabel "${DISC}") || exit $? 85 | show_dialog --msgbox "Now you'll be put into the ${PARTITIONEDITOR} program where you can partition your hard drive.\nYou should make a swap partition and as many data partitions as you will need.\nNOTE:\n${PARTITIONEDITOR} may tell you to reboot after creating partitions.\nIf you need to reboot, just re-enter this install program, skip this step and go on to the next step." 0 0 86 | # switch STDOUT and STDERR 87 | sync 88 | # Partition disc 89 | "${PARTITIONEDITOR}" "${DISC}" 2>&1 > /dev/tty 90 | RET=$? 91 | sync 92 | if [ "${RET}" -ne 0 ]; then 93 | echo "Partition editor ${PARTITIONEDITOR} failed" 1>&2 94 | exit "${RET}" 95 | else 96 | show_dialog --msgbox "Partition editor ${PARTITIONEDITOR} exited successfully" 0 0 97 | exit 0 98 | fi 99 | -------------------------------------------------------------------------------- /share/pentoo-installer/pentoo-installer: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # pentoo-installer 6 | # main menu for the installation 7 | # sub scripts should write only results to STDOUT 8 | # menus and noise go to STDERR 9 | # params: none 10 | # 11 | # returns 0 on success 12 | # returns $ERROR_CANCEL=64 on user cancel 13 | # anything else is a real error 14 | # reason: show_dialog() needs a way to exit "Cancel" 15 | # 16 | 17 | # This introspects the location of this script (pentoo-installer) in relation to 18 | # the structure of this repository and then builds a deterministic path to its 19 | # base location. 20 | # 21 | # It should be noted that both "dirname" and "realname" may encounter issues 22 | # when the installer is called with a path containing spaces in the event that 23 | # instances of ${SHAREDIR} are not properly quoted. This combination of both 24 | # "dirname" and "realpath" should prove more robust to nuances with the 25 | # strucutres of paths in the future. 26 | readonly SHAREDIR="$(dirname "$(realpath -s "$0")")" 27 | 28 | # source common variables, functions and error handling 29 | # also get functions to save settings 30 | source "${SHAREDIR}"/save_settings.sh || exit $? 31 | 32 | if [ -d /sys/firmware/efi ];then 33 | if ! mountpoint -q -- /sys/firmware/efi/efivars ; then 34 | if [ "$(uname -m)" = "i686" ] && [ -r "/sys/firmware/efi/fw_platform_size" ] && [ "$(cat /sys/firmware/efi/fw_platform_size)" = "64" ]; then 35 | show_dialog --msgbox "STOP NOW. You are installing 32 bit on a 64 bit system. Not only do you not want to do that, but you will not have control over any efivars which makes booting...interesting. What you want to do is install the amd64 verson of pentoo. At worst you want to reboot and boot non-uefi to install in legacy mode. You really really really don't want to continue." 0 0 36 | else 37 | show_dialog --msgbox "Something is wrong with your system and we are unable to mount efivars. Please report this issue. You like don't want to continue trying to install without active support." 0 0 38 | fi 39 | fi 40 | fi 41 | 42 | checkvm() { 43 | vm="" 44 | vm_from="" 45 | if [ -d /sys/bus/pci ] || [ -d /sys/bus/pci_express ] || [ -d /proc/bus/pci ]; then 46 | PCI_DEVICES=0 47 | if [ -d /sys/bus/pci/devices ] && [ "$(ls -1 /sys/bus/pci/devices 2>/dev/null | wc -l)" != '0' ]; then 48 | PCI_DEVICES=1 49 | elif [ -r /proc/bus/pci/devices ] && [ -n "$(cat /proc/bus/pci/devices 2>/dev/null)" ]; then 50 | PCI_DEVICES=1 51 | elif [ -d /sys/bus/pci_express/devices ] && [ "$(ls -1 /sys/bus/pci_express/devices 2>/dev/null | wc -l)" != '0' ]; then 52 | PCI_DEVICES=1 53 | fi 54 | if [ ${PCI_DEVICES} -eq 0 ]; then 55 | LSPCI=0 56 | elif [ ! -x "$(command -v lspci 2>&1)" ]; then 57 | printf "Please install lspci from your distro's package manager.\n" 58 | exit 1 59 | else 60 | LSPCI=1 61 | fi 62 | else 63 | LSPCI=0 64 | fi 65 | 66 | #this entire section of code is completely stolen from Carlos Perez's work in checkvm.rb for metasploit and rewritten (poorly) in sh 67 | #check loaded modules 68 | if [ -x "$(command -v lsmod 2>&1)" ]; then 69 | lsmod_data="$(lsmod 2>&1 | awk '{print $1}')" 70 | if [ -n "${lsmod_data}" ]; then 71 | printf "${lsmod_data}" | grep -iqE "vboxsf|vboxguest" 2> /dev/null && vm="VirtualBox" 72 | printf "${lsmod_data}" | grep -iqE "vmw_ballon|vmxnet|vmw" 2> /dev/null && vm="VMware" 73 | printf "${lsmod_data}" | grep -iqE "xen-vbd|xen-vnif" 2> /dev/null && vm="Xen" 74 | printf "${lsmod_data}" | grep -iqE "virtio_pci|virtio_net" 2> /dev/null && vm="Qemu/KVM" 75 | printf "${lsmod_data}" | grep -iqE "hv_vmbus|hv_blkvsc|hv_netvsc|hv_utils|hv_storvsc" && vm="MS Hyper-V" 76 | [ -n "${vm}" ] && vm_from="lsmod" 77 | fi 78 | fi 79 | 80 | #check scsi driver 81 | if [ -z "${vm_from}" ]; then 82 | if [ -r /proc/scsi/scsi ]; then 83 | grep -iq "vmware" /proc/scsi/scsi 2> /dev/null && vm="VMware" 84 | grep -iq "vbox" /proc/scsi/scsi 2> /dev/null && vm="VirtualBox" 85 | [ -n "${vm}" ] && vm_from="/pro/scsi/scsi" 86 | fi 87 | fi 88 | 89 | # Check IDE Devices 90 | if [ -z "${vm_from}" ]; then 91 | if [ -d /proc/ide ]; then 92 | ide_model="$(cat /proc/ide/hd*/model)" 93 | printf "${ide_model}" | grep -iq "vbox" 2> /dev/null && vm="VirtualBox" 94 | printf "${ide_model}" | grep -iq "vmware" 2> /dev/null && vm="VMware" 95 | printf "${ide_model}" | grep -iq "qemu" 2> /dev/null && vm="Qemu/KVM" 96 | printf "${ide_model}" | grep -iqE "virtual (hd|cd)" 2> /dev/null && vm="Hyper-V/Virtual PC" 97 | [ -n "${vm}" ] && vm_from="ide_model" 98 | fi 99 | fi 100 | 101 | # Check using lspci 102 | if [ -z "${vm_from}" ] && [ "${LSPCI}" = "1" ]; then 103 | lspci_data="$(lspci 2>&1)" 104 | printf "${lspci_data}" | grep -iq "vmware" 2> /dev/null && vm="VMware" 105 | printf "${lspci_data}" | grep -iq "virtualbox" 2> /dev/null && vm="VirtualBox" 106 | [ -n "${vm}" ] && vm_from="lspci" 107 | fi 108 | 109 | # Xen bus check 110 | ## XXX: Removing unsafe check 111 | # this check triggers if CONFIG_XEN_PRIVILEGED_GUEST=y et al are set in kconfig (debian default) even in not actually a guest 112 | #if [ -z ${vm} ] 113 | #then 114 | # ls -1 /sys/bus | grep -iq "xen" 2> /dev/null && vm="Xen" 115 | # vm_from="/sys/bus/xen" 116 | #fi 117 | 118 | # Check using lscpu 119 | if [ -z "${vm_from}" ]; then 120 | if [ -x "$(command -v lscpu 2>&1)" ]; then 121 | lscpu_data="$(lscpu 2>&1)" 122 | printf "${lscpu_data}" | grep -iq "Xen" 2> /dev/null && vm="Xen" 123 | printf "${lscpu_data}" | grep -iq "KVM" 2> /dev/null && vm="KVM" 124 | printf "${lscpu_data}" | grep -iq "Microsoft" 2> /dev/null && vm="MS Hyper-V" 125 | [ -n "${vm}" ] && vm_from="lscpu" 126 | fi 127 | fi 128 | 129 | #Check vmnet 130 | if [ -z "${vm_from}" ]; then 131 | if [ -e /dev/vmnet ]; then 132 | vm="VMware" 133 | vm_from="/dev/vmnet" 134 | fi 135 | fi 136 | 137 | #Check dmi info 138 | if [ -z "${vm_from}" ]; then 139 | if [ -x "$(command -v dmidecode 2>&1)" ]; then 140 | dmidecode 2>&1 | grep -iq "microsoft corporation" 2> /dev/null && vm="MS Hyper-V" 141 | dmidecode 2>&1 | grep -iq "vmware" 2> /dev/null && vm="VMware" 142 | dmidecode 2>&1 | grep -iq "virtualbox" 2> /dev/null && vm="VirtualBox" 143 | dmidecode 2>&1 | grep -iq "qemu" 2> /dev/null && vm="Qemu/KVM" 144 | dmidecode 2>&1 | grep -iq "domu" 2> /dev/null && vm="Xen" 145 | [ -n "${vm}" ] && vm_from="dmi_info" 146 | fi 147 | fi 148 | 149 | # Check dmesg Output 150 | if [ -z "${vm_from}" ]; then 151 | if [ -x "$(command -v dmesg 2>&1)" ]; then 152 | dmesg | grep -iqE "vboxbios|vboxcput|vboxfacp|vboxxsdt|(vbox cd-rom)|(vbox harddisk)" && vm="VirtualBox" 153 | dmesg | grep -iqE "(vmware virtual ide)|(vmware pvscsi)|(vmware virtual platform)" && vm="VMware" 154 | dmesg | grep -iqE "(xen_mem)|(xen-vbd)" && vm="Xen" 155 | dmesg | grep -iqE "(qemu virtual cpu version)" && vm="Qemu/KVM" 156 | [ -n "${vm}" ] && vm_from="dmesg" 157 | fi 158 | fi 159 | 160 | export vm 161 | export vm_from 162 | } 163 | 164 | ##################### 165 | ## begin execution ## 166 | 167 | # INSTALLER_HEADLESS: emtpy=false 168 | export INSTALLER_HEADLESS= 169 | export INSTALLER_CONFIGFILE= 170 | 171 | # check passed arguments 172 | while [[ $# -gt 0 ]]; do 173 | # these options require params 174 | case "${1}" in 175 | --config-file) 176 | if [ $# -lt 2 ] || [ "${2:0:2}" == '--' ]; then 177 | show_dialog --msgbox "ERROR: Option '${1}' requires a parameter. Aborting with error." 0 0 178 | exit 1 179 | fi 180 | esac 181 | # process arguments 182 | case "${1}" in 183 | --headless) 184 | export INSTALLER_HEADLESS=1 185 | shift ;; 186 | --config-file) 187 | export INSTALLER_CONFIGFILE="${2}" 188 | shift; shift ;; 189 | *) # unknown option 190 | show_dialog --msgbox "ERROR: Unknown option '${1}'. Aborting with error." 0 0 191 | exit 1 192 | ;; 193 | esac 194 | done 195 | 196 | # display welcome txt depending on used dialog 197 | WHICHDIALOG="$(get_dialog)" 198 | 199 | if [ "$(equery --quiet list pentoo/pentoo-installer 2> /dev/null)" = "pentoo/pentoo-installer-99999999" ]; then 200 | 201 | # check if the installer has been updated and warn the user they may wish to do so 202 | if ! grep -q "completed emerge (.*) pentoo/pentoo-installer-99999999" /var/log/emerge.log; then 203 | UPDATE_WARNING="true" 204 | else 205 | updated_at=$(grep "completed emerge (.*) pentoo/pentoo-installer-99999999" /var/log/emerge.log | tail -n1 | awk -F: '{print $1}') 206 | current=$(date +%s) 207 | delta=$((${current} - ${updated_at})) 208 | if [ ${delta} -ge 86400 ]; then 209 | UPDATE_WARNING="true" 210 | else 211 | UPDATE_WARNING="false" 212 | fi 213 | fi 214 | 215 | if [ "${UPDATE_WARNING}" = "true" ]; then 216 | UPDATE_NOW="$(show_dialog \ 217 | --menu "pentoo-installer gets constant updates to improve experience and fix bugs, would you like to update now?" \ 218 | 0 0 0 \ 219 | 'Yes' 'I would like to exit and update pentoo-installer to get the latest fixes' \ 220 | 'No' 'Why bother to get the latest fixes? I am elite enough to fix it.')" 221 | if [ "${UPDATE_NOW}" = "Yes" ]; then 222 | show_dialog --msgbox "Please ensure you have an internet connection then press OK to update pentoo-installer.\nYou will need to rerun pentoo-installer after it is updated." 8 50 223 | show_dialog --infobox "Updating pentoo-installer..." 3 35 224 | mkdir -p /etc/portage/profile/package.accept_keywords || exit $? 225 | echo "pentoo/pentoo-installer **" >> /etc/portage/profile/package.accept_keywords/pentoo-installer || exit $? 226 | exec /bin/bash -c 'emerge -1 pentoo-installer; rm /etc/portage/profile/package.accept_keywords/pentoo-installer' 227 | exit 1 228 | fi 229 | fi 230 | fi 231 | 232 | show_dialog --exit-label " Continue " --textbox "${SHAREDIR}/welcome.${WHICHDIALOG}.txt" 0 0 || exit $? 233 | #try to maximize, this will quietly do nothing in console mode 234 | wmctrl -r :ACTIVE: -b add,maximized_vert,maximized_horz 235 | 236 | RAMSIZE=$(awk '/MemTotal/ {printf( "%.0f\n", int ( $2 / 1024 ) + 1)}' /proc/meminfo) 237 | export RAMSIZE 238 | if [ "${RAMSIZE}" -le "1500" ]; then 239 | checkvm 240 | if [ -n "${vm}" ]; then 241 | show_dialog --msgbox "WARNING: You appear to be running Pentoo in a VM with almost no RAM. Performance will suffer and so will you. Please give your VM an appropriate amount of RAM for $(date +%Y). If you continue, the install speed will be greatly reduced due to the low RAM limit." 0 0 242 | else 243 | show_dialog --msgbox "WARNING: the install speed will be reduced due to the low system RAM." 0 0 244 | fi 245 | fi 246 | 247 | # check if this boot was verified and warn the user to verify the checksums if not 248 | if ! grep -q verify /proc/cmdline; then 249 | sleep 1 250 | show_dialog --infobox "Integrity was not verified at boot, verification will happen now" 0 0 251 | sleep 3 252 | pushd /mnt/cdrom || exit 1 253 | if ! b2sum -c isoroot_b2sums; then 254 | show_dialog --msgbox "Integrity check failed, exiting installer." 0 0 255 | exit 1 256 | fi 257 | popd || exit 1 258 | fi 259 | 260 | # 'controller' vars 261 | # CONFIG_LIST: One string with 0 or more items of defined FSspec: 262 | CONFIG_LIST= 263 | MAXSELECTION=0 264 | SELECTION=0 265 | 266 | # other vars 267 | NEWSELECTION= 268 | RETSUB= 269 | MENU_ITEMS= 270 | 271 | # check for settings from previous installation attempt 272 | if settings_check; then 273 | # ask if old settings should be loaded 274 | NEWSELECTION="$(show_dialog \ 275 | --menu "Settings from previously aborted installation detected.\nDo you want to load them?" \ 276 | 0 0 0 \ 277 | 'No' 'Start from scratch' \ 278 | 'Yes' 'Load settings (you might have to enter passwords)')" 279 | RETSUB=$? 280 | if [ "${RETSUB}" -eq 0 ] && [ "${NEWSELECTION}" = 'Yes' ]; then 281 | # extra check, pass menu-index of 'Prepare hard drive' 282 | if ! settings_checkmount 1; then 283 | show_dialog --msgbox "ERROR: Unable to load old settings." 0 0 284 | # settings_shred || exit $? 285 | # load 'controller' vars' 286 | else 287 | SELECTION="$(settings_read 1)" || exit $? 288 | MAXSELECTION="$(settings_read 2)" || exit $? 289 | CONFIG_LIST="$(settings_read 3)" || exit $? 290 | fi 291 | # else 292 | # remove old files 293 | # settings_shred || exit $? 294 | fi 295 | fi 296 | 297 | #set pinentry just in case user wants to encrypt 298 | if ! eselect pinentry set pinentry-gnome3; then 299 | if ! eselect pinentry set pinentry-curses; then 300 | show_dialog --msgbox "Unable to eselect pinentry, probably permissions errors. Quitting." 0 0 301 | exit $? 302 | fi 303 | fi 304 | 305 | while [ true ]; do 306 | # define menu items 307 | MENU_ITEMS=() 308 | # enable only valid menu items 309 | # 0 - Set Clock 310 | [ "${MAXSELECTION}" -le 1 ] && MENU_ITEMS+=('0') || MENU_ITEMS+=('') 311 | MENU_ITEMS+=("Set Clock") 312 | # 1 - Prepare Hard Drive 313 | [ "${MAXSELECTION}" -eq 1 ] && MENU_ITEMS+=('1') || MENU_ITEMS+=('') 314 | MENU_ITEMS+=("Prepare Hard Drive") 315 | # 2 - Copy the Distribution 316 | [ "${MAXSELECTION}" -eq 2 ] && MENU_ITEMS+=('2') || MENU_ITEMS+=('') 317 | MENU_ITEMS+=("Copy the Distribution") 318 | # 3 - Select Profile 319 | [ "${MAXSELECTION}" -ge 3 -a "${MAXSELECTION}" -le 5 ] && MENU_ITEMS+=('3') || MENU_ITEMS+=('') 320 | MENU_ITEMS+=("Select Profile") 321 | # 4 - Configure System 322 | [ "${MAXSELECTION}" -ge 4 -a "${MAXSELECTION}" -le 5 ] && MENU_ITEMS+=('4') || MENU_ITEMS+=('') 323 | MENU_ITEMS+=("Configure System") 324 | # 5 - Install Bootloader 325 | [ "${MAXSELECTION}" -eq 5 ] && MENU_ITEMS+=('5') || MENU_ITEMS+=('') 326 | MENU_ITEMS+=("Install Bootloader") 327 | # 6 - Exit Install 328 | [ "${MAXSELECTION}" -eq 6 ] && MENU_ITEMS+=('6') || MENU_ITEMS+=('') 329 | MENU_ITEMS+=("Exit Install") 330 | # expand menu items array below 331 | NEWSELECTION="$(show_dialog --default-item "${SELECTION}" \ 332 | --menu "Use the UP and DOWN arrows to navigate menus. Use TAB to switch between buttons and ENTER to select." \ 333 | 0 0 0 "${MENU_ITEMS[@]}")" 334 | RETSUB=$? 335 | if [ "${RETSUB}" -ne "0" ]; then 336 | show_dialog --yesno "Abort installation?" 0 0 && exit "${RETSUB}" 337 | fi 338 | # call subscript by selected item 339 | case "${NEWSELECTION}" in 340 | "0") 341 | "${SHAREDIR}"/settzclock 342 | RETSUB=$? 343 | ;; 344 | "1") 345 | # prepares (encrypted) partitions and returns a list of partition configs 346 | CONFIG_LIST="$("${SHAREDIR}"/partition_mainmenu)" 347 | RETSUB=$? 348 | ;; 349 | "2") 350 | "${SHAREDIR}"/copy_distro "${CONFIG_LIST}" 351 | RETSUB=$? 352 | ;; 353 | "3") 354 | "${SHAREDIR}"/setprofile "${CONFIG_LIST}" 355 | RETSUB=$? 356 | ;; 357 | "4") 358 | "${SHAREDIR}"/configure_system "${CONFIG_LIST}" 359 | RETSUB=$? 360 | ;; 361 | "5") 362 | "${SHAREDIR}"/bootloader_mainmenu "${CONFIG_LIST}" 363 | RETSUB=$? 364 | ;; 365 | "6") 366 | # umount all again and close cryptsetup 367 | "${SHAREDIR}"/FSspec umountall "${CONFIG_LIST}" 368 | RETSUB=$? 369 | # shred temp config file, it might contain encryption keys 370 | settings_shred 371 | if [ "${RETSUB}" -eq 0 ]; then 372 | echo "" 373 | echo "If the install finished successfully, you can now type 'reboot'" 374 | echo "to restart the system." 375 | echo "" 376 | exit 0 377 | fi 378 | ;; 379 | # disabled but displayed options 380 | '') 381 | continue 382 | ;; 383 | *) 384 | echo "ERROR: Unexpected response '${NEWSELECTION}' in $(basename $0)" 1>&2 385 | exit 1 386 | ;; 387 | esac 388 | # handle errors from sub-script/functions using a common utility function 389 | if ! catch_menuerror "$(basename $0)" "${NEWSELECTION}" "${RETSUB}"; then 390 | # everything ok, increase selection for next menu item 391 | SELECTION="$((NEWSELECTION+1))" || exit $? 392 | if [ "${MAXSELECTION}" -lt "${SELECTION}" ]; then 393 | MAXSELECTION="${SELECTION}" 394 | fi 395 | # write settings to temp file 396 | settings_write "${SELECTION}" "${MAXSELECTION}" "${CONFIG_LIST}" || exit $? 397 | fi 398 | done 399 | -------------------------------------------------------------------------------- /share/pentoo-installer/rsync.awk: -------------------------------------------------------------------------------- 1 | { 2 | if (index($0, "to-check=") > 0) 3 | { 4 | split($0, pieces, "to-check=") 5 | split(pieces[2], term, ")"); 6 | split(term[1], division, "/"); 7 | print (1-(division[1]/division[2]))*100 8 | } 9 | # else 10 | # { 11 | # print "#"$0; 12 | # } 13 | fflush(); 14 | } 15 | -------------------------------------------------------------------------------- /share/pentoo-installer/save_settings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # to be sourced by other scripts 6 | 7 | ############################## 8 | ## START: define constants ## 9 | # tmp file used to backup settings of main menu 10 | readonly SETTINGS_FILE='/tmp/.pentoo-installer' 11 | # non-tmp file used to backup settings of main menu 12 | readonly SETTINGS_FILE_PERMANENT='~/.pentoo-installer' 13 | ## END: define constants ## 14 | ############################ 15 | 16 | # source common variables, functions and error handling 17 | source "${SHAREDIR}"/common.sh || exit $? 18 | 19 | ############################## 20 | ## START: utility functions ## 21 | 22 | # settings_check() 23 | # checks for valid settings file 24 | # 25 | # parameters (none) 26 | # 27 | # returns 0 when a valid settings file is present 28 | # 29 | settings_check(){ 30 | # check input 31 | check_num_args "${FUNCNAME}" 0 $# || return $? 32 | # look for permanent file 33 | if [ -f "${SETTINGS_FILE_PERMANENT}" ]; then 34 | # use only if tmp file not present 35 | if [ ! -f "${SETTINGS_FILE}" ]; then 36 | cp "${SETTINGS_FILE_PERMANENT}" "${SETTINGS_FILE}" || return $? 37 | fi 38 | # delete permantent file 39 | shred -u "${SETTINGS_FILE_PERMANENT}" || return $? 40 | fi 41 | if [ -f "${SETTINGS_FILE}" ]; then 42 | if [ "$(cat "${SETTINGS_FILE}" | wc -l)" -eq 3 ]; then 43 | return 0 44 | fi 45 | # shred wrong files 46 | # shred -u "${SETTINGS_FILE}" || return $? 47 | fi 48 | return 1 49 | } 50 | 51 | # settings_checkmount() 52 | # checks if all partitions from a settings file can be mounted 53 | # 54 | # parameters (required): 55 | # _MOUNT_SELECTION: value for MAXSELECTION after which partitions should be mounted 56 | # (meaning past "Prepare harddrive") 57 | # 58 | # returns 0 if everything looks ok 59 | # 60 | settings_checkmount(){ 61 | # check input 62 | check_num_args "${FUNCNAME}" 1 $# || return $? 63 | local _MOUNT_SELECTION="${1}" 64 | local _SELECTION= 65 | local _MAXSELECTION= 66 | local _CONFIG_LIST= 67 | # check if partitions should be mounted 68 | # read lines of file 69 | _SELECTION="$(sed -n 1p "${SETTINGS_FILE}")" || return $? 70 | _MAXSELECTION="$(sed -n 2p "${SETTINGS_FILE}")" || return $? 71 | _CONFIG_LIST="$(sed -n 3p "${SETTINGS_FILE}")" || return $? 72 | # check integers 73 | [[ "${_SELECTION}" =~ ^[1-9][0-9]*$ ]] || return 1 74 | [[ "${_MAXSELECTION}" =~ ^[1-9][0-9]*$ ]] || return 1 75 | # check if things should be mounted 76 | if [ "${_MAXSELECTION}" -gt "${_MOUNT_SELECTION}" ]; then 77 | # Try to unmount everything 78 | "${SHAREDIR}"/FSspec umountall "${_CONFIG_LIST}" || return $? 79 | # mount everything, including cryptsetup 80 | "${SHAREDIR}"/FSspec mountall "${_CONFIG_LIST}" || return $? 81 | fi 82 | # looking good 83 | return 0 84 | } 85 | 86 | # settings_read() 87 | # reads values from a settings file and prints to STDOUT 88 | # 89 | # parameters (required): 90 | # _INDEX: line number to read 91 | # 92 | settings_read(){ 93 | # check input 94 | check_num_args "${FUNCNAME}" 1 $# || return $? 95 | sed -n "${1}"p "${SETTINGS_FILE}" || return $? 96 | return 0 97 | } 98 | 99 | # settings_write() 100 | # writes config of main menu to a temp file 101 | # 102 | # parameters (vars from main menu): 103 | # SELECTION 104 | # MAXSELECTION 105 | # CONFIG_LIST 106 | # 107 | # returns 0 on success 108 | # anything else is a real error 109 | # 110 | settings_write(){ 111 | # check input 112 | check_num_args "${FUNCNAME}" 3 $# || return $? 113 | echo "${1}">"${SETTINGS_FILE}" || return $? 114 | echo "${2}">>"${SETTINGS_FILE}" || return $? 115 | echo "${3}">>"${SETTINGS_FILE}" || return $? 116 | return 0 117 | } 118 | 119 | # settings_shred() 120 | # shreds config files 121 | # 122 | # parameters (none) 123 | # 124 | # returns 0 on success 125 | # 126 | settings_shred(){ 127 | # check input 128 | check_num_args "${FUNCNAME}" 0 $# || return $? 129 | if [ -e "${SETTINGS_FILE}" ]; then 130 | shred -u "${SETTINGS_FILE}" || return $? 131 | fi 132 | return 0 133 | } 134 | 135 | ## END: utility functions ## 136 | ############################ 137 | -------------------------------------------------------------------------------- /share/pentoo-installer/setprofile: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # setprofile 6 | # allows to choose a new profile in the DESTDIR env 7 | 8 | # partition_finalise 9 | # Creates filesystem, also with encryption, mounts the partitions 10 | # 11 | # parameters (required) 12 | # CONFIG_LIST: One string items of defined FSspec 13 | # 14 | # returns 0 on success 15 | # returns $ERROR_CANCEL=64 on user cancel 16 | # anything else is a real error 17 | # reason: show_dialog() needs a way to exit "Cancel" 18 | # 19 | # writes menus and noise to STDERR 20 | 21 | # location of other scripts to source 22 | readonly SHAREDIR="$(dirname ${0})" || exit $? 23 | 24 | # source common variables, functions and error handling 25 | source "${SHAREDIR}"/common.sh || exit $? 26 | 27 | ##################### 28 | ## begin execution ## 29 | 30 | # check input 31 | check_num_args "$(basename $0)" 1 $# || exit $? 32 | CONFIG_LIST="${1}" 33 | RET_SUB= 34 | 35 | # mount everything, including cryptsetup 36 | "${SHAREDIR}"/FSspec mountall "${CONFIG_LIST}" || exit $? 37 | 38 | chroot_mount || exit $? 39 | 40 | OPTIONS=() 41 | CUR_PROF_TYPE="" 42 | CUR_PROF_NUM="" 43 | CUR_PROF= 44 | LINE= 45 | 46 | show_dialog --infobox "Checking available profiles..." 3 40 47 | CUR_PROF="$(chroot ${DESTDIR} eselect profile show | grep pentoo | awk '{match($1,"pentoo/.*",a)}END{print a[0]}')" || exit $? 48 | 49 | if [[ -n "$(echo ${CUR_PROF} | grep hardened)" ]]; then 50 | CUR_PROF_TYPE="hardened" 51 | elif [[ -n "$(echo ${CUR_PROF} | grep default)" ]]; then 52 | CUR_PROF_TYPE="default" 53 | else 54 | show_dialog --keep-tite --msgbox "Warning: unable to detect a current Pentoo profile in the ${DESTDIR} directory" 0 0 55 | fi 56 | 57 | while read -r LINE; do 58 | #grab all pentoo profiles 59 | if [[ "${LINE}" == *pentoo* ]]; then 60 | #parse profiles based on the current type 61 | if [ "${CUR_PROF_TYPE}" == "hardened" ]; then 62 | PROF="$(echo "${LINE}" | awk '{match($2,"pentoo/hardened/.*",a)}END{print a[0]}')" || exit $? 63 | elif [ "${CUR_PROF_TYPE}" == "default" ]; then 64 | PROF="$(echo "${LINE}" | awk '{match($2,"pentoo/default/.*",a)}END{print a[0]}')" || exit $? 65 | fi 66 | #skip if the type is not current 67 | if [[ -z "${PROF}" ]]; then 68 | continue 69 | fi 70 | #detect its profile number 71 | PROF_NUM="$(echo "${LINE}" | awk '{match($1,"[0-9]+",a)}END{print a[0]}')" || exit $? 72 | #generate OPTIONS menu 73 | OPTIONS+=("${PROF_NUM}" "${PROF}") || exit $? 74 | #find current profile number 75 | if [[ "${PROF}" == "${CUR_PROF}" ]]; then 76 | CUR_PROF_NUM="${PROF_NUM}" 77 | fi 78 | fi 79 | done < <(chroot "${DESTDIR}" eselect profile list | grep --color=never 'stable') || exit $? 80 | 81 | #check if any Pentoo profiles were found 82 | if [ "${#OPTIONS[@]}" -eq 0 ]; then 83 | show_dialog --keep-tite --msgbox "ERROR: Unable to detect any Pentoo profile in the ${DESTDIR} directory" 0 0 84 | exit 1 85 | fi 86 | 87 | # ask for new profile 88 | NEW_PROF_NUM="$(show_dialog --keep-tite --default-item "${CUR_PROF_NUM}" --menu "Select profile:" 0 0 16 "${OPTIONS[@]}")" || exit $? 89 | 90 | show_dialog --infobox "Setting profile..." 3 30 91 | # set new profile 92 | chroot "${DESTDIR}" eselect profile set "${NEW_PROF_NUM}" || exit $? 93 | 94 | chroot_umount || exit $? 95 | 96 | exit 0 97 | -------------------------------------------------------------------------------- /share/pentoo-installer/settzclock: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # settzclock 6 | # prompts user to set hardware clock and timezone 7 | # sets hwclock, timezone and system time 8 | # params: none 9 | 10 | # writes 3 lines to STDOUT 11 | # Example: 12 | # hwclock=[UTC|localtime] 13 | # timezone=Europe/Zurich 14 | # date=2014-11-27 14:23:46 CET 15 | 16 | # writes menus and noise to STDERR 17 | 18 | # returns 0 on success 19 | # returns $ERROR_CANCEL=64 on user cancel 20 | # anything else is a real error 21 | # reason: show_dialog() needs a way to exit "Cancel" 22 | 23 | # location of other scripts to source 24 | readonly SHAREDIR="$(dirname "${0}")" || exit $? 25 | 26 | # source common variables, functions and error handling 27 | source "${SHAREDIR}"/common.sh || exit $? 28 | 29 | HWCLOCK_DEFAULT=utc 30 | TIMEZONE_DEFAULT= 31 | if [ -n "${INSTALLER_CONFIGFILE}" ]; then 32 | # remove comments 33 | CONF_FULL="$(jq 'del(..|.["#"]?)' "${INSTALLER_CONFIGFILE}")" || exit $? 34 | # check if hwclock is set 35 | if echo "${CONF_FULL}" | jq -e ".hwclock" 1>/dev/null; then 36 | HWCLOCK_DEFAULT="$(echo "${CONF_FULL}" | jq -re ".hwclock")" || exit $? 37 | fi 38 | # check if timezone is set 39 | if echo "${CONF_FULL}" | jq -e ".timezone" 1>/dev/null; then 40 | TIMEZONE_DEFAULT="$(echo "${CONF_FULL}" | jq -re ".timezone")" || exit $? 41 | fi 42 | fi 43 | # utc or local? 44 | HARDWARECLOCK="$(show_dialog --default-item "${HWCLOCK_DEFAULT}" --menu "Is your hardware clock in UTC or time?" 0 0 2 \ 45 | "utc" "UTC time" \ 46 | "localtime" "local time")" \ 47 | || exit $? 48 | 49 | # write to STDERR 50 | echo "setting hwclock to: ${HARDWARECLOCK}" 1>&2 51 | /sbin/hwclock --hctosys --"${HARDWARECLOCK}" --noadjfile || exit $? 52 | # this will be copied to chroot later 53 | sed -Ei 's#^clock="[^"]*"$#clock="'"${HARDWARECLOCK:0:5}"'"#' /etc/conf.d/hwclock || exit $? 54 | 55 | # timezone? 56 | if [ -n "${TIMEZONE_DEFAULT}" ]; then 57 | echo "Overriding timezone with value from config file!" 1>&2 58 | TIMEZONE="${TIMEZONE_DEFAULT}" 59 | else 60 | clear 61 | TIMEZONE="$(tzselect 2>&3)" || exit $? 62 | fi 63 | 64 | # this will be copied to chroot later 65 | if [ "${TIMEZONE}" != "" ] && [ -e "/usr/share/zoneinfo/${TIMEZONE}" ]; then 66 | echo "setting timezone to: ${TIMEZONE}" 1>&2 67 | echo "${TIMEZONE}" > /etc/timezone 68 | emerge --config sys-libs/timezone-data || exit $? 69 | else 70 | printf "${TIMEZONE} doesn't seem to be valid, aborting.\n" 71 | exit 1 72 | fi 73 | 74 | # display and ask to set date/time 75 | DATE="$(show_dialog --calendar "Set the date.\nUse to navigate and arrow keys to change values." 0 0 0 0 0)" || exit $? 76 | TIME="$(show_dialog --timebox "Set the time.\nUse to navigate and up/down to change values." 0 0)" || exit $? 77 | 78 | # save the time 79 | # DD/MM/YYYY hh:mm:ss -> YYYY-MM-DD hh:mm:ss 80 | DATETIME="$(echo "${DATE}" "${TIME}" | sed 's#\(..\)/\(..\)/\(....\) \(..\):\(..\):\(..\)#\3-\2-\1 \4:\5:\6#g')" || exit $? 81 | 82 | echo "setting date to: ${DATETIME}" 1>&2 83 | 84 | # write to STDOUT, might be useful 85 | echo "hwclock=${HARDWARECLOCK}" 86 | echo "timezone=${TIMEZONE}" 87 | 88 | # date writes to STDOUT 89 | echo -n "date=" 90 | date -s "${DATETIME}" +'%F %T %Z' || exit $? 91 | /sbin/hwclock --systohc --"${HARDWARECLOCK}" --noadjfile 1>&2 || exit $? 92 | -------------------------------------------------------------------------------- /share/pentoo-installer/template_menu: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | # Check the COPYING file included with this distribution 4 | 5 | # template for menus which call sub-scripts 6 | 7 | # location of other scripts to source 8 | readonly SHAREDIR="$(dirname ${0})" || exit $? 9 | 10 | # source common variables, functions and error handling 11 | source "${SHAREDIR}"/common.sh || exit $? 12 | 13 | ##################### 14 | ## begin execution ## 15 | 16 | NEWSELECTION= 17 | SELECTION='0' 18 | RETSUB= 19 | 20 | while true; do 21 | 22 | NEWSELECTION="$(show_dialog --default-item "${SELECTION}" \ 23 | --menu "Some text" \ 24 | 0 0 0 "${MENU_ITEMS[@]}")" || exit $? 25 | 26 | # Alternative to direct exit 27 | # 28 | # NEWSELECTION="$(show_dialog --default-item "${SELECTION}" \ 29 | # --menu "Some text" \ 30 | # 0 0 0 "${_MENU_ITEMS[@]}")" || exit $? 31 | # RETSUB=$? 32 | # if [ "${RETSUB}" -ne "0" ]; then 33 | # show_dialog --yesno "Abort ....?" 6 40 && exit "${RETSUB}" 34 | # fi 35 | 36 | # call subscript by selected item 37 | case "${NEWSELECTION}" in 38 | '0') 39 | # call sub script/function 40 | subscript 41 | RETSUB=$? 42 | ;; 43 | 'DONE') 44 | # end this, if needed print some result to STDOUT now 45 | exit 0 46 | ;; 47 | *) 48 | echo "ERROR: Unexpected response '${NEWSELECTION}' in $(basename $0)" 1>&2 49 | exit 1 50 | ;; 51 | esac 52 | 53 | # handle errors from sub-script/functions using a common utility function 54 | if ! catch_menuerror "$(basename $0)" "${NEWSELECTION}" "${RETSUB}"; then 55 | # no error in sub-script 56 | # do something, for example: increment selected item 57 | SELECTION="$((NEWSELECTION+1))" || exit $? 58 | # or SELECTION="DONE" || exit $? 59 | fi 60 | 61 | done 62 | -------------------------------------------------------------------------------- /share/pentoo-installer/tzselect_dialog: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # This script is released under the GNU General Public License 3.0 3 | 4 | # sample dialog handler for tzselect 5 | # MUST have same input/output as the showdialog() function in tzselect 6 | 7 | # showdialog() 8 | # All normal user input/output goes through this function 9 | # 10 | # The user dialog of this script can be altered by setting 11 | # the SHOWDIALOG variable as in: 12 | # SHOWDIALOG=$PWD/tzselect_dialog tzselect 13 | # where 'tzselect_dialog' imitates this function 14 | # 15 | # Arguments: 16 | # Type: one of: menu, yesno, msgbox, inputbox 17 | # Message: text to display 18 | # Options: menu-options, only for types menu and yesno 19 | 20 | # location of other scripts to source 21 | readonly SHAREDIR="$(dirname ${0})" || exit $? 22 | 23 | # source common variables, functions and error handling 24 | source "${SHAREDIR}"/common.sh || exit $? 25 | 26 | # get type and message first 27 | TYPE="${1}" 28 | shift 29 | MSG="${1}" 30 | # hotfix message, do not print date/time 31 | MSG="$(echo -n "${MSG}" | grep -v '[tT]ime is now:[[:blank:]]')" || exit $? 32 | shift 33 | MENU_ITEMS=(0 0) 34 | RET_DIALOG= 35 | 36 | case "${TYPE}" in 37 | # prepare arguments to dialog/Xdialog --menu 38 | menu) 39 | # add menu-height: auto 40 | MENU_ITEMS+=(0) 41 | # add value and description 42 | while [ $# -gt 0 ]; do 43 | MENU_ITEMS+=("$(( ( ${#MENU_ITEMS[@]} -1 ) / 2 ))" "${1}") 44 | shift 45 | done ;; 46 | esac 47 | 48 | # use dialog/Xdialog 49 | ANSWER=$(show_dialog \ 50 | --no-cancel \ 51 | "--${TYPE}" \ 52 | "${MSG}" \ 53 | "${MENU_ITEMS[@]}") 54 | RET_DIALOG=$? 55 | 56 | # exit on cancel unless it's a yesno 57 | [ "${TYPE}" != 'yesno' ] && [ "${RET_DIALOG}" -ne 0 ] && exit "${RET_DIALOG}" 58 | 59 | case "${TYPE}" in 60 | yesno) 61 | if [ "${RET_DIALOG}" -eq 0 ]; then 62 | ANSWER=$([ -n "${1}" ] && echo -n "${1}" || echo -n Yes) 63 | else 64 | ANSWER=$([ -n "${2}" ] && echo -n "${2}" || echo -n No) 65 | fi ;; 66 | # get string from index 67 | menu) 68 | ANSWER="${MENU_ITEMS[(($ANSWER * 2 + 2))]}" || exit $? ;; 69 | esac 70 | # print result 71 | echo -n "${ANSWER}" 72 | exit 0 73 | -------------------------------------------------------------------------------- /share/pentoo-installer/welcome.Xdialog.txt: -------------------------------------------------------------------------------- 1 | Welcome to the Pentoo Installation program 2 | 3 | The install process is fairly straightforward, and you should run 4 | through the options in the order they are presented. If you are 5 | unfamiliar with partitioning/making filesystems, you may want to 6 | consult some documentation before continuing. 7 | 8 | You can view all output from commands by checking the logs: 9 | /tmp/pentoo-installer.log <- main pentoo-installer log file 10 | /tmp/pentoo-installer-callbacks.log <- log from some external 11 | -------------------------------------------------------------------------------- /share/pentoo-installer/welcome.dialog.txt: -------------------------------------------------------------------------------- 1 | . 2 | d$b 3 | .d$$$$$$b. .cd$$b. .d$$b. d$$$$$$$$$$$b .d$$b. .d$$b. 4 | .$$$$$$$$$$ d$$$'`$$$. d$$$$$$$b Q$$$$$$$P$$$P.$$$$$$$b. .$$$$$$$b. 5 | $$$$( )$$$d$$$$bd$$P" d$$$PQ$$$$b. $$$$. .$$$P' `$$$ .$$$P' `$$$ 6 | .$$$$$$$$$$P Q$$$$$$$b d$$$P Q$$$$b $$$$b $$$$b..d$$$ $$$$b..d$$$ 7 | d$$$$$$$$$P' "$$$$$$$$ Q$$$ Q$$$$ $$$$$ `Q$$$$$$$P `Q$$$$$$$P 8 | .$$$$P' `""""" "" "" Q$$$P "Q$$$P" "Q$$$P" 9 | d$Q$$' """ 10 | "Q$$P 11 | Welcome to the Pentoo Installation program 12 | 13 | The install process is fairly straightforward, and you should run 14 | through the options in the order they are presented. If you are 15 | unfamiliar with partitioning/making filesystems, you may want to 16 | consult some documentation before continuing. 17 | 18 | You can view all output from commands by checking the logs: 19 | /tmp/pentoo-installer.log <- main pentoo-installer log file 20 | /tmp/pentoo-installer-callbacks.log <- log from some external 21 | --------------------------------------------------------------------------------