manjaro-arm/manjaro-arm-installer

484 lines
15 KiB
Bash

#! /bin/bash
# Set globals
TMPDIR=/var/tmp/manjaro-arm-installer
ARCH='aarch64'
NSPAWN='sudo systemd-nspawn -q --resolv-conf=copy-host --timezone=off -D'
# clearing variables
DEVICE=""
EDITION=""
USER=""
PASSWORD=""
ROOTPASSWORD=""
SDCARD=""
TIMEZONE=""
LOCALE=""
# Sanity checks for dependencies
if [ ! -f /usr/bin/sudo ]; then
echo "sudo command is missing! Please install sudo!"
exit 1
elif [ ! -f /usr/bin/git ]; then
echo "git command is missing! Please install git!"
exit 1
elif [ ! -f /usr/bin/parted ]; then
echo "parted command is missing! Please install parted!"
exit 1
elif [ ! -f /usr/bin/systemd-nspawn ]; then
echo "systemd-nspawn command is missing! Please install systemd!"
exit 1
elif [ ! -f /usr/bin/wget ]; then
echo "wget command is missing! Please install wget!"
exit 1
elif [ ! -f /usr/bin/dialog ]; then
echo "dialog command is missing! Please install dialog!"
exit 1
elif [ ! -f /usr/bin/bsdtar ]; then
echo "bsdtar command is missing! Please install libarchive!"
exit 1
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
}
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)"
}
getarmprofiles () {
if ls $TMPDIR/arm-profiles/* 1> /dev/null 2>&1; then
cd $TMPDIR/arm-profiles
git pull 1> /dev/null 2>&1
else
sudo mkdir -p $TMPDIR
sudo chmod 777 $TMPDIR
cd $TMPDIR
git clone https://gitlab.com/Strit/arm-profiles.git 1> /dev/null 2>&1
fi
}
create_install() {
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
ARCH='armv7h'
else
ARCH='aarch64'
fi
msg "Creating install for $DEVICE..."
# fetch and extract rootfs
msg "Downloading latest $ARCH rootfs..."
cd $TMPDIR
wget -q --show-progress --progress=bar:force:noscroll https://www.strits.dk/files/Manjaro-ARM-$ARCH-latest.tar.gz
msg "Extracting $ARCH rootfs..."
sudo bsdtar -xpf $TMPDIR/Manjaro-ARM-$ARCH-latest.tar.gz -C $TMPDIR/root
msg "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
msg "Installing packages for $EDITION on $DEVICE..."
# Install device and editions specific packages
$NSPAWN $TMPDIR/root pacman -Syy base $PKG_DEVICE $PKG_EDITION --needed --noconfirm
msg "Enabling services..."
# Enable services
$NSPAWN $TMPDIR/root systemctl enable systemd-networkd.service getty.target haveged.service dhcpcd.service 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root systemctl enable $SRV_EDITION 1> /dev/null 2>&1
msg "Applying overlay for $EDITION..."
sudo cp -ap $TMPDIR/arm-profiles/overlays/$EDITION/* $TMPDIR/root/
msg "Setting up users..."
#setup users
echo "$USER" > $TMPDIR/user
echo "$PASSWORD" >> $TMPDIR/password
echo "$PASSWORD" >> $TMPDIR/password
echo "$ROOTPASSWORD" >> $TMPDIR/rootpassword
echo "$ROOTPASSWORD" >> $TMPDIR/rootpassword
$NSPAWN $TMPDIR/root passwd root < $TMPDIR/rootpassword 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root useradd -m -g users -G wheel,storage,network,power -s /bin/bash $(cat $TMPDIR/user) 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root passwd $(cat $TMPDIR/user) < $TMPDIR/password 1> /dev/null 2>&1
msg "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
msg "Setting up system settings..."
#system setup
$NSPAWN $TMPDIR/root chmod u+s /usr/bin/ping 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root update-ca-trust 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root ln -sf /usr/share/zoneinfo/"$TIMEZONE" /etc/localtime 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root sed -i s/"#$LOCALE"/"$LOCALE"/g /etc/locale.gen 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root sed -i s/"LANG=en_US.utf8"/"LANG=$LOCALE"/g /etc/locale.conf 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root locale-gen
msg "Doing device specific setups for $DEVICE..."
if [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "rpi3" ]]; then
echo "dtparam=audio=on" | sudo tee --append $TMPDIR/root/boot/config.txt
echo "hdmi_drive=2" | sudo tee --append $TMPDIR/root/boot/config.txt
echo "audio_pwm_mode=2" | sudo tee --append $TMPDIR/root/boot/config.txt
echo "/dev/mmcblk0p1 /boot vfat defaults 0 0" | sudo tee --append $TMPDIR/root/etc/fstab
elif [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]]; then
$NSPAWN $TMPDIR/root systemctl enable amlogic.service 1> /dev/null 2>&1
elif [[ "$DEVICE" = "rock64" ]] || [[ "$DEVICE" = "rockpro64" ]]; then
echo "No device setups for $DEVICE..."
elif [[ "$DEVICE" = "pinebook" ]]; then
$NSPAWN $TMPDIR/root systemctl enable pinebook-post-install.service 1> /dev/null 2>&1
$NSPAWN $TMPDIR/root --user $(cat $TMPDIR/user) systemctl --user enable pinebook-user.service 1> /dev/null 2>&1
else
echo ""
fi
msg "Cleaning install for unwanted files..."
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
sudo rm $TMPDIR/root/usr/bin/qemu-arm-static
else
sudo rm $TMPDIR/root/usr/bin/qemu-aarch64-static
fi
sudo rm -rf $TMPDIR/root/var/cache/pacman/pkg/*
sudo rm -rf $TMPDIR/root/var/log/*
# Remove temp files on host
sudo rm -rf $TMPDIR/user $TMPDIR/password $TMPDIR/rootpassword
sudo rm -rf $TMPDIR/Manjaro-ARM-$ARCH-latest.tar.gz*
msg "$DEVICE $EDITION install complete"
}
prepare_card () {
msg "Getting $SDCARD ready for $DEVICE..."
# For Raspberry Pi devices
if [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "rpi3" ]]; then
#partition with boot and root
sudo parted -s $SDCARD mklabel msdos 1> /dev/null 2>&1
sudo parted -s $SDCARD mkpart primary fat32 0% 100M 1> /dev/null 2>&1
START=`cat /sys/block/$DEV_NAME/${DEV_NAME}1/start`
SIZE=`cat /sys/block/$DEV_NAME/${DEV_NAME}1/size`
END_SECTOR=$(expr $START + $SIZE)
sudo parted -s $SDCARD mkpart primary ext4 "${END_SECTOR}s" 100% 1> /dev/null 2>&1
sudo partprobe $SDCARD 1> /dev/null 2>&1
sudo mkfs.vfat "${SDCARD}1" 1> /dev/null 2>&1
sudo mkfs.ext4 "${SDCARD}2" 1> /dev/null 2>&1
#Mount SD card
mkdir -p $TMPDIR/root
mkdir -p $TMPDIR/boot
sudo mount ${SDCARD}1 $TMPDIR/boot
sudo mount ${SDCARD}2 $TMPDIR/root
# For Odroid devices
elif [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]] || [[ "$DEVICE" = "xu4" ]]; then
#Clear first 8mb
sudo dd if=/dev/zero of=${SDCARD} bs=1M count=8 1> /dev/null 2>&1
#partition with a single root partition
sudo parted -s $SDCARD mklabel msdos 1> /dev/null 2>&1
sudo parted -s $SDCARD mkpart primary ext4 0% 100% 1> /dev/null 2>&1
sudo partprobe $SDCARD 1> /dev/null 2>&1
sudo mkfs.ext4 -O ^metadata_csum,^64bit ${SDCARD}1 1> /dev/null 2>&1
#Mount SD card
mkdir -p $TMPDIR/root
sudo chmod 777 -R $TMPDIR/root
sudo mount ${SDCARD}1 $TMPDIR/root
# For pine devices
elif [[ "$DEVICE" = "pinebook" ]] || [[ "$DEVICE" = "sopine" ]]; then
#Clear first 8mb
sudo dd if=/dev/zero of=${SDCARD} bs=1M count=8 1> /dev/null 2>&1
#partition with a single root partition
sudo parted -s $SDCARD mklabel msdos 1> /dev/null 2>&1
sudo parted -s $SDCARD mkpart primary ext4 0% 100% 1> /dev/null 2>&1
sudo partprobe $SDCARD 1> /dev/null 2>&1
sudo mkfs.ext4 -O ^metadata_csum,^64bit ${SDCARD}1 1> /dev/null 2>&1
# Mount SD card
mkdir -p $TMPDIR/root
sudo chmod 777 -R $TMPDIR/root
sudo mount ${SDCARD}1 $TMPDIR/root
# For rockpro64 device
elif [[ "$DEVICE" = "rock64" ]] || [[ "$DEVICE" = "rockpro64" ]]; then
#Clear first 8mb
sudo dd if=/dev/zero of=${SDCARD} bs=1M count=32 1> /dev/null 2>&1
#partition with a single root partition
sudo parted -s $SDCARD mklabel msdos 1> /dev/null 2>&1
sudo parted -s $SDCARD mkpart primary ext4 32M 100% 1> /dev/null 2>&1
sudo partprobe $SDCARD 1> /dev/null 2>&1
sudo mkfs.ext4 -O ^metadata_csum,^64bit ${SDCARD}1 1> /dev/null 2>&1
# Mount SD card
mkdir -p $TMPDIR/root
sudo chmod 777 -R $TMPDIR/root
sudo mount ${SDCARD}1 $TMPDIR/root
fi
}
cleanup () {
msg "Writing bootloader and cleaning up after install..."
# For Raspberry Pi devices
if [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "rpi3" ]]; then
#copy rootfs contents over to the FS
sudo mv $TMPDIR/root/boot/* $TMPDIR/boot
#clean up
sudo umount $TMPDIR/root
sudo umount $TMPDIR/boot
sudo rm -r $TMPDIR/root $TMPDIR/boot
sudo partprobe $SDCARD 1> /dev/null 2>&1
# For Odroid devices
elif [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "oc2" ]] || [[ "$DEVICE" = "xu4" ]]; then
#flash bootloader
cd $TMPDIR/root/boot/
sudo ./sd_fusing.sh $SDCARD 1> /dev/null 2>&1
cd ~
#clean up
sudo umount $TMPDIR/root
sudo rm -r $TMPDIR/root
sudo partprobe $SDCARD 1> /dev/null 2>&1
# For pinebook device
elif [[ "$DEVICE" = "pinebook" ]] || [[ "$DEVICE" = "sopine" ]]; then
#flash bootloader
sudo dd if=$TMPDIR/root/boot/u-boot-sunxi-with-spl-$DEVICE.bin of=${SDCARD} bs=8k seek=1 1> /dev/null 2>&1
#clean up
sudo umount $TMPDIR/root
sudo rm -r $TMPDIR/root
sudo partprobe $SDCARD 1> /dev/null 2>&1
# For rockpro64 device
elif [[ "$DEVICE" = "rock64" ]] || [[ "$DEVICE" = "rockpro64" ]]; then
#flash bootloader
sudo dd if=$TMPDIR/root/boot/idbloader.img of=${SDCARD} seek=64 conv=notrunc 1> /dev/null 2>&1
sudo dd if=$TMPDIR/root/boot/uboot.img of=${SDCARD} seek=16384 conv=notrunc 1> /dev/null 2>&1
sudo dd if=$TMPDIR/root/boot/trust.img of=${SDCARD} seek=24576 conv=notrunc 1> /dev/null 2>&1
#clean up
sudo umount $TMPDIR/root
sudo rm -r $TMPDIR/root
sudo partprobe $SDCARD 1> /dev/null 2>&1
fi
}
# Using Dialog to ask for user input for variables
DEVICE=$(dialog --clear --title "Manjaro ARM Installer" \
--menu "Choose a device:" 20 51 6 \
"rpi3" "Raspberry Pi 3" \
"oc2" "Odroid C2" \
"pinebook" "Pinebook" \
"sopine" "Sopine/Pine64-LTS" \
"rock64" "Rock64" \
"rpi2" "Raspberry Pi 2 (unmaintained)" \
"oc1" "Odroid C1/C1+ (unmaintained)" \
"xu4" "Odroid XU4 (unmaintained)" 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
EDITION=$(dialog --clear --title "Manjaro ARM Installer" \
--menu "Choose an edition:" 20 50 5 \
"minimal" "Minimal Edition (Just CLI)" \
"lxqt" "Full LXQT Desktop and apps (lightweight)" \
"kde" "Full KDE/Plasma Desktop (Heavy)" \
"mate" "Full MATE desktop and apps (lightweight, unmaintained)" \
"i3" "Mininal i3 WM with apps (very light)" 3>&1 1>&2 2>&3 3>&-)
else
clear
exit 1
fi
if [ ! -z "$EDITION" ]
then
USER=$(dialog --clear --title "Manjaro ARM Installer" \
--inputbox "Enter username:" 8 50 \
3>&1 1>&2 2>&3 3>&-)
else
clear
exit 1
fi
if [ ! -z "$USER" ]
then
PASSWORD=$(dialog --clear --title "Manjaro ARM Installer" \
--passwordbox "Enter Password for $USER:" 8 50 \
3>&1 1>&2 2>&3 3>&- \
)
else
clear
exit 1
fi
if [ ! -z "$PASSWORD" ]
then
ROOTPASSWORD=$(dialog --clear --title "Manjaro ARM Installer" \
--passwordbox "Enter Root Password:" 8 50 \
3>&1 1>&2 2>&3 3>&- \
)
else
clear
exit 1
fi
if [ ! -z "$ROOTPASSWORD" ]
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" \
--menu "Chose your SDCard - Be sure the correct drive is selected!" 20 50 5 \
"${W[@]}" 3>&2 2>&1 1>&3)
# add /dev/ to the selected option above
SDCARD=/dev/$SDCARD
else
clear
exit 1
fi
if [ ! -z "$SDCARD" ]
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" \
--menu "Chose your timezone!" 20 50 15 \
"${W[@]}" 3>&1 1>&2 2>&3 3>&- \
)
# --inputbox "Enter timezone (example Europe/London):" 8 50 \
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 | awk '{print $1}' | sed -e 's/^#*//' )
LOCALE=$(dialog --clear --title "Manjaro ARM Installer" \
--menu "Chose your locale!" 20 50 15 \
"${W[@]}" 3>&1 1>&2 2>&3 3>&- \
)
# --inputbox "Enter locale (example en_US.UTF-8):" 8 50 \
else
clear
exit 1
fi
if [ ! -z "$LOCALE" ]
then
dialog --clear --title "Manjaro ARM Installer" \
--yesno "Is the below information correct:
Device = $DEVICE
Edition = $EDITION
Username = $USER
Password for $USER = $PASSWORD
Password for root = $ROOTPASSWORD
SD/eMMC card = $SDCARD
Timezone = $TIMEZONE
Locale = $LOCALE" 20 50 \
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;;
255) clear; msg "Installation aborted..."; exit 1;;
esac
if [[ "$DEVICE" = "oc1" ]] || [[ "$DEVICE" = "rpi2" ]] || [[ "$DEVICE" = "xu4" ]]; then
ARCH='armv7h'
else
ARCH='aarch64'
fi
# get the profiles
getarmprofiles
#Package lists
PKG_DEVICE=$(grep "^[^#;]" $TMPDIR/arm-profiles/devices/$DEVICE | awk '{print $1}')
PKG_EDITION=$(grep "^[^#;]" $TMPDIR/arm-profiles/editions/$EDITION | awk '{print $1}')
SRV_EDITION=$(grep "^[^#;]" $TMPDIR/arm-profiles/services/$EDITION | awk '{print $1}')
# Commands
timer_start=$(get_timer)
prepare_card
create_install
cleanup
show_elapsed_time "${FUNCNAME}" "${timer_start}"
sync