diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7667836 --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +help: + @echo "make help - display tasks" + @echo " check - check androot scripts" + @echo " ensureexec - ensure all scripts are executable" + @echo " run - execute androot locally" + @echo " test - execute androot locally with diagnostic log output" + @echo " log - follow androot's log file" +check: + shellcheck *.sh +ensureexec: + chmod +x *.sh +run: ensureexec check + sudo ./androot.sh --local +test: ensureexec check + sudo env DIAG=true ./androot.sh --local +log: + @PS4='';if [ -d "/tmp/androot" ]; then set -x; tail -f /tmp/androot/androot.log; elif [ -d "/data/tmp/androot" ]; then set -x; tail -f /data/tmp/androot/androot.log; else echo ":: Error: androot's log directory could not be determined (start androot first)"; exit 1; fi diff --git a/README.md b/README.md index 6e0c2ab..b2dbee5 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,16 @@ Chroot and systemd-nspawn rootfs installer # Experimental -androot is experimental software and can lead to breakage! \ +**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. +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 +- [*Magisk*](https://github.com/topjohnwu/Magisk)/[*Magisk Delta*](https://github.com/HuskyDG/magisk-files)/[*KernelSU*](https://kernelsu.org) - curl - bash - chroot @@ -49,7 +49,7 @@ If you wish to install a (more limited) Linux distribution without root access u # 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`. +We download & decompress a rootfs, apply some magic and make it "bootable" with the help of `chroot` or `systemd-nspawn`. ## The short answer 1. check architecture 2. ask for target architecture, execution architecture(s) and distribution @@ -65,7 +65,12 @@ We download & decompress a rootfs, apply some magic and make it useable with the 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` +`make test` to run it, `make log` to view the log file. +## Recommendation +We recommend using */dev/shm* as a install location during development. Although using temporary directories \ +is disallowed for normal installations we highly recommend using */dev/shm* during development as you will \ +be wearing out your disk very fast otherwise. Just make sure that you have enough memory available and that you \ +use */dev/shm* instead of */tmp* as your install location (*/tmp* uses your disk while */dev/shm* uses your computer memory). # Annotations ```plain diff --git a/androot.sh b/androot.sh index 21265d8..a499cf4 100755 --- a/androot.sh +++ b/androot.sh @@ -1,5 +1,6 @@ #!/bin/bash # shellcheck disable=SC2181 disable=SC1091 disable=SC2236 +# shellcheck disable=SC2068 ### TOBECHANGED # shellcheck disable=SC2317 ### TOBECHANGED_END @@ -85,12 +86,14 @@ function log_askyn() { } # Global variables +## $BRANCH +export "BRANCH=develop" ## $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/" +export "DOWNLOADSERVER_BOOTSCRIPTS=https://git.staropensource.de/StarOpenSource/androot.git" ## $ARCH case "$(uname -m)" in # 64-bit architectures (supported) @@ -168,35 +171,43 @@ case "${ARCH}" in ;; 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 +function run_script() { + env "TMPDIR=${TMPDIR}" $@ + if [ ! "${?}" == "0" ]; then + exit 1 + fi +} + +case "${1}" in + "--local") + log_diag "Using local mode" + run_script ./prepare.sh + run_script ./rootfsinstall.sh --download + run_script ./rootfsinstall.sh --decompress + run_script ./mount.sh --mount + run_script ./bootscriptdl.sh --download + run_script ./bootscriptdl.sh --configure + run_script ./bootscriptdl.sh --install-qemu + exit 0 + run_script ./installsystem.sh --configure + run_script ./installsystem.sh --update + run_script ./patch.sh + run_script ./mount.sh --unmount + run_script ./finish.sh;; + "--download") + 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 + "--help"|"-h") + 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 diagnostic messages, true/false] ALLOW_SHM [allows using /dev/shm as a location, true/false]";; + *) + 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!";; +esac diff --git a/bootscriptdl.sh b/bootscriptdl.sh index 64a7d6a..395310f 100755 --- a/bootscriptdl.sh +++ b/bootscriptdl.sh @@ -9,13 +9,8 @@ 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" + echo "#### download bootscripts repository" &>> "${TMPDIR}/androot.log" + git clone --quiet --verbose -b "${BRANCH}-bootscripts" "${DOWNLOADSERVER_BOOTSCRIPTS}" "${LOCATION}/bootscripts" &>> "${TMPDIR}/androot.log" if [ ! "${?}" == "0" ]; then log_fail exit 1 @@ -25,18 +20,36 @@ case "${1}" in log_diag "Using configure mode" log_exec "Configuring bootscript scripts" cd "${LOCATION}/bootscripts/"||{ log_error "cd failed";exit 1; } + echo "#### writing bootscripts config.env" &>> "${TMPDIR}/androot.log" 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 + "--install-qemu") + log_diag "Using install-qemu mode" + for ARCH_DOWNLOAD in ${ARCH_EXECUTORS}; do + log_exec "Installing qemu-static for ${ARCH_DOWNLOAD}" + echo "#### download qemu-static for ${ARCH_DOWNLOAD}" &>> "${TMPDIR}/androot.log" + wget "${DOWNLOADSERVER_QEMUSTATIC}${ARCH_DOWNLOAD}.tar.gz" -qqq -O "${TMPDIR}/${ARCH_DOWNLOAD}.tar.gz" &>> "${TMPDIR}/androot.log" + if [ ! "${?}" == "0" ]; then + log_fail; + exit 1 + fi + echo "#### extract qemu-static for ${ARCH_DOWNLOAD}" &>> "${TMPDIR}/androot.log" + mkdir -p "${LOCATION}/bootscripts/qemu-static/${ARCH_DOWNLOAD}" + if [ ! "${?}" == "0" ]; then + log_fail; + exit 1 + fi + bsdtar -xf "${TMPDIR}/${ARCH_DOWNLOAD}.tar.gz" -C "${LOCATION}/bootscripts/qemu-static/${ARCH_DOWNLOAD}/" &>> "${TMPDIR}/andronix.log" + if [ ! "${?}" == "0" ]; then + log_fail; + exit 1 + fi + log_ok + done;; *) log_error "--download or --decompress required" exit 1;; diff --git a/prepare.sh b/prepare.sh index 3a1da1f..40a289a 100755 --- a/prepare.sh +++ b/prepare.sh @@ -22,7 +22,7 @@ function arch_target() { esac echo "ARCH_TARGET=${ANSWER,,}" > "${TMPDIR}/androot.env" } -function arch_executers() { +function arch_executors() { log_info "" log_info "Please specify the execution architecture(s)" log_info "Note: A qemu-static binary is downloaded for each execution" @@ -42,11 +42,11 @@ function arch_executers() { ;; *) log_error "Invalid execution architecture \"${ANSWER,,}\", please retry." - arch_executers + arch_executors return;; esac ### MISIMPLEMENTED - echo "ARCH_EXECUTERS=${ANSWER}" >> "${TMPDIR}/androot.env" + echo "ARCH_EXECUTORS=${ANSWER}" >> "${TMPDIR}/androot.env" } function distribution() { log_info "" @@ -73,18 +73,53 @@ function location() { ### 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." + "") + log_error "Please enter something >.<" location return;; + /tmp*) + log_error "Using /tmp is unsupported as you may run into disk space issues very quickly, please retry." + location + return;; + /dev/shm/*) + if [ ! "${DIAG}" == "true" ]; then + log_error "Using /dev/shm is unsupported as you may run into disk space issues very quickly, please retry." + location + return + fi;; /dev|/proc|/run|/sys|/dev/*|/proc/*|/run/*|/sys/*) log_error "Are you really trying that?" location - return ;; + return;; /) log_error "you're making a recipe for desaster." location - return ;; + return;; + "uwu") + log_error "eww!" + location + return;; + "I'd like to interject for a moment") + echo "#### $(whoami) wants to interject for a moment" &>> "${TMPDIR}/androot.log" + log_info "I'd just like to interject for a moment. What you're referring to as Linux," + log_info "is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux." + log_info "Linux is not an operating system unto itself, but rather another free component" + log_info "of a fully functioning GNU system made useful by the GNU corelibs, shell" + log_info "utilities and vital system components comprising a full OS as defined by POSIX." + log_info "Many computer users run a modified version of the GNU system every day," + log_info "without realizing it. Through a peculiar turn of events, the version of GNU" + log_info "which is widely used today is often called \"Linux\", and many of its users are" + log_info "not aware that it is basically the GNU system, developed by the GNU Project." + log_info "There really is a Linux, and these people are using it, but it is just a" + log_info "part of the system they use. Linux is the kernel: the program in the system" + log_info "that allocates the machine's resources to the other programs that you run." + log_info "The kernel is an essential part of an operating system, but useless by itself;" + log_info "it can only function in the context of a complete operating system. Linux is" + log_info "normally used in combination with the GNU operating system: the whole system" + log_info "is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\"" + log_info "distributions are really distributions of GNU/Linux." + location + return;; esac if [ -a "${ANSWER}" ] && [ ! -d "${ANSWER}" ]; then log_error "The location exists but is not a directory." @@ -99,13 +134,17 @@ function location() { fi else log_info "Creating location directory" - mkdir -p "${ANSWER}/rootfs" "${ANSWER}/bootscripts" + mkdir -p "${ANSWER}/rootfs" + if [ ! "${?}" == "0" ]; then + log_fail; + exit 1 + fi fi echo "LOCATION=${ANSWER}" >> "${TMPDIR}/androot.env" } arch_target -arch_executers +arch_executors distribution location diff --git a/rootfsinstall.sh b/rootfsinstall.sh index a9d1266..ede4d62 100755 --- a/rootfsinstall.sh +++ b/rootfsinstall.sh @@ -58,7 +58,6 @@ case "${1}" in 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