ยง2023-06-048

This is to document manjaro-arm-installer

#! /bin/bash

# Set globals
# *****************************
VERSION="1.5.3"
# *****************************
TMPDIR=/var/tmp/manjaro-arm-installer
ARCH='aarch64'
CARCH=$(uname -m)
NSPAWN='systemd-nspawn -q --resolv-conf=copy-host --timezone=off -D'
srv_list=/var/tmp/manjaro-arm-installer/services_list

# set colorscheme
if [[ -f "./dialogrc_gui" ]]; then
export DIALOGRC="./dialogrc_gui"
else
export DIALOGRC="/etc/manjaro-arm-installer/dialogrc_gui"
fi

# clearing variables
DEVICE=""
EDITION=""
USER=""
USERGROUPS=""
FULLNAME=""
PASSWORD=""
CONFIRMPASSWORD=""
CONFIRMROOTPASSWORD=""
ROOTPASSWORD=""
SDCARD=""
SDTYP=""
SDDEV=""
DEV_NAME=""
FSTYPE=""
TIMEZONE=""
LOCALE=""
HOSTNAME=""
CRYPT=""

# check if root
if [ "$EUID" -ne 0 ]; then
    echo "*******************************************************************************************"
    echo "*                                                                                         *"
    echo "*     This script requires root permissions to run. Please run as root or with sudo!      *"
    echo "*                                                                                         *"
    echo "*******************************************************************************************"
  exit
fi

# Sanity checks for dependencies
declare -a DEPENDENCIES=("git" "parted" "systemd-nspawn" "wget" "dialog" "bsdtar" "openssl" "awk" "btrfs" "mkfs.vfat" "mkfs.btrfs" "mkfs.f2fs" "cryptsetup")

for i in "${DEPENDENCIES[@]}"; do
  if ! [[ -f "/bin/$i" || -f "/sbin/$i" || -f "/usr/bin/$i" || -f "/usr/sbin/$i" ]] ; then
    echo "$i command is missing! Please install the relevant package."
    exit 1
  fi
done

if [[ "$CARCH" != "aarch64" ]]; then
if [ ! -f "/usr/lib/binfmt.d/qemu-aarch64-static.conf" ]; then
    echo "qemu-aarch64-static.conf file is missing. Please install the relevant package."
    exit 1
fi
fi


# Functions
msg() {
    ALL_OFF="\e[1;0m"
    BOLD="\e[1;1m"
    GREEN="${BOLD}\e[1;32m"
      local mesg=$1; shift
      printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
 }

info() {
    ALL_OFF="\e[1;0m"
    BOLD="\e[1;1m"
    BLUE="${BOLD}\e[1;34m"
      local mesg=$1; shift
      printf "${BLUE}  ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
 }

usage_build_installer() {
    echo "Usage: ${0##*/} [options]"
    echo '    -h                 This help'
    echo ''
    echo ''
    exit $1
}

get_timer(){
    echo $(date +%s)
}

# $1: start timer
elapsed_time(){
    echo $(echo $1 $(get_timer) | awk '{ printf "%0.2f",($2-$1)/60 }')
}

show_elapsed_time(){
    msg "Time %s: %s minutes..." "$1" "$(elapsed_time $2)"
}

installer_getarmprofiles () {
    info "Getting package lists ready for $DEVICE $EDITION edition..."
    rm -rf $TMPDIR/arm-profiles
    mkdir -p $TMPDIR
    chmod 777 $TMPDIR
    git clone https://gitlab.manjaro.org/manjaro-arm/applications/arm-profiles.git $TMPDIR/arm-profiles/ 1> /dev/null 2>&1

}

create_install() {
    msg "Creating install for $DEVICE..."
    info "Used device is ${SDCARD}"
    
    # fetch and extract rootfs
    info "Downloading latest $ARCH rootfs..."
    cd $TMPDIR
    if [ -f Manjaro-ARM-$ARCH-latest.tar.gz* ]; then
    rm Manjaro-ARM_$ARCH-latest.tar.gz*
    fi
    wget -q --show-progress --progress=bar:force:noscroll https://github.com/manjaro-arm/rootfs/releases/latest/download/Manjaro-ARM-$ARCH-latest.tar.gz
    
    info "Extracting $ARCH rootfs..."
    bsdtar -xpf $TMPDIR/Manjaro-ARM-$ARCH-latest.tar.gz -C $TMPDIR/root
    
    # Create a "marker" that tells the packages that they're installed as part of building
    # an image, which is currently used by the "generic-post-install" package only
    touch $TMPDIR/root/MANJARO-ARM-IMAGE-BUILD

    # Make this symlink available, it's created by systemd on a running system
    mkdir -p $TMPDIR/root/etc
    ln -sf ../usr/lib/os-release $TMPDIR/root/etc/os-release

    
    info "Setting up keyrings..."
    $NSPAWN $TMPDIR/root pacman-key --init 1> /dev/null 2>&1
    $NSPAWN $TMPDIR/root pacman-key --populate archlinuxarm manjaro manjaro-arm 1> /dev/null 2>&1
    
    info "Generating mirrorlist..."
    $NSPAWN $TMPDIR/root pacman-mirrors -f10 1> /dev/null 2>&1
    
    info "Installing packages for $EDITION on $DEVICE..."
    # Setup cache mount
    mkdir -p $TMPDIR/pkg-cache
    mount -o bind $TMPDIR/pkg-cache $TMPDIR/root/var/cache/pacman/pkg
    # Install device and editions specific packages
    $NSPAWN $TMPDIR/root pacman -Syyu base manjaro-system manjaro-release systemd systemd-libs $PKG_SHARED $PKG_EDITION $PKG_DEVICE --noconfirm
    
    
    info "Enabling services..."
    # Enable services
    $NSPAWN $TMPDIR/root systemctl enable getty.target haveged.service 1>/dev/null

    while read service; do
        if [ -e $TMPDIR/root/usr/lib/systemd/system/$service ]; then
            echo "Enabling $service ..."
            $NSPAWN $TMPDIR/root systemctl enable $service 1>/dev/null
        else
            echo "$service not found in rootfs. Skipping."
        fi
    done < $srv_list
    if [ -f $TMPDIR/root/usr/bin/xdg-user-dirs-update ]; then
    $NSPAWN $TMPDIR/root systemctl --global enable xdg-user-dirs-update.service 1> /dev/null 2>&1
    fi

    info "Applying overlay for $EDITION..."
    cp -ap $TMPDIR/arm-profiles/overlays/$EDITION/* $TMPDIR/root/

    info "Setting up users..."
    #setup users
    echo "$USER" > $TMPDIR/user
    echo "$PASSWORD" > $TMPDIR/password
    echo "$ROOTPASSWORD" > $TMPDIR/rootpassword

    info "Setting password for root ..."
    $NSPAWN $TMPDIR/root awk -i inplace -F: "BEGIN {OFS=FS;} \$1 == \"root\" {\$2=\"$(openssl passwd -6 $(cat $TMPDIR/rootpassword))\"} 1" /etc/shadow 1> /dev/null 2>&1
    
    if [[ "$EDITION" = "plasma-mobile" ]]; then
        $NSPAWN $TMPDIR/root userdel -f -r kde
        elif [[ "$EDITION" = "phosh" ]]; then
            $NSPAWN $TMPDIR/root userdel -f -r manjaro
    fi

    info "Adding user..."
    $NSPAWN $TMPDIR/root useradd -m -G wheel,sys,audio,input,video,storage,lp,network,users,power -p $(openssl passwd -6 $(cat $TMPDIR/password)) -s /bin/bash $(cat $TMPDIR/user) 1> /dev/null 2>&1
    $NSPAWN $TMPDIR/root usermod -aG $USERGROUPS $(cat $TMPDIR/user) 1> /dev/null 2>&1
    $NSPAWN $TMPDIR/root chfn -f "$FULLNAME" $(cat $TMPDIR/user) 1> /dev/null 2>&1
    
    info "Enabling user services..."
    if [[ "$EDITION" = "minimal" ]] || [[ "$EDITION" = "server" ]]; then
        echo "No user services for $EDITION edition"
    else
        $NSPAWN $TMPDIR/root --user $(cat $TMPDIR/user) systemctl --user enable pulseaudio.service 1> /dev/null 2>&1
    fi
    
    info "Setting up system settings..."
    #system setup
    $NSPAWN $TMPDIR/root chmod u+s /usr/bin/ping 1> /dev/null 2>&1
    rm -f $TMPDIR/root/etc/ssl/certs/ca-certificates.crt
    rm -f $TMPDIR/root/etc/ca-certificates/extracted/tls-ca-bundle.pem
    cp -a /etc/ssl/certs/ca-certificates.crt $TMPDIR/root/etc/ssl/certs/
    cp -a /etc/ca-certificates/extracted/tls-ca-bundle.pem $TMPDIR/root/etc/ca-certificates/extracted/
    $NSPAWN $TMPDIR/root ln -sf /usr/share/zoneinfo/"$TIMEZONE" /etc/localtime 1> /dev/null 2>&1
    $NSPAWN $TMPDIR/root timedatectl set-ntp true /dev/null 2>&1
    $NSPAWN $TMPDIR/root sed -i s/"#$LOCALE"/"$LOCALE"/g /etc/locale.gen 1> /dev/null 2>&1
    echo "LANG=$LOCALE" | tee --append $TMPDIR/root/etc/locale.conf 1> /dev/null 2>&1
    $NSPAWN $TMPDIR/root locale-gen
    echo "KEYMAP=$CLIKEYMAP" | tee --append $TMPDIR/root/etc/vconsole.conf 1> /dev/null 2>&1
    if [[ "$EDITION" != "minimal" ]] && [[ "$EDITION" != "server" ]] && [[ "$EDITION" != "sway" ]]; then
    echo 'Section "InputClass"' > $TMPDIR/root/etc/X11/xorg.conf.d/00-keyboard.conf
    echo 'Identifier "system-keyboard"' >> $TMPDIR/root/etc/X11/xorg.conf.d/00-keyboard.conf
    echo 'Option "XkbLayout" "us"' >> $TMPDIR/root/etc/X11/xorg.conf.d/00-keyboard.conf
    echo 'EndSection' >> $TMPDIR/root/etc/X11/xorg.conf.d/00-keyboard.conf
    sed -i s/"us"/"$X11KEYMAP"/ $TMPDIR/root/etc/X11/xorg.conf.d/00-keyboard.conf
    fi
    if [[ "$EDITION" = "sway" ]]; then
        sed -i s/"us"/"$X11KEYMAP"/ $TMPDIR/root/etc/sway/inputs/default-keyboard 1> /dev/null 2>&1
    fi
    echo "$HOSTNAME" | tee --append $TMPDIR/root/etc/hostname 1> /dev/null 2>&1
    sed -i s/"enable systemd-resolved.service"/"#enable systemd-resolved.service"/ $TMPDIR/root/usr/lib/systemd/system-preset/90-systemd.preset
    if [[ "$EDITION" = "plasma-mobile" ]]; then
        sed -i "s/User=kde/User=$USER/g" $TMPDIR/root/etc/sddm.conf.d/00-default.conf
    fi

    echo "Correcting permissions from overlay..."
    chown -R root:root $TMPDIR/root/etc
    chown -R root:root $TMPDIR/root/usr/{local,share}
    if [[ -d $TMPDIR/root/etc/polkit-1/rules.d ]]; then
        chown root:polkitd $TMPDIR/root/etc/polkit-1/rules.d
    fi
    if [[ -d $TMPDIR/root/usr/share/polkit-1/rules.d ]]; then
        chown root:polkitd $TMPDIR/root/usr/share/polkit-1/rules.d
    fi
    if [[ "$EDITION" = "cubocore" ]]; then
        cp $TMPDIR/root/usr/share/applications/corestuff.desktop $TMPDIR/root/etc/xdg/autostart/
    fi
    
    case "$FSTYPE" in
        btrfs)
            info "Adding btrfs support to system..."
            if [ -f $TMPDIR/root/boot/extlinux/extlinux.conf ]; then
                sed -i 's/APPEND/& rootflags=subvol=@/' $TMPDIR/root/boot/extlinux/extlinux.conf
                elif [ -f $TMPDIR/root/boot/boot.ini ]; then
                    sed -i 's/setenv bootargs /&rootflags=subvol=@ /' $TMPDIR/root/boot/boot.ini
                elif [ -f $TMPDIR/root/boot/uEnv.ini ]; then
                    sed -i 's/setenv bootargs /&rootflags=subvol=@ /' $TMPDIR/root/boot/uEnv.ini
                #elif [ -f $TMPDIR/root/boot/cmdline.txt ]; then
                #    sed -i 's/^/rootflags=subvol=@ rootfstype=btrfs /' $TMPDIR/root/boot/cmdline.txt
                elif [ -f $TMPDIR/root/boot/boot.txt ]; then
                    sed -i 's/setenv bootargs/& rootflags=subvol=@/' $TMPDIR/root/boot/boot.txt
                    $NSPAWN $TMPDIR/root mkimage -A arm -O linux -T script -C none -n "U-Boot boot script" -d /boot/boot.txt /boot/boot.scr
            fi
            echo "LABEL=ROOT_MNJRO / btrfs  subvol=@,compress=zstd,defaults,noatime  0  0" >> $TMPDIR/root/etc/fstab
            echo "LABEL=ROOT_MNJRO /home btrfs  subvol=@home,compress=zstd,defaults,noatime  0  0" >> $TMPDIR/root/etc/fstab
            sed -i '/^MODULES/{s/)/ btrfs)/}' $TMPDIR/root/etc/mkinitcpio.conf
            $NSPAWN $TMPDIR/root mkinitcpio -P 1> /dev/null 2>&1
            ;;
        f2fs)
            info "Adding f2fs support to system..."
            $NSPAWN $TMPDIR/root pacman -S f2fs-tools --noconfirm 1> /dev/null 2>&1
            echo "LABEL=ROOT_MNJRO / f2fs  defaults,noatime,compress_algorithm=zstd  0  0" >> $TMPDIR/root/etc/fstab
            sed -i '/^MODULES/{s/)/ f2fs)/}' $TMPDIR/root/etc/mkinitcpio.conf
            $NSPAWN $TMPDIR/root mkinitcpio -P 1> /dev/null 2>&1
            ;;
        *)
            info "Adding ext4 support to system..."
            ;;
    esac

    
    if [[ "$CRYPT" = "yes" ]]; then
    tweakinitrd_crypt
    fi
    
    info "Cleaning install for unwanted files..."
    umount $TMPDIR/root/var/cache/pacman/pkg
    rm -f $TMPDIR/root/usr/bin/qemu-aarch64-static
    rm -f $ROOTFS_IMG/rootfs_$ARCH/MANJARO-ARM-IMAGE-BUILD
    rm -f $TMPDIR/root/var/cache/pacman/pkg/*
    rm -f $TMPDIR/root/var/log/*
    rm -rf $ROOTFS_IMG/rootfs_$ARCH/var/log/journal/*
    rm -f $TMPDIR/root/etc/*.pacnew
    rm -f $TMPDIR/root/usr/lib/systemd/system/systemd-firstboot.service
    rm -f $TMPDIR/root/etc/machine-id
    
    # Remove temp files on host
    rm -f $TMPDIR/user $TMPDIR/password $TMPDIR/rootpassword
    rm -f $TMPDIR/Manjaro-ARM-$ARCH-latest.tar.gz*

    msg "$DEVICE $EDITION install complete"
    if [[ "$DEVICE" = "generic-efi" ]]; then
        msg "Please run 'sudo update-grub' after boot to correctly configure Grub!"
    fi
}

prepare_card () {
    msg "Getting $SDCARD ready with $FSTYPE for $DEVICE..."
        # umount SD card
        umount ${SDCARD}${SDDEV}1 1> /dev/null 2>&1
        umount ${SDCARD}${SDDEV}2 1> /dev/null 2>&1
        # Create partitions
        #remove previous partitions
        for v_partition in $(parted -s $SDCARD print|awk '/^ / {print $1}')
        do
            parted -s $SDCARD rm ${v_partition} 1> /dev/null 2>&1
        done
        #Clear first 32mb
        dd if=/dev/zero of=${SDCARD} bs=1M count=32 1> /dev/null 2>&1
        #partition with boot and root
        case "$DEVICE" in
            edgev|gsking-x|gtking-pro|oc2|on2|on2-plus|oc4|ohc4|pinephone|radxa-zero|rpi4|vim1|vim2|vim3)
            parted -s $SDCARD mklabel msdos 1> /dev/null 2>&1
            ;;
            *)
            parted -s $SDCARD mklabel gpt 1> /dev/null 2>&1
            ;;
        esac
        if [[ "$DEVICE" = "generic-efi" ]]; then
            parted -s $SDCARD mkpart primary fat32 0% 512M > /dev/null 2>&1
        else
            parted -s $SDCARD mkpart primary fat32 32M 512M 1> /dev/null 2>&1
        fi
        sleep 5
        START=`cat /sys/block/$DEV_NAME/${DEV_NAME}${SDDEV}1/start`
        SIZE=`cat /sys/block/$DEV_NAME/${DEV_NAME}${SDDEV}1/size`
        END_SECTOR=$(expr $START + $SIZE)
        case "$FSTYPE" in
            btrfs)
                case "$DEVICE" in
                    generic-efi)
                        parted -s $SDCARD mkpart primary btrfs "${END_SECTOR}s" 100% > /dev/null 2>&1
                        parted -s $SDCARD set 1 esp on
                        partprobe $SDCARD > /dev/null 2>&1
                        mkfs.vfat "${SDCARD}${SDDEV}1" -n BOOT_MNJRO > /dev/null 2>&1
                        mkfs.btrfs -m single -L ROOT_MNJRO "${SDCARD}${SDDEV}p2" > /dev/null 2>&1
                
                        # Create and mount the subvolumes
                        info "Creating btrfs subvolumes..."
                        mkdir -p $TMPDIR/root
                        mkdir -p $TMPDIR/boot/efi
                        mount ${SDCARD}${SDDEV}1 $TMPDIR/boot/efi
                        mount -o compress=zstd "${SDCARD}${SDDEV}2" $TMPDIR/root
                        btrfs su cr $TMPDIR/root/@ > /dev/null 2>&1
                        btrfs su cr $TMPDIR/root/@home > /dev/null 2>&1
                        umount $TMPDIR/root
                        mount -o compress=zstd,subvol=@ "${SDCARD}${SDDEV}2" $TMPDIR/root
                        mkdir -p $TMPDIR/root/home
                        mount -o compress=zstd,subvol=@home "${SDCARD}${SDDEV}2" $TMPDIR/root/home
                        ;;
                    *)
                        parted -s $SDCARD mkpart primary btrfs "${END_SECTOR}s" 100% 1> /dev/null 2>&1
                        partprobe $SDCARD 1> /dev/null 2>&1
                        mkfs.vfat "${SDCARD}${SDDEV}1" -n BOOT_MNJRO 1> /dev/null 2>&1
                        mkfs.btrfs -m single -L ROOT_MNJRO -f "${SDCARD}${SDDEV}2" 1> /dev/null 2>&1

                        mkdir -p $TMPDIR/root
                        mkdir -p $TMPDIR/boot
                        # Do subvolumes
                        mount -o compress=zstd "${SDCARD}${SDDEV}2" $TMPDIR/root
                        btrfs su cr $TMPDIR/root/@ 1> /dev/null 2>&1
                        btrfs su cr $TMPDIR/root/@home 1> /dev/null 2>&1
                        umount $TMPDIR/root
                        mount -o compress=zstd,subvol=@ "${SDCARD}${SDDEV}2" $TMPDIR/root
                        mkdir -p $TMPDIR/root/home
                        mount -o compress=zstd,subvol=@home "${SDCARD}${SDDEV}2" $TMPDIR/root/home
                        mount ${SDCARD}${SDDEV}1 $TMPDIR/boot
                        ;;
                esac
                ;;
            f2fs)
                case "$DEVICE" in
                    generic-efi)
                        parted -s $SDCARD mkpart primary f2fs "${END_SECTOR}s" 100% > /dev/null 2>&1
                        parted -s $SDCARD set 1 esp on
                        partprobe $SDCARD > /dev/null 2>&1
                        mkfs.vfat "${SDCARD}${SDDEV}1" -n BOOT_MNJRO > /dev/null 2>&1
                        mkfs.f2fs -f -l ROOT_MNJRO -O extra_attr,inode_checksum,sb_checksum,compression "${SDCARD}${SDDEV}2" 1> /dev/null 2>&1
                        mkdir -p $TMPDIR/root
                        mkdir -p $TMPDIR/boot/efi
                        mount ${SDCARD}${SDDEV}1 $TMPDIR/boot/efi
                        mount -t f2fs ${SDCARD}${SDDEV}2 $TMPDIR/root
                        ;;
                    *)
                        parted -s $SDCARD mkpart primary f2fs "${END_SECTOR}s" 100% 1> /dev/null 2>&1
                        partprobe $SDCARD 1> /dev/null 2>&1
                        mkfs.vfat "${SDCARD}${SDDEV}1" -n BOOT_MNJRO 1> /dev/null 2>&1
                        mkfs.f2fs -f -l ROOT_MNJRO -O extra_attr,inode_checksum,sb_checksum,compression "${SDCARD}${SDDEV}2" 1> /dev/null 2>&1

                        mkdir -p $TMPDIR/root
                        mkdir -p $TMPDIR/boot
                        mount ${SDCARD}${SDDEV}1 $TMPDIR/boot
                        mount -t f2fs ${SDCARD}${SDDEV}2 $TMPDIR/root
                    ;;
                esac
                ;;
            ext4)
                case "$DEVICE" in
                    generic-efi)
                        parted -s $SDCARD mkpart primary ext4 "${END_SECTOR}s" 100% > /dev/null 2>&1
                        parted -s $SDCARD set 1 esp on
                        partprobe $SDCARD > /dev/null 2>&1
                        mkfs.vfat "${SDCARD}${SDDEV}1" -n BOOT_MNJRO > /dev/null 2>&1
                        mkfs.ext4 -O ^metadata_csum,^64bit "${SDCARD}${SDDEV}2" -L ROOT_MNJRO > /dev/null 2>&1
                        mkdir -p $TMPDIR/root
                        mkdir -p $TMPDIR/boot/efi
                        mount ${SDCARD}${SDDEV}1 $TMPDIR/boot/efi
                        mount ${SDCARD}${SDDEV}2 $TMPDIR/root
                        ;;
                    *)
                        parted -s $SDCARD mkpart primary ext4 "${END_SECTOR}s" 100% 1> /dev/null 2>&1
                        partprobe $SDCARD 1> /dev/null 2>&1
                        mkfs.vfat "${SDCARD}${SDDEV}1" -n BOOT_MNJRO 1> /dev/null 2>&1

                        if [[ "$CRYPT" != "yes" ]]; then
                            mkfs.ext4 -O ^metadata_csum,^64bit "${SDCARD}${SDDEV}2" -L ROOT_MNJRO 1> /dev/null 2>&1
                        else
                            info "Create encryption password:"
                            cryptsetup luksFormat -q "${SDCARD}${SDDEV}2"
                            info "Confirm encryption password:"
                            cryptsetup open "${SDCARD}${SDDEV}2" ROOT_MNJRO
                            mkfs.ext4 -O ^metadata_csum,^64bit /dev/mapper/ROOT_MNJRO 1> /dev/null 2>&1
                        fi

                        mkdir -p $TMPDIR/root
                        mkdir -p $TMPDIR/boot
                        mount ${SDCARD}${SDDEV}1 $TMPDIR/boot
                        if [[ "$CRYPT" != "yes" ]]; then
                            mount ${SDCARD}${SDDEV}2 $TMPDIR/root
                        else
                            [ ! -e /dev/mapper/ROOT_MNJRO ] && cryptsetup open "${SDCARD}${SDDEV}2" ROOT_MNJRO
                            mount /dev/mapper/ROOT_MNJRO $TMPDIR/root
                        fi
                        ;;
                esac
                ;;
        esac
}

cleanup () {
    if [[ "$DEVICE" != "generic-efi" ]]; then
        msg "Writing bootloader and cleaning up after install..."
        # Move boot files
        mv $TMPDIR/root/boot/* $TMPDIR/boot
    fi
    # Flash bootloader
    case "$DEVICE" in
    oc2)
        dd if=$TMPDIR/boot/bl1.bin.hardkernel of=${SDCARD} conv=fsync bs=1 count=442 1> /dev/null 2>&1
        dd if=$TMPDIR/boot/bl1.bin.hardkernel of=${SDCARD} conv=fsync bs=512 skip=1 seek=1 1> /dev/null 2>&1
        dd if=$TMPDIR/boot/u-boot.gxbb of=${SDCARD} conv=fsync bs=512 seek=97 1> /dev/null 2>&1
        ;;
    oc4|ohc4|on2|on2-plus)
        dd if=$TMPDIR/boot/u-boot.bin of=${SDCARD} conv=fsync,notrunc bs=512 seek=1 1> /dev/null 2>&1
        ;;
    radxa-zero|vim1|vim2|vim3)
        dd if=$TMPDIR/boot/u-boot.bin of=${SDCARD} conv=fsync bs=1 count=442 1> /dev/null 2>&1
        dd if=$TMPDIR/boot/u-boot.bin of=${SDCARD} conv=fsync bs=512 skip=1 seek=1 1> /dev/null 2>&1
        ;;
    pine64-lts|pine64|pinebook|pinetab|pine-h64)
        dd if=$TMPDIR/boot/u-boot-sunxi-with-spl-$DEVICE.bin of=${SDCARD} conv=fsync bs=128k seek=1 1> /dev/null 2>&1
        ;;
    pinephone)
        dd if=$TMPDIR/boot/u-boot-sunxi-with-spl-$DEVICE-552.bin of=${SDCARD} conv=fsync bs=8k seek=1 1> /dev/null 2>&1
        ;;
    clockworkpi-a06|nanopc-t4|om1|opi4-lts|pbpro|pinephonepro|quartz64-a|quartz64-b|rock3a|rock64|roc-cc|rockpi4b|rockpi4c|rockpro64)
        dd if=$TMPDIR/boot/idbloader.img of=${SDCARD} seek=64 conv=notrunc,fsync 1> /dev/null 2>&1
        dd if=$TMPDIR/boot/u-boot.itb of=${SDCARD} seek=16384 conv=notrunc,fsync 1> /dev/null 2>&1
        ;;
    esac

    if [[ "$CRYPT" = "yes" ]]; then
    post_crypt
    fi
    
    # edit boot files and fstab
    # set UUID for boot partition in fstab
    BOOT_PARTUUID=$(lsblk -p -o NAME,PARTUUID | grep ${DEV_NAME}${SDDEV}1 | awk '{print $2}')
    sed -i "s/LABEL=BOOT_MNJRO/PARTUUID=$BOOT_PARTUUID/g" $TMPDIR/root/etc/fstab
    info "Set boot partition to $BOOT_PARTUUID in /etc/fstab..."
    
    # Change boot script and fstab to root partition UUID
    ROOT_PARTUUID=$(lsblk -p -o NAME,PARTUUID | grep ${DEV_NAME}${SDDEV}2 | awk '{print $2}')
    ROOT_UUID=$(blkid | grep ${DEV_NAME}${SDDEV}2 | awk '{print $3}' | grep -oP "[^/]=\K.*" | sed 's/\"//g')
    info "Set root partition to $ROOT_PARTUUID in the relevant boot script and /etc/fstab..."
    if [[ "$DEVICE" = "generic-efi" ]]; then
        info "Set root partition to $ROOT_UUID in /boot/grub/grub.cfg..."
    fi
    if [ -f $TMPDIR/boot/extlinux/extlinux.conf ]; then
    sed -i "s/LABEL=ROOT_MNJRO/PARTUUID=$ROOT_PARTUUID/g" $TMPDIR/boot/extlinux/extlinux.conf
        elif [ -f $TMPDIR/boot/efi/extlinux/extlinux.conf ]; then
            sed -i "s/LABEL=ROOT_MNJRO/PARTUUID=$ROOT_PARTUUID/g" $TMPDIR/boot/efi/extlinux/extlinux.conf
        elif [ -f $TMPDIR/boot/boot.ini ]; then
            sed -i "s/LABEL=ROOT_MNJRO/PARTUUID=$ROOT_PARTUUID/g" $TMPDIR/boot/boot.ini
        elif [ -f $TMPDIR/boot/uEnv.ini ]; then
            sed -i "s/LABEL=ROOT_MNJRO/PARTUUID=$ROOT_PARTUUID/g" $TMPDIR/boot/uEnv.ini
        #elif [ -f $TMPDIR/boot/boot.txt ]; then
        #    sed -i "s/PARTUUID=/PARTUUID=$ROOT_PARTUUID/g" $TMPDIR/boot/boot.txt
        #    $NSPAWN $TMPDIR/root mkimage -A arm -O linux -T script -C none -n "U-Boot boot script" -d $TMPDIR/boot/boot.txt $TMPDIR/boot/boot.scr
    fi
    sync
    
    if [[ "$DEVICE" = "rpi4" ]] && [[ "$FSTYPE" = "btrfs" ]]; then
        echo "===> Installing default btrfs RPi cmdline.txt /boot..."
        echo "rootflags=subvol=@ root=PARTUUID=$ROOT_PARTUUID rw rootwait console=serial0,115200 console=tty3 selinux=0 quiet splash plymouth.ignore-serial-consoles smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=serial0,115200 usbhid.mousepoll=8 audit=0" >  $TMPDIR/boot/cmdline.txt
    elif [[ "$DEVICE" = "rpi4" ]]; then
        echo "===> Installing default ext4 RPi cmdline.txt /boot..."
        echo "root=PARTUUID=$ROOT_PARTUUID rw rootwait console=serial0,115200 console=tty3 selinux=0 quiet splash plymouth.ignore-serial-consoles smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0 kgdboc=serial0,115200 usbhid.mousepoll=8 audit=0" >  $TMPDIR/boot/cmdline.txt
    fi
    if [[ "$DEVICE" = "rpi4" ]]; then
        echo "===> Installing default config.txt file to /boot/..."
        echo "# See /boot/overlays/README for all available options" > $TMPDIR/boot/config.txt
        echo "" >> $TMPDIR/boot/config.txt
        echo "#gpu_mem=64" >> $TMPDIR/boot/config.txt
        echo "initramfs initramfs-linux.img followkernel" >> $TMPDIR/boot/config.txt
        echo "kernel=kernel8.img" >> $TMPDIR/boot/config.txt
        echo "arm_64bit=1" >> $TMPDIR/boot/config.txt
        echo "disable_overscan=1" >> $TMPDIR/boot/config.txt
        echo "" >> $TMPDIR/boot/config.txt
        echo "#enable sound" >> $TMPDIR/boot/config.txt
        echo "dtparam=audio=on" >> $TMPDIR/boot/config.txt
        echo "#hdmi_drive=2" >> $TMPDIR/boot/config.txt
        echo "" >> $TMPDIR/boot/config.txt
        echo "#enable vc4" >> $TMPDIR/boot/config.txt
        echo "dtoverlay=vc4-kms-v3d" >> $TMPDIR/boot/config.txt
        echo "max_framebuffers=2"  >> $TMPDIR/boot/config.txt
        echo "disable_splash=1" >> $TMPDIR/boot/config.txt
    fi 
    
    case "$FSTYPE" in
        btrfs|f2fs)
            sed -i "s/LABEL=ROOT_MNJRO/PARTUUID=$ROOT_PARTUUID/g" $TMPDIR/root/etc/fstab
        ;;
        *)
            echo "PARTUUID=$ROOT_PARTUUID   /   $FSTYPE     defaults    0   1" >> $TMPDIR/root/etc/fstab
        ;;
    esac
    
    if [[ "$DEVICE" = "generic-efi" ]]; then
        sed -i "s|/boot|/boot/efi|g" $TMPDIR/root/etc/fstab

    msg "Setup GRUB for EFI..."
    grub-install --target=arm64-efi --efi-directory=$TMPDIR/boot/efi --removable --boot-directory=$TMPDIR/root/boot --bootloader-id=grub ${SDCARD}
    mkdir -p $TMPDIR/root/boot/grub
    if [ -f $TMPDIR/root/boot/Image ]; then
        KERNEL="/boot/Image"
        INITRAMFS="/boot/initramfs-linux.img"
    else
        KERNEL="/boot/$(ls $TMPDIR/root/boot/ | grep vmlinuz)"
        INITRAMFS="/boot/$(ls $TMPDIR/root/boot/ | grep initramfs | grep -v fallback)"
    fi
    echo "Kernel image is $KERNEL..."
    echo "Initramfs image is $INITRAMFS..."
    echo "Creating minimal grub configuration..."
    echo '### BEGIN /etc/grub.d/00_header ###
insmod part_gpt
insmod part_msdos
if [ -s $prefix/grubenv ]; then
  load_env
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="${saved_entry}"
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

set menu_color_normal=white/black
set menu_color_highlight=green/black

if [ x$feature_default_font_path = xy ] ; then
   font=unicode
else
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root $ROOT_UUID
    font="/usr/share/grub/unicode.pf2"
fi

if loadfont $font ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
fi
terminal_input console
terminal_output gfxterm
if [ x$feature_timeout_style = xy ] ; then
  set timeout_style=menu
  set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
  set timeout=5
fi
### END /etc/grub.d/00_header ###' > $TMPDIR/root/boot/grub/grub.cfg

    echo "### BEGIN /etc/grub.d/10_linux ###
menuentry 'Manjaro ARM' --class manjaro --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-$ROOT_UUID' {
	savedefault
	load_video
	set gfxpayload=keep
	insmod gzio
	insmod part_gpt
	insmod ext2
	search --no-floppy --fs-uuid --set=root $ROOT_UUID
	linux	$(if [[ "$FILESYSTEM" = "btrfs" ]]; then echo "/@"; fi)$KERNEL root=UUID=$ROOT_UUID rw quiet splash plymouth.ignore-serial-consoles $(if [[ "$FSTYPE" = "btrfs" ]]; then echo "rootflags=subvol=@ rootfstype=btrfs"; fi)
	initrd	$(if [[ "$FILESYSTEM" = "btrfs" ]]; then echo "/@"; fi)$INITRAMFS
}" >> $TMPDIR/root/boot/grub/grub.cfg
    fi

    #clean up
    if [[ "$FSTYPE" = "btrfs" ]]; then
        umount $TMPDIR/root/home
        umount $TMPDIR/root
        if [[ "$DEVICE" = "generic-efi" ]]; then
            umount $TMPDIR/boot/efi
        else
            umount $TMPDIR/boot
        fi
    else
        umount $TMPDIR/root
        if [[ "$DEVICE" = "generic-efi" ]]; then
            umount $TMPDIR/boot/efi
        else
            umount $TMPDIR/boot
        fi
        if [[ "$CRYPT" = "yes" ]]; then
            cryptsetup close /dev/mapper/ROOT_MNJRO
        fi
    fi

    partprobe $SDCARD 1> /dev/null 2>&1
    info "If you get an error stating 'failed to preserve ownership ... Operation not permitted', it's expected, since the boot partition is FAT32 and does not support ownership permissions..."
}

tweakinitrd_crypt () {
    case "$DEVICE" in
    pbpro|rockpi4b|rockpi4c|rockpro64)
      # Use the proper mkinitcpio.
      cat << EOF > ${TMPDIR}/root/etc/mkinitcpio.conf
MODULES=(panfrost rockchipdrm drm_kms_helper hantro_vpu analogix_dp rockchip_rga panel_edp arc_uart cw2015_battery i2c-hid iscsi_boot_sysfs jsm pwm_bl uhid)
BINARIES=()
FILES=()
HOOKS=(base udev keyboard autodetect keymap modconf block encrypt lvm2 filesystems fsck)
COMPRESSION="cat"
EOF

      # Install lvm2, this will trigger the cpio rebuild
      $NSPAWN $TMPDIR/root pacman -Syyu lvm2 --noconfirm
      ;;
    esac
}

post_crypt () {
    # Get the UUID
    UUID=$(blkid -s UUID -o value "${SDCARD}${SDDEV}2")

    # Modify the /boot/extlinux/extlinux.conf to match our needs
    case "$DEVICE" in
    clockworkpi-a06|pbpro|rockpi4b|rockpi4c|rockpro64)
      # NOTE: I've tried to only modify the cryptdevice and root parameters but bootsplash and console=ttyS2 prevents to show the password prompt
      # TODO: Need to add plymouth support
      sed -i -e "s!APPEND.*!APPEND initrd=/initramfs-linux.img console=tty1 cryptdevice=UUID=${UUID}:ROOT_MNJRO root=/dev/mapper/ROOT_MNJRO rw rootwait!g" ${TMPDIR}/boot/extlinux/extlinux.conf
      ;;
    esac

    # Generate the /etc/crypttab file
    echo "ROOT_MNJRO   UUID=${UUID}    none            luks,discard" > ${TMPDIR}/root/etc/crypttab
}

# Using Dialog to ask for user input for variables
DEVICE=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --menu "Choose a device:" 20 75 10 \
        "clockworkpi-a06" "ClockworkPi DevTerm" \
        "generic"       "Generic" \
        "generic-efi"   "Generic EFI" \
        "gt1-ultimate"  "Beelink GT1 Ultimate" \
        "oc4"           "Odroid C4" \
        "oc2"           "Odroid C2" \
        "ohc4"          "Odroid HC4" \
        "om1"           "Odroid M1" \
        "on2"           "Odroid N2" \
        "on2-plus"      "Odroid N2+" \
        "opi4-lts"      "Orange Pi 4 LTS" \
        "pine64-lts"    "Pine64-LTS / Sopine" \
        "pine64"        "Pine64+" \
        "pinebook"      "Pinebook" \
        "pine-h64"      "Pine H64" \
        "pinephone"     "PinePhone" \
        "pinephonepro"  "PinePhone Pro (Experimental)" \
        "pbpro"         "Pinebook Pro" \
        "pinetab"       "PineTab" \
        "radxa-zero"    "Radxa Zero" \
        "rpi4"          "Raspberry Pi 4/400/3+/3" \
        "rock3a"        "Rock 3A" \
        "rock64"        "Rock64" \
        "rockpi4b"      "Rock Pi 4B" \
        "rockpi4c"      "Rock Pi 4C" \
        "rockpro64"     "RockPro64" \
        "roc-cc"        "LibreComputer Renegade" \
        "nanopc-t4"     "NanoPC T4" \
        "quartz64-a"    "Quartz64 Model A" \
        "quartz64-b"    "Quartz64 Model B" \
        "vim1"          "Khadas Vim 1" \
        "vim2"          "Khadas Vim 2" \
        "vim3"          "Khadas Vim 3" \
        3>&1 1>&2 2>&3 3>&-)


#The if statement makes sure that the user has put in something in the previous prompt. If not (left blank or pressed cancel) the script will end
if [ ! -z "$DEVICE" ]; then
    if [[ "$DEVICE" = "pinetab" ]] || [[ "$DEVICE" = "pinephone" ]] || [[ "$DEVICE" = "pinephonepro" ]]; then
        EDITION=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
            --menu "Choose an edition:" 20 75 10 \
            "plasma-mobile"     "Plasma Mobile (QT based mobile UI)" \
            "phosh"             "Phosh (GTK based mobile UI)" \
            3>&1 1>&2 2>&3 3>&-)
    else
    EDITION=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --menu "Choose an edition:" 20 75 10 \
        "minimal"       "Minimal Edition            (only CLI)" \
        "kde-plasma"    "Full KDE/Plasma Desktop    (full featured)" \
        "xfce"          "Full XFCE desktop and apps (full featured)" \
        "mate"          "Full MATE desktop and apps (lightweight)" \
        "gnome"         "Full Gnome desktop and apps (full featured)" \
        "sway"          "Minimal Sway WM with apps  (very light)" \
        "lxqt"          "Full LXQT Desktop and apps (lightweight)" \
        "i3"            "Mininal i3 WM with apps    (very light)" \
        "server"        "Minimal with LAMP and Docker (only cli)" \
        "budgie"        "Full Budgie desktop (EXPERIMENTAL))" \
        3>&1 1>&2 2>&3 3>&-) 
    fi
else 
    clear
    exit 1
fi

if [[ "$EDITION" = "phosh" ]]; then
    #Set Phosh specific variables
    USER="manjaro"
    PASSWORD="123456"
    CONFIRMPASSWORD="123456"
    ROOTPASSWORD="root"
    CONFIRMROOTPASSWORD="root"
fi
if [ ! -z "$EDITION" ]; then
    if [[ "$EDITION" != "phosh" ]]; then
        USER=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --inputbox "Enter the username you want:
(usernames must be all lowercase and first character may not be a number)" 10 90 \
        3>&1 1>&2 2>&3 3>&-)
    fi
    if [[ "$USER" =~ [A-Z] ]] || [[ "$USER" =~ ^[0-9] ]] || [[ "$USER" == *['!'@#\$%^\&*()_+]* ]]; then
    clear
    msg "Configuration aborted! Username contained invalid characters."
    exit 1
    fi
else 
    clear
    exit 1
fi

if [ ! -z "$USER" ]
then
USERGROUPS=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --inputbox "Enter additional groups for $USER in a comma seperated list: (empty if none)
(default: wheel,sys,audio,input,video,storage,lp,network,users,power)" 10 90 \
        3>&1 1>&2 2>&3 3>&- \
    )
else 
    clear
    exit 1
fi

if [ ! -z "$USER" ]
then
FULLNAME=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --inputbox "Enter desired Full Name for $USER:" 8 50 \
        3>&1 1>&2 2>&3 3>&- \
    )
else
    clear
    exit 1
fi


if [ ! -z "$FULLNAME" ]; then
    if [[ "$EDITION" != "phosh" ]]; then
        PASSWORD=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --insecure --passwordbox "Enter new Password for $USER:" 8 50 \
        3>&1 1>&2 2>&3 3>&- \
        )
    fi
else 
    clear
    exit 1
fi

if [ ! -z "$PASSWORD" ]; then
    if [[ "$EDITION" != "phosh" ]]; then
        CONFIRMPASSWORD=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --insecure --passwordbox "Confirm new Password for $USER:" 8 50 \
        3>&1 1>&2 2>&3 3>&- \
        )
    fi
else 
    clear
    exit 1
fi

if [[ "$PASSWORD" != "$CONFIRMPASSWORD" ]]; then
    clear
    msg "User passwords do not match! Please restart the installer and try again."
    exit 1
fi

if [ ! -z "$CONFIRMPASSWORD" ]; then
    if [[ "$EDITION" != "phosh" ]]; then
        ROOTPASSWORD=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --insecure --passwordbox "Enter new Root Password:" 8 50 \
        3>&1 1>&2 2>&3 3>&- \
        )
    fi
else 
    clear
    exit 1
fi

if [ ! -z "$ROOTPASSWORD" ]; then
    if [[ "$EDITION" != "phosh" ]]; then
        CONFIRMROOTPASSWORD=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --insecure --passwordbox "Confirm new Root Password:" 8 50 \
        3>&1 1>&2 2>&3 3>&- \
        )
    fi
else 
    clear
    exit 1
fi

if [[ "$ROOTPASSWORD" != "$CONFIRMROOTPASSWORD" ]]; then
    clear
    msg "Root passwords do not match! Please restart the installer and try again."
    exit 1
fi

if [ ! -z "$CONFIRMROOTPASSWORD" ]
then

# simple command to put the results of lsblk (just the names of the devices) into an array and make that array populate the options	
    let i=0
    W=()
    while read -r line; do
        let i=$i+1
        W+=($line "")
    done < <( lsblk -dn -o NAME )
    SDCARD=$(dialog --title "Manjaro ARM Installer v${VERSION}" \
    --menu "Choose your SDCard/eMMC/USB - Be sure the correct drive is selected! 
WARNING! This WILL destroy the data on it!" 20 50 10 \
    "${W[@]}" 3>&2 2>&1 1>&3)

# add /dev/ to the selected option above
    DEV_NAME=$SDCARD
    SDCARD=/dev/$SDCARD
    SDTYP=${SDCARD:5:2}
else 
    clear
    exit 1
fi

if [[ "$SDTYP" = "sd" ]]; then
    SDDEV=""
elif [[ "$SDTYP" = "mm" || "$SDTYP" = "nv" ]]; then
    SDDEV="p"
else 
    clear
    echo "Unkown Block Device Type"
    exit 1
fi

if [ ! -z "$SDCARD" ]; then
    if [[ "$DEVICE" = "generic-efi" ]]; then
        FSTYPE="ext4"
    else
        FSTYPE=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
            --menu "Choose a filesystem:" 10 90 10 \
            "ext4"       "Regular ext4 filesystem for the root partition" \
            "btrfs"      "Uses btrfs for root partition and makes / and /home subvolumes" \
            "f2fs"       "Use f2fs for the root partition" \
            3>&1 1>&2 2>&3 3>&-)
    fi
else 
    clear
    exit 1
fi

if [[ "$DEVICE" = "clockworkpi-a06" ]] || [[ "$DEVICE" = "pbpro" ]] || [[ "$DEVICE" = "rockpro64" ]] || [[ "$DEVICE" = "rockpi4b" ]] || [[ "$DEVICE" = "rockpi4c" ]] && [[ "$FSTYPE" != "btrfs" ]] && [[ "$FSTYPE" != "f2fs" ]]; then
    CRYPT=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
        --menu "[Experimental!] Do you want encryption on root partition?" 10 90 10 \
        "no"          "No, thanks" \
        "yes"         "Yes, please" \
        3>&1 1>&2 2>&3 3>&-)
fi

if [[ -d /dev/mapper/ROOT_MNJRO ]] && [[ "$CRYPT" = "yes" ]]; then
    clear
    exit 2
fi

if [ ! -z "$FSTYPE" ]; then
    let i=0
    W=()
    while read -r line; do
        let i=$i+1
        W+=($line "")
    done < <( timedatectl list-timezones )
    TIMEZONE=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --menu "Choose your timezone!" 20 50 15 \
    "${W[@]}" 3>&1 1>&2 2>&3 3>&- \
    )
else 
    clear
    exit 1
fi


if [ ! -z "$TIMEZONE" ]; then
    let i=0
    W=()
    while read -r line; do
        let i=$i+1
        W+=($line "")
    done < <( cat /etc/locale.gen | grep "UTF-8" | tail -n +2 | sed -e 's/^#*//' | awk '{print $1}' )
    LOCALE=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --menu "Choose your locale!" 20 50 15 \
    "${W[@]}" 3>&1 1>&2 2>&3 3>&- \
    )
else 
    clear
    exit 1
fi

if [ ! -z "$LOCALE" ]; then
    let i=0
    W=()
    while read -r line; do
        let i=$i+1
        W+=($line "")
    done < <( localectl list-keymaps )
    CLIKEYMAP=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --menu "Choose your TTY keyboard layout:" 20 50 15 \
    "${W[@]}" 3>&1 1>&2 2>&3 3>&- \
    )
else 
    clear
    exit 1
fi

if [[ "$EDITION" != "minimal" ]]; then
if [ ! -z "$CLIKEYMAP" ]; then
    let i=0
    W=()
    while read -r line; do
        let i=$i+1
        W+=($line "")
    done < <( localectl list-x11-keymap-layouts )
    X11KEYMAP=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --menu "Choose your X11 keyboard layout:" 20 50 15 \
    "${W[@]}" 3>&1 1>&2 2>&3 3>&- \
    )
else 
    clear
    exit 1
fi
fi

if [ ! -z "$CLIKEYMAP" ]; then
    HOSTNAME=$(dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --inputbox "Enter desired hostname for this system:" 8 50 \
    3>&1 1>&2 2>&3 3>&- \
    )
else 
    clear
    exit 1
fi

if [ ! -z "$HOSTNAME" ]; then
    dialog --clear --title "Manjaro ARM Installer v${VERSION}" \
    --yesno "Is the below information correct:
    Device = $DEVICE
    Edition = $EDITION
    Username = $USER
    Full Username = $FULLNAME
    Additional usergroups = $USERGROUPS
    Password for $USER = (password hidden)
    Password for root = (password hidden)
    SDCard/eMMC/USB = $SDCARD
    Filesystem = $FSTYPE
    Encryption (only on select devices) = $CRYPT
    Timezone = $TIMEZONE
    Locale = $LOCALE
    TTY Keyboard layout = $CLIKEYMAP
    X11 Keyboard layout = $X11KEYMAP
    Hostname = $HOSTNAME" 25 70 \
    3>&1 1>&2 2>&3 3>&-
else
    clear
    exit 1
fi

response=$?
case $response in
   0) clear; msg "Proceeding....";;
   1) clear; msg "Installation aborted...."; exit 1;;
   2) clear; msg "Installation not possible from an encrypted system..."; exit 1;;
   255) clear; msg "Installation aborted..."; exit 1;;
esac


# get the profiles
installer_getarmprofiles

#Package lists
sed -i 's/pico-wizard-plamo-scripts//g' $TMPDIR/arm-profiles/editions/$EDITION
sed -i 's/pico-wizard-git//g' $TMPDIR/arm-profiles/editions/$EDITION
PKG_DEVICE=$(grep "^[^#;]" $TMPDIR/arm-profiles/devices/$DEVICE | awk '{print $1}')
PKG_SHARED=$(grep "^[^#;]" $TMPDIR/arm-profiles/editions/shared | awk '{sub(/>pinephone/,""); print $1}')
case "$DEVICE" in
    pinephone)
        PKG_EDITION=$(grep "^[^#;]" $TMPDIR/arm-profiles/editions/$EDITION | awk '{sub(/>pinephone/,""); print $1}')
        cat $TMPDIR/arm-profiles/services/$EDITION | sed -e '/^#/d' -e 's/>pinephone //g' >$srv_list
        ;;
    *)
        PKG_EDITION=$(grep "^[^#;]" $TMPDIR/arm-profiles/editions/$EDITION | awk '{sub(/>pinephone.*/,""); print $1}')
        cat $TMPDIR/arm-profiles/services/$EDITION | sed -e '/^#/d' -e '/>pinephone/d' >$srv_list
        ;;
esac


# Commands
timer_start=$(get_timer)

prepare_card
create_install
cleanup
show_elapsed_time "${FUNCNAME}" "${timer_start}"
sync