From 91d4be98782430e7dfb12c80b52f28490e6844e7 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Tue, 7 Nov 2023 17:23:39 +0100 Subject: [PATCH] Initial commit --- README.md | 76 +++++++++++ androot.sh | 202 ++++++++++++++++++++++++++++++ bootscriptdl.sh | 43 +++++++ mount.sh | 60 +++++++++ prepare.sh | 117 +++++++++++++++++ rootfsbuilder/.gitignore | 14 +++ rootfsbuilder/archlinux-arm64.sh | 57 +++++++++ rootfsbuilder/archlinux-x86_64.sh | 36 ++++++ rootfsinstall.sh | 69 ++++++++++ 9 files changed, 674 insertions(+) create mode 100644 README.md create mode 100755 androot.sh create mode 100644 bootscriptdl.sh create mode 100755 mount.sh create mode 100755 prepare.sh create mode 100644 rootfsbuilder/.gitignore create mode 100755 rootfsbuilder/archlinux-arm64.sh create mode 100755 rootfsbuilder/archlinux-x86_64.sh create mode 100755 rootfsinstall.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..4e65e1f --- /dev/null +++ b/README.md @@ -0,0 +1,76 @@ +# androot +Chroot and systemd-nspawn rootfs installer + +# Experimental +androot is experimental software and can lead to breakage! \ +Only run these scripts with extensive knowledge of Linux (and Android if using Termux)! + +# How to use +## Termux +### WARNING +If you want to use **androot** under Android you need a working Magisk or KernelSU installation. \ +If you wish to install a (more limited) Linux distribution without root access use [Andronix](https://play.google.com/store/apps/details?id=studio.com.techriz.andronix) instead. \ +### Dependencies +- Magisk/KernelSU +- curl +- bash +- chroot +- bsdtar +- tsu +### Use +`curl -sSL "https://git.staropensource.de/StarOpenSource/androot/raw/branch/master/androot.sh"|sudo bash - --download` + +## Linux +### Dependencies +- curl +- bash +- chroot/systemd-nspawn +- bsdtar +### Use +`curl -sSL "https://git.staropensource.de/StarOpenSource/androot/raw/branch/master/androot.sh"|sudo bash - --download` + +# Architectures +## Supported (target architectures) +- x86_64 (amd64) +- arm64 (aarch64) +## Supported (execution architectures) +- x86_64 (amd64) +- arm64 (aarch64) +- powerpc64 (ppc64,ppc64le) +- mips64 +## Unsupported +- x86 (i386,i686) +- arm +- powerpc (ppc,ppcle) +- mips + +# Distributions +- Arch Linux + +# How does this work? +## tldr +We download & decompress a rootfs, apply some magic and make it useable with the help of `chroot` or `systemd-nspawn`. +## The short answer +1. check architecture +2. ask for target architecture, execution architecture(s) and distribution +3. download rootfs +4. decompress rootfs +5. mount rootfs +6. install updates and bootscript dependencies +7. apply patches (if using chroot) +8. download bootscripts +9. unmount rootfs +10. finish and print information about how to "boot" the rootfs +## The long answer +Just read the source code. + +# How to test +`if shellcheck *.sh; then sudo env DIAG=true ./androot.sh --local; else echo ":: shellcheck failed, please resolve these errors"; fi` + +# Annotations +```plain +### TOBECHANGED - this should be changed in the future +### UNIMPLEMENTED - not yet finished +### EXPERIMENTAL - experimental code, probably not safe yet +### MISIMPLEMENTED - implemented, but wrong +``` \ No newline at end of file diff --git a/androot.sh b/androot.sh new file mode 100755 index 0000000..21265d8 --- /dev/null +++ b/androot.sh @@ -0,0 +1,202 @@ +#!/bin/bash +# shellcheck disable=SC2181 disable=SC1091 disable=SC2236 +### TOBECHANGED +# shellcheck disable=SC2317 +### TOBECHANGED_END + +# Check if root +if [ ! "${UID}" == "0" ]; then + echo ":: Error: Not running as root user" + exit 1 +fi + +# Determine $TMPDIR +if [ ! -d "${TMPDIR}" ]; then + if [ -d "/tmp" ]; then + export "TMPDIR=/tmp/androot/" + elif [ -d "/data/tmp" ]; then + export "TMPDIR=/data/tmp/androot/" + else + echo ":: Error: \$TMPDIR could not be determined" + exit 1 + fi +fi +mkdir -p "${TMPDIR}" + +# Write source file +cat << EOF > "${TMPDIR}/androot.source" +# Functions +## Indicate failure +function log_fail() { + echo -e "\r\e[0m[\e[0;31mFAIL\e[0m]" +} +## Indicate success +function log_ok() { + echo -e "\r\e[0m[\e[0;32m OK \e[0m]" +} +## Indicate running execution +function log_exec() { + echo -ne "\e[0m[\e[0;34m....\e[0m] \${*}" +} +## Diagnostic logging +function log_diag() { + if [ "\$DIAG" == "true" ]; then echo -e "\e[0m[\e[0;35mDIAG\e[0m] \${*}"; fi +} +## Informational logging +function log_info() { + echo -e "\r\e[0m[\e[0;32mINFO\e[0m] \${*}" +} +## Warning logging +function log_warn() { + echo -e "\r\e[0m[\e[0;33mWARN\e[0m] \${*}" +} +## Error logging +function log_error() { + echo -e "\r\e[0m[\e[0;31mERR!\e[0m] \${*}" +} +## Ask a question +function log_ask() { + echo -ne "\e[0m[\e[0;36mASKQ\e[0m] \${*}" + read -r ANSWER +} +## Ask for password +function log_askpasswd() { + echo -ne "\e[0m[\e[0;36mASKP\e[0m] \${*}" + read -rs ANSWER + echo "" +} +## Ask for yes or no (agreement) +function log_askyn() { + if [ -z "\${2}" ]; then + log_error "log_askyn requires at least two arguments" + exit 1 + fi + export "ANSWER_FALLBACK=\${1}" + shift + echo -ne "\e[0m[\e[0;36mASKA\e[0m] \${*}" + read -r ANSWER + if [ "\${ANSWER,,}" == "y" ] || [ "\${ANSWER,,}" == "yes" ] || [ "\${ANSWER,,}" == "true" ] || [ "\${ANSWER}" == "" ]; then + export "ANSWER=true" + elif [ "\${ANSWER,,}" == "n" ] || [ "\${ANSWER,,}" == "no" ] || [ "\${ANSWER,,}" == "false" ]; then + export "ANSWER=false" + else + export "ANSWER=\$ANSWER_FALLBACK" + fi +} + +# Global variables +## $DOWNLOADSERVER_ROOTFS +export "DOWNLOADSERVER_ROOTFS=https://fs.staropensource.de/rootfs/" +## $DOWNLOADSERVER_QEMUSTATIC +export "DOWNLOADSERVER_QEMUSTATIC=https://fs.staropensource.de/qemu-static/" +## $DOWNLOADSERVER_BOOTSCRIPTS +export "DOWNLOADSERVER_BOOTSCRIPTS=https://git.staropensource.de/StarOpenSource/androot/raw/branch/develop/" +## $ARCH +case "$(uname -m)" in + # 64-bit architectures (supported) + x86_64|amd64) + export "ARCH=x86_64";; + aarch64|aarch64_be|armv8b|armv8l) + export "ARCH=arm64";; + ppc64|ppc64le) + export "ARCH=powerpc64";; + mips64) + export "ARCH=mips64";; + + # 32-bit architectures (unsupported) + x86|i386|i686) + export "ARCH=x86";; + arm) + export "ARCH=arm";; + powerpc|ppc|ppcle) + export "ARCH=powerpc";; + mips) + export "ARCH=mips";; + *) + export "ARCH=unknown";; +esac +## $IS_ANDROID +if [ -d "/system" ] && [ -d "/data" ] && [ -d "/data/data" ] && [ ! -d "/home" ] && [ ! -d "/root" ]; then + export "IS_ANDROID=true" +else + export "IS_ANDROID=false" +fi +EOF + +# Display banner +echo -e "\e[0;33m ______ __ __ ____ ____ _____ _____ ______" +echo -e "\e[0;33m/\\ _ \\/\\ \\/\\ \\/\\ _\`\\ /\\ _\`\\ /\\ __\`\\/\\ __\`\\/\\__ _\\" +echo -e "\e[0;33m\\ \\ \\L\\ \\ \\ \`\\\\ \\ \\ \\/\\ \\ \\ \\L\\ \\ \\ \\/\\ \\ \\ \\/\\ \\/_/\\ \\/" +echo -e "\e[0;33m \\ \\ __ \\ \\ , \` \\ \\ \\ \\ \\ \\ , /\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\" +echo -e "\e[0;33m \\ \\ \\/\\ \\ \\ \\\`\\ \\ \\ \\_\\ \\ \\ \\\\ \\\\ \\ \\_\\ \\ \\ \\_\\ \\ \\ \\ \\" +echo -e "\e[0;33m \\ \\_\\ \\_\\ \\_\\ \\_\\ \\____/\\ \\_\\ \\_\\ \\_____\\ \\_____\\ \\ \\_\\" +echo -e "\e[0;33m \\/_/\\/_/\\/_/\\/_/\\/___/ \\/_/\\/ /\\/_____/\\/_____/ \\/_/" + +# Load source file +source "${TMPDIR}/androot.source" + +# Clear/create log file +{ + # if in diagnostic mode, print newlines + ## reading the log output using tail during + ## development with this is so much better, believe me + if [ "${DIAG}" == "true" ]; then echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; fi + echo "#### System information" + echo "architecture ${ARCH}" + echo "is_android ${IS_ANDROID}" + echo "download_server_rootfs ${DOWNLOADSERVER_ROOTFS}" + echo "download_server_qemustatic ${DOWNLOADSERVER_QEMUSTATIC}" + echo "download_server_bootscripts ${DOWNLOADSERVER_BOOTSCRIPTS}" + echo "args ${*}" + echo "diag ${DIAG}" + echo "#### System information" +} &> "${TMPDIR}/androot.log" + +# Diagnostic mode +log_diag "Diagnostic mode enabled" +log_diag "Arguments: ${*}" + +# Check architecture +case "${ARCH}" in + "unknown") + log_error "androot failed to detect your architecture. If you believe this is a bug, create a issue at \"https://git.staropensource.de/StarOpenSource/androot\"." + exit 1 + ;; + "x86"|"arm"|"powerpc"|"mips") + log_error "androot does not support legacy 32-bit systems, please use a 64-bit system instead." + exit 1 + ;; +esac + +if [ "${1}" == "--local" ]; then + log_diag "Using local mode" + env "TMPDIR=${TMPDIR}" ./prepare.sh + env "TMPDIR=${TMPDIR}" ./rootfsinstall.sh --download + env "TMPDIR=${TMPDIR}" ./rootfsinstall.sh --decompress + env "TMPDIR=${TMPDIR}" ./mount.sh --mount + env "TMPDIR=${TMPDIR}" ./bootscriptdl.sh --download + exit 0 + env "TMPDIR=${TMPDIR}" ./bootscriptdl.sh --configure + env "TMPDIR=${TMPDIR}" ./bootscriptdl.sh --download-qemu + env "TMPDIR=${TMPDIR}" ./installsystem.sh --configure + env "TMPDIR=${TMPDIR}" ./installsystem.sh --update + env "TMPDIR=${TMPDIR}" ./patch.sh + env "TMPDIR=${TMPDIR}" ./mount.sh --unmount + env "TMPDIR=${TMPDIR}" ./finish.sh +elif [ "${1}" == "--download" ]; then + log_diag "Using download mode" + ### UNIMPLEMENTED + log_exec Downloading files + log_fail + exit 1 + ### UNIMPLEMENTED_END +elif [ "${1}" == "--help" ]; then + log_diag "Displaying help" + log_info "Available arguments:" + log_info "--local [execute androot from cwd] --download [download androot scripts and execute] --help [display args and vars]" + log_info "Available environment variables:" + log_info "DIAG [displays or hides diagnostic messages, true/false]" +else + log_diag "i thought putting a little \"advertisement parody\" in here would be funny" + log_error "StarOpenSource is happy to present the latest and greatest version of --help! --help now uses cutting edge technology to display the most useful help to you, and that for only zero dollars!" +fi diff --git a/bootscriptdl.sh b/bootscriptdl.sh new file mode 100644 index 0000000..64a7d6a --- /dev/null +++ b/bootscriptdl.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# shellcheck disable=SC2181 disable=SC1091 disable=SC2236 + +source "${TMPDIR}/androot.source" +source "${TMPDIR}/androot.env" +log_diag "rootfsinstall is now executing, with arguments \"${*}\"" + +case "${1}" in + "--download") + log_diag "Using download mode" + log_exec "Downloading bootscripts" + cd "${LOCATION}/bootscripts"||{ log_error "cd failed";exit 1; } + git clone "${DOWNLOADSERVER_BOOTSCRIPTS}" . &>> "${TMPDIR}/androot.log" + if [ ! "${?}" == "0" ]; then + log_fail + exit 1 + fi + git checkout develop-bootscripts &>> "${TMPDIR}/androot.log" + if [ ! "${?}" == "0" ]; then + log_fail + exit 1 + fi + log_ok;; + "--configure") + log_diag "Using configure mode" + log_exec "Configuring bootscript scripts" + cd "${LOCATION}/bootscripts/"||{ log_error "cd failed";exit 1; } + cat << EOF >> "${LOCATION}/bootscripts/config.env" +COMMIT=$(git rev-parse HEAD) +LOCATION=${LOCATION} +IS_ANDROID=${IS_ANDROID} +EOF + log_ok;; + "--download-qemu") + log_diag "Using download qemu mode" + ### UNIMPLEMENTED + log_exec "Downloading qemu-static binaries" + log_fail;; + ### UNIMPLEMENTED + *) + log_error "--download or --decompress required" + exit 1;; +esac \ No newline at end of file diff --git a/mount.sh b/mount.sh new file mode 100755 index 0000000..e156872 --- /dev/null +++ b/mount.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# shellcheck disable=SC2181 disable=SC1091 disable=SC2236 +# shellcheck disable=SC2068 + +source "${TMPDIR}/androot.source" +source "${TMPDIR}/androot.env" +log_diag "mount is now executing, with arguments \"${*}\"" + +function mount_fail() { + echo "#### mount ${1}" &>> "${TMPDIR}/androot.log" + shift + mount ${@} &>> "${TMPDIR}/androot.log" + if [ ! "${?}" == "0" ]; then + log_fail + exit 1 + fi +} +function unmount_fail() { + echo "#### unmount ${1}" &>> "${TMPDIR}/androot.log" + shift + umount ${@} &>> "${TMPDIR}/androot.log" + if [ ! "${?}" == "0" ]; then + log_fail + exit 1 + fi +} + +case "${1}" in + "--mount") + log_diag "Using mount mode" + mkdir -p "${LOCATION}/mountdir" + if [ "${IS_ANDROID}" == "true" ]; then + log_exec "Remounting /data" + mount_fail "/data (remount)" "/data" -o remount,suid,exec + log_ok + fi + log_exec "Mounting rootfs" + mount_fail "rootfs" --bind "${LOCATION}/rootfs" "${LOCATION}/mountdir" -o rw,suid,dev,exec,auto,nouser,async + log_ok + log_exec "Binding directories" + mount_fail "/dev" --bind "/dev" "${LOCATION}/mountdir/dev" + mount_fail "/dev/pts" --bind "/dev/pts" "${LOCATION}/mountdir/dev/pts" + mount_fail "/sys" --bind "/sys" "${LOCATION}/mountdir/sys" + mount_fail "/proc" --bind "/proc" "${LOCATION}/mountdir/proc" + log_ok;; + "--unmount") + log_diag "Using unmount mode" + log_exec "Unmounting binds" + unmount_fail "/dev/pts" "${LOCATION}/mountdir/dev/pts" + unmount_fail "/dev" "${LOCATION}/mountdir/dev" + unmount_fail "/sys" "${LOCATION}/mountdir/sys" + unmount_fail "/proc" "${LOCATION}/mountdir/proc" + log_ok + log_exec "Unmounting rootfs" + unmount_fail "rootfs" "${LOCATION}/mountdir" + log_ok;; + *) + log_error "--mount or --unmount required" + exit 1;; +esac \ No newline at end of file diff --git a/prepare.sh b/prepare.sh new file mode 100755 index 0000000..3a1da1f --- /dev/null +++ b/prepare.sh @@ -0,0 +1,117 @@ +#!/bin/bash +# shellcheck disable=SC2181 disable=SC1091 disable=SC2236 + +source "${TMPDIR}/androot.source" +log_diag "prepare is now executing, with arguments \"${*}\"" + +function arch_target() { + log_info "" + log_info "Please select your target architecture" + log_info "Note: The target architecture may be different from the current" + log_info " architecture as it will be emulated with qemu-static (with" + log_info " a slight performance penality)." + log_info "Available target architectures: x86_64, arm64" + log_ask "Target architecture: " + case "${ANSWER,,}" in + "x86_64") ;; + "arm64") ;; + *) + log_error "Invalid target architecture \"${ANSWER,,}\", please retry." + arch_target + return;; + esac + echo "ARCH_TARGET=${ANSWER,,}" > "${TMPDIR}/androot.env" +} +function arch_executers() { + log_info "" + log_info "Please specify the execution architecture(s)" + log_info "Note: A qemu-static binary is downloaded for each execution" + log_info " architecture. If you intend on running the rootfs on this" + log_info " machine only, leave this field empty. Multiple architectures" + log_info " can be specified, if you want." + log_info "Available execution architectures: x86_64, arm64, powerpc64, mips64" + log_ask "Execution architecture(s): " + ### MISIMPLEMENTED + case "${ANSWER}" in + "x86_64") ;; + "arm64") ;; + "powerpc64") ;; + "mips64") ;; + "") + export "ANSWER=${ARCH}" + ;; + *) + log_error "Invalid execution architecture \"${ANSWER,,}\", please retry." + arch_executers + return;; + esac + ### MISIMPLEMENTED + echo "ARCH_EXECUTERS=${ANSWER}" >> "${TMPDIR}/androot.env" +} +function distribution() { + log_info "" + log_info "Please select the target distribution" + log_info "Note: Each distribution you select here will be compatible" + log_info " with every target architecture, unless noted." + log_info "Available distributions: archlinux" + log_ask "Target distribution: " + case "${ANSWER,,}" in + "archlinux") ;; + *) + log_error "Invalid distribution \"${ANSWER,,}\", please retry." + distribution + return;; + esac + echo "DISTRIBUTION=${ANSWER,,}" >> "${TMPDIR}/androot.env" +} +function location() { + log_info "" + log_info "Please enter the rootfs location" + ### TOBECHANGED + log_info "Note: This location is permanent and cannot be" + log_info " changed as of now." + ### TOBECHANGED_END + log_ask "Location: " + case "${ANSWER}" in + /tmp*|/dev/shm/*) + log_error "Using /tmp or /dev/shm is unsupported as you may run into disk space issues very quickly, please retry." + location + return;; + /dev|/proc|/run|/sys|/dev/*|/proc/*|/run/*|/sys/*) + log_error "Are you really trying that?" + location + return ;; + /) + log_error "you're making a recipe for desaster." + location + return ;; + esac + if [ -a "${ANSWER}" ] && [ ! -d "${ANSWER}" ]; then + log_error "The location exists but is not a directory." + location + return + fi + if [ -d "${ANSWER}" ]; then + if [ ! -z "$(ls -A "${ANSWER}")" ]; then + log_error "The location directory is not empty." + location + return + fi + else + log_info "Creating location directory" + mkdir -p "${ANSWER}/rootfs" "${ANSWER}/bootscripts" + fi + echo "LOCATION=${ANSWER}" >> "${TMPDIR}/androot.env" +} + +arch_target +arch_executers +distribution +location + +log_diag "androot.env:\n$(cat "${TMPDIR}/androot.env")" +{ + echo "#### rootfs configuration" + cat "${TMPDIR}/androot.env" + echo "#### rootfs configuration" +}&>> "${TMPDIR}/androot.log" \ No newline at end of file diff --git a/rootfsbuilder/.gitignore b/rootfsbuilder/.gitignore new file mode 100644 index 0000000..c8efb43 --- /dev/null +++ b/rootfsbuilder/.gitignore @@ -0,0 +1,14 @@ +# directories +archlinux-x86_64 +archlinux-arm64 + +# downloaded rootfs +archlinux-arm64-rootfs.tar.gz + +# archived rootfs +archlinux-x86_64.tar +archlinux-arm64.tar + +# compressed rootfs +archlinux-x86_64.tar.gz +archlinux-arm64.tar.gz diff --git a/rootfsbuilder/archlinux-arm64.sh b/rootfsbuilder/archlinux-arm64.sh new file mode 100755 index 0000000..f75f4e8 --- /dev/null +++ b/rootfsbuilder/archlinux-arm64.sh @@ -0,0 +1,57 @@ +#!/bin/bash +set -euo pipefail +shopt -s inherit_errexit +if [ ! "${UID}" == "0" ]; then + echo ":: Error: root user required" + exit 1 +fi +DISTRIBUTION=archlinux +ARCH=arm64 +echo ":: Generating rootfs for ${DISTRIBUTION}-${ARCH}" +if [ -f "./${DISTRIBUTION}-${ARCH}.tar.gz" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}.tar.gz" + rm -rf "./${DISTRIBUTION}-${ARCH}.tar.gz" +fi +if [ -f "./${DISTRIBUTION}-${ARCH}.tar" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}.tar" + rm -rf "./${DISTRIBUTION}-${ARCH}.tar" +fi +if [ -d "./${DISTRIBUTION}-${ARCH}" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}" + rm -rf "./${DISTRIBUTION}-${ARCH}" +fi +if [ -f "./${DISTRIBUTION}-${ARCH}-rootfs.tar" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}-rootfs.tar" + rm -rf "./${DISTRIBUTION}-${ARCH}-rootfs.tar" +fi +mkdir -p "./${DISTRIBUTION}-${ARCH}" +cd "./${DISTRIBUTION}-${ARCH}" +echo ":: Downloading rootfs" +wget "http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz" -O "../${DISTRIBUTION}-${ARCH}-rootfs.tar.gz" +echo ":: Decompressing rootfs" +bsdtar -xpf "../${DISTRIBUTION}-${ARCH}-rootfs.tar.gz" -C "." +rm -rf "../${DISTRIBUTION}-${ARCH}-rootfs.tar.gz" +echo ":: Binding" +mount --bind /dev "./dev" +mount --bind /dev/pts "./dev/pts" +mount --bind /dev/shm "./dev/shm" +mount --bind /sys "./sys" +mount --bind /proc "./proc" +mount --bind /run "./run" +echo ":: Removing packages" +cp "$(which qemu-aarch64-static)" "./bin/qemu-aarch64-static" +echo -e "pacman -R --noconfirm dhcpcd linux-aarch64 nano net-tools netctl openssh vi which\npacman -R \$(pacman -Qdtq) --recursive --unneeded --noconfirm" > "./clean.sh" +chmod +x "./clean.sh" +chroot . /bin/qemu-aarch64-static /bin/bash -c /clean.sh +echo ":: Removing files" +rm -rf "./clean.sh" "./bin/qemu-aarch64-static" "./boot/*" +echo ":: Unmounting" +bash -c "umount ./{dev/pts,dev/shm,dev,sys,proc,run};exit 0" +echo ":: Archiving rootfs" +tar --acls -cpf "../${DISTRIBUTION}-${ARCH}.tar" ./* +cd .. +rm -rf "./${DISTRIBUTION}-${ARCH}" +echo ":: Compressing rootfs" +gzip --best ${DISTRIBUTION}-${ARCH}.tar +rm -rf "./${DISTRIBUTION}-${ARCH}.tar" +echo ":: Generated rootfs for ${DISTRIBUTION}-${ARCH}" diff --git a/rootfsbuilder/archlinux-x86_64.sh b/rootfsbuilder/archlinux-x86_64.sh new file mode 100755 index 0000000..3ff8ad6 --- /dev/null +++ b/rootfsbuilder/archlinux-x86_64.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -euo pipefail +shopt -s inherit_errexit +if [ ! "${UID}" == "0" ]; then + echo ":: Error: root user required" + exit 1 +fi +DISTRIBUTION=archlinux +ARCH=x86_64 +echo ":: Generating rootfs for ${DISTRIBUTION}-${ARCH}" +if [ -f "./${DISTRIBUTION}-${ARCH}.tar.gz" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}.tar.gz" + rm -rf "./${DISTRIBUTION}-${ARCH}.tar.gz" +fi +if [ -f "./${DISTRIBUTION}-${ARCH}.tar" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}.tar" + rm -rf "./${DISTRIBUTION}-${ARCH}.tar" +fi +if [ -d "./${DISTRIBUTION}-${ARCH}" ]; then + echo ":: Removing ${DISTRIBUTION}-${ARCH}" + rm -rf "./${DISTRIBUTION}-${ARCH}" +fi +mkdir -p "./${DISTRIBUTION}-${ARCH}" +cd "./${DISTRIBUTION}-${ARCH}" +echo ":: Installing system" +pacstrap -c -G -K -M -P . base +echo ":: Unmounting (safety measure)" +bash -c "umount ./{dev/pts,dev/shm,dev,sys,proc,run};exit 0" +echo ":: Archiving rootfs" +tar --acls -cpf "../${DISTRIBUTION}-${ARCH}.tar" ./* +cd .. +rm -rf "./${DISTRIBUTION}-${ARCH}" +echo ":: Compressing rootfs" +gzip --best ${DISTRIBUTION}-${ARCH}.tar +rm -rf "./${DISTRIBUTION}-${ARCH}.tar" +echo ":: Generated rootfs for ${DISTRIBUTION}-${ARCH}" diff --git a/rootfsinstall.sh b/rootfsinstall.sh new file mode 100755 index 0000000..a9d1266 --- /dev/null +++ b/rootfsinstall.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# shellcheck disable=SC2181 disable=SC1091 disable=SC2236 + +source "${TMPDIR}/androot.source" +source "${TMPDIR}/androot.env" +log_diag "rootfsinstall is now executing, with arguments \"${*}\"" + +case "${1}" in + "--download") + log_diag "Using download mode" + if [ -f "${TMPDIR}/rootfs.env" ]; then + source "${TMPDIR}/rootfs.env" + if [ "${ARCH_TARGET_WRITTEN}" == "${ARCH_TARGET}" ] && [ "${DISTRIBUTION_WRITTEN}" == "${DISTRIBUTION}" ]; then + echo "#### found existing rootfs archive" &>> "${TMPDIR}/androot.log" + log_askyn "true" "androot found a existing rootfs archive matching your configuration, do you want to use it? " + if [ "${ANSWER}" == "true" ]; then + echo "#### skipping download" &>> "${TMPDIR}/androot.log" + exit 0 + else + echo "#### removing existing rootfs archive" &>> "${TMPDIR}/androot.log" + rm -rf "${TMPDIR}/rootfs.tar.gz" + fi + else + echo "#### removing existing rootfs archive" &>> "${TMPDIR}/androot.log" + log_diag "Removing existing rootfs archive (not matching)" + rm -rf "${TMPDIR}/rootfs.tar.gz" + fi + fi + log_exec "Downloading rootfs" + case "${ARCH_TARGET}" in + "x86_64") ;; + "arm64") ;; + *) + echo "#### invalid architecture \"${ARCH_TARGET}\"" &>> "${TMPDIR}/androot.log" + log_fail + log_error "Internal inconsistency detected: Invalid target architecture \"${ARCH_TARGET}\"" + exit 1;; + esac + case "${DISTRIBUTION}" in + "archlinux") ;; + *) + echo "#### invalid distribution \"${DISTRIBUTION}\"" &>> "${TMPDIR}/androot.log" + log_fail + log_error "Internal inconsistency detected: Invalid distribution \"${DISTRIBUTION}\"" + exit 1;; + esac + echo "#### download rootfs (${DOWNLOADSERVER_ROOTFS}${DISTRIBUTION}-${ARCH_TARGET}.tar.gz)" &>> "${TMPDIR}/androot.log" + wget "${DOWNLOADSERVER_ROOTFS}${DISTRIBUTION}-${ARCH_TARGET}.tar.gz" -qqq -O "${TMPDIR}/rootfs.tar.gz" &>> "${TMPDIR}/androot.log" + if [ ! -f "${TMPDIR}/rootfs.tar.gz" ]; then + echo "#### rootfs not present" &>> "${TMPDIR}/androot.log" + log_fail + fi + echo -e "ARCH_TARGET_WRITTEN=${ARCH_TARGET}\nDISTRIBUTION_WRITTEN=${DISTRIBUTION}" > "${TMPDIR}/rootfs.env" + log_ok;; + "--decompress") + log_diag "Using decompress mode" + log_exec "Decompressing archive" + echo "#### decompress rootfs" &>> "${TMPDIR}/androot.log" + bsdtar -xpf "${TMPDIR}/rootfs.tar.gz" -C "${LOCATION}/rootfs" &>> "${TMPDIR}/androot.log" + if [ ! "${?}" == "0" ]; then + echo "#### bsdtar failed" &>> "${TMPDIR}/androot.log" + log_fail + exit 1 + fi + log_ok;; + *) + log_error "--download or --decompress required" + exit 1;; +esac \ No newline at end of file