docker-seaweedfs/service

396 lines
12 KiB
Bash
Executable File
Raw 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
# SeaweedFS服务管理脚本
# 用法: ./service start|stop|status|restart|help
# 定义颜色输出
echo_green() { echo -e "\033[32m$1\033[0m"; }
echo_yellow() { echo -e "\033[33m$1\033[0m"; }
echo_red() { echo -e "\033[31m$1\033[0m"; }
echo_blue() { echo -e "\033[34m$1\033[0m"; }
# 日志函数
log_info() { echo_blue "[INFO] $1"; }
log_success() { echo_green "[SUCCESS] $1"; }
log_warning() { echo_yellow "[WARNING] $1"; }
log_error() { echo_red "[ERROR] $1"; }
# 获取脚本所在目录的绝对路径
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
# 切换工作目录到脚本所在目录
cd "$SCRIPT_DIR" || {
log_error "无法切换到脚本目录"
exit 1
}
# 检查系统命令
system_commands=("docker" "docker-compose" "openssl")
check_system_commands() {
for cmd in "${system_commands[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
log_error "命令 $cmd 未安装,请先安装"
return 1
fi
done
return 0
}
# 检查并加载环境变量
load_env_variables() {
# 检查必要的命令
if ! check_system_commands; then
return 1
fi
# 首先尝试加载.envrc中的环境变量
if [ -f ".envrc" ]; then
log_info "加载.envrc中的环境变量..."
# 检查是否安装了direnv
if command -v direnv &> /dev/null; then
log_info "使用direnv加载环境变量"
eval "$(direnv export bash)"
else
log_warning "direnv未安装直接加载.envrc中的环境变量"
# 手动加载.envrc中的环境变量排除包含$(...)的行
while IFS= read -r line || [ -n "$line" ]; do
if [[ $line == export* && ! $line =~ \$\(.*\) ]]; then
eval "$line"
fi
done < .envrc
fi
else
log_error ".envrc文件不存在"
return 1
fi
# 特殊处理S3_SECRET_KEY因为它包含解密命令
if [ -z "$S3_SECRET_KEY" ] && [ -f "seaweedfs_password.enc" ]; then
log_info "解密S3_SECRET_KEY..."
# 直接执行解密命令
export S3_SECRET_KEY=$(openssl enc -aes-256-cbc -d -pbkdf2 -iter 10000 -in seaweedfs_password.enc 2>/dev/null)
if [ $? -ne 0 ]; then
log_error "密码解密失败,请检查密码是否正确"
log_error "提示: 可能需要重新初始化密码文件"
return 1
fi
fi
# 定义默认环境变量(如果未设置)
export SEAWEEDFS_VERSION=${SEAWEEDFS_VERSION:-4.00}
export S3_PORT=${S3_PORT:-8333}
export S3_ACCESS_KEY=${S3_ACCESS_KEY:-seaweedfs}
export S3_SECRET_KEY=${S3_SECRET_KEY:-seaweedfs}
export MASTER_CONTAINER_NAME=${MASTER_CONTAINER_NAME:-seaweedfs-master}
export VOLUME_CONTAINER_NAME=${VOLUME_CONTAINER_NAME:-seaweedfs-volume}
export FILER_CONTAINER_NAME=${FILER_CONTAINER_NAME:-seaweedfs-filer}
export S3_CONTAINER_NAME=${S3_CONTAINER_NAME:-seaweedfs-s3}
log_info "环境变量加载完成:"
log_info " - SeaweedFS版本: $SEAWEEDFS_VERSION"
log_info " - S3端口: $S3_PORT"
log_info " - 容器名称:"
log_info " * Master: $MASTER_CONTAINER_NAME"
log_info " * Volume: $VOLUME_CONTAINER_NAME"
log_info " * Filer: $FILER_CONTAINER_NAME"
log_info " * S3: $S3_CONTAINER_NAME"
return 0
}
# 创建必要的目录
create_required_directories() {
log_info "创建必要的数据目录..."
mkdir -p ./master_data ./volume_data ./filer_data
if [ $? -eq 0 ]; then
log_success "数据目录创建成功"
return 0
else
log_error "数据目录创建失败"
return 1
fi
}
# 检查容器是否存在且运行中
is_container_running() {
local container_name=$1
docker ps --format "{{.Names}}" | grep -q "^$container_name$"
return $?
}
# 清理旧容器(避免名称冲突)
clean_old_containers() {
local containers=("$MASTER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$S3_CONTAINER_NAME")
local removed_containers=0
log_info "检查并清理可能存在的旧容器..."
for container in "${containers[@]}"; do
if docker ps -a --format "{{.Names}}" | grep -q "^$container$"; then
log_warning "发现旧容器: $container,正在清理..."
docker rm -f "$container" > /dev/null
if [ $? -eq 0 ]; then
log_success "已移除旧容器: $container"
removed_containers=$((removed_containers + 1))
else
log_error "无法移除容器: $container"
fi
fi
done
# 清理可能存在的旧网络
local network_name="$(basename "$SCRIPT_DIR")_default"
if docker network ls --format "{{.Name}}" | grep -q "^$network_name$"; then
log_warning "发现旧网络: $network_name,正在清理..."
docker network rm "$network_name" > /dev/null
if [ $? -eq 0 ]; then
log_success "已移除旧网络: $network_name"
fi
fi
if [ $removed_containers -gt 0 ]; then
log_success "已清理 $removed_containers 个旧容器"
else
log_info "没有需要清理的旧容器"
fi
}
# 启动服务
start_service() {
log_info "启动SeaweedFS服务..."
# 加载环境变量
if ! load_env_variables; then
log_error "环境变量加载失败,服务启动终止"
return 1
fi
# 创建必要的目录
if ! create_required_directories; then
return 1
fi
# 检查docker-compose.yml是否存在
if [ ! -f "docker-compose.yml" ]; then
log_error "docker-compose.yml文件不存在"
return 1
fi
# 清理旧容器,避免名称冲突
clean_old_containers
# 启动docker容器
log_info "使用docker-compose启动服务..."
docker-compose up -d
# 检查启动是否成功
if [ $? -ne 0 ]; then
log_error "SeaweedFS服务启动失败"
return 1
fi
# 等待几秒钟让容器完全启动
log_info "服务正在初始化,请稍候..."
sleep 3
# 再次检查状态以确保所有容器都已启动
status_service
local status_result=$?
if [ $status_result -eq 0 ]; then
log_success "SeaweedFS服务启动完成!"
log_success "S3服务访问地址: http://localhost:$S3_PORT"
return 0
else
log_warning "服务可能未完全启动,请检查容器状态"
return 1
fi
}
# 停止服务
stop_service() {
log_info "停止SeaweedFS服务..."
# 加载环境变量(包括密码验证)
if ! load_env_variables; then
log_error "环境变量加载失败,服务停止终止"
return 1
fi
# 首先检查服务是否正在运行
if ! docker-compose ps | grep -q "Up"; then
log_info "SeaweedFS服务已经停止或未运行"
return 0
fi
# 使用docker-compose down停止服务
log_info "使用docker-compose停止所有服务..."
docker-compose down
if [ $? -eq 0 ]; then
log_success "SeaweedFS服务已成功停止"
return 0
else
log_warning "docker-compose down命令失败尝试直接停止容器..."
# 尝试逐个停止并删除容器
local containers=("$S3_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$MASTER_CONTAINER_NAME")
local stopped=0
for container in "${containers[@]}"; do
if is_container_running "$container"; then
log_info "直接停止容器: $container"
docker stop "$container" > /dev/null
if [ $? -eq 0 ]; then
docker rm "$container" > /dev/null
log_success "已停止并移除容器: $container"
stopped=$((stopped + 1))
else
log_error "无法停止容器: $container"
fi
fi
done
if [ $stopped -gt 0 ]; then
log_success "已成功停止 $stopped 个容器"
return 0
else
log_error "无法停止任何容器请检查Docker状态"
return 1
fi
fi
}
# 检查服务状态
status_service() {
log_info "检查SeaweedFS服务状态..."
# 加载环境变量
if ! load_env_variables; then
log_error "环境变量加载失败,无法检查状态"
return 2
fi
# 定义容器数组
local containers=("$MASTER_CONTAINER_NAME" "$VOLUME_CONTAINER_NAME" "$FILER_CONTAINER_NAME" "$S3_CONTAINER_NAME")
local container_names=("Master" "Volume" "Filer" "S3")
local running_containers=0
local all_containers=${#containers[@]}
log_info "详细状态检查:"
# 检查每个容器的状态
for i in "${!containers[@]}"; do
local container=${containers[$i]}
local name=${container_names[$i]}
if is_container_running "$container"; then
log_success "$name 容器 ($container) 正在运行"
running_containers=$((running_containers + 1))
else
# 检查容器是否存在但已停止
if docker ps -a --format "{{.Names}}" | grep -q "^$container$"; then
log_warning "⚠️ $name 容器 ($container) 已停止"
# 获取停止原因
local exit_code=$(docker inspect --format='{{.State.ExitCode}}' "$container")
log_warning " 退出代码: $exit_code"
else
log_error "$name 容器 ($container) 不存在"
fi
fi
done
# 输出总体状态
log_info "--------------------------------------------------"
if [ $running_containers -eq $all_containers ]; then
log_success "✅ SeaweedFS服务完全正常运行"
log_success "S3服务访问地址: http://localhost:$S3_PORT"
return 0
elif [ $running_containers -gt 0 ]; then
log_warning "⚠️ SeaweedFS服务部分运行 ($running_containers/$all_containers 容器运行中)"
return 1
else
log_error "❌ SeaweedFS服务未运行"
return 2
fi
}
# 重启服务
restart_service() {
log_info "重启SeaweedFS服务..."
# 先停止服务
stop_service
local stop_result=$?
# 停止成功后,启动服务
if [ $stop_result -eq 0 ]; then
log_info "正在启动SeaweedFS服务..."
start_service
return $?
else
log_error "服务停止失败,无法重启"
return 1
fi
}
# 显示帮助信息
show_help() {
echo ""
echo_blue "📦 SeaweedFS服务管理脚本"
echo ""
echo "用法: ./service [command]"
echo ""
echo "命令:"
echo " start 启动SeaweedFS服务"
echo " stop 停止SeaweedFS服务"
echo " status 检查SeaweedFS服务状态"
echo " restart 重启SeaweedFS服务"
echo " help 显示此帮助信息"
echo ""
echo "示例:"
echo " ./service start # 启动所有SeaweedFS服务"
echo " ./service status # 检查服务运行状态"
echo " ./service restart # 重启所有服务"
echo ""
}
# 检查命令参数
if [ $# -eq 0 ]; then
log_error "请指定命令"
show_help
exit 1
fi
# 执行对应的命令
case "$1" in
start)
start_service
exit $?
;;
stop)
stop_service
exit $?
;;
status)
status_service
exit $?
;;
restart)
restart_service
exit $?
;;
help|\
-h|\
--help)
show_help
exit 0
;;
*)
log_error "未知命令 '$1'"
show_help
exit 1
;;
esac