Initial commit
This commit is contained in:
commit
91d4be9878
9 changed files with 674 additions and 0 deletions
76
README.md
Normal file
76
README.md
Normal file
|
@ -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
|
||||
```
|
202
androot.sh
Executable file
202
androot.sh
Executable file
|
@ -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
|
43
bootscriptdl.sh
Normal file
43
bootscriptdl.sh
Normal file
|
@ -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
|
60
mount.sh
Executable file
60
mount.sh
Executable file
|
@ -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
|
117
prepare.sh
Executable file
117
prepare.sh
Executable file
|
@ -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"
|
14
rootfsbuilder/.gitignore
vendored
Normal file
14
rootfsbuilder/.gitignore
vendored
Normal file
|
@ -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
|
57
rootfsbuilder/archlinux-arm64.sh
Executable file
57
rootfsbuilder/archlinux-arm64.sh
Executable file
|
@ -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}"
|
36
rootfsbuilder/archlinux-x86_64.sh
Executable file
36
rootfsbuilder/archlinux-x86_64.sh
Executable file
|
@ -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}"
|
69
rootfsinstall.sh
Executable file
69
rootfsinstall.sh
Executable file
|
@ -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
|
Loading…
Reference in a new issue