From e5c5f685b966fc4d8ae756e953228d5db7646a43 Mon Sep 17 00:00:00 2001 From: Mark Aaron Shirley Date: Mon, 7 Oct 2013 21:59:26 -0700 Subject: [PATCH] Add compression_level option to vagrant post-processors --- post-processor/vagrant/aws.go | 14 +++++++++++++- post-processor/vagrant/util.go | 7 +++++-- post-processor/vagrant/virtualbox.go | 14 +++++++++++++- post-processor/vagrant/vmware.go | 14 +++++++++++++- .../docs/post-processors/vagrant.html.markdown | 5 +++++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/post-processor/vagrant/aws.go b/post-processor/vagrant/aws.go index 6915fa5fe..04ef43ec0 100644 --- a/post-processor/vagrant/aws.go +++ b/post-processor/vagrant/aws.go @@ -1,6 +1,7 @@ package vagrant import ( + "compress/flate" "fmt" "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/packer" @@ -8,6 +9,7 @@ import ( "log" "os" "path/filepath" + "strconv" "strings" ) @@ -16,6 +18,7 @@ type AWSBoxConfig struct { OutputPath string `mapstructure:"output"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"` + CompressionLevel string `mapstructure:"compression_level"` tpl *packer.ConfigTemplate } @@ -46,6 +49,7 @@ func (p *AWSBoxPostProcessor) Configure(raws ...interface{}) error { validates := map[string]*string{ "output": &p.config.OutputPath, "vagrantfile_template": &p.config.VagrantfileTemplate, + "compression_level": &p.config.CompressionLevel, } for n, ptr := range validates { @@ -127,6 +131,14 @@ func (p *AWSBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact vf.Write([]byte(vagrantfileContents)) vf.Close() + var level int = flate.DefaultCompression + if p.config.CompressionLevel != "" { + level, err = strconv.Atoi(p.config.CompressionLevel) + if err != nil { + return nil, false, err + } + } + // Create the metadata metadata := map[string]string{"provider": "aws"} if err := WriteMetadata(dir, metadata); err != nil { @@ -134,7 +146,7 @@ func (p *AWSBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact } // Compress the directory to the given output path - if err := DirToBox(outputPath, dir, ui); err != nil { + if err := DirToBox(outputPath, dir, ui, level); err != nil { err = fmt.Errorf("error creating box: %s", err) return nil, false, err } diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index 86742abe5..6b9b53fe1 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -44,7 +44,7 @@ func CopyContents(dst, src string) error { // DirToBox takes the directory and compresses it into a Vagrant-compatible // box. This function does not perform checks to verify that dir is // actually a proper box. This is an expected precondition. -func DirToBox(dst, dir string, ui packer.Ui) error { +func DirToBox(dst, dir string, ui packer.Ui, level int) error { log.Printf("Turning dir into box: %s => %s", dir, dst) dstF, err := os.Create(dst) if err != nil { @@ -52,7 +52,10 @@ func DirToBox(dst, dir string, ui packer.Ui) error { } defer dstF.Close() - gzipWriter := gzip.NewWriter(dstF) + gzipWriter, err := gzip.NewWriterLevel(dstF, level) + if err != nil { + return err + } defer gzipWriter.Close() tarWriter := tar.NewWriter(gzipWriter) diff --git a/post-processor/vagrant/virtualbox.go b/post-processor/vagrant/virtualbox.go index 7c77e7ec7..10de66e38 100644 --- a/post-processor/vagrant/virtualbox.go +++ b/post-processor/vagrant/virtualbox.go @@ -2,6 +2,7 @@ package vagrant import ( "archive/tar" + "compress/flate" "errors" "fmt" "github.com/mitchellh/packer/common" @@ -12,6 +13,7 @@ import ( "os" "path/filepath" "regexp" + "strconv" ) type VBoxBoxConfig struct { @@ -19,6 +21,7 @@ type VBoxBoxConfig struct { OutputPath string `mapstructure:"output"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"` + CompressionLevel string `mapstructure:"compression_level"` tpl *packer.ConfigTemplate } @@ -49,6 +52,7 @@ func (p *VBoxBoxPostProcessor) Configure(raws ...interface{}) error { validates := map[string]*string{ "output": &p.config.OutputPath, "vagrantfile_template": &p.config.VagrantfileTemplate, + "compression_level": &p.config.CompressionLevel, } for n, ptr := range validates { @@ -141,6 +145,14 @@ func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifac vf.Write([]byte(vagrantfileContents)) vf.Close() + var level int = flate.DefaultCompression + if p.config.CompressionLevel != "" { + level, err = strconv.Atoi(p.config.CompressionLevel) + if err != nil { + return nil, false, err + } + } + // Create the metadata metadata := map[string]string{"provider": "virtualbox"} if err := WriteMetadata(dir, metadata); err != nil { @@ -155,7 +167,7 @@ func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifac // Compress the directory to the given output path ui.Message(fmt.Sprintf("Compressing box...")) - if err := DirToBox(outputPath, dir, ui); err != nil { + if err := DirToBox(outputPath, dir, ui, level); err != nil { return nil, false, err } diff --git a/post-processor/vagrant/vmware.go b/post-processor/vagrant/vmware.go index 7d04ac991..b12a2d2f6 100644 --- a/post-processor/vagrant/vmware.go +++ b/post-processor/vagrant/vmware.go @@ -1,12 +1,14 @@ package vagrant import ( + "compress/flate" "fmt" "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/packer" "io/ioutil" "os" "path/filepath" + "strconv" ) type VMwareBoxConfig struct { @@ -14,6 +16,7 @@ type VMwareBoxConfig struct { OutputPath string `mapstructure:"output"` VagrantfileTemplate string `mapstructure:"vagrantfile_template"` + CompressionLevel string `mapstructure:"compression_level"` tpl *packer.ConfigTemplate } @@ -40,6 +43,7 @@ func (p *VMwareBoxPostProcessor) Configure(raws ...interface{}) error { validates := map[string]*string{ "output": &p.config.OutputPath, "vagrantfile_template": &p.config.VagrantfileTemplate, + "compression_level": &p.config.CompressionLevel, } for n, ptr := range validates { @@ -111,6 +115,14 @@ func (p *VMwareBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artif vf.Close() } + var level int = flate.DefaultCompression + if p.config.CompressionLevel != "" { + level, err = strconv.Atoi(p.config.CompressionLevel) + if err != nil { + return nil, false, err + } + } + // Create the metadata metadata := map[string]string{"provider": "vmware_desktop"} if err := WriteMetadata(dir, metadata); err != nil { @@ -119,7 +131,7 @@ func (p *VMwareBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artif // Compress the directory to the given output path ui.Message(fmt.Sprintf("Compressing box...")) - if err := DirToBox(outputPath, dir, ui); err != nil { + if err := DirToBox(outputPath, dir, ui, level); err != nil { return nil, false, err } diff --git a/website/source/docs/post-processors/vagrant.html.markdown b/website/source/docs/post-processors/vagrant.html.markdown index 6140b9c09..6b0f3c21a 100644 --- a/website/source/docs/post-processors/vagrant.html.markdown +++ b/website/source/docs/post-processors/vagrant.html.markdown @@ -68,6 +68,11 @@ The AWS provider itself can be configured with specific options: this is a template that simply sets the AMIs for the various regions of the AWS build. +* `compression_level` (integer) - An integer repesenting the + compression level to use when creating the Vagrant box. Valid + values range from 0 to 9, with 0 being no compression and 9 being + the best compression. + The `vagrantfile_template` has the `Images` variable which is a map of region (string) to AMI ID (string). An example Vagrantfile template for AWS is shown below. The example simply sets the AMI for each region.