mirror of
https://github.com/AuxXxilium/arv-v-dsm.git
synced 2024-11-23 23:10:58 +07:00
149 lines
3.3 KiB
Bash
149 lines
3.3 KiB
Bash
#!/usr/bin/env bash
|
||
set -Eeuo pipefail
|
||
|
||
info () { printf "%b%s%b" "\E[1;34m❯ \E[1;36m" "$1" "\E[0m\n"; }
|
||
error () { printf "%b%s%b" "\E[1;31m❯ " "ERROR: $1" "\E[0m\n" >&2; }
|
||
|
||
trap 'error "Status $? while: $BASH_COMMAND (line $LINENO/$BASH_LINENO)"' ERR
|
||
|
||
[ ! -f "/run/entry.sh" ] && error "Script must run inside Docker container!" && exit 11
|
||
[ "$(id -u)" -ne "0" ] && error "Script must be executed with root privileges." && exit 12
|
||
|
||
# Docker environment variables
|
||
|
||
: ${TZ:=''} # System local timezone
|
||
: ${DEBUG:='N'} # Disable debugging mode
|
||
: ${COUNTRY:=''} # Country code for mirror
|
||
: ${CONSOLE:='N'} # Disable console mode
|
||
: ${ALLOCATE:='Y'} # Preallocate diskspace
|
||
: ${ARGUMENTS:=''} # Extra QEMU parameters
|
||
: ${CPU_CORES:='1'} # Amount of CPU cores
|
||
: ${RAM_SIZE:='1G'} # Maximum RAM amount
|
||
: ${DISK_SIZE:='16G'} # Initial data disk size
|
||
|
||
# Helper variables
|
||
|
||
KERNEL=$(uname -r | cut -b 1)
|
||
MINOR=$(uname -r | cut -d '.' -f2)
|
||
ARCH=$(dpkg --print-architecture)
|
||
VERS=$(qemu-system-x86_64 --version | head -n 1 | cut -d '(' -f 1)
|
||
|
||
# Check folder
|
||
|
||
STORAGE="/storage"
|
||
[ ! -d "$STORAGE" ] && error "Storage folder ($STORAGE) not found!" && exit 13
|
||
|
||
# Cleanup files
|
||
|
||
rm -f /run/dsm.url
|
||
rm -f /run/qemu.ip
|
||
rm -f /run/qemu.log
|
||
rm -f /run/qemu.pid
|
||
rm -f /run/qemu.end
|
||
|
||
# Cleanup dirs
|
||
|
||
rm -rf /tmp/dsm
|
||
rm -f /tmp/server.*
|
||
rm -rf "$STORAGE/tmp"
|
||
|
||
# Helper functions
|
||
|
||
isAlive() {
|
||
local pid=$1
|
||
|
||
if kill -0 "$pid" 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
|
||
return 1
|
||
}
|
||
|
||
pKill() {
|
||
local pid=$1
|
||
|
||
{ kill -15 "$pid" || true; } 2>/dev/null
|
||
|
||
while isAlive "$pid"; do
|
||
sleep 0.1
|
||
done
|
||
|
||
return 0
|
||
}
|
||
|
||
fKill() {
|
||
local name=$1
|
||
|
||
{ pkill -f "$name" || true; } 2>/dev/null
|
||
|
||
while pgrep -f -l "$name" >/dev/null; do
|
||
sleep 0.1
|
||
done
|
||
|
||
return 0
|
||
}
|
||
|
||
getCountry() {
|
||
local url=$1
|
||
local query=$2
|
||
local rc json result
|
||
|
||
{ json=$(curl -m 5 -H "Accept: application/json" -sfk "$url"); rc=$?; } || :
|
||
(( rc != 0 )) && return 0
|
||
|
||
{ result=$(echo "$json" | jq -r "$query" 2> /dev/null); rc=$?; } || :
|
||
(( rc != 0 )) && return 0
|
||
|
||
[[ ${#result} -ne 2 ]] && return 0
|
||
[[ "${result^^}" == "XX" ]] && return 0
|
||
|
||
COUNTRY="${result^^}"
|
||
|
||
return 0
|
||
}
|
||
|
||
setCountry() {
|
||
|
||
[[ "${TZ,,}" == "asia/harbin" ]] && COUNTRY="CN"
|
||
[[ "${TZ,,}" == "asia/beijing" ]] && COUNTRY="CN"
|
||
[[ "${TZ,,}" == "asia/urumqi" ]] && COUNTRY="CN"
|
||
[[ "${TZ,,}" == "asia/kashgar" ]] && COUNTRY="CN"
|
||
[[ "${TZ,,}" == "asia/shanghai" ]] && COUNTRY="CN"
|
||
[[ "${TZ,,}" == "asia/chongqing" ]] && COUNTRY="CN"
|
||
|
||
[ -z "$COUNTRY" ] && getCountry "https://api.ipapi.is" ".location.country_code"
|
||
[ -z "$COUNTRY" ] && getCountry "https://ifconfig.co/json" ".country_iso"
|
||
[ -z "$COUNTRY" ] && getCountry "https://api.ip2location.io" ".country_code"
|
||
[ -z "$COUNTRY" ] && getCountry "https://ipinfo.io/json" ".country"
|
||
[ -z "$COUNTRY" ] && getCountry "https://api.myip.com" ".cc"
|
||
|
||
return 0
|
||
}
|
||
|
||
addPackage() {
|
||
local pkg=$1
|
||
local desc=$2
|
||
|
||
if apt-mark showinstall | grep -qx "$pkg"; then
|
||
return 0
|
||
fi
|
||
|
||
info "Installing $desc..."
|
||
|
||
export DEBCONF_NOWARNINGS="yes"
|
||
export DEBIAN_FRONTEND="noninteractive"
|
||
|
||
[ -z "$COUNTRY" ] && setCountry
|
||
|
||
if [[ "${COUNTRY^^}" == "CN" ]]; then
|
||
sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources
|
||
fi
|
||
|
||
apt-get -qq update
|
||
apt-get -qq --no-install-recommends -y install "$pkg" > /dev/null
|
||
|
||
return 0
|
||
}
|
||
|
||
return 0
|