github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/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 checksumFile = p.config.OutputPath 97 98 if _, err := os.Stat(checksumFile); err != nil { 99 newartifact.files = append(newartifact.files, checksumFile) 100 } 101 if err := os.MkdirAll(filepath.Dir(checksumFile), os.FileMode(0755)); err != nil { 102 return nil, false, fmt.Errorf("unable to create dir: %s", err.Error()) 103 } 104 fw, err := os.OpenFile(checksumFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0644)) 105 if err != nil { 106 return nil, false, fmt.Errorf("unable to create file %s: %s", checksumFile, err.Error()) 107 } 108 fr, err := os.Open(art) 109 if err != nil { 110 fw.Close() 111 return nil, false, fmt.Errorf("unable to open file %s: %s", art, err.Error()) 112 } 113 114 if _, err = io.Copy(h, fr); err != nil { 115 fr.Close() 116 fw.Close() 117 return nil, false, fmt.Errorf("unable to compute %s hash for %s", ct, art) 118 } 119 fr.Close() 120 fw.WriteString(fmt.Sprintf("%x\t%s\n", h.Sum(nil), filepath.Base(art))) 121 fw.Close() 122 h.Reset() 123 } 124 } 125 126 return newartifact, true, nil 127 }