diff --git a/post-processor/vagrant/util.go b/post-processor/vagrant/util.go index 86742abe5..0bc4578d0 100644 --- a/post-processor/vagrant/util.go +++ b/post-processor/vagrant/util.go @@ -111,6 +111,48 @@ func DirToBox(dst, dir string, ui packer.Ui) error { return filepath.Walk(dir, tarWalk) } +func OvaToDir(dir, src string) error { + log.Printf("Turning ova to dir: %s => %s", src, dir) + srcF, err := os.Open(src) + if err != nil { + return err + } + defer srcF.Close() + + tarReader := tar.NewReader(srcF) + + for { + + hdr, err := tarReader.Next() + if hdr == nil || err == io.EOF { + break + } + + info := hdr.FileInfo() + + // Shouldn't be any directories, skip them + if info.IsDir() { + continue + } + + path := filepath.Join(dir, info.Name()) + output, err := os.Create(path) + if err != nil { + return err + } + defer output.Close() + + os.Chmod(path, info.Mode()) + os.Chtimes(path, hdr.AccessTime, hdr.ModTime) + + if _, err := io.Copy(output, tarReader); err != nil { + return err + } + } + + return nil +} + // WriteMetadata writes the "metadata.json" file for a Vagrant box. func WriteMetadata(dir string, contents interface{}) error { f, err := os.Create(filepath.Join(dir, "metadata.json")) diff --git a/post-processor/vagrant/virtualbox.go b/post-processor/vagrant/virtualbox.go index 3eab82175..3c945cd95 100644 --- a/post-processor/vagrant/virtualbox.go +++ b/post-processor/vagrant/virtualbox.go @@ -10,7 +10,6 @@ import ( "os" "path/filepath" "regexp" - "strings" ) type VBoxBoxConfig struct { @@ -66,11 +65,6 @@ func (p *VBoxBoxPostProcessor) Configure(raws ...interface{}) error { func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) { var err error - tplData := &VBoxVagrantfileTemplate{} - tplData.BaseMacAddress, err = p.findBaseMacAddress(artifact) - if err != nil { - return nil, false, err - } // Compile the output path outputPath, err := p.config.tpl.Process(p.config.OutputPath, &OutputPathTemplate{ @@ -93,13 +87,27 @@ func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifac for _, path := range artifact.Files() { ui.Message(fmt.Sprintf("Copying: %s", path)) - dstPath := filepath.Join(dir, filepath.Base(path)) - if err := CopyContents(dstPath, path); err != nil { - return nil, false, err + if extension := filepath.Ext(path); extension == ".ova" { + log.Printf("File is an OVA: %s", path) + if err := OvaToDir(dir, filepath.Base(path)); err != nil { + return nil, false, err + } + } else { + dstPath := filepath.Join(dir, filepath.Base(path)) + if err := CopyContents(dstPath, path); err != nil { + return nil, false, err + } } + } // Create the Vagrantfile from the template + tplData := &VBoxVagrantfileTemplate{} + tplData.BaseMacAddress, err = p.findBaseMacAddress(dir) + if err != nil { + return nil, false, err + } + vf, err := os.Create(filepath.Join(dir, "Vagrantfile")) if err != nil { return nil, false, err @@ -150,21 +158,42 @@ func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifac return NewArtifact("virtualbox", outputPath), false, nil } -func (p *VBoxBoxPostProcessor) findBaseMacAddress(a packer.Artifact) (string, error) { - log.Println("Looking for OVF for base mac address...") - var ovf string - for _, f := range a.Files() { - if strings.HasSuffix(f, ".ovf") { - log.Printf("OVF found: %s", f) - ovf = f - break - } +func (p *VBoxBoxPostProcessor) findOvf(dir string) (string, error) { + log.Println("Looking for OVF in artifact...") + file_matches, err := filepath.Glob(filepath.Join(dir, "*.ovf")) + if err != nil { + return "", err } - if ovf == "" { + if len(file_matches) > 1 { + return "", errors.New("More than one OVF file in VirtualBox artifact.") + } + + if len(file_matches) < 1 { return "", errors.New("ovf file couldn't be found") } + return file_matches[0], err +} + +func (p *VBoxBoxPostProcessor) renameOVF(dir string) error { + log.Println("Looking for OVF to rename...") + ovf, err := p.findOvf(dir) + if err != nil { + return err + } + + log.Printf("Renaming: '%s' => box.ovf", ovf) + return os.Rename(ovf, filepath.Join(dir, "box.ovf")) +} + +func (p *VBoxBoxPostProcessor) findBaseMacAddress(dir string) (string, error) { + log.Println("Looking for OVF for base mac address...") + ovf, err := p.findOvf(dir) + if err != nil { + return "", err + } + f, err := os.Open(ovf) if err != nil { return "", err @@ -186,21 +215,6 @@ func (p *VBoxBoxPostProcessor) findBaseMacAddress(a packer.Artifact) (string, er return string(matches[1]), nil } -func (p *VBoxBoxPostProcessor) renameOVF(dir string) error { - log.Println("Looking for OVF to rename...") - matches, err := filepath.Glob(filepath.Join(dir, "*.ovf")) - if err != nil { - return err - } - - if len(matches) > 1 { - return errors.New("More than one OVF file in VirtualBox artifact.") - } - - log.Printf("Renaming: '%s' => box.ovf", matches[0]) - return os.Rename(matches[0], filepath.Join(dir, "box.ovf")) -} - var defaultVBoxVagrantfile = ` Vagrant.configure("2") do |config| config.vm.base_mac = "{{ .BaseMacAddress }}"