enable vsphere-template to work with local builders

This commit is contained in:
bugbuilder 2017-09-20 22:50:37 -03:00
parent 4ce381cae7
commit 644ac5b367
4 changed files with 85 additions and 13 deletions

View File

@ -7,16 +7,19 @@ import (
"strings" "strings"
"time" "time"
"github.com/hashicorp/packer/builder/vmware/iso"
"github.com/hashicorp/packer/common" "github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/config" "github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer" "github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/post-processor/vsphere"
"github.com/hashicorp/packer/template/interpolate" "github.com/hashicorp/packer/template/interpolate"
"github.com/mitchellh/multistep" "github.com/mitchellh/multistep"
"github.com/vmware/govmomi" "github.com/vmware/govmomi"
) )
var builtins = map[string]string{ var builtins = map[string]string{
"mitchellh.vmware-esx": "vmware", vsphere.BuilderId: "vmware",
iso.BuilderIdESX: "vmware",
} }
type Config struct { type Config struct {
@ -90,11 +93,16 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
source := "" source := ""
for _, path := range artifact.Files() { for _, path := range artifact.Files() {
if strings.HasSuffix(path, ".vmx") { if strings.HasSuffix(path, ".vmx") || strings.HasSuffix(path, ".ovf") || strings.HasSuffix(path, ".ova") {
source = path source = path
break break
} }
} }
if source == "" {
return nil, false, fmt.Errorf("VMX, OVF or OVA file not found")
}
// In some occasions the VM state is powered on and if we immediately try to mark as template // In some occasions the VM state is powered on and if we immediately try to mark as template
// (after the ESXi creates it) it will fail. If vSphere is given a few seconds this behavior doesn't reappear. // (after the ESXi creates it) it will fail. If vSphere is given a few seconds this behavior doesn't reappear.
ui.Message("Waiting 10s for VMware vSphere to start") ui.Message("Waiting 10s for VMware vSphere to start")
@ -117,10 +125,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
&stepCreateFolder{ &stepCreateFolder{
Folder: p.config.Folder, Folder: p.config.Folder,
}, },
&stepMarkAsTemplate{ NewStepMarkAsTemplate(artifact.Id(), source),
VMName: artifact.Id(),
Source: source,
},
} }
runner := common.NewRunnerWithPauseFn(steps, p.config.PackerConfig, ui, state) runner := common.NewRunnerWithPauseFn(steps, p.config.PackerConfig, ui, state)
runner.Run(state) runner.Run(state)

View File

@ -13,8 +13,30 @@ import (
) )
type stepMarkAsTemplate struct { type stepMarkAsTemplate struct {
VMName string VMName string
Source string Source string
RemoteFolder string
}
func NewStepMarkAsTemplate(vmname, source string) *stepMarkAsTemplate {
remoteFolder := "Discovered virtual machine"
if strings.Contains(vmname, "::") {
local := strings.Split(vmname, "::")
datastore := local[0]
remoteFolder = local[1]
vmname = local[2]
source = path.Join("/vmfs/volumes/", datastore, vmname, path.Base(source))
}
return &stepMarkAsTemplate{
VMName: vmname,
Source: source,
RemoteFolder: remoteFolder,
}
} }
func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction { func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction {
@ -25,7 +47,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction
ui.Message("Marking as a template...") ui.Message("Marking as a template...")
vm, err := findRuntimeVM(cli, dcPath, s.VMName) vm, err := findRuntimeVM(cli, dcPath, s.VMName, s.RemoteFolder)
if err != nil { if err != nil {
state.Put("error", err) state.Put("error", err)
ui.Error(err.Error()) ui.Error(err.Error())
@ -75,10 +97,10 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction
return multistep.ActionContinue return multistep.ActionContinue
} }
// We will use the virtual machine created by vmware-iso builder // We will use the virtual machine created/uploaded by vmware builder (remote or local)
func findRuntimeVM(cli *govmomi.Client, dcPath, name string) (*object.VirtualMachine, error) { func findRuntimeVM(cli *govmomi.Client, dcPath, name, remoteFolder string) (*object.VirtualMachine, error) {
si := object.NewSearchIndex(cli.Client) si := object.NewSearchIndex(cli.Client)
fullPath := path.Join(dcPath, "vm", "Discovered virtual machine", name) fullPath := path.Join(dcPath, "vm", remoteFolder, name)
ref, err := si.FindByInventoryPath(context.Background(), fullPath) ref, err := si.FindByInventoryPath(context.Background(), fullPath)
if err != nil { if err != nil {

View File

@ -0,0 +1,38 @@
package vsphere
import (
"fmt"
)
const BuilderId = "packer.post-processor.vsphere"
type Artifact struct {
files []string
datastore string
vmfolder string
vmname string
}
func (*Artifact) BuilderId() string {
return BuilderId
}
func (a *Artifact) Files() []string {
return a.files
}
func (a *Artifact) Id() string {
return fmt.Sprintf("%s::%s::%s", a.datastore, a.vmfolder, a.vmname)
}
func (a *Artifact) String() string {
return fmt.Sprintf("VM: %s Folder: %s Datastore: %s", a.vmname, a.vmfolder, a.datastore)
}
func (*Artifact) State(name string) interface{} {
return nil
}
func (a *Artifact) Destroy() error {
return nil
}

View File

@ -142,7 +142,14 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
return nil, false, fmt.Errorf("Failed: %s\n", err) return nil, false, fmt.Errorf("Failed: %s\n", err)
} }
return artifact, false, nil artifact = &Artifact{
datastore: p.config.Datastore,
files: artifact.Files(),
vmfolder: p.config.VMFolder,
vmname: p.config.VMName,
}
return artifact, true, nil
} }
func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) { func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) {