#!/bin/bash # shellcheck disable=SC2010 # ls | grep allowed # shellcheck source=/dev/null # Deactivate SC1090 # shellcheck disable=SC2015 # Deactivate bools hints # shellcheck disable=SC2154 # Deactivate not referenced link # @see https://wiki.polaire.nl/doku.php?id=archlinux-raspberry-encrypted source "$(dirname "$(readlink -f "${0}")")/base.sh" || (echo "Loading base.sh failed." && exit 1) install(){ info "Installing $1..." case "$distribution" in "arch"|"manjaro") echo "pacman --noconfirm -S --needed $1" | chroot "$root_mount_path" /bin/bash || error ;; "moode"|"retropie") echo "yes | apt install $1" | chroot "$root_mount_path" /bin/bash || error ;; *) error "Package manager not supported." ;; esac } replace_in_file() { # Assign the first function argument to the local variable search_string local search_string=$1 # Assign the second function argument to the local variable replace_string local replace_string=$2 # Assign the third function argument to the local variable file_path local file_path=$3 # Create a temporary file and store its path in temp_file temp_file=$(mktemp) # Use sed to replace the search_string with replace_string in the file at file_path # Write the output to the temporary file sed "s/$search_string/$replace_string/g" "$file_path" > "$temp_file" # Compare the original file with the temporary file if cmp -s "$file_path" "$temp_file"; then # If files are identical, remove the temporary file and signal an error rm -f "$temp_file" error "Error: Search string '$search_string' not found in $file_path." else # If files are different, move the temporary file to overwrite the original file mv "$temp_file" "$file_path" fi } info "Setupscript for images started..." info "Checking if root..." if [ "$(id -u)" != "0" ];then error "This script must be executed as root!" fi make_working_folder info "Configure user..." && question "Please type in a valid working username:" && read -r origin_username && getent passwd "$origin_username" > /dev/null 2 || error "User $origin_username doesn't exist." origin_user_home="/home/$origin_username/" info "Image routine starts..." image_folder="$origin_user_home""Software/Images/"; info "The images will be stored in \"$image_folder\"." if [ ! -d "$image_folder" ]; then info "Folder \"$image_folder\" doesn't exist. It will be created now." && mkdir -v "$image_folder" || error fi set_device_path if mount | grep -q "$device_path" then error "Device $device_path is allready mounted. Umount with \"umount $device_path*\"." fi question "Which platform would you like to use [livestick, raspberrypi,...]?" && read -r platform || error question "Which operation system would you like to use [linux,windows,...]?" && read -r operation_system || error case "$operation_system" in "linux") question "Which distribution should be used [arch,moode,retropie,manjaro,torbox...]?" && read -r distribution || error case "$distribution" in "android-x86") base_download_url="https://www.fosshub.com/Android-x86.html?dwl=android-x86_64-9.0-r2.iso"; image_name="android-x86_64-9.0-r2.iso" image_checksum="f7eb8fc56f29ad5432335dc054183acf086c539f3990f0b6e9ff58bd6df4604e" boot_size="+500M" ;; "torbox") base_download_url="https://www.torbox.ch/data/"; image_name="torbox-20220102-v050.gz" image_checksum="0E1BA7FFD14AAAE5F0462C8293D95B62C3BF1D9E726E26977BD04772C55680D3" boot_size="+200M" ;; "arch") question "Which Raspberry Pi will be used (e.g.: 1, 2, 3b, 3b+, 4...):" && read -r raspberry_pi_version boot_size="+500M" base_download_url="http://os.archlinuxarm.org/os/"; case "$raspberry_pi_version" in "1") image_name="ArchLinuxARM-rpi-armv7-latest.tar.gz" luks_memory_cost="64000" ;; "2") image_name="ArchLinuxARM-rpi-armv7-latest.tar.gz" luks_memory_cost="128000" ;; "3b" | "3b+") image_name="ArchLinuxARM-rpi-aarch64-latest.tar.gz" luks_memory_cost="128000" ;; "4" ) image_name="ArchLinuxARM-rpi-aarch64-latest.tar.gz" luks_memory_cost="256000" ;; *) error "Version $raspberry_pi_version isn't supported." ;; esac ;; "manjaro") question "Which version(e.g.:architect,gnome) should be used:" && read -r gnome_version boot_size="+500M" case "$gnome_version" in "architect") image_checksum="6b1c2fce12f244c1e32212767a9d3af2cf8263b2" base_download_url="https://osdn.net/frs/redir.php?m=dotsrc&f=%2Fstorage%2Fg%2Fm%2Fma%2Fmanjaro%2Farchitect%2F20.0%2F"; image_name="manjaro-architect-20.0-200426-linux56.iso" ;; "gnome") question "Which release(e.g.:20,21,raspberrypi) should be used:" && read -r release case "$release" in "20") image_checksum="2df3697908483550d4a473815b08c1377e6b6892" base_download_url="https://osdn.net/projects/manjaro-archive/storage/gnome/20.0/" image_name="manjaro-gnome-20.0-200426-linux56.iso" ;; "21") base_download_url="https://download.manjaro.org/gnome/21.3.7/" image_name="manjaro-gnome-21.3.7-220816-linux515.iso" ;; "22") base_download_url="https://download.manjaro.org/gnome/22.1.3/" image_name="manjaro-gnome-22.1.3-230529-linux61.iso" ;; "raspberrypi") # at the moment just optimized for raspberry pi 4 base_download_url="https://github.com/manjaro-arm/rpi4-images/releases/download/23.02/" image_name="Manjaro-ARM-gnome-rpi4-23.02.img.xz" luks_memory_cost="256000" raspberry_pi_version="4" ;; *) error "Gnome Version $gnome_version isn't supported." ;; esac ;; esac ;; "moode") boot_size="+200M" image_checksum="185cbc9a4994534bb7a4bc2744c78197" base_download_url="https://github.com/moode-player/moode/releases/download/r651prod/" image_name="moode-r651-iso.zip"; ;; "retropie") boot_size="+500M" question "Which version(e.g.:1,2,3,4) should be used:" && read -r raspberry_pi_version base_download_url="https://github.com/RetroPie/RetroPie-Setup/releases/download/4.8/"; case "$raspberry_pi_version" in "1") image_checksum="95a6f84453df36318830de7e8507170e" image_name="retropie-buster-4.8-rpi1_zero.img.gz" ;; "2" | "3") image_checksum="224e64d8820fc64046ba3850f481c87e" image_name="retropie-buster-4.8-rpi2_3_zero2w.img.gz" ;; "4") image_checksum="b5daa6e7660a99c246966f3f09b4014b" image_name="retropie-buster-4.8-rpi4_400.img.gz" ;; esac ;; esac question "Should the system be encrypted?(y/N)" && read -r encrypt_system info "Generating os-image..." download_url="$base_download_url$image_name" image_path="$image_folder$image_name" question "Should the image download be forced?(y/N)" && read -r force_image_download if [ "$force_image_download" = "y" ] then if [ -f "$image_path" ] then info "Removing image $image_path." && rm "$image_path" || error "Removing image \"$image_path\" failed." else info "Forcing download wasn't neccessary. File $image_path doesn't exist." fi fi info "Start Download procedure..." if [ -f "$image_path" ] then info "Image exist local. Download skipped." else info "Image \"$image_name\" doesn't exist under local path \"$image_path\"." && info "Image \"$image_name\" gets downloaded from \"$download_url\"..." && wget "$download_url" -O "$image_path" || error "Download from \"$download_url\" failed." fi ;; *) info "Available images:" ls -l "$image_folder" question "Which image would you like to use?" && read -r image_name || error image_path="$image_folder$image_name" ;; esac info "Verifying image..." info "Verifying checksum..." if [ -z "$image_checksum" ]; then for ext in sha1 sha512 md5; do sha_download_url="$download_url.$ext" info "Image Checksum is not defined. Try to download image signature from $sha_download_url." if wget -q --method=HEAD "$sha_download_url"; then image_checksum="$(wget $sha_download_url -q -O - | cut -d ' ' -f1)" info "Defined image_checksum as $image_checksum" break else warning "No checksum found under $sha_download_url." fi done fi if [[ -v image_checksum ]] then (info "Checking md5 checksum..." && echo "$image_checksum $image_path"| md5sum -c -) || (info "Checking sha1 checksum..." && echo "$image_checksum $image_path"| sha1sum -c -) || (info "Checking sha256 checksum..." && echo "$image_checksum $image_path"| sha256sum -c -) || error "Verification failed. HINT: Force the download of the image." else warning "Verification is not possible. No checksum is defined." fi info "Verifying signature..." signature_download_url="$download_url.sig" info "Try to download image signature from $signature_download_url." if wget -q --method=HEAD "$signature_download_url"; then signature_name="${image_name}.sig" signature_path="${image_folder}${signature_name}" info "Download the signature file" if wget -q -O "$signature_path" "$signature_download_url"; then info "Extract the key ID from the signature file" key_id=$(gpg --status-fd 1 --verify "$signature_path" "$image_path" 2>&1 | grep 'NO_PUBKEY' | awk '{print $NF}') if [ -n "$key_id" ]; then info "Check if the key is already in the keyring" if gpg --list-keys "$key_id" > /dev/null 2>&1; then info "Key $key_id already in keyring." else info "Import the public key" gpg --keyserver keyserver.ubuntu.com --recv-keys "$key_id" fi info "Verify the signature again after importing the key" if gpg --verify "$signature_path" "$image_path"; then info "Signature verification succeeded." else warning "Signature verification failed." fi else warning "No public key found in the signature file." fi else warning "Failed to download the signature file." fi else warning "No signature found under $signature_download_url." fi make_mount_folders set_partition_paths question "Which filesystem should be used? E.g.:btrfs,ext4... (none):" && read -r root_filesystem question "Should the image be transfered to $device_path?(y/N)" && read -r transfer_image if [ "$transfer_image" = "y" ] then question "Should the partition table of $device_path be deleted?(y/N)" && read -r delete_partition_table if [ "$delete_partition_table" = "y" ] then info "Deleting..." && wipefs -a "$device_path" || error else info "Skipping partition table deletion..." fi overwrite_device info "Starting image transfer..." if [ "$distribution" = "arch" ] then # Set default size of the boot partition boot_size=${boot_size:-"+500M"} # Use the provided size or the default size info "The boot partition will be set to $boot_size." # Partitioning with the specified size info "Creating partitions..." && ( echo "o" # Type o. This will clear out any partitions on the drive. echo "p" # Type p to list partitions. There should be no partitions left echo "n" # Type n, echo "p" # then p for primary, echo "1" # 1 for the first partition on the drive, echo "" # Default start sector echo "$boot_size" # Size of the boot partition echo "t" # Type t, echo "c" # then c to set the first partition to type W95 FAT32 (LBA). echo "n" # Type n, echo "p" # then p for primary, echo "2" # 2 for the second partition on the drive, echo "" # Default start sector echo "" # Default end sector echo "w" # Write the partition table and exit by typing w. ) | fdisk "$device_path" || error info "Format boot partition..." && mkfs.vfat "$boot_partition_path" || error if [ "$encrypt_system" == "y" ] then # Check if luks_memory_cost is defined and set the luksAddKey command accordingly # @see https://chatgpt.com/share/008ea5f1-670c-467c-8320-1ca67f25ac9a if [ -n "$luks_memory_cost" ]; then info "Formating $root_partition_path with LUKS with --pbkdf-memory set to $luks_memory_cost" && sudo cryptsetup -v luksFormat -c aes-xts-plain64 -s 512 -h sha512 --use-random -i 1000 --pbkdf-memory "$luks_memory_cost" "$root_partition_path" || error else info "Formating $root_partition_path with LUKS" && sudo cryptsetup -v luksFormat -c aes-xts-plain64 -s 512 -h sha512 --use-random -i 1000 "$root_partition_path" || error fi decrypt_root || error fi info "Format root partition..." && "mkfs.$root_filesystem" -f "$root_mapper_path" || error mount_partitions; info "Root files will be transfered to device..." && bsdtar -xpf "$image_path" -C "$root_mount_path" && sync || error info "Boot files will be transfered to device..." && mv -v "$root_mount_path""boot/"* "$boot_mount_path" || error elif [ "${image_path: -4}" = ".zip" ] then info "Transfering .zip file..." && unzip -p "$image_path" | sudo dd of="$device_path" bs="$OPTIMAL_BLOCKSIZE" conv=fsync status=progress || error "DD $image_path to $device_path failed." && sync || error elif [ "${image_path: -3}" = ".gz" ] then info "Transfering .gz file..." && gunzip -c "$image_path" | sudo dd of="$device_path" bs="$OPTIMAL_BLOCKSIZE" conv=fsync status=progress && sync || error elif [ "${image_path: -4}" = ".iso" ] then info "Transfering .iso file..." && sudo dd if="$image_path" of="$device_path" bs="$OPTIMAL_BLOCKSIZE" conv=fsync status=progress && sync || error elif [ "${image_path: -3}" = ".xz" ] then info "Transferring .xz file..." && unxz -c "$image_path" | sudo dd of="$device_path" bs="$OPTIMAL_BLOCKSIZE" conv=fsync status=progress && sync || error else error "Image transfer for operation system \"$distribution\" is not supported yet!"; fi else info "Skipping image transfer..." fi if [ "$platform" == "raspberrypi" ] then info "Start regular mounting procedure..." if mount | grep -q "$boot_partition_path" then info "$boot_partition_path is allready mounted..." else if mount | grep -q "$root_mapper_path" then info "$root_mapper_path is allready mounted..." else decrypt_root mount_partitions fi fi fstab_path="$root_mount_path""etc/fstab" && fstab_search_string=$(echo "/dev/mmcblk0p1"| sed -e 's/[\/&]/\\&/g') && fstab_replace_string=$(echo "UUID=$boot_partition_uuid"| sed -e 's/[\/&]/\\&/g') && info "Seeding UUID to $fstab_path to avoid path conflicts..." && sed -i "s/$fstab_search_string/$fstab_replace_string/g" "$fstab_path" && info "Content of $fstab_path:$(cat "$fstab_path")" || error info "Define target paths..." && administrator_username="administrator" target_home_path="$root_mount_path""home/" && default_username=$(ls "$target_home_path") && question "Should the $default_username be renamed to $administrator_username? (y/N):" && read -r rename_decision if [ "$rename_decision" == "y" ]; then variable_old_username="$default_username" && target_username="$administrator_username" && info "Rename home directory from $target_home_path$variable_old_username to $target_home_path$target_username..." && mv -v "$target_home_path$variable_old_username" "$target_home_path$target_username" || error "Failed to rename home directory" else target_username="$default_username" fi target_user_home_folder_path="$target_home_path$target_username/" && target_user_ssh_folder_path="$target_user_home_folder_path"".ssh/" && target_authorized_keys="$target_user_ssh_folder_path""authorized_keys" && # Activate later. Here was a bug question "Should the $target_username have sudo rights? (y/N):" && read -r sudo_decision if [ "$sudo_decision" == "y" ]; then sudo_config_dir="$root_mount_path""etc/sudoers.d/" sudo_config_file="$sudo_config_dir$target_username" mkdir -vp $sudo_config_dir echo "$target_username ALL=(ALL:ALL) ALL" > "$sudo_config_file" || error "Failed to create sudoers file for $target_username" chmod 440 "$sudo_config_file" || error "Failed to set permissions on sudoers file for $target_username" fi question "Enter the path to the SSH key to be added to the image (default: none):" && read -r origin_user_rsa_pub || error if [ -z "$origin_user_rsa_pub" ] then info "Skipped SSH-key copying.." else if [ -f "$origin_user_rsa_pub" ] then info "Copy ssh key to target..." mkdir -v "$target_user_ssh_folder_path" || warning "Folder \"$target_user_ssh_folder_path\" exists. Can't be created." cat "$origin_user_rsa_pub" > "$target_authorized_keys" && target_authorized_keys_content=$(cat "$target_authorized_keys") && info "$target_authorized_keys contains the following: $target_authorized_keys_content" && info "Set permissions with chmod..." && chmod -v 700 "$target_user_ssh_folder_path" && chmod -v 600 "$target_authorized_keys" || error "Failed to set ownership and permissions on ssh folder" else error "The ssh key \"$origin_user_rsa_pub\" can't be copied to \"$target_authorized_keys\" because it doesn't exist." fi fi info "Start chroot procedures..." mount_chroot_binds copy_qemu copy_resolve_conf chroot_user_home_path="/home/$target_username/" chroot_user_ssh_folder_path="$chroot_user_home_path.ssh" if [ "$rename_decision" == "y" ]; then info "Delete old user and create new user" && ( echo "userdel -r $variable_old_username" echo "useradd -m -d $chroot_user_home_path -s /bin/bash $target_username" echo "chown -R $target_username:$target_username $chroot_user_home_path" ) | chroot "$root_mount_path" /bin/bash || error "Failed to delete old user and create new user" fi if [ -n "$origin_user_rsa_pub" ] then info "Chroot to set ownership..." && ( echo "chown -vR $target_username:$target_username $chroot_user_ssh_folder_path" ) | chroot "$root_mount_path" /bin/bash || error fi question "Type in new password for user root and $target_username (leave empty to skip): " && read -r password_1 if [ -n "$password_1" ]; then question "Repeat new password for \"$target_username\": " && read -r password_2 if [ "$password_1" = "$password_2" ]; then info "Changing passwords on target system..." ( echo "( echo '$password_1' echo '$password_1' ) | passwd $target_username" echo "( echo '$password_1' echo '$password_1' ) | passwd" ) | chroot "$root_mount_path" /bin/bash || error "Failed to change password." else error "Passwords didn't match." fi else info "No password change requested, skipped password change..." fi hostname_path="$root_mount_path/etc/hostname" question "Type in the hostname (leave empty to skip): " && read -r target_hostname if [ -n "$target_hostname" ]; then echo "$target_hostname" > "$hostname_path" || error "Failed to set hostname." else target_hostname=$(cat "$hostname_path") info "No hostname change requested, skipped hostname change..." fi info "Used hostname is: $target_hostname" case "$distribution" in "arch"|"manjaro") info "Populating keys..." && ( echo "yes | pacman-key --init" echo "yes | pacman-key --populate archlinuxarm" ) | chroot "$root_mount_path" /bin/bash || error ;; esac question "Should the system be updated?(y/N)" && read -r update_system if [ "$update_system" == "y" ] then info "Updating system..." case "$distribution" in "arch"|"manjaro") echo "pacman --noconfirm -Syyu" | chroot "$root_mount_path" /bin/bash || error ;; "moode"|"retropie") ( echo "yes | apt update" echo "yes | apt upgrade" ) | chroot "$root_mount_path" /bin/bash || error ;; *) warning "System update for operation system \"$distribution\" is not supported yet. Skipped." ;; esac fi info "Installing software for filesystem $root_filesystem..." if [ "$root_filesystem" == "btrfs" ] then install "btrfs-progs" else info "Skipped." fi if [ "$encrypt_system" == "y" ] then # Adapted this instruction for setting up encrypted systems # @see https://gist.github.com/gea0/4fc2be0cb7a74d0e7cc4322aed710d38 # @see https://gist.github.com/EnigmaCurry/2f9bed46073da8e38057fe78a61e7994 info "Setup encryption..." && info "Installing neccessary software..." && install "$(get_packages "server/luks")" && dropbear_root_key_path="$root_mount_path""etc/dropbear/root_key" && info "Adding $target_authorized_keys to dropbear..." && cp -v "$target_authorized_keys" "$dropbear_root_key_path" && # Concerning mkinitcpio warning # @see https://gist.github.com/imrvelj/c65cd5ca7f5505a65e59204f5a3f7a6d mkinitcpio_path="$root_mount_path""etc/mkinitcpio.conf" && info "Configuring $mkinitcpio_path..." && mkinitcpio_search_modules="MODULES=()" || error # Concerning which moduls to load # @see https://raspberrypi.stackexchange.com/questions/67051/raspberry-pi-3-with-archarm-and-encrypted-disk-will-not-boot-how-can-be-identif case "$raspberry_pi_version" in "1" | "2") mkinitcpio_additional_modules="" ;; "3b") mkinitcpio_additional_modules="smsc95xx" ;; "3b+" | "4") mkinitcpio_additional_modules="lan78xx" ;; *) warning "Version $raspberry_pi_version isn't supported." ;; esac mkinitcpio_replace_modules="MODULES=(g_cdc usb_f_acm usb_f_ecm $mkinitcpio_additional_modules g_ether)" || error mkinitcpio_search_binaries="BINARIES=()" && mkinitcpio_replace_binaries=$(echo "BINARIES=(/usr/lib/libgcc_s.so.1)"| sed -e 's/[\/&]/\\&/g') && mkinitcpio_encrypt_hooks="sleep netconf dropbear encryptssh" && mkinitcpio_hooks_prefix="base udev autodetect microcode modconf kms keyboard keymap consolefont block" mkinitcpio_hooks_suffix="filesystems fsck" mkinitcpio_search_hooks="HOOKS=($mkinitcpio_hooks_prefix $mkinitcpio_hooks_suffix)" && mkinitcpio_replace_hooks="HOOKS=($mkinitcpio_hooks_prefix $mkinitcpio_encrypt_hooks $mkinitcpio_hooks_suffix)" && replace_in_file "$mkinitcpio_search_modules" "$mkinitcpio_replace_modules" "$mkinitcpio_path" && replace_in_file "$mkinitcpio_search_binaries" "$mkinitcpio_replace_binaries" "$mkinitcpio_path" && replace_in_file "$mkinitcpio_search_hooks" "$mkinitcpio_replace_hooks" "$mkinitcpio_path" && info "Content of $mkinitcpio_path:$(cat "$mkinitcpio_path")" && info "Generating mkinitcpio..." && echo "mkinitcpio -vP" | chroot "$root_mount_path" /bin/bash && fstab_insert_line="UUID=$root_partition_uuid / $root_filesystem defaults,noatime 0 1" && info "Configuring $fstab_path..." || error if grep -q "$fstab_insert_line" "$fstab_path" then warning "$fstab_path contains allready $fstab_insert_line - Skipped." else echo "$fstab_insert_line" >> "$fstab_path" || error fi info "Content of $fstab_path:$(cat "$fstab_path")" && crypttab_path="$root_mount_path""etc/crypttab" && crypttab_insert_line="$root_mapper_name UUID=$root_partition_uuid none luks" && info "Configuring $crypttab_path..." || error if grep -q "$crypttab_insert_line" "$crypttab_path" then warning "$crypttab_path contains allready $crypttab_insert_line - Skipped." else echo "$crypttab_insert_line" >> "$crypttab_path" || error fi info "Content of $crypttab_path:$(cat "$crypttab_path")" && boot_txt_path="$boot_mount_path""boot.txt" && cryptdevice_configuration="cryptdevice=UUID=$root_partition_uuid:$root_mapper_name root=$root_mapper_path" || error if [ -f "$boot_txt_path" ]; then info "Configuring $boot_txt_path..." && boot_txt_delete_line=$(echo "part uuid \${devtype} \${devnum}:2 uuid" | sed -e 's/[]\/$*.^[]/\\&/g') && boot_txt_setenv_origin=$(echo "setenv bootargs console=ttyS1,115200 console=tty0 root=PARTUUID=\${uuid} rw rootwait smsc95xx.macaddr=\"\${usbethaddr}\"" | sed -e 's/[]\/$*.^[]/\\&/g') && # Concerning issues with network adapter names; # @see https://forum.iobroker.net/topic/40542/raspberry-pi4-kein-eth0-mehr/16 boot_txt_setenv_replace=$(echo "setenv bootargs console=ttyS1,115200 console=tty0 ip=::::$target_hostname:eth0:dhcp $cryptdevice_configuration rw rootwait smsc95xx.macaddr=\"\${usbethaddr}\" net.ifnames=0 biosdevname=0"| sed -e 's/[\/&]/\\&/g') && replace_in_file "$boot_txt_delete_line" "" "$boot_txt_path" && replace_in_file "$boot_txt_setenv_origin" "$boot_txt_setenv_replace" "$boot_txt_path" && info "Content of $boot_txt_path:$(cat "$boot_txt_path")" && info "Generating..." && echo "cd /boot/ && ./mkscr || exit 1" | chroot "$root_mount_path" /bin/bash || error else cmdline_txt_path="$boot_mount_path""cmdline.txt" && info "Configuring $cmdline_txt_path..." && cmdline_search_string=$(echo "root=/dev/mmcblk0p2" | sed -e 's/[\/&]/\\&/g') && cmdline_replace_string=$(echo "$cryptdevice_configuration rootfstype=$root_filesystem"| sed -e 's/[\/&]/\\&/g') && replace_in_file "$cmdline_search_string" "$cmdline_replace_string" "$cmdline_txt_path" && info "Content of $cmdline_txt_path:$(cat "$cmdline_txt_path")" || error fi fi info "Running system specific procedures..." if [ "$distribution" = "retropie" ] then if [ -n "$origin_user_rsa_pub" ] then ssh_file="$boot_mount_path""ssh" && echo "" > "$ssh_file" fi question "Should the RetroFlag specific procedures be executed?(y/N)" && read -r setup_retroflag if [ "$setup_retroflag" == "y" ] then info "Executing RetroFlag specific procedures..." && ( echo 'wget -O - "https://raw.githubusercontent.com/RetroFlag/retroflag-picase/master/install_gpi.sh" | bash' ) | chroot "$root_mount_path" /bin/bash || error fi fi fi destructor success "Setup successfull :)" && exit 0