From 1d1650bdbf8dd2bd909bc17691ad7df9830a3d73 Mon Sep 17 00:00:00 2001 From: ssongliu Date: Wed, 24 Jun 2026 10:17:15 +0800 Subject: [PATCH] fix: resolve snapshot extraction directory missing issue --- agent/utils/cmd/cmd.go | 39 ++++++++++++++++++++++++++++++++++++ agent/utils/cmd/cmdx.go | 8 +++++++- agent/utils/files/file_op.go | 4 ++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/agent/utils/cmd/cmd.go b/agent/utils/cmd/cmd.go index ddfcb0a1e050..a7b7eae3b8ba 100644 --- a/agent/utils/cmd/cmd.go +++ b/agent/utils/cmd/cmd.go @@ -2,6 +2,7 @@ package cmd import ( "bytes" + "fmt" "io" "os" "os/exec" @@ -67,3 +68,41 @@ func Which(name string) bool { _, err := exec.LookPath(name) return err == nil } + +func commandStartDiagnostics(name, resolvedName, workDir string, env []string) string { + items := []string{ + fmt.Sprintf("command=%q", name), + fmt.Sprintf("resolved=%q", resolvedName), + fmt.Sprintf("path=%q", envValue(env, "PATH")), + } + if workDir != "" { + items = append(items, describeWorkDir(workDir)) + } + return "; " + strings.Join(items, "; ") +} + +func describeWorkDir(name string) string { + statText := "stat=ok" + if info, err := os.Stat(name); err != nil { + statText = fmt.Sprintf("stat=%v", err) + } else { + statText = fmt.Sprintf("stat=mode:%s", info.Mode().String()) + } + lstatText := "lstat=ok" + if info, err := os.Lstat(name); err != nil { + lstatText = fmt.Sprintf("lstat=%v", err) + } else { + lstatText = fmt.Sprintf("lstat=mode:%s", info.Mode().String()) + } + return fmt.Sprintf("workdir=%q[%s %s]", name, statText, lstatText) +} + +func envValue(env []string, key string) string { + prefix := key + "=" + for i := len(env) - 1; i >= 0; i-- { + if strings.HasPrefix(env[i], prefix) { + return strings.TrimPrefix(env[i], prefix) + } + } + return os.Getenv(key) +} diff --git a/agent/utils/cmd/cmdx.go b/agent/utils/cmd/cmdx.go index 376f6b054dc2..76162016106e 100644 --- a/agent/utils/cmd/cmdx.go +++ b/agent/utils/cmd/cmdx.go @@ -274,7 +274,10 @@ func startPipeCommands(cmds []*exec.Cmd) error { for i := len(cmds) - 1; i >= 0; i-- { if err := cmds[i].Start(); err != nil { killStarted(cmds[i+1:]) - return err + if os.IsNotExist(err) { + return fmt.Errorf("cmd start failed: %w%s", err, commandStartDiagnostics(cmds[i].Args[0], cmds[i].Path, cmds[i].Dir, cmds[i].Env)) + } + return fmt.Errorf("cmd start failed: %w", err) } } return nil @@ -376,6 +379,9 @@ func (c *CommandHelper) run(name string, arg ...string) (string, error) { }() if err := cmd.Start(); err != nil { + if os.IsNotExist(err) { + return "", fmt.Errorf("cmd start failed: %w%s", err, commandStartDiagnostics(cmd.Args[0], cmd.Path, cmd.Dir, cmd.Env)) + } return "", fmt.Errorf("cmd start failed: %w", err) } if c.taskItem != nil { diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go index cfaac6bedaf0..c2647c029fd8 100644 --- a/agent/utils/files/file_op.go +++ b/agent/utils/files/file_op.go @@ -1376,8 +1376,8 @@ func (f FileOp) TarGzFilesWithCompressPro(list []string, dst, secret string) err } func (f FileOp) TarGzExtractPro(src, dst string, secret string) error { - if _, err := os.Stat(path.Dir(dst)); err != nil && os.IsNotExist(err) { - if err = os.MkdirAll(path.Dir(dst), os.ModePerm); err != nil { + if _, err := os.Stat(dst); err != nil && os.IsNotExist(err) { + if err = os.MkdirAll(dst, os.ModePerm); err != nil { return err } }