aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorJason Song <i@wolfogre.com>2023-06-29 01:07:29 +0800
committerGitHub <noreply@github.com>2023-06-28 19:07:29 +0200
commit6daf21c9b722e31ea5e3b1ec48caa69327580abd (patch)
treed689df26a38ed3a6124d475613c4f899127aa7bf /modules
parentb6693a2c9a6010463950bbd89a2bfee88bde5e5f (diff)
downloadgitea-6daf21c9b722e31ea5e3b1ec48caa69327580abd.tar.gz
gitea-6daf21c9b722e31ea5e3b1ec48caa69327580abd.zip
Fix content holes in Actions task logs file (#25560)
Fix #25451. Bugfixes: - When stopping the zombie or endless tasks, set `LogInStorage` to true after transferring the file to storage. It was missing, it could write to a nonexistent file in DBFS because `LogInStorage` was false. - Always update `ActionTask.Updated` when there's a new state reported by the runner, even if there's no change. This is to avoid the task being judged as a zombie task. Enhancement: - Support `Stat()` for DBFS file. - `WriteLogs` refuses to write if it could result in content holes. --------- Co-authored-by: Giteabot <teabot@gitea.io>
Diffstat (limited to 'modules')
-rw-r--r--modules/actions/log.go18
1 files changed, 17 insertions, 1 deletions
diff --git a/modules/actions/log.go b/modules/actions/log.go
index 3868101992..36bed931fa 100644
--- a/modules/actions/log.go
+++ b/modules/actions/log.go
@@ -29,12 +29,28 @@ const (
)
func WriteLogs(ctx context.Context, filename string, offset int64, rows []*runnerv1.LogRow) ([]int, error) {
+ flag := os.O_WRONLY
+ if offset == 0 {
+ // Create file only if offset is 0, or it could result in content holes if the file doesn't exist.
+ flag |= os.O_CREATE
+ }
name := DBFSPrefix + filename
- f, err := dbfs.OpenFile(ctx, name, os.O_WRONLY|os.O_CREATE)
+ f, err := dbfs.OpenFile(ctx, name, flag)
if err != nil {
return nil, fmt.Errorf("dbfs OpenFile %q: %w", name, err)
}
defer f.Close()
+
+ stat, err := f.Stat()
+ if err != nil {
+ return nil, fmt.Errorf("dbfs Stat %q: %w", name, err)
+ }
+ if stat.Size() < offset {
+ // If the size is less than offset, refuse to write, or it could result in content holes.
+ // However, if the size is greater than offset, we can still write to overwrite the content.
+ return nil, fmt.Errorf("size of %q is less than offset", name)
+ }
+
if _, err := f.Seek(offset, io.SeekStart); err != nil {
return nil, fmt.Errorf("dbfs Seek %q: %w", name, err)
}