mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-12 10:54:09 +00:00
refactor(container): stream copies into the job and archives out of the host (#1340)
Adds `CopyTarStream` to the job environments. It extracts directories and files into the job as they are written, kept below the destination and owned by the job user along with any directories it creates, so built-in actions can put large content in place without buffering it. The host's `GetContainerArchive` now streams instead of building the archive in memory. --------- Co-authored-by: silverwind <[email protected]> Co-authored-by: silverwind <[email protected]> Co-authored-by: Lunny Xiao <[email protected]> Reviewed-on: https://gitea.com/gitea/runner/pulls/1340 Reviewed-by: Lunny Xiao <[email protected]> Reviewed-by: silverwind <[email protected]> Co-authored-by: bircni <[email protected]>
This commit is contained in:
1 parent
b88d111cc5
commit
8c8950d9ef
9 files changed
+313
-40
No files matched your search
@@ -938,10 +938,7 @@ func (cr *containerReference) copyDir(dstPath, srcPath string, useGitIgnore, ski
|
||||
logger.Error(err)
|
||||
}
|
||||
}()
|
||||
extractionRoot := "/"
|
||||
if actPath := cr.GetActPath(); strings.HasPrefix(dstPath+"/", actPath+"/") {
|
||||
extractionRoot = actPath // keeps tar entries from crossing the image's /var/run symlink
|
||||
}
|
||||
extractionRoot := cr.extractionRoot(dstPath)
|
||||
if err := writeDirTar(ctx, tarFile, path.Join("/", strings.TrimPrefix(dstPath, extractionRoot)), srcPath, useGitIgnore, skipGitDir, cr.UID, cr.GID, cr.markExecutable(ctx)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -954,6 +951,44 @@ func (cr *containerReference) copyDir(dstPath, srcPath string, useGitIgnore, ski
|
||||
}
|
||||
}
|
||||
|
||||
func (cr *containerReference) extractionRoot(dstPath string) string {
|
||||
if actPath := cr.GetActPath(); strings.HasPrefix(dstPath+"/", actPath+"/") {
|
||||
return actPath // keeps tar entries from crossing the image's /var/run symlink
|
||||
}
|
||||
return "/"
|
||||
}
|
||||
|
||||
func (cr *containerReference) CopyTarStream(ctx context.Context, destPath string, write func(*TarWriter) error) error {
|
||||
if common.Dryrun(ctx) {
|
||||
return nil
|
||||
}
|
||||
if err := cr.connect()(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := cr.find()(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if cr.id == "" {
|
||||
return cr.missingContainerError("copy to %s", destPath)
|
||||
}
|
||||
destPath = path.Clean(destPath)
|
||||
root := cr.extractionRoot(destPath)
|
||||
rel := func(fullPath string) string { return strings.TrimPrefix(strings.TrimPrefix(fullPath, root), "/") }
|
||||
var parents []string // sent as entries so they belong to the job user, the daemon creates missing ones as root
|
||||
for dir := destPath; dir != root && dir != "/" && dir != "."; dir = path.Dir(dir) {
|
||||
if _, err := cr.cli.ContainerStatPath(ctx, cr.id, client.ContainerStatPathOptions{Path: dir}); err == nil {
|
||||
break
|
||||
} else if !cerrdefs.IsNotFound(err) {
|
||||
return fmt.Errorf("stat %s: %w", dir, err)
|
||||
}
|
||||
parents = append(parents, rel(dir))
|
||||
}
|
||||
slices.Reverse(parents)
|
||||
content := pipeTar(cr.UID, cr.GID, rel(destPath), parents, write)
|
||||
defer content.Close()
|
||||
return cr.upload(ctx, root, content)
|
||||
}
|
||||
|
||||
func (cr *containerReference) copyContent(dstPath string, files ...*FileEntry) common.Executor {
|
||||
return func(ctx context.Context) error {
|
||||
if cr.id == "" {
|
||||
|
||||
Reference in new issue
Block a user