github.com/marksheahan/packer@v0.10.2-0.20160613200515-1acb2d6645a0/post-processor/checksum/post-processor.go (about) 1 package checksum 2 3 import ( 4 "crypto/md5" 5 "crypto/sha1" 6 "crypto/sha256" 7 "crypto/sha512" 8 "fmt" 9 "hash" 10 "io" 11 "os" 12 "path/filepath" 13 14 "github.com/mitchellh/packer/common" 15 "github.com/mitchellh/packer/helper/config" 16 "github.com/mitchellh/packer/packer" 17 "github.com/mitchellh/packer/template/interpolate" 18 ) 19 20 type Config struct { 21 common.PackerConfig `mapstructure:",squash"` 22 23 Keep bool `mapstructure:"keep_input_artifact"` 24 ChecksumTypes []string `mapstructure:"checksum_types"` 25 OutputPath string `mapstructure:"output"` 26 ctx interpolate.Context 27 } 28 29 type PostProcessor struct { 30 config Config 31 } 32 33 func (p *PostProcessor) Configure(raws ...interface{}) error { 34 err := config.Decode(&p.config, &config.DecodeOpts{ 35 Interpolate: true, 36 InterpolateFilter: &interpolate.RenderFilter{ 37 Exclude: []string{}, 38 }, 39 }, raws...) 40 if err != nil { 41 return err 42 } 43 44 if p.config.ChecksumTypes == nil { 45 p.config.ChecksumTypes = []string{"md5"} 46 } 47 48 if p.config.OutputPath == "" { 49 p.config.OutputPath = "packer_{{.BuildName}}_{{.BuilderType}}" + ".checksum" 50 } 51 52 errs := new(packer.MultiError) 53 54 if err = interpolate.Validate(p.config.OutputPath, &p.config.ctx); err != nil { 55 errs = packer.MultiErrorAppend( 56 errs, fmt.Errorf("Error parsing target template: %s", err)) 57 } 58 59 if len(errs.Errors) > 0 { 60 return errs 61 } 62 63 return nil 64 } 65 66 func getHash(t string) hash.Hash { 67 var h hash.Hash 68 switch t { 69 case "md5": 70 h = md5.New() 71 case "sha1": 72 h = sha1.New() 73 case "sha224": 74 h = sha256.New224() 75 case "sha256": 76 h = sha256.New() 77 case "sha384": 78 h = sha512.New384() 79 case "sha512": 80 h = sha512.New() 81 } 82 return h 83 } 84 85 func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { 86 files := artifact.Files() 87 var h hash.Hash 88 var checksumFile string 89 90 newartifact := NewArtifact(artifact.Files()) 91 92 for _, ct := range p.config.ChecksumTypes { 93 h = getHash(ct) 94 95 for _, art := range files { 96 if len(artifact.Files()) > 1 { 97 checksumFile = filepath.Join(filepath.Dir(art), ct+"sums") 98 } else if p.config.OutputPath != "" { 99 checksumFile = p.config.OutputPath 100 } else { 101 checksumFile = fmt.Sprintf("%s.%s", art, ct+"sum") 102 } 103 if _, err := os.Stat(checksumFile); err != nil { 104 newartifact.files = append(newartifact.files, checksumFile) 105 } 106 107 fw, err := os.OpenFile(checksumFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0644)) 108 if err != nil { 109 return nil, false, fmt.Errorf("unable to create file %s: %s", checksumFile, err.Error()) 110 } 111 fr, err := os.Open(art) 112 if err != nil { 113 fw.Close() 114 return nil, false, fmt.Errorf("unable to open file %s: %s", art, err.Error()) 115 } 116 117 if _, err = io.Copy(h, fr); err != nil { 118 fr.Close() 119 fw.Close() 120 return nil, false, fmt.Errorf("unable to compute %s hash for %s", ct, art) 121 } 122 fr.Close() 123 fw.WriteString(fmt.Sprintf("%x\t%s\n", h.Sum(nil), filepath.Base(art))) 124 fw.Close() 125 } 126 } 127 128 return newartifact, true, nil 129 }