nats dump keeps and says the snapshot's exit status; restic blots JSON credentials and cuts on a character
mesh/delivery merged: source.main moved to novox/mesh-catalog@7fe569ef4067
mesh/check being carried to 4aa77a4237dd on 7fe569ef4067 | from 7f626147be0c

Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
This commit is contained in:
2026-11-04 11:50:29 +01:00
parent 6a39f43404
commit 4aa77a4237
4 changed files with 82 additions and 3 deletions
+7 -2
View File
@@ -36,6 +36,7 @@ import (
"sync"
"syscall"
"time"
"unicode/utf8"
)
// Runner runs one command and answers what it printed, so the backups can be tested without restic
@@ -69,7 +70,7 @@ func execRunner(ctx context.Context, name string, args ...string) (string, error
// failureTail bounds what a failed command's output adds to the failure it reports: its last 2 KB.
const failureTail = 2048
var secretLooking = regexp.MustCompile(`(?i)((?:pass(?:word|wd)?|secret|token|api[_-]?key)\s*[=:]\s*)\S+`)
var secretLooking = regexp.MustCompile(`(?i)((?:pass(?:word|wd)?|secret|token|api[_-]?key)["']?\s*[=:]\s*)("[^"]*"|'[^']*'|\S+)`)
// failure is the error of a command that exited badly: its last lines of stderr (stdout when stderr is
// empty), bounded to failureTail bytes, with what looks like a secret blotted out, so the report of a
@@ -86,7 +87,11 @@ func failure(program, name string, err error, stdout, stderr string) error {
return fmt.Errorf("%s: %w (it printed nothing)", name, err)
}
if len(said) > failureTail {
said = "..." + said[len(said)-failureTail:]
cut := len(said) - failureTail
for cut < len(said) && !utf8.RuneStart(said[cut]) {
cut++
}
said = "..." + said[cut:]
}
said = secretLooking.ReplaceAllString(said, "${1}***")
return fmt.Errorf("%s: %v: %s", name, err, strings.Join(strings.Split(said, "\n"), " / "))
@@ -342,6 +342,8 @@ func TestAFailedCommandReportsTheTailOfWhatItPrintedWithSecretsBlotted(t *testin
{"stdout when stderr is empty", "sh", "dump failed\n", "", "sh: exit status 1: dump failed", ""},
{"nothing printed", "sh", "", "", "sh: exit status 1 (it printed nothing)", ""},
{"bounded and blotted", "sh", "", long, "password=*** refused", "hunter2"},
{"json credential", "sh", "", `{"password": "hunter2", "user": "a"}`, `"password": ***`, "hunter2"},
{"cut on a character", "sh", "", strings.Repeat("é", 1500), "...é", ""},
{"sudo prompt", "sudo", "", "sudo: a password is required", "needs root", ""},
} {
got := failure(c.program, "sh", exit, c.out, c.errOut).Error()