enable vsphere-template to work with local builders
This commit is contained in:
parent
4ce381cae7
commit
644ac5b367
|
@ -7,16 +7,19 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/packer/builder/vmware/iso"
|
||||
"github.com/hashicorp/packer/common"
|
||||
"github.com/hashicorp/packer/helper/config"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/hashicorp/packer/post-processor/vsphere"
|
||||
"github.com/hashicorp/packer/template/interpolate"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/vmware/govmomi"
|
||||
)
|
||||
|
||||
var builtins = map[string]string{
|
||||
"mitchellh.vmware-esx": "vmware",
|
||||
vsphere.BuilderId: "vmware",
|
||||
iso.BuilderIdESX: "vmware",
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
@ -90,11 +93,16 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
|
||||
source := ""
|
||||
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
|
||||
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
|
||||
// (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")
|
||||
|
@ -117,10 +125,7 @@ func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (pac
|
|||
&stepCreateFolder{
|
||||
Folder: p.config.Folder,
|
||||
},
|
||||
&stepMarkAsTemplate{
|
||||
VMName: artifact.Id(),
|
||||
Source: source,
|
||||
},
|
||||
NewStepMarkAsTemplate(artifact.Id(), source),
|
||||
}
|
||||
runner := common.NewRunnerWithPauseFn(steps, p.config.PackerConfig, ui, state)
|
||||
runner.Run(state)
|
||||
|
|
|
@ -13,8 +13,30 @@ import (
|
|||
)
|
||||
|
||||
type stepMarkAsTemplate struct {
|
||||
VMName string
|
||||
Source string
|
||||
VMName 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 {
|
||||
|
@ -25,7 +47,7 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction
|
|||
|
||||
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 {
|
||||
state.Put("error", err)
|
||||
ui.Error(err.Error())
|
||||
|
@ -75,10 +97,10 @@ func (s *stepMarkAsTemplate) Run(state multistep.StateBag) multistep.StepAction
|
|||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
// We will use the virtual machine created by vmware-iso builder
|
||||
func findRuntimeVM(cli *govmomi.Client, dcPath, name string) (*object.VirtualMachine, error) {
|
||||
// We will use the virtual machine created/uploaded by vmware builder (remote or local)
|
||||
func findRuntimeVM(cli *govmomi.Client, dcPath, name, remoteFolder string) (*object.VirtualMachine, error) {
|
||||
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)
|
||||
if err != nil {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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 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) {
|
||||
|
|
Loading…
Reference in New Issue