From 438bab68ee8a46c22aa5d034d087145343c53711 Mon Sep 17 00:00:00 2001 From: hoangvv Date: Mon, 18 Nov 2024 16:16:36 +0700 Subject: [PATCH] create version-1.4-dev --- version-1.4-dev/errors | 0 version-1.4-dev/install.sh | 771 +++++++++++++++++++++++++++++++++++ version-1.4-dev/services.sh | 250 ++++++++++++ version-1.4-dev/uninstall.sh | 318 +++++++++++++++ version-1.4-dev/update.sh | 566 +++++++++++++++++++++++++ 5 files changed, 1905 insertions(+) create mode 100644 version-1.4-dev/errors create mode 100755 version-1.4-dev/install.sh create mode 100755 version-1.4-dev/services.sh create mode 100644 version-1.4-dev/uninstall.sh create mode 100644 version-1.4-dev/update.sh diff --git a/version-1.4-dev/errors b/version-1.4-dev/errors new file mode 100644 index 0000000..e69de29 diff --git a/version-1.4-dev/install.sh b/version-1.4-dev/install.sh new file mode 100755 index 0000000..7f3461d --- /dev/null +++ b/version-1.4-dev/install.sh @@ -0,0 +1,771 @@ +#!/usr/bin/bash +# +# NextZenOS Installer Script v1.0 +# Requires: bash, mv, rm, tr, grep, sed, curl/wget, tar, smartmontools, parted, ntfs-3g, net-tools +# +# This script installs NextZenOS to your system. +# Usage: +# +# $ wget -qO- https://dl.nextzenos.com/| bash +# or +# $ curl -fsSL https://dl.nextzenos.com/ | bash +# +# In automated environments, you may want to run as root. +# If using curl, we recommend using the -fsSL flags. +# +# This only work on Linux systems. Please +# open an issue if you notice any bugs. +# +echo -e "\e[0m\c" + +# shellcheck disable=SC2016 +echo ' + _ _ _______ _______ __________ _ _ +| \ | | ____\ \/ /_ _|__ / ____| \ | | +| \| | _| \ / | | / /| _| | \| | +| |\ | |___ / \ | | / /_| |___| |\ | +|_| \_|_____/_/\_\ |_| /____|_____|_| \_| + --- Power by NextZEN --- +' +export PATH=/usr/sbin:$PATH +export DEBIAN_FRONTEND=noninteractive +# set -x +set -e + +############################################################################### +# GOLBALS # +############################################################################### + +((EUID)) && sudo_cmd="sudo" + +# shellcheck source=/dev/null +source /etc/os-release +# Version +readonly Version="version-1.4-dev" +readonly Branch="version-1.x" +# SYSTEM REQUIREMENTS +readonly MINIMUM_DISK_SIZE_GB="5" +readonly MINIMUM_MEMORY="400" +readonly MINIMUM_DOCKER_VERSION="20" +readonly NEXTZEN_DEPENDS_PACKAGE=('wget' 'curl' 'smartmontools' 'parted' 'ntfs-3g' 'net-tools' 'udevil' 'samba' 'cifs-utils' 'mergerfs' 'unzip') +readonly NEXTZEN_DEPENDS_COMMAND=('wget' 'curl' 'smartctl' 'parted' 'ntfs-3g' 'netstat' 'udevil' 'smbd' 'mount.cifs' 'mount.mergerfs' 'unzip') + +# SYSTEM INFO +PHYSICAL_MEMORY=$(LC_ALL=C free -m | awk '/Mem:/ { print $2 }') +readonly PHYSICAL_MEMORY + +FREE_DISK_BYTES=$(LC_ALL=C df -P / | tail -n 1 | awk '{print $4}') +readonly FREE_DISK_BYTES + +readonly FREE_DISK_GB=$((FREE_DISK_BYTES / 1024 / 1024)) + +LSB_DIST=$( ([ -n "${ID_LIKE}" ] && echo "${ID_LIKE}") || ([ -n "${ID}" ] && echo "${ID}")) +readonly LSB_DIST + +DIST=$(echo "${ID}") +readonly DIST + +UNAME_M="$(uname -m)" +readonly UNAME_M + +UNAME_U="$(uname -s)" +readonly UNAME_U + +readonly NEXTZEN_CONF_PATH=/etc/casaos/gateway.ini +readonly NEXTZEN_UNINSTALL_URL="https://git.nextzenos.com/CDN/NextZenOS/raw/branch/$Branch/$Version/uninstall.sh" +readonly BACKUP_UNINSTALL_URL="https://raw.githubusercontent.com/KaySar12/NextZen-Script/refs/heads/$Version/uninstall.sh" +readonly NEXTZEN_UNINSTALL_PATH=/usr/bin/nextzenos-uninstall + +# REQUIREMENTS CONF PATH +# Udevil +readonly UDEVIL_CONF_PATH=/etc/udevil/udevil.conf +readonly DEVMON_CONF_PATH=/etc/conf.d/devmon + +# COLORS +readonly COLOUR_RESET='\e[0m' +readonly aCOLOUR=( + '\e[38;5;154m' # green | Lines, bullets and separators + '\e[1m' # Bold white | Main descriptions + '\e[90m' # Grey | Credits + '\e[91m' # Red | Update notifications Alert + '\e[33m' # Yellow | Emphasis +) + +readonly GREEN_LINE=" ${aCOLOUR[0]}─────────────────────────────────────────────────────$COLOUR_RESET" +readonly GREEN_BULLET=" ${aCOLOUR[0]}-$COLOUR_RESET" +readonly GREEN_SEPARATOR="${aCOLOUR[0]}:$COLOUR_RESET" + +# CASAOS VARIABLES +TARGET_ARCH="" +TMP_ROOT=/tmp/casaos-installer +REGION="UNKNOWN" +DOWNLOAD_DOMAIN="https://cdn.nextzenos.com" +trap 'onCtrlC' INT +onCtrlC() { + echo -e "${COLOUR_RESET}" + exit 1 +} + +############################################################################### +# Helpers # +############################################################################### + +####################################### +# Custom printing function +# Globals: +# None +# Arguments: +# $1 0:OK 1:FAILED 2:INFO 3:NOTICE +# message +# Returns: +# None +####################################### + +Show() { + # OK + if (($1 == 0)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} OK $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + # FAILED + elif (($1 == 1)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]}FAILED$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + exit 1 + # INFO + elif (($1 == 2)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} INFO $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + # NOTICE + elif (($1 == 3)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]}NOTICE$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + fi +} + +Warn() { + echo -e "${aCOLOUR[3]}$1$COLOUR_RESET" +} + +GreyStart() { + echo -e "${aCOLOUR[2]}\c" +} + +ColorReset() { + echo -e "$COLOUR_RESET\c" +} + +# Clear Terminal +Clear_Term() { + + # Without an input terminal, there is no point in doing this. + [[ -t 0 ]] || return + + # Printing terminal height - 1 newlines seems to be the fastest method that is compatible with all terminal types. + lines=$(tput lines) i newlines + local lines + + for ((i = 1; i < ${lines% *}; i++)); do newlines+='\n'; done + echo -ne "\e[0m$newlines\e[H" + +} + +# Check file exists +exist_file() { + if [ -e "$1" ]; then + return 1 + else + return 2 + fi +} + +############################################################################### +# FUNCTIONS # +############################################################################### + +# 0 Get download url domain +# To solve the problem that Chinese users cannot access github. +# Get_Download_Url_Domain() { +# # Use ipconfig.io/country and https://ifconfig.io/country_code to get the country code +# REGION=$(${sudo_cmd} curl --connect-timeout 2 -s ipconfig.io/country || echo "") +# if [ "${REGION}" = "" ]; then +# REGION=$(${sudo_cmd} curl --connect-timeout 2 -s https://ifconfig.io/country_code || echo "") +# fi +# if [[ "${REGION}" = "China" ]] || [[ "${REGION}" = "CN" ]]; then +# GITEA_DOWNLOAD_DOMAIN="https://casaos.oss-cn-shanghai.aliyuncs.com/" +# fi +# } + +# 1 Check Archclient_iduip +Check_Arch() { + case $UNAME_M in + *aarch64*) + TARGET_ARCH="arm64" + ;; + *64*) + TARGET_ARCH="amd64" + ;; + *armv7*) + TARGET_ARCH="arm-7" + ;; + *) + Show 1 "Aborted, unsupported or unknown architecture: $UNAME_M" + exit 1 + ;; + esac + Show 0 "Your hardware architecture is : $UNAME_M" + NEXTZEN_PACKAGES=( + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-gateway.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-message-bus.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-user-service.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-local-storage.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-app-management.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-cli.tar.gz" + "${DOWNLOAD_DOMAIN}/CDN/NextZenOS/releases/download/$Version/linux-${TARGET_ARCH}-nextzenos-ui.tar.gz" + ) +} +# PACKAGE LIST OF CASAOS (make sure the services are in the right order) +NEXTZEN_SERVICES=( + "casaos-gateway.service" + "casaos-message-bus.service" + "casaos-user-service.service" + "casaos-local-storage.service" + "casaos-app-management.service" + "rclone.service" + "casaos.service" # must be the last one so update from UI can work +) + +# 2 Check Distribution +Check_Distribution() { + sType=0 + notice="" + case $LSB_DIST in + *debian*) ;; + + *ubuntu*) ;; + + *raspbian*) ;; + + *openwrt*) + Show 1 "Aborted, OpenWrt cannot be installed using this script." + exit 1 + ;; + *alpine*) + Show 1 "Aborted, Alpine installation is not yet supported." + exit 1 + ;; + *trisquel*) ;; + + *) + sType=3 + notice="We have not tested it on this system and it may fail to install." + ;; + esac + Show ${sType} "Your Linux Distribution is : ${DIST} ${notice}" + + if [[ ${sType} == 1 ]]; then + select yn in "Yes" "No"; do + case $yn in + [yY][eE][sS] | [yY]) + Show 0 "Distribution check has been ignored." + break + ;; + [nN][oO] | [nN]) + Show 1 "Already exited the installation." + exit 1 + ;; + esac + done "${PREFIX}/tmp/nextzenos-uninstall" + else + echo "Backup URL is also not working, cannot uninstall Nextzen." + return 1 + fi + else + curl -fsSLk "$NEXTZEN_UNINSTALL_URL" >"${PREFIX}/tmp/nextzenos-uninstall" + fi +} +Check_Dependency_Installation() { + for ((i = 0; i < ${#NEXTZEN_DEPENDS_COMMAND[@]}; i++)); do + cmd=${NEXTZEN_DEPENDS_COMMAND[i]} + if [[ ! -x $(${sudo_cmd} which "$cmd") ]]; then + packagesNeeded=${NEXTZEN_DEPENDS_PACKAGE[i]} + Show 1 "Dependency \e[33m$packagesNeeded \e[0m installation failed, please try again manually!" + exit 1 + fi + done +} + +# Check Docker running +Check_Docker_Running() { + for ((i = 1; i <= 3; i++)); do + sleep 3 + if [[ ! $(${sudo_cmd} systemctl is-active docker) == "active" ]]; then + Show 1 "Docker is not running, try to start" + ${sudo_cmd} systemctl start docker + else + break + fi + done +} + +#Check Docker Installed and version +Check_Docker_Install() { + if [[ -x "$(command -v docker)" ]]; then + Docker_Version=$(${sudo_cmd} docker version --format '{{.Server.Version}}') + if [[ $? -ne 0 ]]; then + Install_Docker + elif [[ ${Docker_Version:0:2} -lt "${MINIMUM_DOCKER_VERSION}" ]]; then + Show 1 "Recommended minimum Docker version is \e[33m${MINIMUM_DOCKER_VERSION}.xx.xx\e[0m,\Current Docker version is \e[33m${Docker_Version}\e[0m,\nPlease uninstall current Docker and rerun the NextZenOS installation script." + exit 1 + else + Show 0 "Current Docker version is ${Docker_Version}." + fi + else + Install_Docker + fi +} + +# Check Docker installed +Check_Docker_Install_Final() { + if [[ -x "$(command -v docker)" ]]; then + Docker_Version=$(${sudo_cmd} docker version --format '{{.Server.Version}}') + if [[ $? -ne 0 ]]; then + Install_Docker + elif [[ ${Docker_Version:0:2} -lt "${MINIMUM_DOCKER_VERSION}" ]]; then + Show 1 "Recommended minimum Docker version is \e[33m${MINIMUM_DOCKER_VERSION}.xx.xx\e[0m,\Current Docker version is \e[33m${Docker_Version}\e[0m,\nPlease uninstall current Docker and rerun the NextZenOS installation script." + exit 1 + else + Show 0 "Current Docker version is ${Docker_Version}." + Check_Docker_Running + fi + else + Show 1 "Installation failed, please run 'curl -fsSL https://get.docker.com | bash' and rerun the NextZenOS installation script." + exit 1 + fi +} + +#Install Docker +Install_Docker() { + Show 2 "Install the necessary dependencies: \e[33mDocker \e[0m" + if [[ ! -d "${PREFIX}/etc/apt/sources.list.d" ]]; then + ${sudo_cmd} mkdir -p "${PREFIX}/etc/apt/sources.list.d" + fi + GreyStart + if [[ "${REGION}" = "CN" ]]; then + ${sudo_cmd} curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun + else + ${sudo_cmd} curl -fsSL https://get.docker.com | bash + fi + ColorReset + if [[ $? -ne 0 ]]; then + Show 1 "Installation failed, please try again." + exit 1 + else + Check_Docker_Install_Final + fi +} + +#Install Rclone +Install_rclone_from_source() { + ${sudo_cmd} wget -qO ./install.sh https://rclone.org/install.sh + if [[ "${REGION}" = "China" ]] || [[ "${REGION}" = "CN" ]]; then + sed -i 's/downloads.rclone.org/casaos.oss-cn-shanghai.aliyuncs.com/g' ./install.sh + else + sed -i 's/downloads.rclone.org/get.casaos.io/g' ./install.sh + fi + ${sudo_cmd} chmod +x ./install.sh + ${sudo_cmd} ./install.sh || { + Show 1 "Installation failed, please try again." + ${sudo_cmd} rm -rf install.sh + exit 1 + } + ${sudo_cmd} rm -rf install.sh + Show 0 "Rclone v1.61.1 installed successfully." +} + +Install_Rclone() { + Show 2 "Install the necessary dependencies: Rclone" + if [[ -x "$(command -v rclone)" ]]; then + version=$(rclone --version 2>>errors | head -n 1) + target_version="rclone v1.61.1" + rclone1="${PREFIX}/usr/share/man/man1/rclone.1.gz" + if [ "$version" != "$target_version" ]; then + Show 3 "Will change rclone from $version to $target_version." + rclone_path=$(command -v rclone) + ${sudo_cmd} rm -rf "${rclone_path}" + if [[ -f "$rclone1" ]]; then + ${sudo_cmd} rm -rf "$rclone1" + fi + Install_rclone_from_source + else + Show 2 "Target version already installed." + fi + else + Install_rclone_from_source + fi + ${sudo_cmd} systemctl enable rclone || Show 3 "Service rclone does not exist." +} + +#Configuration Addons +Configuration_Addons() { + Show 2 "Configuration Addons" + #Remove old udev rules + if [[ -f "${PREFIX}/etc/udev/rules.d/11-usb-mount.rules" ]]; then + ${sudo_cmd} rm -rf "${PREFIX}/etc/udev/rules.d/11-usb-mount.rules" + fi + + if [[ -f "${PREFIX}/etc/systemd/system/usb-mount@.service" ]]; then + ${sudo_cmd} rm -rf "${PREFIX}/etc/systemd/system/usb-mount@.service" + fi + + #Udevil + if [[ -f $PREFIX${UDEVIL_CONF_PATH} ]]; then + + # GreyStart + # Add a devmon user + USERNAME=devmon + id ${USERNAME} &>/dev/null || { + ${sudo_cmd} useradd -M -u 300 ${USERNAME} + ${sudo_cmd} usermod -L ${USERNAME} + } + + ${sudo_cmd} sed -i '/exfat/s/, nonempty//g' "$PREFIX"${UDEVIL_CONF_PATH} + ${sudo_cmd} sed -i '/default_options/s/, noexec//g' "$PREFIX"${UDEVIL_CONF_PATH} + ${sudo_cmd} sed -i '/^ARGS/cARGS="--mount-options nosuid,nodev,noatime --ignore-label EFI"' "$PREFIX"${DEVMON_CONF_PATH} + + # Add and start Devmon service + GreyStart + ${sudo_cmd} systemctl enable devmon@devmon + ${sudo_cmd} systemctl start devmon@devmon + ColorReset + # ColorReset + fi +} + +# Download And Install NextZenOS +DownloadAndInstallNextzenOS() { + if [ -z "${BUILD_DIR}" ]; then + ${sudo_cmd} rm -rf ${TMP_ROOT} + mkdir -p ${TMP_ROOT} || Show 1 "Failed to create temporary directory" + TMP_DIR=$(${sudo_cmd} mktemp -d -p ${TMP_ROOT} || Show 1 "Failed to create temporary directory") + ${sudo_cmd} chmod 755 "${TMP_DIR}" + ${sudo_cmd} chown "$USER" "${TMP_DIR}" + pushd "${TMP_DIR}" + + for PACKAGE in "${NEXTZEN_PACKAGES[@]}"; do + Show 2 "Downloading ${PACKAGE}..." + GreyStart + ${sudo_cmd} wget -t 3 -q --show-progress -c "${PACKAGE}" || Show 1 "Failed to download package" + ColorReset + done + + for PACKAGE_FILE in linux-*.tar.gz; do + Show 2 "Extracting ${PACKAGE_FILE}..." + GreyStart + ${sudo_cmd} tar zxf "${PACKAGE_FILE}" || Show 1 "Failed to extract package" + ColorReset + done + + BUILD_DIR=$(${sudo_cmd} realpath -e "${TMP_DIR}"/build || Show 1 "Failed to find build directory") + echo "${BUILD_DIR}" + popd + + fi + + for SERVICE in "${NEXTZEN_SERVICES[@]}"; do + if ${sudo_cmd} systemctl --quiet is-active "${SERVICE}"; then + Show 2 "Stopping ${SERVICE}..." + GreyStart + ${sudo_cmd} systemctl stop "${SERVICE}" || Show 3 "Service ${SERVICE} does not exist." + ColorReset + fi + done + + Show 2 "Installing NextZenOS..." + SYSROOT_DIR=$(realpath -e "${BUILD_DIR}"/sysroot || Show 1 "Failed to find sysroot directory") + + # Generate manifest for uninstallation + MANIFEST_FILE=${BUILD_DIR}/sysroot/var/lib/casaos/manifest + ${sudo_cmd} touch "${MANIFEST_FILE}" || Show 1 "Failed to create manifest file" + + GreyStart + find "${SYSROOT_DIR}" -type f | ${sudo_cmd} cut -c ${#SYSROOT_DIR}- | ${sudo_cmd} cut -c 2- | ${sudo_cmd} tee "${MANIFEST_FILE}" >/dev/null || Show 1 "Failed to create manifest file" + + ${sudo_cmd} cp -rf "${SYSROOT_DIR}"/* / || Show 1 "Failed to install NextZenOS" + ColorReset + + SETUP_SCRIPT_DIR=$(realpath -e "${BUILD_DIR}"/scripts/setup/script.d || Show 1 "Failed to find setup script directory") + + for SETUP_SCRIPT in "${SETUP_SCRIPT_DIR}"/*.sh; do + Show 2 "Running ${SETUP_SCRIPT}..." + GreyStart + ${sudo_cmd} bash "${SETUP_SCRIPT}" || Show 1 "Failed to run setup script" + ColorReset + done + + UI_EVENTS_REG_SCRIPT=/etc/casaos/start.d/register-ui-events.sh + if [[ -f ${UI_EVENTS_REG_SCRIPT} ]]; then + ${sudo_cmd} chmod +x $UI_EVENTS_REG_SCRIPT + fi + # Modify app store configuration + #Download Uninstall Script + if [[ -f $PREFIX/tmp/nextzenos-uninstall ]]; then + ${sudo_cmd} rm -rf "$PREFIX/tmp/nextzenos-uninstall" + fi + # ${sudo_cmd} curl -fsSLk "$NEXTZEN_UNINSTALL_URL" >"$PREFIX/tmp/nextzenos-uninstall" + setup_uninstall_nextzen + ${sudo_cmd} cp -rf "$PREFIX/tmp/nextzenos-uninstall" $NEXTZEN_UNINSTALL_PATH || { + Show 1 "Download uninstall script failed, Please check if your internet connection is working and retry." + exit 1 + } + + ${sudo_cmd} chmod +x $NEXTZEN_UNINSTALL_PATH + + Install_Rclone + + for SERVICE in "${NEXTZEN_SERVICES[@]}"; do + Show 2 "Starting ${SERVICE}..." + GreyStart + ${sudo_cmd} systemctl start "${SERVICE}" || Show 3 "Service ${SERVICE} does not exist." + ColorReset + done +} + +Clean_Temp_Files() { + Show 2 "Clean temporary files..." + ${sudo_cmd} rm -rf "${TMP_DIR}" || Show 1 "Failed to clean temporary files" +} + +Check_Service_status() { + for SERVICE in "${NEXTZEN_SERVICES[@]}"; do + Show 2 "Checking ${SERVICE}..." + if [[ $(${sudo_cmd} systemctl is-active "${SERVICE}") == "active" ]]; then + Show 0 "${SERVICE} is running." + else + Show 1 "${SERVICE} is not running, Please reinstall." + exit 1 + fi + done +} + +# Get the physical NIC IP +Get_IPs() { + PORT=$(${sudo_cmd} cat ${NEXTZEN_CONF_PATH} | grep port | sed 's/port=//') + ALL_NIC=$($sudo_cmd ls /sys/class/net/ | grep -v "$(ls /sys/devices/virtual/net/)") + for NIC in ${ALL_NIC}; do + IP=$($sudo_cmd ifconfig "${NIC}" | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | sed -e 's/addr://g') + if [[ -n $IP ]]; then + if [[ "$PORT" -eq "80" ]]; then + echo -e "${GREEN_BULLET} http://$IP (${NIC})" + else + echo -e "${GREEN_BULLET} http://$IP:$PORT (${NIC})" + fi + fi + done +} + +# Show Welcome Banner +Welcome_Banner() { + NEXTZEN_TAG=$(casaos -v) + + echo -e "${GREEN_LINE}${aCOLOUR[1]}" + echo -e " NextZenOS ${NEXTZEN_TAG}${COLOUR_RESET} is running at${COLOUR_RESET}${GREEN_SEPARATOR}" + echo -e "${GREEN_LINE}" + Get_IPs + echo -e " Open your browser and visit the above address." + echo -e "${GREEN_LINE}" + echo -e " ${COLOUR_RESET}${aCOLOUR[1]}Uninstall ${COLOUR_RESET}: nextzenos-uninstall" + echo -e "${COLOUR_RESET}" +} + +############################################################################### +# Main # +############################################################################### + +#Usage +usage() { + cat <<-EOF + Usage: install.sh [options] + Valid options are: + -p Specify build directory (Local install) + -h Show this help message and exit + EOF + exit "$1" +} + +while getopts ":p:h" arg; do + case "$arg" in + p) + BUILD_DIR=$OPTARG + ;; + h) + usage 0 + ;; + *) + usage 1 + ;; + esac +done + +# Step 0 : Get Download Url Domain +# Get_Download_Url_Domain +# Step 1: Check ARCH +Check_Arch + +# Step 2: Check OS +Check_OS + +# Step 3: Check Distribution +Check_Distribution + +# Step 4: Check System Required +Check_Memory +Check_Disk + +# Step 5: Install Depends +Update_Package_Resource +Install_Depends +Check_Dependency_Installation + +# Step 6: Check And Install Docker +Check_Docker_Install + +# Step 7: Configuration Addon +Configuration_Addons + +# Step 8: Download And Install NextZenOS +DownloadAndInstallNextzenOS + +# Step 9: Check Service Status +Check_Service_status + +# Step 10: Clear Term and Show Welcome Banner +Welcome_Banner + +# set +x diff --git a/version-1.4-dev/services.sh b/version-1.4-dev/services.sh new file mode 100755 index 0000000..9e4459f --- /dev/null +++ b/version-1.4-dev/services.sh @@ -0,0 +1,250 @@ +#! /bin/bash + +############################################################################### +# GOLBALS # +############################################################################### +echo ' + _ _ _______ _______ __________ _ _ +| \ | | ____\ \/ /_ _|__ / ____| \ | | +| \| | _| \ / | | / /| _| | \| | +| |\ | |___ / \ | | / /_| |___| |\ | +|_| \_|_____/_/\_\ |_| /____|_____|_| \_| + --- Power by NextZEN --- +' +((EUID)) && sudo_cmd="sudo" +SERVICES=( + "casaos-gateway.service" + "casaos-message-bus.service" + "casaos-user-service.service" + "casaos-local-storage.service" + "casaos-app-management.service" + "rclone.service" + "casaos.service" # must be the last one so update from UI can work +) +# COLORS +readonly COLOUR_RESET='\e[0m' +readonly aCOLOUR=( + '\e[38;5;154m' # green | Lines, bullets and separators + '\e[1m' # Bold white | Main descriptions + '\e[90m' # Grey | Credits + '\e[91m' # Red | Update notifications Alert + '\e[33m' # Yellow | Emphasis +) + +readonly GREEN_LINE=" ${aCOLOUR[0]}─────────────────────────────────────────────────────$COLOUR_RESET" +readonly GREEN_BULLET=" ${aCOLOUR[0]}-$COLOUR_RESET" +readonly GREEN_SEPARATOR="${aCOLOUR[0]}:$COLOUR_RESET" +NEXTZEN_DOWNLOAD_DOMAIN="https://dl.nextzenos.com" +CASAOS_DOWNLOAD_DOMAIN="https://get.casaos.io" +Show() { + # OK + if (($1 == 0)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} OK $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + # FAILED + elif (($1 == 1)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]}FAILED$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + exit 1 + # INFO + elif (($1 == 2)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} INFO $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + # NOTICE + elif (($1 == 3)); then + echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]}NOTICE$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2" + fi +} +stop() { + for SERVICE in "${SERVICES[@]}"; do + Show 2 "Stopping ${SERVICE}..." + + ${sudo_cmd} systemctl stop "${SERVICE}" || Show 3 "Service ${SERVICE} does not exist." + + done + main +} + +restart() { + for SERVICE in "${SERVICES[@]}"; do + Show 2 "restart ${SERVICE}..." + + ${sudo_cmd} systemctl restart "${SERVICE}" || Show 3 "Service ${SERVICE} does not exist." + + done + main +} +status() { + ${sudo_cmd} systemctl --type service --all | grep casaos + main +} +stopOne() { + echo service name: + read -r service /dev/null 2>&1; then + echo "valid version. Installing nextzenos $version" + curl -fsSL "${NEXTZEN_DOWNLOAD_DOMAIN}/setup/nextzenos/$version/install.sh" | ${sudo_cmd} bash + else + echo "Invalid version. Please enter a valid version number." + fi +} +installCasa() { + echo "Enter Version:" + read -r version /dev/null 2>&1; then + echo "valid version. Installing casaos v$version..." + curl -fsSL "${CASAOS_DOWNLOAD_DOMAIN}/install/v$version" | ${sudo_cmd} bash + else + echo "Invalid version. Please enter a valid version number." + fi +} +update() { + echo "Enter Version:" + read -r version /dev/null 2>&1; then + echo "valid version. Updating nextzen $version" + curl -fsSL "${NEXTZEN_DOWNLOAD_DOMAIN}/setup/nextzenos/$version/update.sh" | ${sudo_cmd} bash + else + echo "Invalid version. Please enter a valid version number." + fi +} + +updateCasa() { + echo "Enter Version:" + read -r version /dev/null 2>&1; then + echo "valid version. Updating casaos v$version" + curl -fsSL "${CASAOS_DOWNLOAD_DOMAIN}/update/v$version" | ${sudo_cmd} bash + else + echo "Invalid version. Please enter a valid version number." + fi +} +uninstall() { + ${sudo_cmd} nextzenos-uninstall + reload +} +uninstallCasa() { + ${sudo_cmd} casaos-uninstall + reload +} +log() { + # sudo journalctl -xef -u ${service name} + echo "Enter Services name:" + read -r service "${PREFIX}/tmp/nextzenos-uninstall" + else + echo "Backup URL is also not working, cannot uninstall Nextzen." + return 1 + fi + else + curl -fsSLk "$NEXTZEN_UNINSTALL_URL" >"${PREFIX}/tmp/nextzenos-uninstall" + fi +} +Check_Dependency_Installation() { + for ((i = 0; i < ${#NEXTZEN_DEPANDS_COMMAND[@]}; i++)); do + cmd=${NEXTZEN_DEPANDS_COMMAND[i]} + if [[ ! -x $(command -v "${cmd}") ]]; then + packagesNeeded=${NEXTZEN_DEPANDS_PACKAGE[i]} + Show 1 "Dependency \e[33m$packagesNeeded \e[0m installation failed, please try again manually!" + exit 1 + fi + done +} + +#Install Rclone +Install_rclone_from_source() { + ${sudo_cmd} wget -qO ./install.sh https://rclone.org/install.sh + if [[ "${REGION}" = "China" ]] || [[ "${REGION}" = "CN" ]]; then + sed -i 's/downloads.rclone.org/casaos.oss-cn-shanghai.aliyuncs.com/g' ./install.sh + else + sed -i 's/downloads.rclone.org/get.casaos.io/g' ./install.sh + fi + ${sudo_cmd} chmod +x ./install.sh + ${sudo_cmd} ./install.sh || { + Show 1 "Installation failed, please try again." + ${sudo_cmd} rm -rf install.sh + exit 1 + } + ${sudo_cmd} rm -rf install.sh + Show 0 "Rclone v1.61.1 installed successfully." +} + +Install_Rclone() { + Show 2 "Install the necessary dependencies: Rclone" + if [[ -x "$(command -v rclone)" ]]; then + version=$(rclone --version 2>>errors | head -n 1) + target_version="rclone v1.61.1" + rclone1="${PREFIX}/usr/share/man/man1/rclone.1.gz" + if [ "$version" != "$target_version" ]; then + Show 3 "Will change rclone from $version to $target_version." + rclone_path=$(command -v rclone) + ${sudo_cmd} rm -rf "${rclone_path}" + if [[ -f "$rclone1" ]]; then + ${sudo_cmd} rm -rf "$rclone1" + fi + Install_rclone_from_source + else + Show 2 "Target version already installed." + fi + else + Install_rclone_from_source + fi + ${sudo_cmd} systemctl enable rclone || Show 3 "Service rclone does not exist." +} + +#Configuration Addons +Configuration_Addons() { + Show 2 "Configuration Addons" + #Remove old udev rules + if [[ -f "${PREFIX}/etc/udev/rules.d/11-usb-mount.rules" ]]; then + ${sudo_cmd} rm -rf "${PREFIX}/etc/udev/rules.d/11-usb-mount.rules" + fi + + if [[ -f "${PREFIX}/etc/systemd/system/usb-mount@.service" ]]; then + ${sudo_cmd} rm -rf "${PREFIX}/etc/systemd/system/usb-mount@.service" + fi + + #Udevil + if [[ -f "${PREFIX}${UDEVIL_CONF_PATH}" ]]; then + + # Revert previous udevil configuration + #shellcheck disable=SC2016 + ${sudo_cmd} sed -i 's/allowed_media_dirs = \/DATA, \/DATA\/$USER/allowed_media_dirs = \/media, \/media\/$USER, \/run\/media\/$USER/g' "${PREFIX}${UDEVIL_CONF_PATH}" + ${sudo_cmd} sed -i '/exfat/s/, nonempty//g' "$PREFIX"${UDEVIL_CONF_PATH} + ${sudo_cmd} sed -i '/default_options/s/, noexec//g' "$PREFIX"${UDEVIL_CONF_PATH} + ${sudo_cmd} sed -i '/^ARGS/cARGS="--mount-options nosuid,nodev,noatime --ignore-label EFI"' "$PREFIX"${DEVMON_CONF_PATH} + + # GreyStart + # Add a devmon user + USERNAME=devmon + id ${USERNAME} &>/dev/null || { + ${sudo_cmd} useradd -M -u 300 ${USERNAME} + ${sudo_cmd} usermod -L ${USERNAME} + } + + # Add and start Devmon service + GreyStart + ${sudo_cmd} systemctl enable devmon@devmon + ${sudo_cmd} systemctl start devmon@devmon + ColorReset + # ColorReset + fi +} + +# Download And Install NextZenOS +DownloadAndInstallNextzenOS() { + + if [ -z "${BUILD_DIR}" ]; then + + ${sudo_cmd} mkdir -p ${TMP_ROOT} || Show 1 "Failed to create temporary directory" + TMP_DIR=$(${sudo_cmd} mktemp -d -p ${TMP_ROOT} || Show 1 "Failed to create temporary directory") + ${sudo_cmd} chmod 755 "${TMP_DIR}" + ${sudo_cmd} chown "$USER" "${TMP_DIR}" + pushd "${TMP_DIR}" + + for PACKAGE in "${NEXTZEN_PACKAGES[@]}"; do + Show 2 "Downloading ${PACKAGE}..." + + ${sudo_cmd} wget -t 3 -q --show-progress -c "${PACKAGE}" || Show 1 "Failed to download package" + + done + + for PACKAGE_FILE in linux-*.tar.gz; do + Show 2 "Extracting ${PACKAGE_FILE}..." + ${sudo_cmd} tar zxf "${PACKAGE_FILE}" || Show 1 "Failed to extract package" + done + + BUILD_DIR=$(realpath -e "${TMP_DIR}"/build || Show 1 "Failed to find build directory") + + popd + fi + + # for SERVICE in "${NEXTZEN_SERVICES[@]}"; do + # Show 2 "Stopping ${SERVICE}..." + + # systemctl stop "${SERVICE}" || Show 3 "Service ${SERVICE} does not exist." + + # done + + MIGRATION_SCRIPT_DIR=$(realpath -e "${BUILD_DIR}"/scripts/migration/script.d || Show 1 "Failed to find migration script directory") + + for MIGRATION_SCRIPT in "${MIGRATION_SCRIPT_DIR}"/*.sh; do + Show 2 "Running ${MIGRATION_SCRIPT}..." + + ${sudo_cmd} bash "${MIGRATION_SCRIPT}" || Show 1 "Failed to run migration script" + + done + + Show 2 "Installing NextzenOS..." + SYSROOT_DIR=$(realpath -e "${BUILD_DIR}"/sysroot || Show 1 "Failed to find sysroot directory") + + # Generate manifest for uninstallation + MANIFEST_FILE=${BUILD_DIR}/sysroot/var/lib/casaos/manifest + ${sudo_cmd} touch "${MANIFEST_FILE}" || Show 1 "Failed to create manifest file" + + find "${SYSROOT_DIR}" -type f | ${sudo_cmd} cut -c ${#SYSROOT_DIR}- | ${sudo_cmd} cut -c 2- | ${sudo_cmd} tee "${MANIFEST_FILE}" >/dev/null || Show 1 "Failed to create manifest file" + + # Remove old UI files. + ${sudo_cmd} rm -rf /var/lib/casaos/www/* + + ${sudo_cmd} cp -rf "${SYSROOT_DIR}"/* / >>/dev/null || Show 1 "Failed to install NextzenOS" + + SETUP_SCRIPT_DIR=$(realpath -e "${BUILD_DIR}"/scripts/setup/script.d || Show 1 "Failed to find setup script directory") + + for SETUP_SCRIPT in "${SETUP_SCRIPT_DIR}"/*.sh; do + Show 2 "Running ${SETUP_SCRIPT}..." + ${sudo_cmd} bash "${SETUP_SCRIPT}" || Show 1 "Failed to run setup script" + done + + # Reset Permissions + UI_EVENTS_REG_SCRIPT=/etc/casaos/start.d/register-ui-events.sh + if [[ -f ${UI_EVENTS_REG_SCRIPT} ]]; then + ${sudo_cmd} chmod +x $UI_EVENTS_REG_SCRIPT + fi + + # Modify app store configuration + sed -i "/ServerAPI/d" "$PREFIX/etc/casaos/app-management.conf" + sed -i "/ServerApi/d" "$PREFIX/etc/casaos/app-management.conf" + if grep -q "IceWhaleTech/_appstore/archive/refs/heads/main.zip" "$PREFIX/etc/casaos/app-management.conf"; then + sed -i "/https:\/\/github.com\/IceWhaleTech/c\appstore = ${NEXTZEN_DOWNLOAD_DOMAIN}IceWhaleTech/_appstore/archive/refs/heads/main.zip" "$PREFIX/etc/casaos/app-management.conf" + else + echo "appstore = ${NEXTZEN_DOWNLOAD_DOMAIN}IceWhaleTech/_appstore/archive/refs/heads/main.zip" >>"$PREFIX/etc/casaos/app-management.conf" + fi + + #Download Uninstall Script + if [[ -f ${PREFIX}/tmp/nextzenos-uninstall ]]; then + ${sudo_cmd} rm -rf "${PREFIX}/tmp/nextzenos-uninstall" + fi + # ${sudo_cmd} curl -fsSLk "$NEXTZEN_UNINSTALL_URL" >"${PREFIX}/tmp/nextzenos-uninstall" + setup_uninstall_nextzen + ${sudo_cmd} cp -rvf "${PREFIX}/tmp/nextzenos-uninstall" $NEXTZEN_UNINSTALL_PATH || { + Show 1 "Download uninstall script failed, Please check if your internet connection is working and retry." + exit 1 + } + + ${sudo_cmd} chmod +x $NEXTZEN_UNINSTALL_PATH + Install_Rclone + + ## Special markings + + Show 0 "NextzenOS upgrade successfully" + for SERVICE in "${NEXTZEN_SERVICES[@]}"; do + Show 2 "restart ${SERVICE}..." + + ${sudo_cmd} systemctl restart "${SERVICE}" || Show 3 "Service ${SERVICE} does not exist." + + done + +} + +############################################################################### +# Main # +############################################################################### + +#Usage +usage() { + cat <<-EOF + Usage: get.sh [options] + Valid options are: + -p Specify build directory + -h Show this help message and exit + EOF + exit "$1" +} + +while getopts ":p:h" arg; do + case "$arg" in + p) + BUILD_DIR=$OPTARG + ;; + h) + usage 0 + ;; + *) + usage 1 + ;; + esac +done + +# Step 0: Get Download Url Domain +Get_Download_Url_Domain + +# Step 1: Check ARCH +Check_Arch + +# Step 2: Install Depends +Update_Package_Resource +Install_Depends +Check_Dependency_Installation + +# Step 3: Configuration Addon +Configuration_Addons + +# Step 4: Download And Install NextzenOS +DownloadAndInstallNextzenOS