fix: add -settingStatus CLI flag to reduce DB inits during install/update

Worker nodes with remote MariaDB experienced slow configuration because
config_after_update() and config_after_install() made 5-8 separate
x-ui setting CLI calls, each spawning a new Go process and re-initing
the DB connection. Add a single -settingStatus flag that returns all
needed info in one call, reducing DB inits from 5-6 down to 2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root 2026-04-25 15:05:11 +08:00
parent 88584a1f70
commit b53703f1a1
3 changed files with 72 additions and 12 deletions

View file

@ -1295,10 +1295,11 @@ config_after_install() {
is_fresh_install=true
fi
local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}' | sed 's#^/##')
local existing_port=$(${xui_folder}/x-ui setting -show true | grep '^port:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
# 通过检查 cert: 行是否存在且之后有内容来正确检测空证书
local existing_cert=$(${xui_folder}/x-ui setting -getCert true | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
# Single CLI call for all settings (1 DB init instead of 3)
local settings_output=$(${xui_folder}/x-ui setting -settingStatus true 2>/dev/null)
local existing_webBasePath=$(echo "$settings_output" | grep '^webBasePath:' | cut -d: -f2-)
local existing_port=$(echo "$settings_output" | grep '^port:' | cut -d: -f2-)
local existing_cert=$(echo "$settings_output" | grep '^certFile:' | cut -d: -f2-)
local URL_lists=(
"https://api4.ipify.org"
"https://ipv4.icanhazip.com"
@ -1513,7 +1514,8 @@ config_after_install() {
return 1
fi
local saved_port
saved_port=$(${xui_folder}/x-ui setting -show true 2>/dev/null | grep '^port:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
local verify_output=$(${xui_folder}/x-ui setting -settingStatus true 2>/dev/null)
saved_port=$(echo "$verify_output" | grep '^port:' | cut -d: -f2-)
if [[ "${saved_port}" != "${config_port}" ]]; then
echo -e "${red}端口未写入配置文件:期望 ${config_port},实际 ${saved_port:-}${plain}"
return 1
@ -1551,7 +1553,7 @@ config_after_install() {
else
# 已有安装(存在 x-ui.json 或 x-ui.db保留所有配置不重新输入
local config_webBasePath="${existing_webBasePath}"
local existing_webDomain=$(${xui_folder}/x-ui setting -show true | grep '^webDomain:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
local existing_webDomain=$(echo "$settings_output" | grep '^webDomain:' | cut -d: -f2-)
if [[ ${#config_webBasePath} -lt 4 ]]; then
config_webBasePath=$(gen_random_string 18)
echo -e "${yellow}WebBasePath 缺失或过短,正在生成新的...${plain}"

40
main.go
View file

@ -51,6 +51,7 @@ type settingCommandOptions struct {
nodeIDSet bool
syncIntervalSet bool
trafficFlushIntervalSet bool
settingStatus bool
}
func (o settingCommandOptions) needsDBInit() bool {
@ -63,6 +64,7 @@ func (o settingCommandOptions) needsDBInit() bool {
o.show ||
o.getListen ||
o.getCert ||
o.settingStatus ||
o.resetTwoFactor ||
o.tgbotToken != "" ||
o.tgbotChatID != "" ||
@ -258,6 +260,37 @@ func showSetting(show bool) {
}
}
// showSettingStatus outputs all settings in a single machine-parseable call.
// This avoids multiple CLI invocations that each re-init the database.
func showSettingStatus() {
settingService := service.SettingService{}
port, _ := settingService.GetPort()
webBasePath, _ := settingService.GetBasePath()
webDomain, _ := settingService.GetWebDomain()
certFile, _ := settingService.GetCertFile()
keyFile, _ := settingService.GetKeyFile()
userService := service.UserService{}
userModel, _ := userService.GetFirstUser()
hasDefaultCredential := userModel.Username == "admin" && crypto.CheckPasswordHash(userModel.Password, "admin")
nodeCfg := config.GetNodeConfigFromJSON()
fmt.Printf("port:%d\n", port)
fmt.Printf("webBasePath:%s\n", webBasePath)
fmt.Printf("webDomain:%s\n", webDomain)
fmt.Printf("certFile:%s\n", certFile)
fmt.Printf("keyFile:%s\n", keyFile)
fmt.Printf("hasDefaultCredential:%v\n", hasDefaultCredential)
fmt.Printf("username:%s\n", userModel.Username)
fmt.Printf("nodeRole:%s\n", nodeCfg.Role)
fmt.Printf("nodeId:%s\n", nodeCfg.NodeID)
fmt.Printf("syncInterval:%d\n", nodeCfg.SyncIntervalSeconds)
fmt.Printf("trafficFlushInterval:%d\n", nodeCfg.TrafficFlushSeconds)
}
// updateTgbotEnableSts enables or disables the Telegram bot notifications based on the status parameter.
func updateTgbotEnableSts(status bool) {
settingService := service.SettingService{}
@ -545,8 +578,10 @@ func main() {
var show bool
var getCert bool
var resetTwoFactor bool
var settingStatus bool
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
settingCmd.BoolVar(&show, "show", false, "Display current settings")
settingCmd.BoolVar(&settingStatus, "settingStatus", false, "Display all settings and cert info in one call")
settingCmd.IntVar(&port, "port", 0, "Set panel port number")
settingCmd.StringVar(&username, "username", "", "Set login username")
settingCmd.StringVar(&password, "password", "", "Set login password")
@ -769,6 +804,7 @@ func main() {
nodeIDSet: nodeIDSet,
syncIntervalSet: syncIntervalSet,
trafficFlushIntervalSet: trafficFlushIntervalSet,
settingStatus: settingStatus,
}
if opts.needsDBInit() {
if err := database.InitDB(); err != nil {
@ -776,6 +812,10 @@ func main() {
return
}
}
if settingStatus {
showSettingStatus()
return
}
if reset {
resetSetting()
} else {

View file

@ -668,15 +668,33 @@ prompt_and_setup_ssl() {
}
config_after_update() {
# Single CLI call for all settings (1 DB init instead of 5)
local settings_output=$(${xui_folder}/x-ui setting -settingStatus true 2>/dev/null)
local existing_port=$(echo "$settings_output" | grep '^port:' | cut -d: -f2-)
local existing_webBasePath=$(echo "$settings_output" | grep '^webBasePath:' | cut -d: -f2-)
local existing_cert=$(echo "$settings_output" | grep '^certFile:' | cut -d: -f2-)
local keyFile=$(echo "$settings_output" | grep '^keyFile:' | cut -d: -f2-)
local existing_webDomain=$(echo "$settings_output" | grep '^webDomain:' | cut -d: -f2-)
# Show human-readable settings
echo -e "${yellow}x-ui settings:${plain}"
${xui_folder}/x-ui setting -show true
echo "current panel settings as follows:"
if [[ -z "$existing_cert" || -z "$keyFile" ]]; then
echo "Warning: Panel is not secure with SSL"
else
echo "Panel is secure with SSL"
fi
echo "hasDefaultCredential: $(echo "$settings_output" | grep '^hasDefaultCredential:' | cut -d: -f2-)"
echo "port: $existing_port"
echo "webDomain: $existing_webDomain"
echo "webBasePath: $existing_webBasePath"
echo "nodeRole: $(echo "$settings_output" | grep '^nodeRole:' | cut -d: -f2-)"
echo "nodeId: $(echo "$settings_output" | grep '^nodeId:' | cut -d: -f2-)"
echo "syncInterval: $(echo "$settings_output" | grep '^syncInterval:' | cut -d: -f2-)"
echo "trafficFlushInterval: $(echo "$settings_output" | grep '^trafficFlushInterval:' | cut -d: -f2-)"
${xui_folder}/x-ui migrate
# Properly detect empty cert by checking if cert: line exists and has content after it
local existing_cert=$(${xui_folder}/x-ui setting -getCert true 2>/dev/null | grep 'cert:' | awk -F': ' '{print $2}' | tr -d '[:space:]')
local existing_port=$(${xui_folder}/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
local existing_webBasePath=$(${xui_folder}/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}' | sed 's#^/##')
# Get server IP
local URL_lists=(
"https://api4.ipify.org"