init
This commit is contained in:
298
install_patch_system.sh
Normal file
298
install_patch_system.sh
Normal file
@@ -0,0 +1,298 @@
|
||||
#!/bin/bash
|
||||
# install_patch_system.sh - 补丁管理系统安装脚本
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALL_DIR="/opt/patch-management"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/patch_config.sh"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# 配置加载
|
||||
load_config() {
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
error "配置文件不存在: $CONFIG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$CONFIG_FILE"
|
||||
info "配置文件加载完成"
|
||||
}
|
||||
|
||||
install_dependencies() {
|
||||
info "安装系统依赖..."
|
||||
|
||||
local sudo_prefix
|
||||
sudo_prefix=$(get_cmd_prefix)
|
||||
|
||||
|
||||
local will_install_dependencies=false
|
||||
local dependencies=(
|
||||
"tar"
|
||||
"gzip"
|
||||
"bzip2"
|
||||
"jq"
|
||||
"gpg"
|
||||
"bc"
|
||||
)
|
||||
|
||||
for dep in "${dependencies[@]}"; do
|
||||
if command -v "$dep" >/dev/null 2>&1; then
|
||||
info "系统依赖 $dep 已安装"
|
||||
else
|
||||
warn "系统依赖 $dep 未安装"
|
||||
will_install_dependencies=true
|
||||
fi
|
||||
done
|
||||
|
||||
if ! $will_install_dependencies; then
|
||||
info "系统依赖已安装"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 关键依赖
|
||||
local keys_deps=(
|
||||
"coreutils"
|
||||
"findutils"
|
||||
"util-linux"
|
||||
)
|
||||
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
# Debian/Ubuntu
|
||||
$sudo_prefix apt-get update
|
||||
$sudo_prefix apt-get install -y $(printf "%s " "${keys_deps[@]}") $(printf "%s " "${dependencies[@]}")
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
# CentOS/RHEL
|
||||
$sudo_prefix yum install -y $(printf "%s " "${keys_deps[@]}") $(printf "%s " "${dependencies[@]}")
|
||||
else
|
||||
warn "无法自动安装依赖,请手动安装: $(printf "%s " "${keys_deps[@]}") $(printf "%s " "${dependencies[@]}")"
|
||||
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_gpg_key() {
|
||||
local name="${1:-John Doe}"
|
||||
local email="${2:-johndoe@example.com}"
|
||||
local key_type="${3:-RSA}"
|
||||
local key_length="${4:-4096}"
|
||||
|
||||
cat > /tmp/gpg_batch << EOF
|
||||
Key-Type: $key_type
|
||||
Key-Length: $key_length
|
||||
Subkey-Type: $key_type
|
||||
Subkey-Length: $key_length
|
||||
Name-Real: $name
|
||||
Name-Email: $email
|
||||
Expire-Date: 0
|
||||
%commit
|
||||
EOF
|
||||
|
||||
gpg --batch --generate-key /tmp/gpg_batch
|
||||
rm -f /tmp/gpg_batch
|
||||
|
||||
echo "✅ 密钥生成完成"
|
||||
gpg --list-secret-keys --keyid-format LONG "$email"
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
# 生成GPG密钥对
|
||||
generate_gpg_key "$PATCH_AUTHOR" "$PATCH_EMAIL" "RSA" "4096"
|
||||
|
||||
# 生成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 "========================================"
|
||||
echo "📋 安装配置文件: $INSTALL_DIR/patch_config.sh"
|
||||
|
||||
# 加载配置
|
||||
load_config
|
||||
|
||||
# 检查运行环境
|
||||
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 "$@"
|
||||
Reference in New Issue
Block a user