Update status check endpoint 
[multicloud/k8s.git] / src / k8splugin / internal / rb / archive.go
1 /*
2  * Copyright 2018 Intel Corporation, Inc
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package rb
18
19 import (
20         "archive/tar"
21         "compress/gzip"
22         "github.com/onap/multicloud-k8s/src/k8splugin/internal/utils"
23         pkgerrors "github.com/pkg/errors"
24         "io"
25         "io/ioutil"
26         "os"
27         "path/filepath"
28 )
29
30 func isTarGz(r io.Reader) error {
31         //Check if it is a valid gz
32         gzf, err := gzip.NewReader(r)
33         if err != nil {
34                 return pkgerrors.Wrap(err, "Invalid gzip format")
35         }
36
37         //Check if it is a valid tar file
38         //Unfortunately this can only be done by inspecting all the tar contents
39         tarR := tar.NewReader(gzf)
40         first := true
41
42         for true {
43                 header, err := tarR.Next()
44
45                 if err == io.EOF {
46                         //Check if we have just a gzip file without a tar archive inside
47                         if first {
48                                 return pkgerrors.New("Empty or non-existant Tar file found")
49                         }
50                         //End of archive
51                         break
52                 }
53
54                 if err != nil {
55                         return pkgerrors.Errorf("Error reading tar file %s", err.Error())
56                 }
57
58                 //Check if files are of type directory and regular file
59                 if header.Typeflag != tar.TypeDir &&
60                         header.Typeflag != tar.TypeReg {
61                         return pkgerrors.Errorf("Unknown header in tar %s, %s",
62                                 header.Name, string(header.Typeflag))
63                 }
64
65                 first = false
66         }
67
68         return nil
69 }
70
71 //ExtractTarBall provides functionality to extract a tar.gz file
72 //into a temporary location for later use.
73 //It returns the path to the new location
74 func ExtractTarBall(r io.Reader) (string, error) {
75         //Check if it is a valid gz
76         gzf, err := gzip.NewReader(r)
77         if err != nil {
78                 return "", pkgerrors.Wrap(err, "Invalid gzip format")
79         }
80
81         //Check if it is a valid tar file
82         //Unfortunately this can only be done by inspecting all the tar contents
83         tarR := tar.NewReader(gzf)
84         first := true
85
86         outDir, _ := ioutil.TempDir("", "k8s-ext-")
87
88         for true {
89                 header, err := tarR.Next()
90
91                 if err == io.EOF {
92                         //Check if we have just a gzip file without a tar archive inside
93                         if first {
94                                 return "", pkgerrors.New("Empty or non-existant Tar file found")
95                         }
96                         //End of archive
97                         break
98                 }
99
100                 if err != nil {
101                         return "", pkgerrors.Wrap(err, "Error reading tar file")
102                 }
103
104                 target := filepath.Join(outDir, header.Name)
105
106                 switch header.Typeflag {
107                 case tar.TypeDir:
108                         if _, err := os.Stat(target); err != nil {
109                                 // Using 755 read, write, execute for owner
110                                 // groups and others get read and execute permissions
111                                 // on the folder.
112                                 if err := os.MkdirAll(target, 0755); err != nil {
113                                         return "", pkgerrors.Wrap(err, "Creating directory")
114                                 }
115                         }
116                 case tar.TypeReg:
117                         if target == outDir { // Handle '.' substituted to '' entry
118                                 continue
119                         }
120
121                         err = utils.EnsureDirectory(target)
122                         if err != nil {
123                                 return "", pkgerrors.Wrap(err, "Creating Directory")
124                         }
125
126                         f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
127                         if err != nil {
128                                 return "", pkgerrors.Wrap(err, "Creating file")
129                         }
130
131                         // copy over contents
132                         if _, err := io.Copy(f, tarR); err != nil {
133                                 return "", pkgerrors.Wrap(err, "Copying file content")
134                         }
135
136                         // close for each file instead of a defer for all
137                         // at the end of the function
138                         f.Close()
139                 }
140
141                 first = false
142         }
143
144         return outDir, nil
145 }