commit fb3f3a1611893f1ec8748db7f876b6749dffc1be Author: timoxa0 Date: Mon Oct 28 00:28:19 2024 +0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59bbb47 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +alpine_chroot/ +alpine.tar.gz diff --git a/common.d/functions.sh b/common.d/functions.sh new file mode 100644 index 0000000..7f59848 --- /dev/null +++ b/common.d/functions.sh @@ -0,0 +1,266 @@ +#!/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 <>\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 + } +} diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..3288356 --- /dev/null +++ b/setup.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +source ./common.d/functions.sh + +if [ "$(id -u)" != "0" ]; then + log "$0 must be run as root" + exit 3 +fi + +arguments "$*" +