/
context_manager.go
143 lines (119 loc) · 4.38 KB
/
context_manager.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package context_manager
import (
"archive/tar"
"context"
"crypto/sha256"
"fmt"
"io"
"os"
"path/filepath"
uuid "github.com/satori/go.uuid"
"github.com/werf/logboek"
"github.com/werf/werf/pkg/path_matcher"
"github.com/werf/werf/pkg/util"
"github.com/werf/werf/pkg/werf"
)
func GetTmpDir() string {
return filepath.Join(werf.GetServiceDir(), "tmp", "context")
}
func GetTmpArchivePath() string {
return filepath.Join(GetTmpDir(), uuid.NewV4().String())
}
func GetContextAddFilesPaths(projectDir string, contextDir string, contextAddFiles []string) ([]string, error) {
var addFilePaths []string
for _, addFile := range contextAddFiles {
addFilePath := filepath.Join(projectDir, contextDir, addFile)
addFileInfo, err := os.Lstat(addFilePath)
if err != nil {
return nil, fmt.Errorf("unable to get file info for contextAddFile %q: %s", addFilePath, err)
}
if addFileInfo.IsDir() {
if err := filepath.Walk(addFilePath, func(path string, fileInfo os.FileInfo, err error) error {
if err != nil {
return err
}
if fileInfo.IsDir() {
return nil
}
addFilePaths = append(addFilePaths, path)
return nil
}); err != nil {
return nil, fmt.Errorf("error occurred when recursively walking the contextAddFile dir %q: %s", addFilePath, err)
}
} else {
addFilePaths = append(addFilePaths, addFilePath)
}
}
return util.UniqStrings(addFilePaths), nil
}
func ContextAddFilesChecksum(ctx context.Context, projectDir string, contextDir string, contextAddFiles []string, matcher path_matcher.PathMatcher) (string, error) {
addFilePaths, err := GetContextAddFilesPaths(projectDir, contextDir, contextAddFiles)
if err != nil {
return "", err
}
var projectRelativeAddFilePaths []string
for _, addFilePath := range addFilePaths {
projectRelativeAddFilePath, err := filepath.Rel(projectDir, addFilePath)
if err != nil {
return "", fmt.Errorf("unable to get context relative path for %q: %s", addFilePath, err)
}
if !matcher.IsPathMatched(projectRelativeAddFilePath) {
continue
}
projectRelativeAddFilePaths = append(projectRelativeAddFilePaths, projectRelativeAddFilePath)
}
if len(projectRelativeAddFilePaths) == 0 {
return "", nil
}
h := sha256.New()
for _, projectRelativeAddFilePath := range projectRelativeAddFilePaths {
projectRelativeAddFilePath = filepath.ToSlash(projectRelativeAddFilePath)
h.Write([]byte(projectRelativeAddFilePath))
addFilePath := filepath.Join(projectDir, projectRelativeAddFilePath)
if exists, err := util.RegularFileExists(addFilePath); err != nil {
return "", fmt.Errorf("unable to check existence of file %q: %s", addFilePath, err)
} else if !exists {
continue
}
if err := func() error {
f, err := os.Open(addFilePath)
if err != nil {
return fmt.Errorf("unable to open %q: %s", addFilePath, err)
}
defer f.Close()
if _, err := io.Copy(h, f); err != nil {
return fmt.Errorf("unable to copy file %q: %s", addFilePath, err)
}
return nil
}(); err != nil {
return "", err
}
logboek.Context(ctx).Debug().LogF("File was added: %q\n", projectRelativeAddFilePath)
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
func AddContextAddFilesToContextArchive(ctx context.Context, originalArchivePath string, projectDir string, contextDir string, contextAddFiles []string) (string, error) {
destinationArchivePath := GetTmpArchivePath()
pathsToExcludeFromSourceArchive := contextAddFiles
if err := util.CreateArchiveBasedOnAnotherOne(ctx, originalArchivePath, destinationArchivePath, pathsToExcludeFromSourceArchive, func(tw *tar.Writer) error {
addFilePathsToCopy, err := GetContextAddFilesPaths(projectDir, contextDir, contextAddFiles)
if err != nil {
return err
}
for _, addFilePathToCopy := range addFilePathsToCopy {
tarEntryName, err := filepath.Rel(filepath.Join(projectDir, contextDir), addFilePathToCopy)
if err != nil {
return fmt.Errorf("unable to get context relative path for %q: %s", addFilePathToCopy, err)
}
tarEntryName = filepath.ToSlash(tarEntryName)
if err := util.CopyFileIntoTar(tw, tarEntryName, addFilePathToCopy); err != nil {
return fmt.Errorf("unable to add contextAddFile %q to archive %q: %s", addFilePathToCopy, destinationArchivePath, err)
}
logboek.Context(ctx).Debug().LogF("Extra file was added to the current context: %q\n", tarEntryName)
}
return nil
}); err != nil {
return "", err
}
return destinationArchivePath, nil
}