aboutsummaryrefslogtreecommitdiffstats
path: root/src/k8splugin/internal/rb/archive.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/k8splugin/internal/rb/archive.go')
-rw-r--r--src/k8splugin/internal/rb/archive.go72
1 files changed, 71 insertions, 1 deletions
diff --git a/src/k8splugin/internal/rb/archive.go b/src/k8splugin/internal/rb/archive.go
index 8eb0fbed..624adfba 100644
--- a/src/k8splugin/internal/rb/archive.go
+++ b/src/k8splugin/internal/rb/archive.go
@@ -21,13 +21,16 @@ import (
"compress/gzip"
pkgerrors "github.com/pkg/errors"
"io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
)
func isTarGz(r io.Reader) error {
//Check if it is a valid gz
gzf, err := gzip.NewReader(r)
if err != nil {
- return pkgerrors.Errorf("Invalid gz format %s", err.Error())
+ return pkgerrors.Wrap(err, "Invalid gzip format")
}
//Check if it is a valid tar file
@@ -63,3 +66,70 @@ func isTarGz(r io.Reader) error {
return nil
}
+
+//ExtractTarBall provides functionality to extract a tar.gz file
+//into a temporary location for later use.
+//It returns the path to the new location
+func ExtractTarBall(r io.Reader) (string, error) {
+ //Check if it is a valid gz
+ gzf, err := gzip.NewReader(r)
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Invalid gzip format")
+ }
+
+ //Check if it is a valid tar file
+ //Unfortunately this can only be done by inspecting all the tar contents
+ tarR := tar.NewReader(gzf)
+ first := true
+
+ outDir, _ := ioutil.TempDir("", "k8s-ext-")
+
+ for true {
+ header, err := tarR.Next()
+
+ if err == io.EOF {
+ //Check if we have just a gzip file without a tar archive inside
+ if first {
+ return "", pkgerrors.New("Empty or non-existant Tar file found")
+ }
+ //End of archive
+ break
+ }
+
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Error reading tar file")
+ }
+
+ target := filepath.Join(outDir, header.Name)
+
+ switch header.Typeflag {
+ case tar.TypeDir:
+ if _, err := os.Stat(target); err != nil {
+ // Using 755 read, write, execute for owner
+ // groups and others get read and execute permissions
+ // on the folder.
+ if err := os.MkdirAll(target, 0755); err != nil {
+ return "", pkgerrors.Wrap(err, "Creating directory")
+ }
+ }
+ case tar.TypeReg:
+ f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
+ if err != nil {
+ return "", pkgerrors.Wrap(err, "Creating file")
+ }
+
+ // copy over contents
+ if _, err := io.Copy(f, tarR); err != nil {
+ return "", pkgerrors.Wrap(err, "Copying file content")
+ }
+
+ // close for each file instead of a defer for all
+ // at the end of the function
+ f.Close()
+ }
+
+ first = false
+ }
+
+ return outDir, nil
+}