From 2a49088785c19c8e9ff68d58e8870e1d159c2b0a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 27 Jun 2013 19:21:03 -0400 Subject: [PATCH] post-processor: recognize vmware and build vmware boxes --- post-processor/vagrant/post-processor.go | 3 + post-processor/vagrant/vmware.go | 105 +++++++++++++++++++++++ post-processor/vagrant/vmware_test.go | 14 +++ 3 files changed, 122 insertions(+) create mode 100644 post-processor/vagrant/vmware.go create mode 100644 post-processor/vagrant/vmware_test.go diff --git a/post-processor/vagrant/post-processor.go b/post-processor/vagrant/post-processor.go index dccf403e9..0e35cece5 100644 --- a/post-processor/vagrant/post-processor.go +++ b/post-processor/vagrant/post-processor.go @@ -14,6 +14,7 @@ import ( var builtins = map[string]string{ "mitchellh.amazonebs": "aws", "mitchellh.virtualbox": "virtualbox", + "mitchellh.vmware": "vmware", } type Config struct { @@ -101,6 +102,8 @@ func keyToPostProcessor(key string) packer.PostProcessor { return new(AWSBoxPostProcessor) case "virtualbox": return new(VBoxBoxPostProcessor) + case "vmware": + return new(VMwareBoxPostProcessor) default: return nil } diff --git a/post-processor/vagrant/vmware.go b/post-processor/vagrant/vmware.go new file mode 100644 index 000000000..2bb215c57 --- /dev/null +++ b/post-processor/vagrant/vmware.go @@ -0,0 +1,105 @@ +package vagrant + +import ( + "fmt" + "github.com/mitchellh/mapstructure" + "github.com/mitchellh/packer/packer" + "io" + "io/ioutil" + "os" + "path/filepath" + "text/template" +) + +type VMwareBoxConfig struct { + OutputPath string `mapstructure:"output"` + VagrantfileTemplate string `mapstructure:"vagrantfile_template"` +} + +type VMwareBoxPostProcessor struct { + config VMwareBoxConfig +} + +func (p *VMwareBoxPostProcessor) Configure(raw interface{}) error { + err := mapstructure.Decode(raw, &p.config) + if err != nil { + return err + } + + return nil +} + +func (p *VMwareBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, error) { + // Compile the output path + outputPath, err := ProcessOutputPath(p.config.OutputPath, "vmware", artifact) + if err != nil { + return nil, 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, err + } + defer os.RemoveAll(dir) + + // Copy all of the original contents into the temporary directory + for _, path := range artifact.Files() { + ui.Message(fmt.Sprintf("Copying: %s", path)) + src, err := os.Open(path) + if err != nil { + return nil, err + } + defer src.Close() + + dst, err := os.Create(filepath.Join(dir, filepath.Base(path))) + if err != nil { + return nil, err + } + defer dst.Close() + + if _, err := io.Copy(dst, src); err != nil { + return nil, err + } + } + + + if p.config.VagrantfileTemplate != "" { + f, err := os.Open(p.config.VagrantfileTemplate) + if err != nil { + return nil, err + } + defer f.Close() + + contents, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + + // Create the Vagrantfile from the template + vf, err := os.Create(filepath.Join(dir, "Vagrantfile")) + if err != nil { + return nil, err + } + defer vf.Close() + + t := template.Must(template.New("vagrantfile").Parse(string(contents))) + t.Execute(vf, new(struct{})) + vf.Close() + } + + + // Create the metadata + metadata := map[string]string{"provider": "vmware"} + if err := WriteMetadata(dir, metadata); err != nil { + return nil, err + } + + // Compress the directory to the given output path + ui.Message(fmt.Sprintf("Compressing box...")) + if err := DirToBox(outputPath, dir); err != nil { + return nil, err + } + + return NewArtifact("vmware", outputPath), nil +} diff --git a/post-processor/vagrant/vmware_test.go b/post-processor/vagrant/vmware_test.go new file mode 100644 index 000000000..ca3cbe7cd --- /dev/null +++ b/post-processor/vagrant/vmware_test.go @@ -0,0 +1,14 @@ +package vagrant + +import ( + "github.com/mitchellh/packer/packer" + "testing" +) + +func TestVMwareBoxPostProcessor_ImplementsPostProcessor(t *testing.T) { + var raw interface{} + raw = &VMwareBoxPostProcessor{} + if _, ok := raw.(packer.PostProcessor); !ok { + t.Fatalf("VMware PostProcessor should be a PostProcessor") + } +}