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 }