-
Notifications
You must be signed in to change notification settings - Fork 88
/
archives.go
129 lines (106 loc) · 2.6 KB
/
archives.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
package archives
import (
"archive/tar"
"bytes"
"compress/gzip"
"io"
"os"
"path/filepath"
"github.com/pkg/errors"
)
// todo, figure out why this doesn't use the mholt tgz archiver that we
// use elsewhere in kots
func ExtractTGZArchiveFromFile(tgzFile string, destDir string) error {
fileReader, err := os.Open(tgzFile)
if err != nil {
return errors.Wrap(err, "failed to open tgz file")
}
defer fileReader.Close()
err = ExtractTGZArchiveFromReader(fileReader, destDir)
if err != nil {
return errors.Wrap(err, "failed to extract archive")
}
return nil
}
func GetFileFromAirgap(fileToGet string, archive string) ([]byte, error) {
fileReader, err := os.Open(archive)
if err != nil {
return nil, errors.Wrap(err, "failed to open file")
}
defer fileReader.Close()
gzipReader, err := gzip.NewReader(fileReader)
if err != nil {
return nil, errors.Wrap(err, "failed to get new gzip reader")
}
defer gzipReader.Close()
tarReader := tar.NewReader(gzipReader)
var fileData []byte
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return nil, errors.Wrap(err, "failed to get read archive")
}
if header.Typeflag != tar.TypeReg {
continue
}
if header.Name != fileToGet {
continue
}
buf := new(bytes.Buffer)
_, err = buf.ReadFrom(tarReader)
if err != nil {
return nil, errors.Wrap(err, "failed to read file from tar archive")
}
fileData = buf.Bytes()
break
}
if fileData == nil {
return nil, errors.New("file not found in archive")
}
return fileData, nil
}
func ExtractTGZArchiveFromReader(tgzReader io.Reader, destDir string) error {
gzReader, err := gzip.NewReader(tgzReader)
if err != nil {
return errors.Wrap(err, "failed to get new gzip reader")
}
defer gzReader.Close()
tarReader := tar.NewReader(gzReader)
for {
hdr, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
return errors.Wrap(err, "failed to read tar data")
}
if hdr.Typeflag != tar.TypeReg {
continue
}
err = func() error {
fileName := filepath.Join(destDir, hdr.Name)
filePath, _ := filepath.Split(fileName)
err := os.MkdirAll(filePath, 0755)
if err != nil {
return errors.Wrapf(err, "failed to create directory %q", filePath)
}
fileWriter, err := os.Create(fileName)
if err != nil {
return errors.Wrapf(err, "failed to create file %q", hdr.Name)
}
defer fileWriter.Close()
_, err = io.Copy(fileWriter, tarReader)
if err != nil {
return errors.Wrapf(err, "failed to write file %q", hdr.Name)
}
return nil
}()
if err != nil {
return err
}
}
return nil
}