v0.294.0: off-site clean-up guard follows the policy's own constants (R-867); no image clean-up while compose pulls (R-863); stderr tail (R-864); move-aside destination logged (R-869)
gates / gates (push) Successful in 28s
gates / gates (push) Successful in 28s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/appbackup"
|
||||
"gitea.dooplex.hu/admin/felhom-controller/internal/config"
|
||||
@@ -1446,6 +1447,7 @@ func (m *Manager) composeExec(dir string, args ...string) (string, error) {
|
||||
}
|
||||
|
||||
func (m *Manager) composeExecCustomEnv(dir string, env []string, args ...string) (string, error) {
|
||||
defer dockerexec.BeginImageWork(args)() // R-863: no image clean-up while this may pull
|
||||
var cmd *exec.Cmd
|
||||
|
||||
if m.composeCmd == "docker compose" {
|
||||
@@ -1511,10 +1513,12 @@ func (m *Manager) composeExecCustomEnv(dir string, env []string, args ...string)
|
||||
if stdoutStr := truncateStr(stdout.String(), 500); stdoutStr != "" {
|
||||
m.logger.Printf("[ERROR] [stacks] stdout: %s", stdoutStr)
|
||||
}
|
||||
if stderrStr := truncateStr(stderr.String(), 500); stderrStr != "" {
|
||||
m.logger.Printf("[ERROR] [stacks] stderr: %s", stderrStr)
|
||||
// R-864 (v0.294.0): the TAIL of stderr — compose prints its pull progress first and the reason last, so
|
||||
// the head (v0.293.0 and earlier) logged "Image … Pulling" and cut the error itself.
|
||||
if stderrStr := tailStr(stderr.String(), 500); stderrStr != "" {
|
||||
m.logger.Printf("[ERROR] [stacks] stderr (last part): %s", stderrStr)
|
||||
}
|
||||
return stdout.String(), fmt.Errorf("exit code %d\nstderr: %s", exitCode, truncateStr(stderr.String(), 500))
|
||||
return stdout.String(), fmt.Errorf("exit code %d\nstderr: %s", exitCode, tailStr(stderr.String(), 500))
|
||||
}
|
||||
|
||||
m.logger.Printf("[DEBUG] Command completed: %s %s (took %.1fs)", m.composeCmd, strings.Join(args, " "), time.Since(start).Seconds())
|
||||
@@ -1549,6 +1553,20 @@ func (m *Manager) isDebug() bool {
|
||||
}
|
||||
|
||||
// truncateStr truncates a string to maxLen characters, appending "..." if truncated.
|
||||
// tailStr keeps the LAST maxLen bytes of s (an error is printed last), marked with a leading "...". The cut
|
||||
// moves forward to a UTF-8 boundary so a Hungarian letter is never split. Pinned by TestR864_*.
|
||||
func tailStr(s string, maxLen int) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) <= maxLen {
|
||||
return s
|
||||
}
|
||||
i := len(s) - maxLen
|
||||
for i < len(s) && !utf8.RuneStart(s[i]) {
|
||||
i++
|
||||
}
|
||||
return "..." + s[i:]
|
||||
}
|
||||
|
||||
func truncateStr(s string, maxLen int) string {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) <= maxLen {
|
||||
|
||||
Reference in New Issue
Block a user