builder/vmware-vmx: Added tools_upload_flavor support
This commit is contained in:
parent
c1cfd1da46
commit
ba13239672
|
@ -0,0 +1,40 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/mitchellh/multistep"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StepPrepareTools struct{
|
||||||
|
RemoteType string `mapstructure:"remote_type"`
|
||||||
|
ToolsUploadFlavor string `mapstructure:"tools_upload_flavor"`
|
||||||
|
ToolsUploadPath string `mapstructure:"tools_upload_path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *StepPrepareTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
driver := state.Get("driver").(Driver)
|
||||||
|
|
||||||
|
if c.RemoteType == "esx5" {
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.ToolsUploadFlavor == "" {
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
path := driver.ToolsIsoPath(c.ToolsUploadFlavor)
|
||||||
|
if _, err := os.Stat(path); err != nil {
|
||||||
|
state.Put("error", fmt.Errorf(
|
||||||
|
"Couldn't find VMware tools for '%s'! VMware often downloads these\n"+
|
||||||
|
"tools on-demand. However, to do this, you need to create a fake VM\n"+
|
||||||
|
"of the proper type then click the 'install tools' option in the\n"+
|
||||||
|
"VMware GUI.", c.ToolsUploadFlavor))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
state.Put("tools_upload_source", path)
|
||||||
|
return multistep.ActionContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *StepPrepareTools) Cleanup(multistep.StateBag) {}
|
|
@ -1,9 +1,8 @@
|
||||||
package iso
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/mitchellh/multistep"
|
"github.com/mitchellh/multistep"
|
||||||
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
|
|
||||||
"github.com/mitchellh/packer/packer"
|
"github.com/mitchellh/packer/packer"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
@ -12,20 +11,24 @@ type toolsUploadPathTemplate struct {
|
||||||
Flavor string
|
Flavor string
|
||||||
}
|
}
|
||||||
|
|
||||||
type stepUploadTools struct{}
|
type StepUploadTools struct{
|
||||||
|
RemoteType string `mapstructure:"remote_type"`
|
||||||
|
ToolsUploadFlavor string `mapstructure:"tools_upload_flavor"`
|
||||||
|
ToolsUploadPath string `mapstructure:"tools_upload_path"`
|
||||||
|
Tpl *packer.ConfigTemplate
|
||||||
|
}
|
||||||
|
|
||||||
func (*stepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
func (c *StepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
config := state.Get("config").(*config)
|
driver := state.Get("driver").(Driver)
|
||||||
driver := state.Get("driver").(vmwcommon.Driver)
|
|
||||||
|
|
||||||
if config.RemoteType == "esx5" {
|
if c.RemoteType == "esx5" {
|
||||||
if err := driver.ToolsInstall(); err != nil {
|
if err := driver.ToolsInstall(); err != nil {
|
||||||
state.Put("error", fmt.Errorf("Couldn't mount VMware tools ISO."))
|
state.Put("error", fmt.Errorf("Couldn't mount VMware tools ISO."))
|
||||||
}
|
}
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ToolsUploadFlavor == "" {
|
if c.ToolsUploadFlavor == "" {
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +36,7 @@ func (*stepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
tools_source := state.Get("tools_upload_source").(string)
|
tools_source := state.Get("tools_upload_source").(string)
|
||||||
ui := state.Get("ui").(packer.Ui)
|
ui := state.Get("ui").(packer.Ui)
|
||||||
|
|
||||||
ui.Say(fmt.Sprintf("Uploading the '%s' VMware Tools", config.ToolsUploadFlavor))
|
ui.Say(fmt.Sprintf("Uploading the '%s' VMware Tools", c.ToolsUploadFlavor))
|
||||||
f, err := os.Open(tools_source)
|
f, err := os.Open(tools_source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state.Put("error", fmt.Errorf("Error opening VMware Tools ISO: %s", err))
|
state.Put("error", fmt.Errorf("Error opening VMware Tools ISO: %s", err))
|
||||||
|
@ -41,8 +44,10 @@ func (*stepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
tplData := &toolsUploadPathTemplate{Flavor: config.ToolsUploadFlavor}
|
tplData := &toolsUploadPathTemplate{
|
||||||
config.ToolsUploadPath, err = config.tpl.Process(config.ToolsUploadPath, tplData)
|
Flavor: c.ToolsUploadFlavor,
|
||||||
|
}
|
||||||
|
c.ToolsUploadPath, err = c.Tpl.Process(c.ToolsUploadPath, tplData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("Error preparing upload path: %s", err)
|
err := fmt.Errorf("Error preparing upload path: %s", err)
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
|
@ -50,7 +55,7 @@ func (*stepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := comm.Upload(config.ToolsUploadPath, f); err != nil {
|
if err := comm.Upload(c.ToolsUploadPath, f); err != nil {
|
||||||
err := fmt.Errorf("Error uploading VMware Tools: %s", err)
|
err := fmt.Errorf("Error uploading VMware Tools: %s", err)
|
||||||
state.Put("error", err)
|
state.Put("error", err)
|
||||||
ui.Error(err.Error())
|
ui.Error(err.Error())
|
||||||
|
@ -60,4 +65,4 @@ func (*stepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*stepUploadTools) Cleanup(multistep.StateBag) {}
|
func (c *StepUploadTools) Cleanup(multistep.StateBag) {}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ToolsConfig struct {
|
||||||
|
ToolsUploadFlavor string `mapstructure:"tools_upload_flavor"`
|
||||||
|
ToolsUploadPath string `mapstructure:"tools_upload_path"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ToolsConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||||
|
if c.ToolsUploadPath == "" {
|
||||||
|
c.ToolsUploadPath = "{{ .Flavor }}.iso"
|
||||||
|
}
|
||||||
|
|
||||||
|
templates := map[string]*string{
|
||||||
|
"tools_upload_flavor": &c.ToolsUploadFlavor,
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
errs := make([]error, 0)
|
||||||
|
for n, ptr := range templates {
|
||||||
|
*ptr, err = t.Process(*ptr, nil)
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := template.New("path").Parse(c.ToolsUploadPath); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("tools_upload_path invalid: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,6 +29,7 @@ type config struct {
|
||||||
vmwcommon.RunConfig `mapstructure:",squash"`
|
vmwcommon.RunConfig `mapstructure:",squash"`
|
||||||
vmwcommon.ShutdownConfig `mapstructure:",squash"`
|
vmwcommon.ShutdownConfig `mapstructure:",squash"`
|
||||||
vmwcommon.SSHConfig `mapstructure:",squash"`
|
vmwcommon.SSHConfig `mapstructure:",squash"`
|
||||||
|
vmwcommon.ToolsConfig `mapstructure:",squash"`
|
||||||
vmwcommon.VMXConfig `mapstructure:",squash"`
|
vmwcommon.VMXConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
DiskName string `mapstructure:"vmdk_name"`
|
DiskName string `mapstructure:"vmdk_name"`
|
||||||
|
@ -46,8 +46,6 @@ type config struct {
|
||||||
HTTPPortMax uint `mapstructure:"http_port_max"`
|
HTTPPortMax uint `mapstructure:"http_port_max"`
|
||||||
BootCommand []string `mapstructure:"boot_command"`
|
BootCommand []string `mapstructure:"boot_command"`
|
||||||
SkipCompaction bool `mapstructure:"skip_compaction"`
|
SkipCompaction bool `mapstructure:"skip_compaction"`
|
||||||
ToolsUploadFlavor string `mapstructure:"tools_upload_flavor"`
|
|
||||||
ToolsUploadPath string `mapstructure:"tools_upload_path"`
|
|
||||||
VMXTemplatePath string `mapstructure:"vmx_template_path"`
|
VMXTemplatePath string `mapstructure:"vmx_template_path"`
|
||||||
VNCPortMin uint `mapstructure:"vnc_port_min"`
|
VNCPortMin uint `mapstructure:"vnc_port_min"`
|
||||||
VNCPortMax uint `mapstructure:"vnc_port_max"`
|
VNCPortMax uint `mapstructure:"vnc_port_max"`
|
||||||
|
@ -84,6 +82,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(b.config.tpl)...)
|
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(b.config.tpl)...)
|
||||||
errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(b.config.tpl)...)
|
errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(b.config.tpl)...)
|
||||||
errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(b.config.tpl)...)
|
errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(b.config.tpl)...)
|
||||||
|
errs = packer.MultiErrorAppend(errs, b.config.ToolsConfig.Prepare(b.config.tpl)...)
|
||||||
errs = packer.MultiErrorAppend(errs, b.config.VMXConfig.Prepare(b.config.tpl)...)
|
errs = packer.MultiErrorAppend(errs, b.config.VMXConfig.Prepare(b.config.tpl)...)
|
||||||
warnings := make([]string, 0)
|
warnings := make([]string, 0)
|
||||||
|
|
||||||
|
@ -144,10 +143,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
b.config.RemotePort = 22
|
b.config.RemotePort = 22
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.ToolsUploadPath == "" {
|
|
||||||
b.config.ToolsUploadPath = "{{ .Flavor }}.iso"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
templates := map[string]*string{
|
templates := map[string]*string{
|
||||||
"disk_name": &b.config.DiskName,
|
"disk_name": &b.config.DiskName,
|
||||||
|
@ -156,7 +151,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
"iso_checksum": &b.config.ISOChecksum,
|
"iso_checksum": &b.config.ISOChecksum,
|
||||||
"iso_checksum_type": &b.config.ISOChecksumType,
|
"iso_checksum_type": &b.config.ISOChecksumType,
|
||||||
"iso_url": &b.config.RawSingleISOUrl,
|
"iso_url": &b.config.RawSingleISOUrl,
|
||||||
"tools_upload_flavor": &b.config.ToolsUploadFlavor,
|
|
||||||
"vm_name": &b.config.VMName,
|
"vm_name": &b.config.VMName,
|
||||||
"vmx_template_path": &b.config.VMXTemplatePath,
|
"vmx_template_path": &b.config.VMXTemplatePath,
|
||||||
"remote_type": &b.config.RemoteType,
|
"remote_type": &b.config.RemoteType,
|
||||||
|
@ -245,11 +239,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := template.New("path").Parse(b.config.ToolsUploadPath); err != nil {
|
|
||||||
errs = packer.MultiErrorAppend(
|
|
||||||
errs, fmt.Errorf("tools_upload_path invalid: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.config.VMXTemplatePath != "" {
|
if b.config.VMXTemplatePath != "" {
|
||||||
if err := b.validateVMXTemplatePath(); err != nil {
|
if err := b.validateVMXTemplatePath(); err != nil {
|
||||||
errs = packer.MultiErrorAppend(
|
errs = packer.MultiErrorAppend(
|
||||||
|
@ -320,7 +309,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
rand.Seed(time.Now().UTC().UnixNano())
|
||||||
|
|
||||||
steps := []multistep.Step{
|
steps := []multistep.Step{
|
||||||
&stepPrepareTools{},
|
&vmwcommon.StepPrepareTools{
|
||||||
|
RemoteType: b.config.RemoteType,
|
||||||
|
ToolsUploadFlavor: b.config.ToolsUploadFlavor,
|
||||||
|
ToolsUploadPath: b.config.ToolsUploadPath,
|
||||||
|
},
|
||||||
&common.StepDownload{
|
&common.StepDownload{
|
||||||
Checksum: b.config.ISOChecksum,
|
Checksum: b.config.ISOChecksum,
|
||||||
ChecksumType: b.config.ISOChecksumType,
|
ChecksumType: b.config.ISOChecksumType,
|
||||||
|
@ -363,7 +356,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
SSHWaitTimeout: b.config.SSHWaitTimeout,
|
SSHWaitTimeout: b.config.SSHWaitTimeout,
|
||||||
NoPty: b.config.SSHSkipRequestPty,
|
NoPty: b.config.SSHSkipRequestPty,
|
||||||
},
|
},
|
||||||
&stepUploadTools{},
|
&vmwcommon.StepUploadTools{
|
||||||
|
RemoteType: b.config.RemoteType,
|
||||||
|
ToolsUploadFlavor: b.config.ToolsUploadFlavor,
|
||||||
|
ToolsUploadPath: b.config.ToolsUploadPath,
|
||||||
|
Tpl: b.config.tpl,
|
||||||
|
},
|
||||||
&common.StepProvision{},
|
&common.StepProvision{},
|
||||||
&vmwcommon.StepShutdown{
|
&vmwcommon.StepShutdown{
|
||||||
Command: b.config.ShutdownCommand,
|
Command: b.config.ShutdownCommand,
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
package iso
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/mitchellh/multistep"
|
|
||||||
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type stepPrepareTools struct{}
|
|
||||||
|
|
||||||
func (*stepPrepareTools) Run(state multistep.StateBag) multistep.StepAction {
|
|
||||||
config := state.Get("config").(*config)
|
|
||||||
driver := state.Get("driver").(vmwcommon.Driver)
|
|
||||||
|
|
||||||
if config.RemoteType == "esx5" {
|
|
||||||
return multistep.ActionContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.ToolsUploadFlavor == "" {
|
|
||||||
return multistep.ActionContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
path := driver.ToolsIsoPath(config.ToolsUploadFlavor)
|
|
||||||
if _, err := os.Stat(path); err != nil {
|
|
||||||
state.Put("error", fmt.Errorf(
|
|
||||||
"Couldn't find VMware tools for '%s'! VMware often downloads these\n"+
|
|
||||||
"tools on-demand. However, to do this, you need to create a fake VM\n"+
|
|
||||||
"of the proper type then click the 'install tools' option in the\n"+
|
|
||||||
"VMware GUI.", config.ToolsUploadFlavor))
|
|
||||||
return multistep.ActionHalt
|
|
||||||
}
|
|
||||||
|
|
||||||
state.Put("tools_upload_source", path)
|
|
||||||
return multistep.ActionContinue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*stepPrepareTools) Cleanup(multistep.StateBag) {}
|
|
|
@ -52,6 +52,11 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
|
|
||||||
// Build the steps.
|
// Build the steps.
|
||||||
steps := []multistep.Step{
|
steps := []multistep.Step{
|
||||||
|
&vmwcommon.StepPrepareTools{
|
||||||
|
RemoteType: b.config.RemoteType,
|
||||||
|
ToolsUploadFlavor: b.config.ToolsUploadFlavor,
|
||||||
|
ToolsUploadPath: b.config.ToolsUploadPath,
|
||||||
|
},
|
||||||
&vmwcommon.StepOutputDir{
|
&vmwcommon.StepOutputDir{
|
||||||
Force: b.config.PackerForce,
|
Force: b.config.PackerForce,
|
||||||
},
|
},
|
||||||
|
@ -78,6 +83,12 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
SSHWaitTimeout: b.config.SSHWaitTimeout,
|
SSHWaitTimeout: b.config.SSHWaitTimeout,
|
||||||
NoPty: b.config.SSHSkipRequestPty,
|
NoPty: b.config.SSHSkipRequestPty,
|
||||||
},
|
},
|
||||||
|
&vmwcommon.StepUploadTools{
|
||||||
|
RemoteType: b.config.RemoteType,
|
||||||
|
ToolsUploadFlavor: b.config.ToolsUploadFlavor,
|
||||||
|
ToolsUploadPath: b.config.ToolsUploadPath,
|
||||||
|
Tpl: b.config.tpl,
|
||||||
|
},
|
||||||
&common.StepProvision{},
|
&common.StepProvision{},
|
||||||
&vmwcommon.StepShutdown{
|
&vmwcommon.StepShutdown{
|
||||||
Command: b.config.ShutdownCommand,
|
Command: b.config.ShutdownCommand,
|
||||||
|
|
|
@ -17,9 +17,11 @@ type Config struct {
|
||||||
vmwcommon.RunConfig `mapstructure:",squash"`
|
vmwcommon.RunConfig `mapstructure:",squash"`
|
||||||
vmwcommon.ShutdownConfig `mapstructure:",squash"`
|
vmwcommon.ShutdownConfig `mapstructure:",squash"`
|
||||||
vmwcommon.SSHConfig `mapstructure:",squash"`
|
vmwcommon.SSHConfig `mapstructure:",squash"`
|
||||||
|
vmwcommon.ToolsConfig `mapstructure:",squash"`
|
||||||
vmwcommon.VMXConfig `mapstructure:",squash"`
|
vmwcommon.VMXConfig `mapstructure:",squash"`
|
||||||
|
|
||||||
FloppyFiles []string `mapstructure:"floppy_files"`
|
FloppyFiles []string `mapstructure:"floppy_files"`
|
||||||
|
RemoteType string `mapstructure:"remote_type"`
|
||||||
SkipCompaction bool `mapstructure:"skip_compaction"`
|
SkipCompaction bool `mapstructure:"skip_compaction"`
|
||||||
SourcePath string `mapstructure:"source_path"`
|
SourcePath string `mapstructure:"source_path"`
|
||||||
VMName string `mapstructure:"vm_name"`
|
VMName string `mapstructure:"vm_name"`
|
||||||
|
@ -52,9 +54,11 @@ func NewConfig(raws ...interface{}) (*Config, []string, error) {
|
||||||
errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(c.tpl)...)
|
errs = packer.MultiErrorAppend(errs, c.RunConfig.Prepare(c.tpl)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(c.tpl)...)
|
errs = packer.MultiErrorAppend(errs, c.ShutdownConfig.Prepare(c.tpl)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
|
errs = packer.MultiErrorAppend(errs, c.SSHConfig.Prepare(c.tpl)...)
|
||||||
|
errs = packer.MultiErrorAppend(errs, c.ToolsConfig.Prepare(c.tpl)...)
|
||||||
errs = packer.MultiErrorAppend(errs, c.VMXConfig.Prepare(c.tpl)...)
|
errs = packer.MultiErrorAppend(errs, c.VMXConfig.Prepare(c.tpl)...)
|
||||||
|
|
||||||
templates := map[string]*string{
|
templates := map[string]*string{
|
||||||
|
"remote_type": &c.RemoteType,
|
||||||
"source_path": &c.SourcePath,
|
"source_path": &c.SourcePath,
|
||||||
"vm_name": &c.VMName,
|
"vm_name": &c.VMName,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue