mirror of
https://github.com/garethgeorge/backrest.git
synced 2025-12-11 16:25:39 +00:00
fix: limit run command output to 2MB
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user