mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	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>
This commit is contained in:
		@@ -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)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user