fix: preserve runtime DB config for reposync subprocess

This commit is contained in:
limitcool
2026-04-01 13:57:21 +08:00
parent 1297457cd6
commit 82bb54e97c
3 changed files with 61 additions and 12 deletions
+15 -1
View File
@@ -123,7 +123,7 @@ const (
// Agent 状态
AgentStatusOnline = "online"
AgentStatusOffline = "offline"
// AppLog 分类
LogCategoryDefault = "default"
LogCategorySystemNotice = "system_notice"
@@ -149,6 +149,20 @@ const (
// TablePrefix 表前缀,从配置文件读取
var TablePrefix string
// Runtime 数据库配置快照,用于需要单独启动内部子进程(如 reposync)时显式透传数据库连接信息,
// 避免主进程启动阶段清理环境变量后,子进程意外回退到默认 sqlite 配置。
var (
RuntimeDBType string
RuntimeDBHost string
RuntimeDBPort int
RuntimeDBUser string
RuntimeDBPassword string
RuntimeDBName string
RuntimeDBPath string
RuntimeDBDSN string
RuntimeDBTablePrefix string
)
// Secret JWT和密码salt密钥,运行中自动从数据库加载
var Secret string
+10 -1
View File
@@ -11,7 +11,7 @@ import (
)
type ServerConfig struct {
Port int `ini:"port"`
Port int `ini:"port"`
Host string `ini:"host"`
URLPrefix string `ini:"url_prefix"`
PprofEnabled bool `ini:"pprof_enabled"`
@@ -125,6 +125,15 @@ func LoadConfig(path string) (*AppConfig, error) {
// 设置表前缀到 constant 包
constant.TablePrefix = Config.Database.TablePrefix
constant.RuntimeDBType = Config.Database.Type
constant.RuntimeDBHost = Config.Database.Host
constant.RuntimeDBPort = Config.Database.Port
constant.RuntimeDBUser = Config.Database.User
constant.RuntimeDBPassword = Config.Database.Password
constant.RuntimeDBName = Config.Database.DBName
constant.RuntimeDBPath = Config.Database.Path
constant.RuntimeDBDSN = Config.Database.DSN
constant.RuntimeDBTablePrefix = Config.Database.TablePrefix
// 暂存旧的 Secret,不再直接给 constant 赋值(改为到 settings 初始化时判断)
// constant.Secret = Config.Security.Secret
+36 -10
View File
@@ -243,8 +243,6 @@ func (h *ServerSchedulerHandler) OnTaskCompleted(req *executor.ExecutionRequest,
// 处理任务完成(更新统计、清理旧日志等)
h.es.taskLogService.ProcessTaskCompletion(taskLog)
// 更新内存缓冲
h.es.UpdateResult(*result)
@@ -362,14 +360,14 @@ func (es *ExecutorService) HandleTaskRetry(task *models.Task, req *executor.Exec
if task == nil {
return
}
if !isSuccess || status == constant.TaskStatusFailed || status == constant.TaskStatusTimeout || exitCode != 0 {
retryIndex := req.Metadata.RetryIndex
if retryIndex < task.RetryCount {
retryIndex++
logger.Infof("[Executor] 任务 #%s 执行失败/出错,将在 %d 秒后进行第 %d/%d 次重试...", task.ID, task.RetryInterval, retryIndex, task.RetryCount)
es.scheduler.EnqueueDelayed(time.Duration(task.RetryInterval)*time.Second, func() *executor.ExecutionRequest {
latestTask := es.taskService.GetTaskByID(task.ID)
if latestTask == nil || !latestTask.Enabled {
@@ -427,7 +425,7 @@ func (h *LocalTaskHooks) OnHeartbeat(ctx context.Context, logID string, duration
// ExecuteDispatcher 实现任务分发逻辑
func (es *ExecutorService) ExecuteDispatcher(ctx context.Context, req *executor.ExecutionRequest, stdout, stderr io.Writer) (*executor.Result, error) {
taskID := req.TaskID
// 解析路径变量 (如 $SCRIPTS_DIR$)
req.Command = es.ResolvePath(req.Command)
req.WorkDir = es.ResolvePath(req.WorkDir)
@@ -770,8 +768,8 @@ func (es *ExecutorService) CheckConcurrency(taskID string) error {
if string(task.RunningGo) != "" {
_ = json.Unmarshal([]byte(string(task.RunningGo)), &goids)
}
var config models.TaskConfig
var config models.TaskConfig
if string(task.Config) != "" {
_ = json.Unmarshal([]byte(string(task.Config)), &config)
}
@@ -990,7 +988,7 @@ func (es *ExecutorService) BuildRepoCommand(task *models.Task) (string, string)
if config.Extensions != "" {
args = append(args, "--extensions", config.Extensions)
}
// 传递任务 ID,以便 reposync 内部直接处理脚本注册并输出日志
args = append(args, "--task-id", task.ID)
args = append(args, "--task-timeout", fmt.Sprintf("%d", task.Timeout))
@@ -1005,7 +1003,7 @@ func (es *ExecutorService) BuildRepoCommand(task *models.Task) (string, string)
}
cmdStr := utils.QuotePath(exePath) + " " + strings.Join(quotedArgs, " ")
return buildRepoCommandEnvPrefix()+cmdStr, filepath.Dir(exePath)
return buildRepoCommandEnvPrefix() + cmdStr, filepath.Dir(exePath)
}
// loadEnvVars 加载环境变量和掩码信息,支持全局注入及重名合并
@@ -1083,7 +1081,35 @@ func buildRepoCommandEnvPrefix() string {
}
absScriptsDir := resolveAbsScriptsDir()
return "BH_CONFIG_PATH='" + strings.ReplaceAll(absConfig, "'", "'\\''") + "' BH_SCRIPTS_DIR='" + strings.ReplaceAll(absScriptsDir, "'", "'\\''") + "' "
parts := []string{
shellEnvAssignment("BH_CONFIG_PATH", absConfig),
shellEnvAssignment("BH_SCRIPTS_DIR", absScriptsDir),
}
appendIfSet := func(key string, value string) {
if strings.TrimSpace(value) == "" {
return
}
parts = append(parts, shellEnvAssignment(key, value))
}
appendIfSet("BH_DB_TYPE", constant.RuntimeDBType)
appendIfSet("BH_DB_HOST", constant.RuntimeDBHost)
if constant.RuntimeDBPort > 0 {
parts = append(parts, shellEnvAssignment("BH_DB_PORT", fmt.Sprintf("%d", constant.RuntimeDBPort)))
}
appendIfSet("BH_DB_USER", constant.RuntimeDBUser)
appendIfSet("BH_DB_PASSWORD", constant.RuntimeDBPassword)
appendIfSet("BH_DB_NAME", constant.RuntimeDBName)
appendIfSet("BH_DB_PATH", constant.RuntimeDBPath)
appendIfSet("BH_DB_DSN", constant.RuntimeDBDSN)
appendIfSet("BH_DB_TABLE_PREFIX", constant.RuntimeDBTablePrefix)
return strings.Join(parts, " ") + " "
}
func shellEnvAssignment(key, value string) string {
return key + "='" + strings.ReplaceAll(value, "'", "'\\''") + "'"
}
func resolveAbsScriptsDir() string {