2025-09-16 11:54:39 +08:00

368 lines
9.9 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
set -e
# =========================================== 基础检查与更新 ===========================================
SCRIPT_PATH=`pwd`
function check() {
if [ "$(id -u)" -ne 0 ]; then
echo "请以root权限运行此脚本" >&2
exit 1
fi
osCheck=`uname -a`
if [[ $osCheck =~ 'x86_64' ]];then
architecture="amd64"
else
echo "暂不支持的系统架构,选择受支持的系统。"
exit 1
fi
if [ ! -d "offline_resources" ]; then
echo "未找到资源目录请确保offline_resources目录与脚本在同一位置" >&2
exit 1
fi
}
function upgrade() {
echo "更新系统源"
sudo apt update -y
sudo apt upgrade -y
}
# =========================================== Docker与1Panel ===========================================
function check_docker_installed() {
if command -v docker &> /dev/null; then
echo "Docker 已安装,版本: $(docker --version)"
return 0
else
echo "Docker 未安装"
return 1
fi
}
function check_1panel_installed() {
if systemctl status 1panel-core &> /dev/null; then
echo "1Panel 已安装,状态: $(systemctl is-active 1panel-core)"
return 0
else
echo "1Panel 未安装"
return 1
fi
}
function install_docker() {
if check_docker_installed; then
echo "Docker 已经安装,跳过安装步骤"
return 0
fi
echo && echo "正在安装依赖包和Docker..." && echo
dpkg -i debs/*.deb || apt-get -f install -y
echo && echo "启动Docker服务..." && echo
systemctl start docker
systemctl enable docker
echo && echo "安装Docker Compose..." && echo
cp docker-compose/`ls docker-compose/ | grep docker-compose | head -n 1` /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
if check_docker_installed; then
echo "Docker 安装成功!"
else
echo "Docker 安装失败!" >&2
exit 1
fi
}
function install_1panel() {
if check_1panel_installed; then
echo "1Panel 已经安装,跳过安装步骤"
return 0
fi
echo && echo "安装1Panel..." && echo
panel_package=$(ls 1panel | grep -G '1panel-v.*\.tar\.gz' | head -n 1)
if [ -z "${panel_package}" ]; then
echo "未找到1Panel安装包" >&2
exit 1
fi
tar -zxvf "1panel/${panel_package}" -C 1panel
panel_dir=$(ls -l 1panel | grep '^d' | grep 1panel | awk '{print $NF}' | head -n 1)
if [ -z "$panel_dir" ]; then
echo "未找到1Panel解压目录" >&2
exit 1
fi
chmod u+x "./1panel/$panel_dir/install.sh"
sudo "./1panel/$panel_dir/install.sh"
sleep 3
if check_1panel_installed; then
echo "1Panel 安装成功!"
else
echo "1Panel 安装失败!" >&2
exit 1
fi
}
# =========================================== 通用函数处理 ===========================================
# 主函数:空处理
function process_empty() {
return 0
}
# 主函数处理tar文件并执行指定函数
function process_tar_files() {
local resource_dir="$1"
local process_function="$2"
local file_patterns=("${@:3}")
if [ ${#file_patterns[@]} -eq 0 ]; then
file_patterns=("*.tar")
fi
if [ ! -d "$resource_dir" ]; then
echo "错误: 目录 $resource_dir 不存在"
return 1
fi
if ! declare -f "$process_function" > /dev/null; then
echo "错误: 函数 $process_function 未定义"
return 1
fi
local file_count=0
local success_count=0
local fail_count=0
echo "开始在目录 $resource_dir 中查找文件..."
for pattern in "${file_patterns[@]}"; do
echo "搜索模式: $pattern"
for tar_file in "$resource_dir"/$pattern; do
filename=$(basename "$tar_file")
"$process_function" "$tar_file" "${filename}"
file_count=$((file_count + 1))
done
done
echo "=== 处理完成 ==="
echo "总共找到: $file_count 个文件"
echo "成功: $success_count"
echo "失败: $fail_count"
if [ $file_count -eq 0 ]; then
echo "在目录 $resource_dir 中未找到以下模式的文件: ${file_patterns[*]}"
echo "目录内容:"
ls -la "$resource_dir/" 2>/dev/null || echo "无法列出目录内容"
fi
return $fail_count
}
# 处理关联数组的函数
function process_associative_array() {
# arg1: 默认路径
# arg2: 执行数组
# arg3: 自定义初始化函数
local path="$1"
local array_name="$2"
local func_name="$3"
eval "local keys=(\"\${!${array_name}[@]}\")"
for key in "${keys[@]}"; do
eval "local value=\"\${${array_name}[\$key]}\""
name=$(echo "${key}" | awk -F. '{if (NF>1) {for(i=1;i<NF;i++) printf "%s%s", $i, (i<NF-1?".":"")}}')
"${func_name}" "${path}/${name}" "${key}" "${value}"
done
}
# =========================================== 部署容器 ===========================================
function docker_load_tar() {
# arg1 加载的镜像文件名称
# arg2 镜像描述
SOURCE_FILE=$1
SOURCE_DESCRIPTION=$2
echo "加载 ${SOURCE_DESCRIPTION} 镜像"
docker load -i ${SOURCE_FILE} || { echo "加载 ${SOURCE_DESCRIPTION} 镜像失败"; exit 1; }
}
function docker_installer() {
# arg1: 安装到 1panel 的程序目录
# arg2: 迁移到 1panel 程序目录的压缩文件
# arg3: 自定义初始化函数(可选)
local TARGET_DIR="${1}"
local SOURCE_FILE="${2}"
local CUSTOM_INIT_FUNC="${3}"
local SOURCE_PATH=$(pwd)
local DEFAULT_DOCKER_COMPOSE="docker-compose.yml"
local TIMESTAMP=$(date +%Y%m%d_%H%M%S)
local BACKUP_DIR="${TARGET_DIR}_backup_${TIMESTAMP}"
if [ $# -lt 2 ]; then
echo "错误:缺少必要参数"
echo "用法: docker_installer <目标目录> <源压缩文件> [自定义初始化函数]"
return 1
fi
if [ ! -f "${SOURCE_FILE}" ] || [ ! -r "${SOURCE_FILE}" ]; then
echo "错误:源文件 ${SOURCE_FILE} 不存在或不可读"
return 1
fi
if [ ! -d "${TARGET_DIR}" ]; then
echo "目录 ${TARGET_DIR} 不存在,尝试创建..."
mkdir -p "${TARGET_DIR}" || {
echo "无法创建目录 ${TARGET_DIR}"
return 1
}
fi
echo "复制文件到 ${TARGET_DIR}"
cp "${SOURCE_FILE}" "${TARGET_DIR}/" || {
echo "复制文件失败"
return 1
}
cd "${TARGET_DIR}" || {
echo "无法进入目录 ${TARGET_DIR}"
return 1
}
local FILENAME=$(basename "${SOURCE_FILE}")
echo "开始解压 ${FILENAME}"
case "${FILENAME##*.}" in
zip)
unzip -q "${FILENAME}" || {
echo "解压 ${FILENAME} 失败"
return 1
}
;;
tar|gz|tgz|bz2)
tar -xf "${FILENAME}" || {
echo "解压 ${FILENAME} 失败"
return 1
}
;;
*)
echo "不支持的压缩格式: ${FILENAME##*.}"
return 1
;;
esac
rm -f "${FILENAME}"
if [ -n "${CUSTOM_INIT_FUNC}" ]; then
if type "${CUSTOM_INIT_FUNC}" &>/dev/null; then
echo "执行自定义初始化函数 ${CUSTOM_INIT_FUNC}"
${CUSTOM_INIT_FUNC} || {
echo "自定义初始化函数执行失败"
return 1
}
else
echo "警告:初始化函数 ${CUSTOM_INIT_FUNC} 不存在,跳过"
fi
fi
local COMPOSE_FILE="${DEFAULT_DOCKER_COMPOSE}"
if [ -f "${COMPOSE_FILE}" ]; then
echo "${TARGET_DIR} 下启动 Docker Compose"
if ! command -v docker-compose &>/dev/null; then
echo "错误docker-compose 未安装"
return 1
fi
if ! docker info &>/dev/null; then
echo "错误Docker 守护进程未运行"
return 1
fi
docker-compose up -d || {
echo "Docker Compose 启动失败"
return 1
}
echo "Docker Compose 启动成功"
else
echo "${TARGET_DIR} 下未找到 ${COMPOSE_FILE}"
echo "可用文件:"
ls -la
return 1
fi
cd "${SOURCE_PATH}" >/dev/null
echo && echo "操作完成" && echo
echo "目标目录: ${TARGET_DIR}"
if [ -d "${BACKUP_DIR}" ]; then
echo "备份位置: ${BACKUP_DIR}"
fi
}
# =========================================== 特殊初始化 ===========================================
function init_rocketmq() {
cd rocketmq
sh scripts/init.sh || { echo "初始化 init.sh 失败"; exit 1; }
}
# =========================================== 主流程 ===========================================
function main() {
check
# upgrade
cd ${SCRIPT_PATH}/offline_resources
install_docker
install_1panel
echo && echo "验证安装结果..."
echo && echo "Docker版本: $(docker --version)"
echo && echo "Docker Compose版本: $(docker-compose --version)"
echo && echo "1Panel状态: $(systemctl status 1panel-core | grep Active)"
echo && echo
echo && echo "所有组件安装完成!" && echo && echo
cd ${SCRIPT_PATH}/busicess_resources
process_tar_files "`pwd`/containers" "docker_load_tar"
echo && echo "所有镜像安装完成!" && echo && echo
NETWORK_NAME="1panel-network"
if ! docker network ls | grep -q "$NETWORK_NAME"; then
echo "网络 $NETWORK_NAME 不存在,正在创建..."
docker network create "$NETWORK_NAME"
echo "网络 $NETWORK_NAME 创建成功!"
fi
cd ${SCRIPT_PATH}/busicess_resources/dataset
declare -A my_assoc_array=(
["minio.zip"]="process_empty"
["mysql.zip"]="process_empty"
["redis.zip"]="process_empty"
["rocketmq.zip"]="init_rocketmq"
["portainer-ce.zip"]="process_empty"
["phpmyadmin.zip"]="process_empty"
["simulation.zip"]="process_empty"
)
process_associative_array "/opt/1panel/apps" my_assoc_array "docker_installer" || { echo "初始化 init.sh 失败"; exit 1; }
echo && echo "所有容器安装完成!" && echo && echo
}
main