Files
lxdapi-web-server/Shell/lxdapi_install.sh

511 lines
17 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
cd /root >/dev/null 2>&1
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
REGEX=("debian|astra" "ubuntu")
RELEASE=("Debian" "Ubuntu")
CMD=("$(grep -i pretty_name /etc/os-release 2>/dev/null | cut -d \" -f2)" "$(lsb_release -sd 2>/dev/null)")
SYS="${CMD[0]}"
[[ -n $SYS ]] || exit 1
for ((int = 0; int < ${#REGEX[@]}; int++)); do
if [[ $(echo "$SYS" | tr '[:upper:]' '[:lower:]') =~ ${REGEX[int]} ]]; then
SYSTEM="${RELEASE[int]}"
[[ -n $SYSTEM ]] && break
fi
done
if [[ "$SYSTEM" != "Debian" && "$SYSTEM" != "Ubuntu" ]]; then
echo -e "${RED}[ERR]${NC} 此脚本仅支持 Debian 和 Ubuntu 系统"
exit 1
fi
log() { echo -e "$1"; }
ok() { log "${GREEN}[OK]${NC} $1"; }
info() { log "${BLUE}[INFO]${NC} $1"; }
warn() { log "${YELLOW}[WARN]${NC} $1"; }
err() { log "${RED}[ERR]${NC} $1"; exit 1; }
reading() { read -rp "$(echo -e "${GREEN}$1${NC}")" "$2"; }
install_package() {
package_name=$1
if dpkg -l 2>/dev/null | grep -q "^ii.*$package_name"; then
ok "$package_name 已安装"
else
apt-get install -y $package_name >/dev/null 2>&1
if [ $? -ne 0 ]; then
apt-get install -y $package_name --fix-missing >/dev/null 2>&1
fi
if dpkg -l 2>/dev/null | grep -q "^ii.*$package_name"; then
ok "$package_name 已安装"
else
warn "$package_name 安装失败"
fi
fi
}
install_base_packages() {
info "更新软件包列表..."
apt-get update >/dev/null 2>&1
apt-get autoremove -y >/dev/null 2>&1
info "安装基础软件包..."
DEBIAN_FRONTEND=noninteractive apt-get install -y unzip e2fsprogs bc nftables fdisk parted iptables-persistent nginx >/dev/null 2>&1
ok "软件包安装完成"
systemctl enable nftables >/dev/null 2>&1
systemctl start nftables >/dev/null 2>&1
ok "nftables 已启动"
if command -v lxc &>/dev/null && lxc network show lxdbr0 &>/dev/null; then
lxc network set lxdbr0 ipv4.nat true 2>/dev/null
lxc network set lxdbr0 ipv6.nat true 2>/dev/null
ok "LXD NAT 规则已重建"
fi
systemctl enable nginx >/dev/null 2>&1
systemctl start nginx >/dev/null 2>&1
ok "nginx 已启动"
}
deploy_lxdapi() {
info "检测系统架构..."
sys_arch=$(uname -m)
case $sys_arch in
x86_64)
arch="amd64"
ok "检测到架构: x86_64"
;;
aarch64|arm64)
arch="arm64"
ok "检测到架构: $sys_arch"
;;
*)
err "不支持的架构: $sys_arch"
;;
esac
while true; do
reading "请选择下载源 github/gitee [github]" download_source
download_source=${download_source:-github}
if [[ "$download_source" =~ ^(github|gitee)$ ]]; then
break
else
warn "请输入 github 或 gitee"
fi
done
if [[ "$download_source" == "github" ]]; then
latest_tag=$(curl -s https://api.github.com/repos/xkatld/lxdapi-web-server/releases/latest | grep '"tag_name"' | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
base_url="https://github.com/xkatld/lxdapi-web-server/releases/download"
else
latest_tag=$(curl -s https://gitee.com/api/v5/repos/xkatld/lxdapi-web-server/releases/latest | grep '"tag_name"' | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
base_url="https://gitee.com/xkatld/lxdapi-web-server/releases/download"
fi
if [ -z "$latest_tag" ]; then
err "无法获取最新版本信息"
fi
info "最新版本: $latest_tag"
reading "请输入安装版本 [$latest_tag]" install_version
install_version=${install_version:-$latest_tag}
ok "安装版本: $install_version"
download_url="${base_url}/${install_version}/lxdapi-linux-${arch}.tar.gz"
info "下载 lxdapi..."
info "下载地址: $download_url"
temp_file=$(mktemp)
if wget -q --show-progress -O "$temp_file" "$download_url" 2>&1; then
ok "下载完成"
else
rm -f "$temp_file"
err "下载失败"
fi
info "解压到 /opt/lxdapi..."
mkdir -p /opt/lxdapi
tar -xzf "$temp_file" -C /opt/lxdapi --strip-components=1
rm -f "$temp_file"
}
configure_lxdapi() {
info "配置 lxdapi..."
config_file="/opt/lxdapi/configs/config.yaml"
if [ ! -f "$config_file" ]; then
err "配置文件不存在: $config_file"
fi
reading "请输入服务端口 [8443]" server_port
server_port=${server_port:-8443}
reading "请输入API密钥 [随机生成]" api_hash
if [ -z "$api_hash" ]; then
api_hash=$(openssl rand -hex 16)
ok "API密钥已生成: $api_hash"
fi
reading "请输入管理员用户名 [admin]" admin_user
admin_user=${admin_user:-admin}
reading "请输入管理员密码 [随机生成]" admin_pass
if [ -z "$admin_pass" ]; then
admin_pass=$(openssl rand -hex 8)
ok "管理员密码已生成: $admin_pass"
fi
session_secret=$(openssl rand -hex 16)
reading "请输入流量采集间隔秒数 [20]" traffic_interval
traffic_interval=${traffic_interval:-20}
reading "请输入流量批量更新数量 [10]" traffic_batch_size
traffic_batch_size=${traffic_batch_size:-10}
reading "请输入任务自动清理天数 [7]" auto_cleanup_days
auto_cleanup_days=${auto_cleanup_days:-7}
while true; do
reading "请选择任务队列后端 memory/redis [memory]" task_backend
task_backend=${task_backend:-memory}
if [[ "$task_backend" =~ ^(memory|redis)$ ]]; then
break
else
warn "请输入 memory 或 redis"
fi
done
if [[ "$task_backend" == "redis" ]]; then
while true; do
reading "使用本地安装还是远程配置local/remote [local]" redis_location
redis_location=${redis_location:-local}
if [[ "$redis_location" =~ ^(local|remote)$ ]]; then
break
else
warn "请输入 local 或 remote"
fi
done
if [[ "$redis_location" == "local" ]]; then
info "安装 Redis..."
apt-get install -y redis-server >/dev/null 2>&1
systemctl start redis-server
systemctl enable redis-server
redis_host="localhost"
redis_port="6379"
redis_password=""
redis_db="0"
ok "Redis 已安装"
else
reading "请输入 Redis 主机地址:" redis_host
reading "请输入 Redis 端口 [6379]" redis_port
redis_port=${redis_port:-6379}
reading "请输入 Redis 密码 [留空表示无密码]" redis_password
reading "请输入 Redis 数据库编号 [0]" redis_db
redis_db=${redis_db:-0}
fi
else
redis_host="localhost"
redis_port="6379"
redis_password=""
redis_db="0"
fi
while true; do
reading "请选择数据库类型 sqlite/mysql/postgres [sqlite]" db_type
db_type=${db_type:-sqlite}
if [[ "$db_type" =~ ^(sqlite|mysql|postgres)$ ]]; then
break
else
warn "请输入 sqlite、mysql 或 postgres"
fi
done
if [[ "$db_type" == "mysql" ]]; then
while true; do
reading "使用本地安装还是远程配置local/remote [local]" mysql_location
mysql_location=${mysql_location:-local}
if [[ "$mysql_location" =~ ^(local|remote)$ ]]; then
break
else
warn "请输入 local 或 remote"
fi
done
if [[ "$mysql_location" == "local" ]]; then
info "安装 MariaDB..."
apt-get install -y mariadb-server >/dev/null 2>&1
systemctl start mariadb
systemctl enable mariadb
mysql_host="localhost"
mysql_port="3306"
mysql_user="lxdapi"
mysql_password=$(openssl rand -hex 8)
mysql_database="lxdapi"
info "创建数据库和用户..."
mysql -u root << EOF
CREATE DATABASE IF NOT EXISTS ${mysql_database};
CREATE USER IF NOT EXISTS '${mysql_user}'@'localhost' IDENTIFIED BY '${mysql_password}';
GRANT ALL PRIVILEGES ON ${mysql_database}.* TO '${mysql_user}'@'localhost';
FLUSH PRIVILEGES;
EOF
ok "MariaDB 数据库已创建"
ok "用户: $mysql_user"
ok "密码: $mysql_password"
else
reading "请输入 MySQL 主机地址:" mysql_host
reading "请输入 MySQL 端口 [3306]" mysql_port
mysql_port=${mysql_port:-3306}
reading "请输入 MySQL 用户名:" mysql_user
reading "请输入 MySQL 密码:" mysql_password
reading "请输入 MySQL 数据库名:" mysql_database
fi
elif [[ "$db_type" == "postgres" ]]; then
while true; do
reading "使用本地安装还是远程配置local/remote [local]" postgres_location
postgres_location=${postgres_location:-local}
if [[ "$postgres_location" =~ ^(local|remote)$ ]]; then
break
else
warn "请输入 local 或 remote"
fi
done
if [[ "$postgres_location" == "local" ]]; then
info "安装 PostgreSQL..."
apt-get install -y postgresql >/dev/null 2>&1
systemctl start postgresql
systemctl enable postgresql
postgres_host="localhost"
postgres_port="5432"
postgres_user="lxdapi"
postgres_password=$(openssl rand -hex 8)
postgres_database="lxdapi"
postgres_sslmode="disable"
info "创建数据库和用户..."
sudo -u postgres psql << EOF
CREATE DATABASE ${postgres_database};
CREATE USER ${postgres_user} WITH PASSWORD '${postgres_password}';
GRANT ALL PRIVILEGES ON DATABASE ${postgres_database} TO ${postgres_user};
EOF
ok "PostgreSQL 数据库已创建"
ok "用户: $postgres_user"
ok "密码: $postgres_password"
else
reading "请输入 PostgreSQL 主机地址:" postgres_host
reading "请输入 PostgreSQL 端口 [5432]" postgres_port
postgres_port=${postgres_port:-5432}
reading "请输入 PostgreSQL 用户名:" postgres_user
reading "请输入 PostgreSQL 密码:" postgres_password
reading "请输入 PostgreSQL 数据库名:" postgres_database
reading "请输入 PostgreSQL SSL模式 [disable]" postgres_sslmode
postgres_sslmode=${postgres_sslmode:-disable}
fi
fi
info "写入配置文件..."
sed -i "s|__SERVER_PORT__|$server_port|g" "$config_file"
sed -i "s|__API_HASH__|$api_hash|g" "$config_file"
sed -i "s|__ADMIN_USER__|$admin_user|g" "$config_file"
sed -i "s|__ADMIN_PASS__|$admin_pass|g" "$config_file"
sed -i "s|__SESSION_SECRET__|$session_secret|g" "$config_file"
sed -i "s|__TRAFFIC_INTERVAL__|$traffic_interval|g" "$config_file"
sed -i "s|__TRAFFIC_BATCH_SIZE__|$traffic_batch_size|g" "$config_file"
sed -i "s|__AUTO_CLEANUP_DAYS__|$auto_cleanup_days|g" "$config_file"
sed -i "s|__TASK_BACKEND__|$task_backend|g" "$config_file"
sed -i "s|__REDIS_HOST__|$redis_host|g" "$config_file"
sed -i "s|__REDIS_PORT__|$redis_port|g" "$config_file"
sed -i "s|__REDIS_PASSWORD__|$redis_password|g" "$config_file"
sed -i "s|__REDIS_DB__|$redis_db|g" "$config_file"
sed -i "s|__DB_TYPE__|$db_type|g" "$config_file"
if [[ "$db_type" == "mysql" ]]; then
sed -i "s|__MYSQL_HOST__|$mysql_host|g" "$config_file"
sed -i "s|__MYSQL_PORT__|$mysql_port|g" "$config_file"
sed -i "s|__MYSQL_USER__|$mysql_user|g" "$config_file"
sed -i "s|__MYSQL_PASSWORD__|$mysql_password|g" "$config_file"
sed -i "s|__MYSQL_DATABASE__|$mysql_database|g" "$config_file"
else
sed -i "s|__MYSQL_HOST__|localhost|g" "$config_file"
sed -i "s|__MYSQL_PORT__|3306|g" "$config_file"
sed -i "s|__MYSQL_USER__|root|g" "$config_file"
sed -i "s|__MYSQL_PASSWORD__||g" "$config_file"
sed -i "s|__MYSQL_DATABASE__|lxdapi|g" "$config_file"
fi
if [[ "$db_type" == "postgres" ]]; then
sed -i "s|__POSTGRES_HOST__|$postgres_host|g" "$config_file"
sed -i "s|__POSTGRES_PORT__|$postgres_port|g" "$config_file"
sed -i "s|__POSTGRES_USER__|$postgres_user|g" "$config_file"
sed -i "s|__POSTGRES_PASSWORD__|$postgres_password|g" "$config_file"
sed -i "s|__POSTGRES_DATABASE__|$postgres_database|g" "$config_file"
sed -i "s|__POSTGRES_SSLMODE__|$postgres_sslmode|g" "$config_file"
else
sed -i "s|__POSTGRES_HOST__|localhost|g" "$config_file"
sed -i "s|__POSTGRES_PORT__|5432|g" "$config_file"
sed -i "s|__POSTGRES_USER__|postgres|g" "$config_file"
sed -i "s|__POSTGRES_PASSWORD__||g" "$config_file"
sed -i "s|__POSTGRES_DATABASE__|lxdapi|g" "$config_file"
sed -i "s|__POSTGRES_SSLMODE__|disable|g" "$config_file"
fi
ok "配置文件已更新"
}
setup_lxdapi_service() {
info "配置 lxdapi 系统服务..."
config_file="/opt/lxdapi/configs/config.yaml"
if [ ! -f "$config_file" ]; then
err "配置文件不存在: $config_file"
fi
if grep -q "__SERVER_PORT__" "$config_file"; then
err "配置文件未完成配置"
fi
sys_arch=$(uname -m)
case $sys_arch in
x86_64)
exec_bin="/opt/lxdapi/lxdapi-amd64"
;;
aarch64|arm64)
exec_bin="/opt/lxdapi/lxdapi-arm64"
;;
*)
err "不支持的架构: $sys_arch"
;;
esac
service_file="/etc/systemd/system/lxdapi.service"
cat > "$service_file" << EOF
[Unit]
Description=LXD API Server
After=network.target lxd.service
Wants=lxd.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/lxdapi
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
ExecStart=$exec_bin
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
ok "服务文件已创建: $service_file"
systemctl daemon-reload
systemctl enable lxdapi
systemctl start lxdapi
info "等待服务启动..."
for i in {1..10}; do
printf "\r[%-10s] %d/10s" "$(printf '#%.0s' $(seq 1 $i))" "$i"
sleep 1
done
echo
if systemctl is-active --quiet lxdapi; then
ok "lxdapi 服务已启动"
else
warn "lxdapi 服务启动失败"
journalctl -u lxdapi -n 20 --no-pager
fi
}
main() {
echo
echo "========================================"
echo " LXDAPI 安装脚本"
echo " by Github-xkatld"
echo "========================================"
echo
echo "======== 步骤 1/5: 基础软件包安装 ========"
reading "是否安装基础软件包?(y/n) [y]" step1_confirm
step1_confirm=${step1_confirm:-y}
if [[ "$step1_confirm" =~ ^[yY]$ ]]; then
install_base_packages
ok "基础软件包安装完成"
else
info "已跳过基础软件包安装"
fi
echo
echo "======== 步骤 2/5: 下载 ========"
reading "是否下载 lxdapi(y/n) [y]" step2_confirm
step2_confirm=${step2_confirm:-y}
if [[ "$step2_confirm" =~ ^[yY]$ ]]; then
deploy_lxdapi
ok "下载完成"
else
info "已跳过下载"
fi
echo
echo "======== 步骤 3/5: 配置 ========"
reading "是否配置 lxdapi(y/n) [y]" step3_confirm
step3_confirm=${step3_confirm:-y}
if [[ "$step3_confirm" =~ ^[yY]$ ]]; then
configure_lxdapi
ok "配置完成"
else
info "已跳过配置"
fi
echo
echo "======== 步骤 4/5: 启动服务 ========"
reading "是否启动 lxdapi 服务?(y/n) [y]" step4_confirm
step4_confirm=${step4_confirm:-y}
if [[ "$step4_confirm" =~ ^[yY]$ ]]; then
setup_lxdapi_service
ok "服务已启动"
else
info "已跳过服务启动"
fi
echo
echo "======== 步骤 5/5: 完成 ========"
echo
echo "========================================"
echo " LXDAPI 安装完成"
echo "========================================"
echo
info "服务端口: $server_port"
info "API密钥: $api_hash"
info "管理员用户: $admin_user"
info "管理员密码: $admin_pass"
info "数据库类型: $db_type"
info "任务队列: $task_backend"
info "流量采集间隔: ${traffic_interval}s"
echo
systemctl status lxdapi --no-pager | head -5
}
main