提交 24038b8f authored 作者: 陈泽健's avatar 陈泽健

feat(update): 增强前端安全覆盖功能并优化PowerShell脚本

- 实现前端更新时对Bak*/bak*/new目录的兜底保护机制
- 添加临时移出和恢复保护目录的功能防止误删
- 增强PowerShell脚本的UTF-8编码支持避免中文乱码
- 优化PowerShell中的路径解析和文件读取编码处理
上级 aa175bf1
...@@ -306,10 +306,11 @@ sync_overwrite_globs() { ...@@ -306,10 +306,11 @@ sync_overwrite_globs() {
fi fi
} }
# 前端安全覆盖(只更新主文件;不影响目标目录下 Bak*/bak*/new 等原有目录 # 前端安全覆盖(只更新主文件;强制保留目标目录 Bak*/bak*/new
# 规则: # 规则:
# - 覆盖:index.html、根目录 *.js # - 覆盖:index.html、根目录 *.js
# - static:只同步 static/ 内部内容(不删除 static 目录本身) # - static:只同步 static/ 内部内容(不删除 static 目录本身)
# - 保护:目标目录下 Bak*/bak*/new 在更新过程中会被临时移出并恢复(兜底防误删)
sync_frontend_preserve() { sync_frontend_preserve() {
local sourceDir="$1" local sourceDir="$1"
local targetDir="$2" local targetDir="$2"
...@@ -323,12 +324,30 @@ sync_frontend_preserve() { ...@@ -323,12 +324,30 @@ sync_frontend_preserve() {
log "UPDATE (frontend-preserve) [$label]: $sourceDir -> $targetDir (preserve: Bak*/bak*/new)" log "UPDATE (frontend-preserve) [$label]: $sourceDir -> $targetDir (preserve: Bak*/bak*/new)"
# 1) 覆盖 index.html(如果存在) # ---- 0) 兜底保护:把目标目录的 Bak*/bak*/new 临时移走,避免被任何覆盖/清空逻辑误删 ----
local preserveRoot="/tmp/program_update_preserve_$(date +%Y%m%d_%H%M%S)_$$"
mkdir -p "$preserveRoot"
local movedAny=0
shopt -s nullglob
local d bn
for d in "$targetDir"/Bak* "$targetDir"/bak* "$targetDir"/new; do
if [[ -d "$d" ]]; then
bn="$(basename "$d")"
log "PRESERVE: move out $d -> $preserveRoot/$bn"
rm -rf "$preserveRoot/$bn" 2>/dev/null || true
mv "$d" "$preserveRoot/$bn"
movedAny=1
fi
done
shopt -u nullglob
# ---- 1) 覆盖 index.html(如果存在)----
if [[ -f "$sourceDir/index.html" ]]; then if [[ -f "$sourceDir/index.html" ]]; then
cp -a "$sourceDir/index.html" "$targetDir/index.html" cp -a "$sourceDir/index.html" "$targetDir/index.html"
fi fi
# 2) 覆盖根目录 *.js(如果存在) # ---- 2) 覆盖根目录 *.js(如果存在)----
shopt -s nullglob shopt -s nullglob
local f local f
for f in "$sourceDir"/*.js; do for f in "$sourceDir"/*.js; do
...@@ -336,17 +355,16 @@ sync_frontend_preserve() { ...@@ -336,17 +355,16 @@ sync_frontend_preserve() {
done done
shopt -u nullglob shopt -u nullglob
# 3) 同步 static(只同步内容,不 rm -rf static) # ---- 3) 同步 static(只同步内容,不 rm -rf static)----
if [[ -d "$sourceDir/static" ]]; then if [[ -d "$sourceDir/static" ]]; then
mkdir -p "$targetDir/static" mkdir -p "$targetDir/static"
# 优先 rsync(不使用 --delete,避免误删目标里多余文件;并排除备份目录 # 优先 rsync(不使用 --delete;排除 Bak/bak/new
if command -v rsync >/dev/null 2>&1; then if command -v rsync >/dev/null 2>&1; then
rsync -a \ rsync -a \
--exclude 'Bak*/' --exclude 'bak*/' --exclude 'new/' \ --exclude 'Bak*/' --exclude 'bak*/' --exclude 'new/' \
"${sourceDir%/}/static/" "${targetDir%/}/static/" "${sourceDir%/}/static/" "${targetDir%/}/static/"
else else
# 无 rsync:逐项覆盖复制 static 内部内容
shopt -s dotglob nullglob shopt -s dotglob nullglob
for f in "$sourceDir/static/"*; do for f in "$sourceDir/static/"*; do
# 源里如果也带 Bak/bak/new 目录,跳过 # 源里如果也带 Bak/bak/new 目录,跳过
...@@ -355,13 +373,31 @@ sync_frontend_preserve() { ...@@ -355,13 +373,31 @@ sync_frontend_preserve() {
Bak*|bak*|new) continue ;; Bak*|bak*|new) continue ;;
esac esac
fi fi
# 覆盖同名项:仅对 static 内的同名项处理,不涉及 targetDir 根目录的 Bak/new
rm -rf "$targetDir/static/$(basename "$f")" rm -rf "$targetDir/static/$(basename "$f")"
cp -a "$f" "$targetDir/static/" cp -a "$f" "$targetDir/static/"
done done
shopt -u dotglob nullglob shopt -u dotglob nullglob
fi fi
fi fi
# ---- 4) 恢复被保护的目录 ----
if [[ "$movedAny" -eq 1 ]]; then
shopt -s nullglob
for d in "$preserveRoot"/*; do
bn="$(basename "$d")"
# 如果更新包里恰好也有同名目录(不应该),优先保留原来的备份目录
if [[ -e "$targetDir/$bn" ]]; then
log "PRESERVE: target already has $bn, keep preserved copy at $preserveRoot/$bn"
continue
fi
log "PRESERVE: restore $bn -> $targetDir/$bn"
mv "$d" "$targetDir/$bn"
done
shopt -u nullglob
# 清理空目录
rmdir "$preserveRoot" 2>/dev/null || true
fi
} }
# 后端目录安全覆盖(适用于 cmdb / UbainsDevOps 这类“目录型后端”) # 后端目录安全覆盖(适用于 cmdb / UbainsDevOps 这类“目录型后端”)
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
# 让当前 PowerShell 会话使用 UTF-8(尽量避免中文乱码)
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
function Write-Info($msg) { Write-Host "[INFO] $msg" -ForegroundColor Cyan } function Write-Info($msg) { Write-Host "[INFO] $msg" -ForegroundColor Cyan }
function Write-Warn($msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow } function Write-Warn($msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow }
function Write-Err ($msg) { Write-Host "[ERROR] $msg" -ForegroundColor Red } function Write-Err ($msg) { Write-Host "[ERROR] $msg" -ForegroundColor Red }
...@@ -43,7 +46,7 @@ function Find-Tool([string]$name) { ...@@ -43,7 +46,7 @@ function Find-Tool([string]$name) {
if ($cmd) { return $cmd.Source } if ($cmd) { return $cmd.Source }
$local = Join-Path $PSScriptRoot $name $local = Join-Path $PSScriptRoot $name
if (Test-Path $local) { return $local } if (Test-Path $local) { return (Resolve-Path $local).Path }
return $null return $null
} }
...@@ -88,8 +91,8 @@ function Invoke-PlinkCommand { ...@@ -88,8 +91,8 @@ function Invoke-PlinkCommand {
$outText = "" $outText = ""
$errText = "" $errText = ""
if (Test-Path $tmpOut) { $outText = (Get-Content $tmpOut -Raw) } if (Test-Path $tmpOut) { $outText = (Get-Content $tmpOut -Raw -Encoding utf8) }
if (Test-Path $tmpErr) { $errText = (Get-Content $tmpErr -Raw) } if (Test-Path $tmpErr) { $errText = (Get-Content $tmpErr -Raw -Encoding utf8) }
if (-not [string]::IsNullOrWhiteSpace($outText)) { Write-Host $outText } if (-not [string]::IsNullOrWhiteSpace($outText)) { Write-Host $outText }
if (-not [string]::IsNullOrWhiteSpace($errText)) { Write-Warn $errText } if (-not [string]::IsNullOrWhiteSpace($errText)) { Write-Warn $errText }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论