diff options
author | Jason Song <i@wolfogre.com> | 2023-06-29 01:07:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-28 19:07:29 +0200 |
commit | 6daf21c9b722e31ea5e3b1ec48caa69327580abd (patch) | |
tree | d689df26a38ed3a6124d475613c4f899127aa7bf /modules | |
parent | b6693a2c9a6010463950bbd89a2bfee88bde5e5f (diff) | |
download | gitea-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.go | 18 |
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) } |