From 23e73b12264035dc37412c456d79328bc207f60e Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 19 Dec 2013 13:41:48 -0800 Subject: [PATCH] post-processor/vagrant: DigitalOcean --- post-processor/vagrant/aws.go | 3 +- post-processor/vagrant/digitalocean.go | 147 +++----------------- post-processor/vagrant/digitalocean_test.go | 9 +- 3 files changed, 20 insertions(+), 139 deletions(-) diff --git a/post-processor/vagrant/aws.go b/post-processor/vagrant/aws.go index 04e074bc5..cddadd7e6 100644 --- a/post-processor/vagrant/aws.go +++ b/post-processor/vagrant/aws.go @@ -3,9 +3,10 @@ package vagrant import ( "bytes" "fmt" - "github.com/mitchellh/packer/packer" "strings" "text/template" + + "github.com/mitchellh/packer/packer" ) type AWSProvider struct{} diff --git a/post-processor/vagrant/digitalocean.go b/post-processor/vagrant/digitalocean.go index 3ff83d04e..aa7a757ff 100644 --- a/post-processor/vagrant/digitalocean.go +++ b/post-processor/vagrant/digitalocean.go @@ -1,155 +1,41 @@ package vagrant import ( - "compress/flate" + "bytes" "fmt" - "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/packer" - "io/ioutil" - "log" - "os" - "path/filepath" - "strconv" "strings" + "text/template" ) -type DigitalOceanBoxConfig struct { - common.PackerConfig `mapstructure:",squash"` - - OutputPath string `mapstructure:"output"` - VagrantfileTemplate string `mapstructure:"vagrantfile_template"` - CompressionLevel string `mapstructure:"compression_level"` - - tpl *packer.ConfigTemplate -} - -type DigitalOceanVagrantfileTemplate struct { +type digitalOceanVagrantfileTemplate struct { Image string "" Region string "" } -type DigitalOceanBoxPostProcessor struct { - config DigitalOceanBoxConfig -} +type DigitalOceanProvider struct{} -func (p *DigitalOceanBoxPostProcessor) Configure(rDigitalOcean ...interface{}) error { - md, err := common.DecodeConfig(&p.config, rDigitalOcean...) - if err != nil { - return err - } +func (p *DigitalOceanProvider) Process(ui packer.Ui, artifact packer.Artifact, dir string) (vagrantfile string, metadata map[string]interface{}, err error) { + // Create the metadata + metadata = map[string]interface{}{"provider": "digital_ocean"} - p.config.tpl, err = packer.NewConfigTemplate() - if err != nil { - return err - } - p.config.tpl.UserVars = p.config.PackerUserVars - - // Accumulate any errors - errs := common.CheckUnusedConfig(md) - - validates := map[string]*string{ - "output": &p.config.OutputPath, - "vagrantfile_template": &p.config.VagrantfileTemplate, - "compression_level": &p.config.CompressionLevel, - } - - for n, ptr := range validates { - if err := p.config.tpl.Validate(*ptr); err != nil { - errs = packer.MultiErrorAppend( - errs, fmt.Errorf("Error parsing %s: %s", n, err)) - } - } - - if errs != nil && len(errs.Errors) > 0 { - return errs - } - - return nil -} - -func (p *DigitalOceanBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { // Determine the image and region... - tplData := &DigitalOceanVagrantfileTemplate{} + tplData := &digitalOceanVagrantfileTemplate{} parts := strings.Split(artifact.Id(), ":") if len(parts) != 2 { - return nil, false, fmt.Errorf("Poorly formatted artifact ID: %s", artifact.Id()) + err = fmt.Errorf("Poorly formatted artifact ID: %s", artifact.Id()) + return } - tplData.Region = parts[0] tplData.Image = parts[1] - // Compile the output path - outputPath, err := p.config.tpl.Process(p.config.OutputPath, &OutputPathTemplate{ - ArtifactId: artifact.Id(), - BuildName: p.config.PackerBuildName, - Provider: "digitalocean", - }) - if err != nil { - return nil, false, err - } - - // Create a temporary directory for us to build the contents of the box in - dir, err := ioutil.TempDir("", "packer") - if err != nil { - return nil, false, err - } - defer os.RemoveAll(dir) - - // Create the Vagrantfile from the template - vf, err := os.Create(filepath.Join(dir, "Vagrantfile")) - if err != nil { - return nil, false, err - } - defer vf.Close() - - vagrantfileContents := defaultDigitalOceanVagrantfile - if p.config.VagrantfileTemplate != "" { - log.Printf("Using vagrantfile template: %s", p.config.VagrantfileTemplate) - f, err := os.Open(p.config.VagrantfileTemplate) - if err != nil { - err = fmt.Errorf("error opening vagrantfile template: %s", err) - return nil, false, err - } - defer f.Close() - - contents, err := ioutil.ReadAll(f) - if err != nil { - err = fmt.Errorf("error reading vagrantfile template: %s", err) - return nil, false, err - } - - vagrantfileContents = string(contents) - } - - vagrantfileContents, err = p.config.tpl.Process(vagrantfileContents, tplData) - if err != nil { - return nil, false, fmt.Errorf("Error writing Vagrantfile: %s", err) - } - vf.Write([]byte(vagrantfileContents)) - vf.Close() - - // Create the metadata - metadata := map[string]string{"provider": "digital_ocean"} - if err := WriteMetadata(dir, metadata); err != nil { - return nil, false, err - } - - // Compress the directory to the given output path - var level int = flate.DefaultCompression - if p.config.CompressionLevel != "" { - level, err = strconv.Atoi(p.config.CompressionLevel) - if err != nil { - return nil, false, err - } - } - - if err := DirToBox(outputPath, dir, ui, level); err != nil { - err = fmt.Errorf("error creating box: %s", err) - return nil, false, err - } - - return NewArtifact("DigitalOcean", outputPath), true, nil + // Build up the Vagrantfile + var contents bytes.Buffer + t := template.Must(template.New("vf").Parse(defaultDigitalOceanVagrantfile)) + err = t.Execute(&contents, tplData) + vagrantfile = contents.String() + return } var defaultDigitalOceanVagrantfile = ` @@ -159,5 +45,4 @@ Vagrant.configure("2") do |config| digital_ocean.region = "{{ .Region }}" end end - ` diff --git a/post-processor/vagrant/digitalocean_test.go b/post-processor/vagrant/digitalocean_test.go index 44451c6a4..09ca6fdf4 100644 --- a/post-processor/vagrant/digitalocean_test.go +++ b/post-processor/vagrant/digitalocean_test.go @@ -1,14 +1,9 @@ package vagrant import ( - "github.com/mitchellh/packer/packer" "testing" ) -func TestDigitalOceanBoxPostProcessor_ImplementsPostProcessor(t *testing.T) { - var raw interface{} - raw = &DigitalOceanBoxPostProcessor{} - if _, ok := raw.(packer.PostProcessor); !ok { - t.Fatalf("Digitalocean PostProcessor should be a PostProcessor") - } +func TestDigitalOceanProvider_impl(t *testing.T) { + var _ Provider = new(DigitalOceanProvider) }