267 lines
6.5 KiB
Bash
267 lines
6.5 KiB
Bash
|
#!/usr/bin/env bash
|
||
|
|
||
|
ALPINE="https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86_64/alpine-minirootfs-3.20.3-x86_64.tar.gz"
|
||
|
CHROOTDIR="./alpine_chroot"
|
||
|
|
||
|
log()
|
||
|
{
|
||
|
case "$2" in
|
||
|
error)
|
||
|
printf "\e[1m\e[31mERROR:\e[0m \e[1m%s\e[0m\n" "$1">&2;;
|
||
|
internal)
|
||
|
printf "\e[1m\e[96m >>\e[0m \e[1m%s\e[0m\n" "$1">&2;;
|
||
|
ierror)
|
||
|
printf "\e[1m\e[31m >>\e[0m \e[1m%s\e[0m\n" "$1">&2;;
|
||
|
*)
|
||
|
printf "\e[1m\e[92m>>>\e[0m \e[1m%s\e[0m\n" "$1">&2;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
mkdir_if_not_exists()
|
||
|
{
|
||
|
[ -d "$1" ] && return 0
|
||
|
[ -f "$1" ] && rm -f "$1"
|
||
|
mkdir "$1"
|
||
|
}
|
||
|
|
||
|
umount_if_mouted()
|
||
|
{
|
||
|
[ ! -d "$1" ] && return 0
|
||
|
if grep -qs "$(realpath "$1")" /proc/mounts; then
|
||
|
umount "$1"
|
||
|
return $?
|
||
|
else
|
||
|
return 0
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
require ()
|
||
|
{
|
||
|
which "$1" > /dev/null 2>&1 ||
|
||
|
{
|
||
|
log "$1 not found" error
|
||
|
exit 1
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# shellcheck disable=SC2161
|
||
|
# shellcheck disable=SC2086
|
||
|
arguments() {
|
||
|
while [[ $# -gt 0 ]]; do
|
||
|
opt="$1"
|
||
|
|
||
|
shift
|
||
|
|
||
|
case "$(echo ${opt} | tr '[:upper:]' '[:lower:]')" in
|
||
|
install)
|
||
|
install_chroot
|
||
|
break 2 ;;
|
||
|
|
||
|
remove)
|
||
|
remove_chroot
|
||
|
break 2 ;;
|
||
|
|
||
|
chroot)
|
||
|
chroot_into
|
||
|
break 2 ;;
|
||
|
|
||
|
-h | -help | --help)
|
||
|
usage ;;
|
||
|
|
||
|
*)
|
||
|
log "Unknown option: $opt" error
|
||
|
break 2 ;;
|
||
|
esac
|
||
|
done
|
||
|
}
|
||
|
|
||
|
usage() {
|
||
|
log "Usage commands:"
|
||
|
|
||
|
cat <<EOF
|
||
|
# Help screen (this)
|
||
|
$0 --help or $0 -h
|
||
|
|
||
|
# Setup build chroot
|
||
|
$0 install
|
||
|
|
||
|
# Remove build chroot
|
||
|
$0 uninstall
|
||
|
|
||
|
# Chroot into
|
||
|
$0 chroot
|
||
|
EOF
|
||
|
exit 0
|
||
|
}
|
||
|
|
||
|
# shellcheck disable=SC2317
|
||
|
_shutdown()
|
||
|
{
|
||
|
detach_chroot
|
||
|
if [ -z ${1+x} ]; then
|
||
|
exit 0
|
||
|
else
|
||
|
exit "$1"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
sigterm_handler()
|
||
|
{
|
||
|
sig=$?
|
||
|
printf "\e[1m\e[31m>>\e[0m \e[1m%s\e[0m\n" "Shutdown signal received."
|
||
|
_shutdown $sig
|
||
|
}
|
||
|
|
||
|
trap 'trap " " SIGINT SIGTERM SIGHUP; kill 0; wait; sigterm_handler' SIGINT SIGTERM SIGHUP
|
||
|
|
||
|
|
||
|
# Chroot functions
|
||
|
require "lsof"
|
||
|
require "tar"
|
||
|
require "gzip"
|
||
|
require "wget"
|
||
|
|
||
|
setup_inet()
|
||
|
{
|
||
|
[ ! -d "$CHROOTDIR" ] && {
|
||
|
log "Rootdir [$CHROOTDIR] does not exists" ierror
|
||
|
return 2
|
||
|
}
|
||
|
echo "nameserver 1.1.1.1" > "$CHROOTDIR/etc/resolv.conf"
|
||
|
echo "makelnichroot" > "$CHROOTDIR/etc/hostname"
|
||
|
echo "127.0.0.1 localhost" > "$CHROOTDIR/etc/hosts"
|
||
|
}
|
||
|
|
||
|
prepare_chroot()
|
||
|
{
|
||
|
[ ! -d "$CHROOTDIR" ] && {
|
||
|
log "Rootdir [$CHROOTDIR] does not exists" ierror
|
||
|
return 2
|
||
|
}
|
||
|
|
||
|
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:\$PATH
|
||
|
|
||
|
mount --bind "$CHROOTDIR" "$CHROOTDIR"
|
||
|
mount -t proc proc "$CHROOTDIR/proc"
|
||
|
mount -t sysfs sysfs "$CHROOTDIR/sys"
|
||
|
mount -t devtmpfs devtmpfs "$CHROOTDIR/dev"
|
||
|
mount -t devpts devpts "$CHROOTDIR/dev/pts"
|
||
|
mount -t tmpfs devshm "$CHROOTDIR/dev/shm"
|
||
|
|
||
|
if uname -m | grep -q aarch64 || [ -f "/proc/sys/fs/binfmt_misc/qemu-aarch64" ]; then
|
||
|
log "Cancel qemu-aarch64-static register"
|
||
|
else
|
||
|
|
||
|
# shellcheck disable=SC2028
|
||
|
echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:'"$(realpath $CHROOTDIR/qemu-aarch64-static):PF" > /proc/sys/fs/binfmt_misc/register 2> /dev/null || true
|
||
|
|
||
|
# shellcheck disable=SC2028
|
||
|
echo ':aarch64ld:M::\x7fELF\x02\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:'"$(realpath $CHROOTDIR/qemu-aarch64-static):PF" > /proc/sys/fs/binfmt_misc/register 2> /dev/null || true
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
detach_chroot()
|
||
|
{
|
||
|
[ ! -d "$CHROOTDIR" ] && {
|
||
|
log "Rootdir [$CHROOTDIR] does not exists" ierror
|
||
|
return 2
|
||
|
}
|
||
|
|
||
|
umount_if_mouted "$CHROOTDIR/sys"
|
||
|
umount_if_mouted "$CHROOTDIR/dev/pts"
|
||
|
umount_if_mouted "$CHROOTDIR/dev/shm"
|
||
|
umount_if_mouted "$CHROOTDIR/dev"
|
||
|
umount_if_mouted "$CHROOTDIR/proc"
|
||
|
umount_if_mouted "$CHROOTDIR"
|
||
|
|
||
|
if [ -f "/proc/sys/fs/binfmt_misc/aarch64" ]; then
|
||
|
echo -1 > /proc/sys/fs/binfmt_misc/aarch64 2> /dev/null
|
||
|
fi
|
||
|
if [ -f "/proc/sys/fs/binfmt_misc/aarch64ld" ]; then
|
||
|
echo -1 > /proc/sys/fs/binfmt_misc/aarch64ld 2> /dev/null
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
install_chroot()
|
||
|
{
|
||
|
[ -d "$CHROOTDIR" ] && {
|
||
|
log "Chroot already installed" error
|
||
|
exit 1
|
||
|
}
|
||
|
mkdir "$CHROOTDIR"
|
||
|
[ ! -f "./alpine.tar.gz" ] && {
|
||
|
log "Downloading alpine rootfs tarball"
|
||
|
wget -q --show-progress "$ALPINE" -O "./alpine.tar.gz" || {
|
||
|
ec=$?
|
||
|
log "Failed to download rootfs tarball" error
|
||
|
exit "$ec"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
log "Extracting alpine rootfs tarball"
|
||
|
tar -xzf "./alpine.tar.gz" -C "$CHROOTDIR/" || {
|
||
|
log "Failed to extract rootfs" error
|
||
|
}
|
||
|
setup_inet
|
||
|
prepare_chroot || {
|
||
|
log "Failed to setup chroot" error
|
||
|
exit 1
|
||
|
}
|
||
|
log "Updating apk repos"
|
||
|
chroot "$CHROOTDIR" apk update || {
|
||
|
log "Failed to update apk repos" error
|
||
|
exit 1
|
||
|
}
|
||
|
log "Installing pakages"
|
||
|
chroot "$CHROOTDIR" apk add shadow fish bash git debootstrap pixz losetup rsync pv wget e2fsprogs libarchive-tools coreutils || {
|
||
|
log "Failed to install packages" error
|
||
|
exit 1
|
||
|
}
|
||
|
chroot "$CHROOTDIR" chsh -s /usr/bin/fish root
|
||
|
log "Cloning makelni repo"
|
||
|
chroot "$CHROOTDIR" git clone "https://git.timoxa0.su/timoxa0/makelni.git" /makelni || {
|
||
|
log "Failed to clone makelni repo" error
|
||
|
exit 1
|
||
|
}
|
||
|
log "Installing qemu-aarch64-static"
|
||
|
{
|
||
|
wget -q --show-progress -N https://github.com/multiarch/qemu-user-static/releases/download/v7.2.0-1/qemu-aarch64-static -O "$CHROOTDIR/qemu-aarch64-static" && chmod 755 "$CHROOTDIR/qemu-aarch64-static"
|
||
|
} || {
|
||
|
log "Failed to install qemu-aarch64-static" error
|
||
|
exit 1
|
||
|
}
|
||
|
detach_chroot || {
|
||
|
log "Failed to detach chroot" error
|
||
|
exit 1
|
||
|
}
|
||
|
log "Done!"
|
||
|
exit 0
|
||
|
}
|
||
|
|
||
|
remove_chroot()
|
||
|
{
|
||
|
[ ! -d "$CHROOTDIR" ] && {
|
||
|
log "Chroot not installed" error
|
||
|
exit 1
|
||
|
}
|
||
|
detach_chroot || {
|
||
|
log "Failed to umount chroot" error
|
||
|
exit 1
|
||
|
}
|
||
|
log "Done!"
|
||
|
rm -rf "${CHROOTDIR:?}/"
|
||
|
}
|
||
|
|
||
|
chroot_into()
|
||
|
{
|
||
|
prepare_chroot || {
|
||
|
log "Failed to setup chroot" error
|
||
|
exit 1
|
||
|
}
|
||
|
chroot "$CHROOTDIR" /usr/bin/fish
|
||
|
detach_chroot || {
|
||
|
log "Failed to detach chroot" error
|
||
|
exit 1
|
||
|
}
|
||
|
}
|