/
build_context_archive.go
118 lines (96 loc) · 3.71 KB
/
build_context_archive.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package image
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/werf/logboek"
"github.com/werf/werf/pkg/container_backend"
"github.com/werf/werf/pkg/context_manager"
"github.com/werf/werf/pkg/git_repo"
"github.com/werf/werf/pkg/giterminism_manager"
"github.com/werf/werf/pkg/path_matcher"
"github.com/werf/werf/pkg/util"
)
func NewBuildContextArchive(giterminismMgr giterminism_manager.Interface, extractionRootTmpDir string) *BuildContextArchive {
return &BuildContextArchive{
giterminismMgr: giterminismMgr,
extractionRootTmpDir: extractionRootTmpDir,
}
}
type BuildContextArchive struct {
giterminismMgr giterminism_manager.Interface
path string
extractionRootTmpDir string
extractionDir string
}
func (a *BuildContextArchive) Create(ctx context.Context, opts container_backend.BuildContextArchiveCreateOptions) error {
contextPathRelativeToGitWorkTree := filepath.Join(a.giterminismMgr.RelativeToGitProjectDir(), opts.ContextGitSubDir)
dockerIgnorePathMatcher, err := createDockerIgnorePathMatcher(ctx, a.giterminismMgr, opts.ContextGitSubDir, opts.DockerfileRelToContextPath)
if err != nil {
return fmt.Errorf("unable to create dockerignore path matcher: %w", err)
}
archive, err := a.giterminismMgr.LocalGitRepo().GetOrCreateArchive(ctx, git_repo.ArchiveOptions{
PathScope: contextPathRelativeToGitWorkTree,
PathMatcher: path_matcher.NewMultiPathMatcher(path_matcher.NewPathMatcher(
path_matcher.PathMatcherOptions{BasePath: contextPathRelativeToGitWorkTree}),
dockerIgnorePathMatcher,
),
Commit: a.giterminismMgr.HeadCommit(),
})
if err != nil {
return fmt.Errorf("unable to get or create archive: %w", err)
}
a.path = archive.GetFilePath()
if len(opts.ContextAddFiles) > 0 {
if err := logboek.Context(ctx).Debug().LogProcess("Add contextAddFiles to build context archive %s", a.path).DoError(func() error {
a.path, err = context_manager.AddContextAddFilesToContextArchive(ctx, a.path, a.giterminismMgr.ProjectDir(), opts.ContextGitSubDir, opts.ContextAddFiles)
return err
}); err != nil {
return fmt.Errorf("unable to add contextAddFiles to build context archive %s: %w", a.path, err)
}
}
return nil
}
func (a *BuildContextArchive) Path() string {
return a.path
}
func (a *BuildContextArchive) ExtractOrGetExtractedDir(ctx context.Context) (string, error) {
if a.extractionDir != "" {
return a.extractionDir, nil
}
if err := os.MkdirAll(a.extractionRootTmpDir, os.ModePerm); err != nil {
return "", fmt.Errorf("unable to create extraction root tmp dir %q: %w", a.extractionRootTmpDir, err)
}
var err error
a.extractionDir, err = ioutil.TempDir(a.extractionRootTmpDir, "context")
if err != nil {
return "", fmt.Errorf("unable to create context tmp dir: %w", err)
}
archiveReader, err := os.Open(a.path)
if err != nil {
return "", fmt.Errorf("unable to open context archive %q: %w", a.path, err)
}
defer archiveReader.Close()
if err := util.ExtractTar(archiveReader, a.extractionDir, util.ExtractTarOptions{}); err != nil {
return "", fmt.Errorf("unable to extract context tar to tmp context dir %q: %w", a.extractionDir, err)
}
return a.extractionDir, nil
}
func (a *BuildContextArchive) CleanupExtractedDir(ctx context.Context) {
if a.extractionDir == "" {
return
}
if err := os.RemoveAll(a.extractionDir); err != nil {
logboek.Context(ctx).Warn().LogF("WARNING: unable to remove extracted context dir %q: %s", a.extractionDir, err)
}
}
func (a *BuildContextArchive) CalculatePathsChecksum(ctx context.Context, paths []string) (string, error) {
dir, err := a.ExtractOrGetExtractedDir(ctx)
if err != nil {
return "", fmt.Errorf("unable to access context directory: %w", err)
}
_ = dir
return "", nil
}