websoft9/install/install.sh
qiaofeng1227 f32fcc4d05 websoft9
2024-10-23 15:14:19 +08:00

525 lines
No EOL
15 KiB
Bash

#!/bin/bash
# Define PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# Export PATH
export PATH
# Command-line options
# ==============================================================================
#
# --version
# Use the --version option to install a special version for installation. default is latest, for example:
#
# $ sudo bash install.sh --version "0.8.25"
#
# --port <9000>
# Use the --port option to set Websoft9 cosole port. default is 9000, for example:
#
# $ sudo bash install.sh --port 9001
#
# --channel <release|dev>
# Use the --channel option to install a release(production) or dev distribution. default is release, for example:
#
# $ sudo bash install.sh --channel release
#
# --path
# Use the --path option to for installation path for example:
#
# $ sudo bash install.sh --path "/data/websoft9/source"
#
# --apps <wordpress,gitlab>
# Use the --apps option to set Websoft9 appstore dispaly. default is null and display all applicaionts. If you set it, appstore only display the defined, for example:
#
# $ sudo bash install.sh --apps "wordpress,gitlab"
#
# --mirrors <https://docker.rainbond.cc,https://registry.inner.websoft9.cn>
# Use the --mirrors option to set docker image mirrors when can not pull image from docker-hub, for example:
#
# $ sudo bash install.sh --mirrors "https://docker.rainbond.cc,https://registry.inner.websoft9.cn"
#
# --devto
# Use the --devto option to developer mode, devto is the developer code path, for example:
#
# $ sudo bash install.sh --devto "/data/dev/mycode"
#
# ==============================================================================
# 设置参数的默认值
version="latest"
channel="release"
path="/data/websoft9/source"
apps=""
mirrors="https://dockerhub.websoft9.com"
# 获取参数值
while [[ $# -gt 0 ]]; do
case $1 in
--version)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --version"
exit 1
fi
version="$1"
shift
;;
--port)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --port"
exit 1
fi
port="$1"
shift
;;
--channel)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --channel"
exit 1
fi
channel="$1"
shift
;;
--path)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --path"
exit 1
fi
path="$1"
shift
;;
--apps)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --apps"
exit 1
fi
apps="$1"
shift
;;
--mirrors)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --mirrors"
exit 1
fi
mirrors="$1"
shift
;;
--devto)
shift
if [[ $1 == --* ]]; then
echo "Missing value for --devto"
exit 1
fi
devto="$1"
shift
;;
*)
echo "Unknown parameter: $1"
exit 1
;;
esac
done
if [ -n "$port" ]; then
export port
else
export port=9000
fi
starttime=$(date +%s)
# Check is install or upgrade
if systemctl cat websoft9 >/dev/null 2>&1 && systemctl cat cockpit >/dev/null 2>&1 && sudo docker ps -a --format '{{.Names}}' 2>/dev/null | grep -q '^websoft9-apphub'; then
echo "execute_mode=upgrade"
export execute_mode="upgrade"
else
echo "execute_mode=install"
export execute_mode="install"
fi
# 输出参数值
echo -e "\n------ Welcome to install Websoft9, it will take 3-5 minutes ------"
echo -e "\nYour installation parameters are as follows: "
echo "--version: $version"
echo "--port: $port"
echo "--channel: $channel"
echo "--path: $path"
echo "--apps: $apps"
echo "--mirrors: $mirrors"
echo "--devto: $devto"
echo -e "\nYour OS: "
cat /etc/os-release | head -n 3 2>/dev/null
# Define global vars
# export var can send it to subprocess
export http_port=80
export https_port=443
export install_path=$path
export channel
export version
export apps
export mirrors
export systemd_path="/opt/websoft9/systemd"
export source_zip="websoft9-$version.zip"
export source_unzip="websoft9"
export source_github_pages="https://websoft9.github.io/websoft9"
# inotify-tools is at epel-release
export repo_tools_yum="epel-release"
export tools_yum="git curl wget yum-utils jq bc unzip inotify-tools"
export tools_apt="git curl wget jq bc unzip inotify-tools"
export docker_network="websoft9"
export artifact_url="https://artifact.websoft9.com/$channel/websoft9"
# export OS release environments
if [ -f /etc/os-release ]; then
. /etc/os-release
else
echo "Can't judge your Linux distribution"
exit 1
fi
echo Install from url: $artifact_url
if [ -d "$install_path" ]; then
echo "Directory $install_path already exists and installation will cover it."
else
sudo mkdir -p "$install_path"
fi
# Define common functions
Wait_apt() {
# Function to check if apt is locked
local lock_files=("/var/lib/dpkg/lock" "/var/lib/apt/lists/lock")
for lock_file in "${lock_files[@]}"; do
while fuser "${lock_file}" >/dev/null 2>&1 ; do
echo "${lock_file} is locked by another process. Waiting..."
sleep 5
done
done
echo "APT locks are not held by any processes. You can proceed."
}
export -f Wait_apt
install_tools(){
echo_prefix_tools=$'\n[Tools] - '
echo "$echo_prefix_tools Starting install necessary tool..."
if [ "$ID" = "rhel" ] || [ "$ID" = "ol" ]; then
RHEL_VERSION=${VERSION_ID%%.*}
sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${RHEL_VERSION}.noarch.rpm >/dev/null
if [ $? -ne 0 ]; then
exit 1
fi
elif [ "$ID" = "centos" ] || [ "$ID" = "rocky" ]; then
sudo yum install -y "$repo_tools_yum" >/dev/null
if [ $? -ne 0 ]; then
exit 1
fi
elif [ "$ID" = "amzn" ]; then
sudo amazon-linux-extras install epel -y >/dev/null
if [ $? -ne 0 ]; then
exit 1
fi
fi
dnf --version >/dev/null 2>&1
dnf_status=$?
yum --version >/dev/null 2>&1
yum_status=$?
apt --version >/dev/null 2>&1
apt_status=$?
if [ $dnf_status -eq 0 ]; then
for package in $tools_yum; do
echo "Start to install $package"
sudo dnf install -y $package > /dev/null
if [ $? -ne 0 ]; then
exit 1
fi
done
elif [ $yum_status -eq 0 ]; then
for package in $tools_yum; do
echo "Start to install $package"
sudo yum install -y $package > /dev/null
if [ $? -ne 0 ]; then
exit 1
fi
done
elif [ $apt_status -eq 0 ]; then
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
echo "Waiting for other software managers to finish..."
sleep 5
done
sudo apt-get update -y 1>/dev/null 2>&1
for package in $tools_apt; do
echo "Start to install $package"
sudo apt-get install $package -y > /dev/null
if [ $? -ne 0 ]; then
exit 1
fi
done
else
echo "You system can not install Websoft9 because not have available Linux Package Manager"
exit 1
fi
}
download_source_and_checkimage() {
echo_prefix_source=$'\n[Download Source] - '
echo "$echo_prefix_source Download Websoft9 source code from $artifact_url/$source_zip"
find . -type f -name "websoft9*.zip*" -exec rm -f {} \;
rm -rf /tmp/$source_unzip
wget -P /tmp "$artifact_url/$source_zip"
if [ $? -ne 0 ]; then
echo "Failed to download source package."
exit 1
fi
## unzip and check image
sudo unzip -o "/tmp/$source_zip" -d /tmp > /dev/null
if [ $? -ne 0 ]; then
echo "Failed to unzip source package."
exit 1
fi
bash /tmp/$source_zip/install/install_docker.sh
if [ $? -ne 0 ]; then
echo "install_docker failed with error $?. Exiting."
exit 1
fi
cd /tmp/$source_unzip/docker
docker compose pull
if [ $? -ne 0 ]; then
echo "Can not pull images from docker hub, set mirrors...."
if [ -f "/etc/docker/daemon.json" ]; then
if grep -q "registry-mirrors" "/etc/docker/daemon.json"; then
mv /etc/docker/daemon.json /etc/docker/daemon.json.bak
cp daemon.json /etc/docker/daemon.json
else
rm -f /etc/docker/daemon.json
cp daemon.json /etc/docker/daemon.json
fi
else
cp daemon.json /etc/docker/daemon.json
fi
sudo systemctl daemon-reload
sudo systemctl restart docker
# pull image by new mirrors
docker compose pull
if [ $? -ne 0 ]; then
echo "image pull failed again, exit install"
exit 1
else
echo "image pull success by new mirrors"
fi
else
echo "image pull success"
fi
rm -rf /tmp/$source_unzip
sudo unzip -o "/tmp/$source_zip" -d "$install_path" > /dev/null
if [ $? -ne 0 ]; then
echo "Failed to unzip source package."
exit 1
fi
cp -r $install_path/$source_unzip/* "$install_path"
if [ $? -ne 0 ]; then
echo "Move directory failed"
exit 1
fi
rm -rf "/tmp/$source_zip" "$install_path/$source_unzip"
}
check_ports() {
local ports=("$@")
echo "Stop Websoft9 Proxy and Cockpit service for reserve ports..."
sudo docker stop websoft9-proxy 2>/dev/null || echo "docker stop websoft9-proxy not need "
for port in "${ports[@]}"; do
if [[ $port =~ ^[0-9]+$ ]] && [ $port -ge 0 ] && [ $port -le 65535 ]; then
if ss -tuln | grep ":$port " >/dev/null && ! systemctl status cockpit.socket | grep "$port" >/dev/null; then
echo "Port $port is in use or not in cockpit.socket, install failed"
exit 1
fi
else
echo "Invalid port: $port"
exit 1
fi
done
echo "All ports are available"
}
set_docker(){
echo "Set Docker for Websoft9 backend service..."
if ! systemctl is-active --quiet firewalld; then
echo "firewalld is not running"
else
echo "Set firewall for Docker..."
sudo sudo firewall-cmd --permanent --new-zone=docker 2> /dev/null
sudo firewall-cmd --permanent --zone=docker --add-interface=docker0 2> /dev/null
sudo firewall-cmd --permanent --zone=docker --set-target=ACCEPT
sudo firewall-cmd --reload
sudo systemctl stop firewalld
sudo systemctl disable firewalld
fi
if [ "$execute_mode" = "install" ]; then
sudo systemctl restart docker
fi
}
install_backends() {
echo_prefix_backends=$'\n[Backend] - '
echo "$echo_prefix_backends Install backend docker services"
set_docker
cd "$install_path/docker"
if [ $? -ne 0 ]; then
echo "Failed to change directory."
exit 1
fi
sudo docker network inspect $docker_network >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Docker network '$docker_network' already exists."
else
sudo docker network create $docker_network
if [ $? -ne 0 ]; then
echo "Failed to create docker network."
exit 1
fi
fi
# set to devloper mode
if [ -n "$devto" ]; then
sed -i "s|\(- \).*:/websoft9/apphub-dev|\1$devto:/websoft9/apphub-dev|g" docker-compose-dev.yml
composefile=docker-compose-dev.yml
else
composefile=docker-compose.yml
fi
container_names=$(docker ps -a --format "{{.Names}}" --filter "name=websoft9")
sudo docker compose -p websoft9 -f $composefile down
# delete some dead containers that docker compose cannot deleted
if [ ! -z "$container_names" ]; then
echo "Deleting containers:"
echo $container_names
docker rm -f $container_names 2>/dev/null
else
echo "No containers to delete."
fi
sudo docker compose -p websoft9 -f $composefile up -d
if [ $? -ne 0 ]; then
echo "Failed to start docker services."
exit 1
fi
if [ "$execute_mode" = "install" ]; then
sudo docker exec -i websoft9-apphub apphub setconfig --section domain --key wildcard_domain --value ""
if [ -n "$apps" ]; then
sudo docker exec -i websoft9-apphub apphub setconfig --section initial_apps --key keys --value "$apps"
fi
fi
if [ -f "/etc/docker/daemon.json.bak" ]; then
rm -rf /etc/docker/daemon.json
mv /etc/docker/daemon.json.bak /etc/docker/daemon.json
fi
}
install_systemd() {
echo -e "\n\n-------- Systemd --------"
echo_prefix_systemd=$'\n[Systemd] - '
echo "$echo_prefix_systemd Install Systemd service"
if [ ! -d "$systemd_path" ]; then
sudo mkdir -p "$systemd_path"
fi
sudo cp -r $install_path/systemd/script/* "$systemd_path"
sudo cp -f "$install_path/systemd/websoft9.service" /lib/systemd/system/
if [ $? -ne 0 ]; then
echo "Failed to copy Systemd service file."
exit 1
fi
sudo systemctl daemon-reload
if [ $? -ne 0 ]; then
echo "Failed to reload Systemd daemon."
exit 1
fi
sudo systemctl enable websoft9.service
if [ $? -ne 0 ]; then
echo "Failed to enable Systemd service."
exit 1
fi
sudo systemctl start websoft9
if [ $? -ne 0 ]; then
echo "Failed to start Systemd service."
exit 1
fi
}
#--------------- main-----------------------------------------
log_path="$install_path/install.log"
check_ports $http_port $https_port $port | tee -a $log_path
install_tools | tee -a $log_path
download_source_and_checkimage | tee -a $log_path
install_backends | tee -a $log_path
install_systemd | tee -a $log_path
bash $install_path/install/install_cockpit.sh | tee -a $log_path
if [ $? -ne 0 ]; then
echo "install_cockpit failed with error $?. Exiting."
exit 1
fi
bash $install_path/install/install_plugins.sh | tee -a $log_path
if [ $? -ne 0 ]; then
echo "install_plugins failed with error $?. Exiting."
exit 1
fi
echo "Restart Docker for Firewalld..."
if [ "$execute_mode" = "install" ]; then
sudo systemctl restart docker
fi
endtime=$(date +%s)
runtime=$((endtime-starttime))
echo "Script execution time: $runtime seconds"
echo -e "\n-- Install success! ------"
echo "Access Websoft9 console by: http://Internet IP:$(grep ListenStream /lib/systemd/system/cockpit.socket | cut -d= -f2) and using Linux user for login"