2014-04-26 12:22:10 -04:00
|
|
|
package compress
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/tar"
|
|
|
|
"compress/gzip"
|
|
|
|
"fmt"
|
2014-06-12 16:45:37 -04:00
|
|
|
"io"
|
|
|
|
"os"
|
2014-09-08 13:28:16 -04:00
|
|
|
|
|
|
|
"github.com/mitchellh/packer/common"
|
2015-05-27 17:56:22 -04:00
|
|
|
"github.com/mitchellh/packer/helper/config"
|
2014-09-08 13:28:16 -04:00
|
|
|
"github.com/mitchellh/packer/packer"
|
2015-05-27 17:56:22 -04:00
|
|
|
"github.com/mitchellh/packer/template/interpolate"
|
2014-04-26 12:22:10 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
type Config struct {
|
|
|
|
common.PackerConfig `mapstructure:",squash"`
|
|
|
|
|
2014-04-28 20:30:36 -04:00
|
|
|
OutputPath string `mapstructure:"output"`
|
2014-04-26 12:22:10 -04:00
|
|
|
|
2015-05-27 17:56:22 -04:00
|
|
|
ctx interpolate.Context
|
2014-04-26 12:22:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
type PostProcessor struct {
|
|
|
|
config Config
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *PostProcessor) Configure(raws ...interface{}) error {
|
2015-05-27 17:56:22 -04:00
|
|
|
err := config.Decode(&self.config, &config.DecodeOpts{
|
|
|
|
Interpolate: true,
|
|
|
|
InterpolateFilter: &interpolate.RenderFilter{
|
|
|
|
Exclude: []string{},
|
|
|
|
},
|
|
|
|
}, raws...)
|
2014-04-26 12:22:10 -04:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (self *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
|
|
|
|
ui.Say(fmt.Sprintf("Creating archive for '%s'", artifact.BuilderId()))
|
|
|
|
|
|
|
|
// Create the compressed archive file at the appropriate OutputPath.
|
|
|
|
fw, err := os.Create(self.config.OutputPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, fmt.Errorf(
|
|
|
|
"Failed creating file for compressed archive: %s", self.config.OutputPath)
|
|
|
|
}
|
|
|
|
defer fw.Close()
|
|
|
|
|
|
|
|
gw := gzip.NewWriter(fw)
|
|
|
|
defer gw.Close()
|
|
|
|
|
|
|
|
// Iterate through all of the artifact's files and put them into the
|
|
|
|
// compressed archive using the tar/gzip writers.
|
|
|
|
for _, path := range artifact.Files() {
|
|
|
|
fi, err := os.Stat(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, fmt.Errorf(
|
|
|
|
"Failed stating file: %s", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
target, _ := os.Readlink(path)
|
|
|
|
header, err := tar.FileInfoHeader(fi, target)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, fmt.Errorf(
|
|
|
|
"Failed creating archive header: %s", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
tw := tar.NewWriter(gw)
|
|
|
|
defer tw.Close()
|
|
|
|
|
|
|
|
// Write the header first to the archive. This takes partial data
|
|
|
|
// from the FileInfo that is grabbed by running the stat command.
|
|
|
|
if err := tw.WriteHeader(header); err != nil {
|
|
|
|
return nil, false, fmt.Errorf(
|
|
|
|
"Failed writing archive header: %s", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open the target file for archiving and compressing.
|
|
|
|
fr, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, fmt.Errorf(
|
|
|
|
"Failed opening file '%s' to write compressed archive.", path)
|
|
|
|
}
|
|
|
|
defer fr.Close()
|
|
|
|
|
|
|
|
if _, err = io.Copy(tw, fr); err != nil {
|
|
|
|
return nil, false, fmt.Errorf(
|
|
|
|
"Failed copying file to archive: %s", path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NewArtifact(artifact.BuilderId(), self.config.OutputPath), false, nil
|
|
|
|
}
|