-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathtar_util.go
166 lines (134 loc) · 3.22 KB
/
tar_util.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package elasticthought
import (
"archive/tar"
"bufio"
"bytes"
"compress/gzip"
"fmt"
"io"
"log"
"net/http"
"os"
"path"
"path/filepath"
"strings"
"github.com/couchbaselabs/logg"
)
type tarFile struct {
Name string
Body string
}
// Opens tar.gz stream
func openTarGzStream(url string) (*tar.Reader, error) {
resp, err := http.Get(url)
if err != nil {
return nil, err
}
gzipReader, err := gzip.NewReader(resp.Body)
if err != nil {
return nil, err
}
tarReader := tar.NewReader(gzipReader)
return tarReader, nil
}
func untarWithToc(reader io.Reader, destDirectory string) ([]string, error) {
toc := []string{}
tr := tar.NewReader(reader)
// Iterate through the files in the archive.
for {
hdr, err := tr.Next()
if err == io.EOF {
// end of tar archive
break
}
if err != nil {
return nil, err
}
if err := writeToDest(hdr, tr, destDirectory); err != nil {
return nil, err
}
// add to toc
if hdr.Typeflag != tar.TypeDir {
toc = append(toc, hdr.Name)
}
}
return toc, nil
}
// Given a reader, wrap in a tar.gz reader and write all entries
// to destDirectory. Also return a table of contents.
func untarGzWithToc(reader io.Reader, destDirectory string) ([]string, error) {
gzipReader, err := gzip.NewReader(reader)
if err != nil {
return nil, err
}
return untarWithToc(gzipReader, destDirectory)
}
func writeToDest(hdr *tar.Header, tr *tar.Reader, destDirectory string) error {
destPath := filepath.Join(destDirectory, hdr.Name)
if strings.HasPrefix(hdr.Name, ".") {
msg := "Cannot process tar since it has hidden files/directories " +
"which may cause issues. If on OSX, set COPYFILE_DISABLE=1 and " +
"rebuild .tar.gz file"
return fmt.Errorf(msg)
}
switch hdr.Typeflag {
case tar.TypeDir:
// does dir exist? if not, make it
if err := Mkdir(destPath); err != nil {
logg.LogTo("TRAINING_JOB", "mkdir failed on %v", destPath)
return err
}
default:
// make the directory in case it doesn't already exist.
// this is a workaround for the fact that we don't have directory
// entries on both of our split tars.
destPathDir := path.Dir(destPath)
if err := Mkdir(destPathDir); err != nil {
logg.LogTo("TRAINING_JOB", "mkdir failed on %v", destPath)
return err
}
f, err := os.Create(destPath)
if err != nil {
logg.LogTo("TRAINING_JOB", "calling os.Create failed on %v", destPath)
return err
}
w := bufio.NewWriter(f)
defer w.Flush()
_, err = io.Copy(w, tr)
if err != nil {
logg.LogTo("TRAINING_JOB", "io.Copy failed: %v", err)
return err
}
}
return nil
}
func createArchive(buf *bytes.Buffer, tarFiles []tarFile) {
// Create a new tar archive.
tw := tar.NewWriter(buf)
for _, file := range tarFiles {
hdr := &tar.Header{
Name: file.Name,
Size: int64(len(file.Body)),
Uid: 100,
Gid: 101,
}
if err := tw.WriteHeader(hdr); err != nil {
log.Fatalln(err)
}
if _, err := tw.Write([]byte(file.Body)); err != nil {
log.Fatalln(err)
}
}
// Make sure to check the error on Close.
if err := tw.Close(); err != nil {
log.Fatalln(err)
}
}
// TempDir returns the default directory to use for temporary files.
func TempDir() string {
dir := os.Getenv("TMPDIR")
if dir == "" {
dir = "/tmp"
}
return dir
}