修复目录服务套接字停止后阻止安装器升级

This commit is contained in:
xuans 2026-09-27 00:35:42 +08:00
parent 4f7e2bdbc8
commit 68a7304d46
2 changed files with 67 additions and 0 deletions

View File

@ -3,12 +3,76 @@ package admin
import (
"bufio"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"testing"
)
func TestLinuxInstallerStoppedUnitStates(t *testing.T) {
bash, err := exec.LookPath("bash")
if err != nil {
t.Skip(err)
}
data, err := os.ReadFile(filepath.Join("..", "..", "..", "deploy", "install-linux.sh"))
if err != nil {
t.Fatal(err)
}
content := string(data)
start := strings.Index(content, "ensure_services_stopped() {")
if start < 0 {
t.Fatal("ensure_services_stopped")
}
end := strings.Index(content[start:], "\n}\n")
if end < 0 {
t.Fatal("ensure_services_stopped")
}
guard := content[start : start+end+3]
stopped := "LoadState=loaded\nActiveState=inactive\nSubState=dead\nControlPID=0\nJob=\n"
for _, tc := range []struct {
name string
unit string
properties string
allowed bool
}{
{"socket-missing-main-pid", "Scert-storage.socket", stopped, true},
{"socket-zero-main-pid", "Scert-storage.socket", stopped + "MainPID=0\n", true},
{"socket-active", "Scert-storage.socket", strings.ReplaceAll(strings.ReplaceAll(stopped, "inactive", "active"), "dead", "listening"), false},
{"socket-control-process", "Scert-storage.socket", strings.ReplaceAll(stopped, "ControlPID=0", "ControlPID=52"), false},
{"socket-missing-control-pid", "Scert-storage.socket", strings.ReplaceAll(stopped, "ControlPID=0\n", ""), false},
{"socket-pending-job", "Scert-storage.socket", strings.ReplaceAll(stopped, "Job=", "Job=7"), false},
{"socket-missing-job", "Scert-storage.socket", strings.ReplaceAll(stopped, "Job=\n", ""), false},
{"socket-nonzero-main-pid", "Scert-storage.socket", stopped + "MainPID=51\n", false},
{"service-missing-main-pid", "Scert.service", stopped, false},
{"admin-missing-main-pid", "Scert-admin.service", stopped, false},
{"storage-missing-main-pid", "Scert-storage.service", stopped, false},
{"service-stopped", "Scert.service", stopped + "MainPID=0\n", true},
} {
t.Run(tc.name, func(t *testing.T) {
script := `set -Eeuo pipefail
fail() { printf '%s\n' "$1" >&2; exit 1; }
systemctl() {
[[ "$1" == show ]] || exit 97
if [[ "$2" == "$TEST_UNIT" ]]; then
printf '%s' "$TEST_PROPERTIES"
else
printf '%s' "$TEST_STOPPED"
[[ "$2" == *.socket ]] || printf 'MainPID=0\n'
fi
return 0
}
` + guard + "\nensure_services_stopped\n"
command := exec.Command(bash, "--noprofile", "--norc", "-c", script)
command.Env = append(os.Environ(), "TEST_UNIT="+tc.unit, "TEST_PROPERTIES="+tc.properties, "TEST_STOPPED="+stopped)
output, err := command.CombinedOutput()
if (err == nil) != tc.allowed {
t.Fatalf("allowed=%t, err=%v, output=%s", tc.allowed, err, output)
}
})
}
}
func TestLinuxInstallerPolicy(t *testing.T) {
installerPath := filepath.Join("..", "..", "..", "deploy", "install-linux.sh")
data, err := os.ReadFile(installerPath)

View File

@ -292,6 +292,9 @@ ensure_services_stopped() {
loaded:inactive:dead|loaded:failed:failed|not-found:inactive:dead) ;;
*) fail "升级或安装前必须确认 $unit 已停止,当前状态:$load_state/$active_state/$sub_state" ;;
esac
if [[ "$unit" == *.socket && -z "$main_pid" ]]; then
main_pid="0"
fi
[[ "$main_pid" == "0" && "$control_pid" == "0" && -z "$job" ]] || \
fail "$unit 仍有进程、排队任务或缺失状态,拒绝安装"
done