223 lines
6.2 KiB
Bash
223 lines
6.2 KiB
Bash
#!/bin/bash
|
||
# install_patch_system.sh - 补丁管理系统安装脚本
|
||
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
INSTALL_DIR="/opt/patch-management"
|
||
|
||
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"; }
|
||
info() { log "INFO: $1"; }
|
||
error() { log "ERROR: $1"; exit 1; }
|
||
warn() { log "WARNING: $1"; }
|
||
|
||
# 检测是否在Docker容器中运行
|
||
is_docker_environment() {
|
||
# 检查多种Docker环境标识
|
||
if [[ -f /.dockerenv ]]; then
|
||
return 0
|
||
fi
|
||
|
||
if grep -q docker /proc/1/cgroup 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
|
||
if grep -q lxc /proc/1/cgroup 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
|
||
if [[ -n "${container:-}" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
if [[ -n "${DOCKER_CONTAINER:-}" ]]; then
|
||
return 0
|
||
fi
|
||
|
||
# 检查容器相关的环境变量组合
|
||
local env_vars=(
|
||
"HOSTNAME"
|
||
"HOME"
|
||
"USER"
|
||
)
|
||
|
||
for var in "${env_vars[@]}"; do
|
||
if [[ -n "${!var:-}" ]] && [[ "${!var}" =~ ^[a-f0-9]{12,}$ ]]; then
|
||
# 检查环境变量值是否像容器ID
|
||
if [[ ${!var} =~ ^[a-f0-9]{12,64}$ ]]; then
|
||
return 0
|
||
fi
|
||
fi
|
||
done
|
||
|
||
return 1
|
||
}
|
||
|
||
# 获取适当的命令前缀(在Docker中使用空前缀,否则使用sudo)
|
||
get_cmd_prefix() {
|
||
if is_docker_environment; then
|
||
echo ""
|
||
else
|
||
echo "sudo"
|
||
fi
|
||
}
|
||
|
||
install_dependencies() {
|
||
info "安装系统依赖..."
|
||
|
||
local sudo_prefix
|
||
sudo_prefix=$(get_cmd_prefix)
|
||
|
||
if command -v apt-get >/dev/null 2>&1; then
|
||
# Debian/Ubuntu
|
||
$sudo_prefix apt-get update
|
||
$sudo_prefix apt-get install -y tar gzip jq coreutils findutils util-linux bc
|
||
elif command -v yum >/dev/null 2>&1; then
|
||
# CentOS/RHEL
|
||
$sudo_prefix yum install -y tar gzip jq coreutils findutils util-linux bc
|
||
else
|
||
warn "无法自动安装依赖,请手动安装: tar, gzip, jq, coreutils, findutils, util-linux, bc"
|
||
fi
|
||
|
||
# 安装GPG(用于签名验证)
|
||
if command -v apt-get >/dev/null 2>&1; then
|
||
$sudo_prefix apt-get install -y gnupg
|
||
elif command -v yum >/dev/null 2>&1; then
|
||
$sudo_prefix yum install -y gnupg
|
||
fi
|
||
}
|
||
|
||
create_directories() {
|
||
info "创建目录结构..."
|
||
|
||
local sudo_prefix
|
||
sudo_prefix=$(get_cmd_prefix)
|
||
|
||
$sudo_prefix mkdir -p "$INSTALL_DIR"
|
||
$sudo_prefix mkdir -p "/var/backups/patch"
|
||
$sudo_prefix mkdir -p "/var/log/patch_system"
|
||
$sudo_prefix mkdir -p "/etc/patch/keys"
|
||
|
||
# 设置权限
|
||
$sudo_prefix chmod 755 "$INSTALL_DIR"
|
||
$sudo_prefix chmod 755 "/var/backups/patch"
|
||
$sudo_prefix chmod 755 "/var/log/patch_system"
|
||
$sudo_prefix chmod 700 "/etc/patch/keys"
|
||
}
|
||
|
||
install_scripts() {
|
||
info "安装脚本文件..."
|
||
|
||
local sudo_prefix
|
||
sudo_prefix=$(get_cmd_prefix)
|
||
|
||
# 复制脚本文件, 存在则覆盖
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_generator.sh" "$INSTALL_DIR/"
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_fnc.sh" "$INSTALL_DIR/"
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_applier.sh" "$INSTALL_DIR/"
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_rollback.sh" "$INSTALL_DIR/"
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_verifier.sh" "$INSTALL_DIR/"
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_workflow.sh" "$INSTALL_DIR/"
|
||
$sudo_prefix cp --force "$SCRIPT_DIR/patch_config.sh" "$INSTALL_DIR/"
|
||
|
||
info "脚本文件已安装在: $INSTALL_DIR/"
|
||
|
||
# 设置执行权限
|
||
$sudo_prefix chmod +x "$INSTALL_DIR"/*.sh
|
||
|
||
# 创建符号链接
|
||
$sudo_prefix ln -sf "$INSTALL_DIR/patch_workflow.sh" "/usr/local/bin/patch-mgmt"
|
||
info "符号链接已创建: /usr/local/bin/patch-mgmt"
|
||
}
|
||
|
||
setup_cron() {
|
||
info "设置定时任务..."
|
||
|
||
if is_docker_environment; then
|
||
info "Docker环境,跳过系统定时任务设置"
|
||
info "如需定时任务,请考虑使用宿主机的crontab或Docker运行参数"
|
||
return 0
|
||
fi
|
||
|
||
local sudo_prefix
|
||
sudo_prefix=$(get_cmd_prefix)
|
||
|
||
local cron_job="0 2 * * * $INSTALL_DIR/patch_verifier.sh /opt/patches batch > /var/log/patch_system/batch_verify.log 2>&1"
|
||
|
||
if ! crontab -l 2>/dev/null | grep -q "patch_verifier.sh"; then
|
||
(crontab -l 2>/dev/null; echo "$cron_job") | crontab -
|
||
info "定时任务已添加"
|
||
else
|
||
info "定时任务已存在"
|
||
fi
|
||
}
|
||
|
||
generate_keys() {
|
||
info "生成签名密钥..."
|
||
|
||
local key_dir="/etc/patch/keys"
|
||
local sudo_prefix
|
||
sudo_prefix=$(get_cmd_prefix)
|
||
|
||
if [[ ! -f "$key_dir/private.pem" ]]; then
|
||
$sudo_prefix mkdir -p "$key_dir"
|
||
|
||
# 生成RSA密钥对
|
||
openssl genrsa -out "$key_dir/private.pem" 4096
|
||
openssl rsa -in "$key_dir/private.pem" -pubout -out "$key_dir/public.pem"
|
||
|
||
$sudo_prefix chmod 600 "$key_dir/private.pem"
|
||
$sudo_prefix chmod 644 "$key_dir/public.pem"
|
||
|
||
info "密钥对已生成: $key_dir/"
|
||
else
|
||
info "密钥对已存在"
|
||
fi
|
||
}
|
||
|
||
main() {
|
||
info "开始安装企业级补丁管理系统"
|
||
echo "========================================"
|
||
|
||
# 检查运行环境
|
||
if is_docker_environment; then
|
||
info "检测到Docker容器环境,将以root权限执行(不适用sudo)"
|
||
SUDO_CMD=""
|
||
else
|
||
info "检测到主机环境,将使用sudo执行管理员操作"
|
||
SUDO_CMD="sudo"
|
||
|
||
# 在非Docker环境中,建议非root用户运行
|
||
if [[ $EUID -eq 0 ]]; then
|
||
warn "检测到以root用户运行,建议在非Docker环境中使用具备sudo权限的普通用户"
|
||
fi
|
||
fi
|
||
|
||
# 安装依赖
|
||
install_dependencies
|
||
|
||
# 创建目录
|
||
create_directories
|
||
|
||
# 安装脚本
|
||
install_scripts
|
||
|
||
# 设置定时任务
|
||
setup_cron
|
||
|
||
# 生成密钥
|
||
generate_keys
|
||
|
||
info "🎉 补丁管理系统安装完成!"
|
||
echo ""
|
||
echo "📁 安装目录: $INSTALL_DIR"
|
||
echo "🔧 使用命令: patch-mgmt"
|
||
echo "📋 配置文件: $INSTALL_DIR/patch_config.sh"
|
||
echo ""
|
||
echo "💡 下一步操作:"
|
||
echo " 1. 编辑配置文件: $INSTALL_DIR/patch_config.sh"
|
||
echo " 2. 测试系统: patch-mgmt --help"
|
||
echo " 3. 配置通知: 修改SLACK_WEBHOOK等设置"
|
||
}
|
||
|
||
main "$@" |