diff --git a/internal/ioutil/ioutil.go b/internal/ioutil/ioutil.go index 696a987..efc59b8 100644 --- a/internal/ioutil/ioutil.go +++ b/internal/ioutil/ioutil.go @@ -2,6 +2,7 @@ package ioutil import ( "bytes" + "fmt" "io" "sync" "sync/atomic" @@ -101,3 +102,25 @@ func (w *SizeTrackingWriter) Write(p []byte) (n int, err error) { func (w *SizeTrackingWriter) Size() uint64 { return w.size.Load() } + +type SizeLimitedWriter struct { + SizeTrackingWriter + Limit uint64 +} + +var _ io.Writer = &SizeLimitedWriter{} + +func (w *SizeLimitedWriter) Write(p []byte) (n int, err error) { + size := w.Size() + if size+uint64(len(p)) > w.Limit { + p = p[:w.Limit-size] + err = fmt.Errorf("size limit exceeded: %d bytes written, limit is %d bytes", size, w.Limit) + } + + var e error + n, e = w.Writer.Write(p) + if e != nil { + err = e + } + return +} diff --git a/internal/orchestrator/tasks/taskruncommand.go b/internal/orchestrator/tasks/taskruncommand.go index 3a5c066..b23ebcc 100644 --- a/internal/orchestrator/tasks/taskruncommand.go +++ b/internal/orchestrator/tasks/taskruncommand.go @@ -9,6 +9,8 @@ import ( "github.com/garethgeorge/backrest/internal/ioutil" ) +var DefaultCommandOutputSizeLimit uint64 = 2_000_000 // 2MB + func NewOneoffRunCommandTask(repo *v1.Repo, planID string, flowID int64, at time.Time, command string) Task { return &GenericOneoffTask{ OneoffTask: OneoffTask{ @@ -54,9 +56,13 @@ func runCommandHelper(ctx context.Context, st ScheduledTask, taskRunner TaskRunn return fmt.Errorf("get logref writer: %w", err) } defer writer.Close() - sizeWriter := &ioutil.SizeTrackingWriter{Writer: writer} + sizeWriter := &ioutil.SizeLimitedWriter{ + SizeTrackingWriter: ioutil.SizeTrackingWriter{Writer: writer}, + Limit: DefaultCommandOutputSizeLimit, // 2 MB max output size + } defer func() { - runCmdOp.OutputSizeBytes = int64(sizeWriter.Size()) + size := sizeWriter.Size() + runCmdOp.OutputSizeBytes = int64(size) }() runCmdOp.OutputLogref = id diff --git a/internal/resticinstaller/resticinstaller.go b/internal/resticinstaller/resticinstaller.go index 56607ae..36c253a 100644 --- a/internal/resticinstaller/resticinstaller.go +++ b/internal/resticinstaller/resticinstaller.go @@ -145,7 +145,7 @@ func removeOldVersions(installDir string) { func installResticHelper(resticInstallPath string) { if _, err := os.Stat(resticInstallPath); err == nil { - zap.S().Infof("replacing restic binary in data dir due to failed check: %w", err) + zap.S().Infof("replacing restic binary in data dir due to failed check: %v", err) if err := os.Remove(resticInstallPath); err != nil { zap.S().Errorf("failed to remove old restic binary %v: %v", resticInstallPath, err) } @@ -211,6 +211,7 @@ func tryFindOrInstall() (string, error) { // Check again after acquiring the lock. if err := assertResticVersion(resticInstallPath); err != nil { + zap.S().Errorf("could not verify version of binary %v: %v", resticInstallPath, err) installResticHelper(resticInstallPath) } }