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  }