github.com/cloudfoundry-incubator/stembuild@v0.0.0-20211223202937-5b61d62226c6/package_stemcell/packagers/packager_utility.go (about)

     1  package packagers
     2  
     3  import (
     4  	"archive/tar"
     5  	"compress/gzip"
     6  	"crypto/sha1"
     7  	"errors"
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  	"path/filepath"
    12  )
    13  
    14  func WriteManifest(manifestContents, manifestPath string) error {
    15  
    16  	manifestPath = filepath.Join(manifestPath, "stemcell.MF")
    17  
    18  	f, err := os.OpenFile(manifestPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644)
    19  	if err != nil {
    20  		return fmt.Errorf("creating stemcell.MF (%s): %s", manifestPath, err)
    21  	}
    22  	defer f.Close()
    23  
    24  	if _, err := fmt.Fprintf(f, manifestContents); err != nil {
    25  		os.Remove(manifestPath)
    26  		return fmt.Errorf("writing stemcell.MF (%s): %s", manifestPath, err)
    27  	}
    28  	return nil
    29  }
    30  
    31  func CreateManifest(osVersion, version, sha1sum string) string {
    32  	const format = `---
    33  name: bosh-vsphere-esxi-windows%[1]s-go_agent
    34  version: '%[2]s'
    35  api_version: 3
    36  sha1: %[3]s
    37  operating_system: windows%[1]s
    38  cloud_properties:
    39    infrastructure: vsphere
    40    hypervisor: esxi
    41  stemcell_formats:
    42  - vsphere-ovf
    43  - vsphere-ova
    44  `
    45  	return fmt.Sprintf(format, osVersion, version, sha1sum)
    46  
    47  }
    48  
    49  func TarGenerator(destinationfileName string, sourceDirName string) (string, error) {
    50  
    51  	sourcedir, err := os.Open(sourceDirName)
    52  	if err != nil {
    53  		return "", errors.New(fmt.Sprintf("unable to open %s", sourceDirName))
    54  	}
    55  	defer sourcedir.Close()
    56  
    57  	// get list of files
    58  	files, err := sourcedir.Readdir(0)
    59  	if err != nil {
    60  		return "", errors.New(fmt.Sprintf("unable to list files in %s", sourceDirName))
    61  	}
    62  
    63  	// create tar file
    64  	destinationFile, err := os.Create(destinationfileName)
    65  	if err != nil {
    66  		return "", errors.New(fmt.Sprintf("unable to create destination file with name %s", destinationfileName))
    67  	}
    68  	defer destinationFile.Close()
    69  
    70  	sha1Hash := sha1.New()
    71  	gzw := gzip.NewWriter(io.MultiWriter(destinationFile, sha1Hash))
    72  	tarfileWriter := tar.NewWriter(gzw)
    73  
    74  	for _, fileInfo := range files {
    75  
    76  		if fileInfo.IsDir() {
    77  			continue
    78  		}
    79  
    80  		file, err := os.Open(sourcedir.Name() + string(filepath.Separator) + fileInfo.Name())
    81  		if err != nil {
    82  			return "", errors.New(fmt.Sprintf("unable to open files in %s", sourceDirName))
    83  		}
    84  		defer file.Close()
    85  
    86  		// prepare the tar header
    87  		header := new(tar.Header)
    88  		header.Name = fileInfo.Name()
    89  		header.Size = fileInfo.Size()
    90  		header.Mode = int64(fileInfo.Mode())
    91  		header.ModTime = fileInfo.ModTime()
    92  
    93  		err = tarfileWriter.WriteHeader(header)
    94  		if err != nil {
    95  			return "", errors.New("unable to write to header of destination tar file")
    96  		}
    97  
    98  		_, err = io.Copy(tarfileWriter, file)
    99  		if err != nil {
   100  			return "", errors.New("unable to write contents to destination tar file")
   101  		}
   102  	}
   103  
   104  	//Shouldn't be a deferred call as closing the tar writer flushes padding and writes footer which impacts the sha1sum
   105  
   106  	err = tarfileWriter.Close()
   107  	if err != nil {
   108  		return "", errors.New("unable to close tar file")
   109  	}
   110  	err = gzw.Close()
   111  	if err != nil {
   112  		return "", errors.New("unable to close tar file (gzip)")
   113  	}
   114  
   115  	return fmt.Sprintf("%x", sha1Hash.Sum(nil)), nil
   116  }
   117  
   118  func StemcellFilename(version, os string) string {
   119  	return fmt.Sprintf("bosh-stemcell-%s-vsphere-esxi-windows%s-go_agent.tgz",
   120  		version, os)
   121  }