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  }