github.com/openshift/installer@v1.4.17/pkg/gather/gather.go (about) 1 package gather 2 3 import ( 4 "archive/tar" 5 "compress/gzip" 6 "io" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/pkg/errors" 12 "github.com/sirupsen/logrus" 13 14 "github.com/openshift/installer/pkg/asset/cluster/metadata" 15 "github.com/openshift/installer/pkg/gather/providers" 16 ) 17 18 // New returns a Gather based on `metadata.json` in `rootDir`. 19 func New(logger logrus.FieldLogger, serialLogBundle string, bootstrap string, masters []string, rootDir string) (providers.Gather, error) { 20 metadata, err := metadata.Load(rootDir) 21 if err != nil { 22 return nil, err 23 } 24 25 platform := metadata.Platform() 26 if platform == "" { 27 return nil, errors.New("no platform configured in metadata") 28 } 29 30 creator, ok := providers.Registry[platform] 31 if !ok { 32 return nil, errors.Errorf("no gather methods registered for %q", platform) 33 } 34 return creator(logger, serialLogBundle, bootstrap, masters, metadata) 35 } 36 37 // CreateArchive creates a gzipped tar file. 38 func CreateArchive(files []string, archiveName string) error { 39 file, err := os.Create(archiveName) 40 if err != nil { 41 return err 42 } 43 defer file.Close() 44 45 gzipWriter := gzip.NewWriter(file) 46 defer gzipWriter.Close() 47 48 tarWriter := tar.NewWriter(gzipWriter) 49 defer tarWriter.Close() 50 51 for _, filename := range files { 52 err := addToArchive(tarWriter, filename) 53 if err != nil { 54 return err 55 } 56 } 57 58 return nil 59 } 60 61 func addToArchive(tarWriter *tar.Writer, filename string) error { 62 file, err := os.Open(filename) 63 if err != nil { 64 return err 65 } 66 defer file.Close() 67 68 st, err := file.Stat() 69 if err != nil { 70 return err 71 } 72 73 header, err := tar.FileInfoHeader(st, st.Name()) 74 if err != nil { 75 return err 76 } 77 78 header.Name = filename 79 err = tarWriter.WriteHeader(header) 80 if err != nil { 81 return err 82 } 83 84 _, err = io.Copy(tarWriter, file) 85 if err != nil { 86 return err 87 } 88 89 return nil 90 } 91 92 // CombineArchives creates a single gzipped tar file from multiple archives. 93 // archiveName is the target gzipped tar file. archives maps the existing 94 // gzipped tar files to a subdirectory in the new gzipped tar file. 95 func CombineArchives(archiveName string, archives map[string]string) error { 96 suffix := ".tar.gz" 97 98 combinedArchive, err := os.Create(archiveName) 99 if err != nil { 100 return err 101 } 102 defer combinedArchive.Close() 103 104 combinedGzipWriter := gzip.NewWriter(combinedArchive) 105 defer combinedGzipWriter.Close() 106 107 combinedTarWriter := tar.NewWriter(combinedGzipWriter) 108 defer combinedTarWriter.Close() 109 110 combinedDirectory := strings.TrimSuffix(archiveName, suffix) 111 if archiveName[0] == '.' || archiveName[0] == '/' { 112 combinedDirectory = strings.TrimSuffix(filepath.Base(archiveName), suffix) 113 } 114 115 for archive, subDirectory := range archives { 116 _, err := os.Stat(archive) 117 if err != nil { 118 logrus.Warnf("Unable to stat %s, skipping", archive) 119 continue 120 } 121 122 file, err := os.Open(archive) 123 if err != nil { 124 return err 125 } 126 defer file.Close() 127 128 directory := strings.TrimSuffix(archive, suffix) + "/" 129 if subDirectory != "" && !strings.HasSuffix(subDirectory, "/") { 130 subDirectory += "/" 131 } 132 133 gzipReader, err := gzip.NewReader(file) 134 if err != nil { 135 return err 136 } 137 defer gzipReader.Close() 138 tarReader := tar.NewReader(gzipReader) 139 140 for { 141 header, err := tarReader.Next() 142 if err == io.EOF { 143 break 144 } 145 if err != nil { 146 return err 147 } 148 149 newHeaderName := strings.Replace(header.Name, directory, subDirectory, 1) 150 // Do not nest `log-bundle-XXXX` directories 151 if !strings.HasPrefix(newHeaderName, combinedDirectory) { 152 newHeaderName = filepath.Join(combinedDirectory, newHeaderName) 153 } 154 header.Name = newHeaderName 155 156 err = combinedTarWriter.WriteHeader(header) 157 if err != nil { 158 return err 159 } 160 161 _, err = io.Copy(combinedTarWriter, tarReader) 162 if err != nil { 163 return err 164 } 165 } 166 167 // The files are now part of the combined archive, so clean it up 168 if err := os.Remove(archive); err != nil { 169 logrus.Warnf("Could not remove %s: %v\n", archive, err) 170 } 171 } 172 173 return nil 174 } 175 176 // DeleteArchiveDirectory deletes an archive directory 177 func DeleteArchiveDirectory(archiveDirectory string) error { 178 if archiveDirectory == "" { 179 return nil 180 } 181 182 _, err := os.Stat(archiveDirectory) 183 if err == nil && !strings.HasPrefix(archiveDirectory, ".") && archiveDirectory != "/" { 184 err := os.RemoveAll(archiveDirectory) 185 if err != nil { 186 return err 187 } 188 } 189 190 return nil 191 }