mirror of
https://github.com/hashicorp/packer.git
synced 2026-04-23 23:27:00 -04:00
vmware/iso: new interpolation
This commit is contained in:
parent
0dc4226810
commit
f5945eeb1b
17 changed files with 118 additions and 255 deletions
|
|
@ -1,17 +1,16 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type DriverConfig struct {
|
||||
FusionAppPath string `mapstructure:"fusion_app_path"`
|
||||
}
|
||||
|
||||
func (c *DriverConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
func (c *DriverConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
if c.FusionAppPath == "" {
|
||||
c.FusionAppPath = os.Getenv("FUSION_APP_PATH")
|
||||
}
|
||||
|
|
@ -19,18 +18,5 @@ func (c *DriverConfig) Prepare(t *packer.ConfigTemplate) []error {
|
|||
c.FusionAppPath = "/Applications/VMware Fusion.app"
|
||||
}
|
||||
|
||||
templates := map[string]*string{
|
||||
"fusion_app_path": &c.FusionAppPath,
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
return errs
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,33 +2,22 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/packer/common"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os"
|
||||
|
||||
"github.com/mitchellh/packer/common"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type OutputConfig struct {
|
||||
OutputDir string `mapstructure:"output_directory"`
|
||||
}
|
||||
|
||||
func (c *OutputConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig) []error {
|
||||
func (c *OutputConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error {
|
||||
if c.OutputDir == "" {
|
||||
c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName)
|
||||
}
|
||||
|
||||
templates := map[string]*string{
|
||||
"output_directory": &c.OutputDir,
|
||||
}
|
||||
|
||||
errs := make([]error, 0)
|
||||
for n, ptr := range templates {
|
||||
var err error
|
||||
*ptr, err = t.Process(*ptr, nil)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err))
|
||||
}
|
||||
}
|
||||
|
||||
var errs []error
|
||||
if !pc.PackerForce {
|
||||
if _, err := os.Stat(c.OutputDir); err == nil {
|
||||
errs = append(errs, fmt.Errorf(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type RunConfig struct {
|
||||
|
|
@ -22,7 +22,7 @@ type RunConfig struct {
|
|||
BootWait time.Duration ``
|
||||
}
|
||||
|
||||
func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
if c.RawBootWait == "" {
|
||||
c.RawBootWait = "10s"
|
||||
}
|
||||
|
|
@ -43,20 +43,8 @@ func (c *RunConfig) Prepare(t *packer.ConfigTemplate) []error {
|
|||
c.VNCPortMax = 6000
|
||||
}
|
||||
|
||||
templates := map[string]*string{
|
||||
"boot_wait": &c.RawBootWait,
|
||||
"http_directory": &c.HTTPDir,
|
||||
}
|
||||
|
||||
var errs []error
|
||||
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 c.RawBootWait != "" {
|
||||
c.BootWait, err = time.ParseDuration(c.RawBootWait)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type ShutdownConfig struct {
|
||||
|
|
@ -13,25 +14,12 @@ type ShutdownConfig struct {
|
|||
ShutdownTimeout time.Duration ``
|
||||
}
|
||||
|
||||
func (c *ShutdownConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
func (c *ShutdownConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
if c.RawShutdownTimeout == "" {
|
||||
c.RawShutdownTimeout = "5m"
|
||||
}
|
||||
|
||||
templates := map[string]*string{
|
||||
"shutdown_command": &c.ShutdownCommand,
|
||||
"shutdown_timeout": &c.RawShutdownTimeout,
|
||||
}
|
||||
|
||||
errs := make([]error, 0)
|
||||
for n, ptr := range templates {
|
||||
var err error
|
||||
*ptr, err = t.Process(*ptr, nil)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err))
|
||||
}
|
||||
}
|
||||
|
||||
var errs []error
|
||||
var err error
|
||||
c.ShutdownTimeout, err = time.ParseDuration(c.RawShutdownTimeout)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
commonssh "github.com/mitchellh/packer/common/ssh"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type SSHConfig struct {
|
||||
|
|
@ -23,7 +23,7 @@ type SSHConfig struct {
|
|||
SSHWaitTimeout time.Duration
|
||||
}
|
||||
|
||||
func (c *SSHConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
if c.SSHPort == 0 {
|
||||
c.SSHPort = 22
|
||||
}
|
||||
|
|
@ -32,23 +32,7 @@ func (c *SSHConfig) Prepare(t *packer.ConfigTemplate) []error {
|
|||
c.RawSSHWaitTimeout = "20m"
|
||||
}
|
||||
|
||||
templates := map[string]*string{
|
||||
"ssh_host": &c.SSHHost,
|
||||
"ssh_key_path": &c.SSHKeyPath,
|
||||
"ssh_password": &c.SSHPassword,
|
||||
"ssh_username": &c.SSHUser,
|
||||
"ssh_wait_timeout": &c.RawSSHWaitTimeout,
|
||||
}
|
||||
|
||||
errs := make([]error, 0)
|
||||
for n, ptr := range templates {
|
||||
var err error
|
||||
*ptr, err = t.Process(*ptr, nil)
|
||||
if err != nil {
|
||||
errs = append(errs, fmt.Errorf("Error processing %s: %s", n, err))
|
||||
}
|
||||
}
|
||||
|
||||
var errs []error
|
||||
if c.SSHKeyPath != "" {
|
||||
if _, err := os.Stat(c.SSHKeyPath); err != nil {
|
||||
errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err))
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/mitchellh/go-vnc"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
const KeyLeftShift uint32 = 0xFFE1
|
||||
|
|
@ -35,7 +36,7 @@ type bootCommandTemplateData struct {
|
|||
type StepTypeBootCommand struct {
|
||||
BootCommand []string
|
||||
VMName string
|
||||
Tpl *packer.ConfigTemplate
|
||||
Ctx interpolate.Context
|
||||
}
|
||||
|
||||
func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
|
@ -87,7 +88,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
|
|||
|
||||
log.Printf("Host IP for the VMware machine: %s", hostIp)
|
||||
|
||||
tplData := &bootCommandTemplateData{
|
||||
s.Ctx.Data = &bootCommandTemplateData{
|
||||
hostIp,
|
||||
httpPort,
|
||||
s.VMName,
|
||||
|
|
@ -95,7 +96,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
|
|||
|
||||
ui.Say("Typing the boot command over VNC...")
|
||||
for _, command := range s.BootCommand {
|
||||
command, err := s.Tpl.Process(command, tplData)
|
||||
command, err := interpolate.Render(command, &s.Ctx)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error preparing boot command: %s", err)
|
||||
state.Put("error", err)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ package common
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type toolsUploadPathTemplate struct {
|
||||
|
|
@ -15,7 +17,7 @@ type StepUploadTools struct {
|
|||
RemoteType string
|
||||
ToolsUploadFlavor string
|
||||
ToolsUploadPath string
|
||||
Tpl *packer.ConfigTemplate
|
||||
Ctx interpolate.Context
|
||||
}
|
||||
|
||||
func (c *StepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
||||
|
|
@ -44,10 +46,10 @@ func (c *StepUploadTools) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
tplData := &toolsUploadPathTemplate{
|
||||
c.Ctx.Data = &toolsUploadPathTemplate{
|
||||
Flavor: c.ToolsUploadFlavor,
|
||||
}
|
||||
c.ToolsUploadPath, err = c.Tpl.Process(c.ToolsUploadPath, tplData)
|
||||
c.ToolsUploadPath, err = interpolate.Render(c.ToolsUploadPath, &c.Ctx)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error preparing upload path: %s", err)
|
||||
state.Put("error", err)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"text/template"
|
||||
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type ToolsConfig struct {
|
||||
|
|
@ -12,27 +9,10 @@ type ToolsConfig struct {
|
|||
ToolsUploadPath string `mapstructure:"tools_upload_path"`
|
||||
}
|
||||
|
||||
func (c *ToolsConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
func (c *ToolsConfig) Prepare(ctx *interpolate.Context) []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
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type VMXConfig struct {
|
||||
|
|
@ -11,49 +9,6 @@ type VMXConfig struct {
|
|||
VMXDataPost map[string]string `mapstructure:"vmx_data_post"`
|
||||
}
|
||||
|
||||
func (c *VMXConfig) Prepare(t *packer.ConfigTemplate) []error {
|
||||
errs := make([]error, 0)
|
||||
newVMXData := make(map[string]string)
|
||||
for k, v := range c.VMXData {
|
||||
var err error
|
||||
k, err = t.Process(k, nil)
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error processing vmx_data key %s: %s", k, err))
|
||||
continue
|
||||
}
|
||||
|
||||
v, err = t.Process(v, nil)
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error processing vmx_data value '%s': %s", v, err))
|
||||
continue
|
||||
}
|
||||
|
||||
newVMXData[k] = v
|
||||
}
|
||||
c.VMXData = newVMXData
|
||||
|
||||
newVMXDataPost := make(map[string]string)
|
||||
for k, v := range c.VMXDataPost {
|
||||
var err error
|
||||
k, err = t.Process(k, nil)
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error processing vmx_post_data key %s: %s", k, err))
|
||||
continue
|
||||
}
|
||||
|
||||
v, err = t.Process(v, nil)
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error processing vmx_post_data value '%s': %s", v, err))
|
||||
continue
|
||||
}
|
||||
|
||||
newVMXDataPost[k] = v
|
||||
}
|
||||
c.VMXDataPost = newVMXDataPost
|
||||
|
||||
return errs
|
||||
func (c *VMXConfig) Prepare(ctx *interpolate.Context) []error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,26 +3,29 @@ package iso
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
|
||||
"github.com/mitchellh/packer/common"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/multistep"
|
||||
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
|
||||
"github.com/mitchellh/packer/common"
|
||||
"github.com/mitchellh/packer/helper/config"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
const BuilderIdESX = "mitchellh.vmware-esx"
|
||||
|
||||
type Builder struct {
|
||||
config config
|
||||
config Config
|
||||
runner multistep.Runner
|
||||
}
|
||||
|
||||
type config struct {
|
||||
type Config struct {
|
||||
common.PackerConfig `mapstructure:",squash"`
|
||||
vmwcommon.DriverConfig `mapstructure:",squash"`
|
||||
vmwcommon.OutputConfig `mapstructure:",squash"`
|
||||
|
|
@ -57,31 +60,33 @@ type config struct {
|
|||
|
||||
RawSingleISOUrl string `mapstructure:"iso_url"`
|
||||
|
||||
tpl *packer.ConfigTemplate
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||
md, err := common.DecodeConfig(&b.config, raws...)
|
||||
err := config.Decode(&b.config, &config.DecodeOpts{
|
||||
Interpolate: true,
|
||||
InterpolateFilter: &interpolate.RenderFilter{
|
||||
Exclude: []string{
|
||||
"boot_command",
|
||||
"tools_upload_path",
|
||||
},
|
||||
},
|
||||
}, raws...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.config.tpl, err = packer.NewConfigTemplate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b.config.tpl.UserVars = b.config.PackerUserVars
|
||||
|
||||
// Accumulate any errors
|
||||
errs := common.CheckUnusedConfig(md)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.DriverConfig.Prepare(b.config.tpl)...)
|
||||
// Accumulate any errors and warnings
|
||||
var errs *packer.MultiError
|
||||
errs = packer.MultiErrorAppend(errs, b.config.DriverConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
b.config.OutputConfig.Prepare(b.config.tpl, &b.config.PackerConfig)...)
|
||||
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.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)...)
|
||||
b.config.OutputConfig.Prepare(&b.config.ctx, &b.config.PackerConfig)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.RunConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.ShutdownConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.SSHConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.ToolsConfig.Prepare(&b.config.ctx)...)
|
||||
errs = packer.MultiErrorAppend(errs, b.config.VMXConfig.Prepare(&b.config.ctx)...)
|
||||
warnings := make([]string, 0)
|
||||
|
||||
if b.config.DiskName == "" {
|
||||
|
|
@ -137,59 +142,6 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
|||
b.config.RemotePort = 22
|
||||
}
|
||||
|
||||
// Errors
|
||||
templates := map[string]*string{
|
||||
"disk_name": &b.config.DiskName,
|
||||
"guest_os_type": &b.config.GuestOSType,
|
||||
"iso_checksum": &b.config.ISOChecksum,
|
||||
"iso_checksum_type": &b.config.ISOChecksumType,
|
||||
"iso_url": &b.config.RawSingleISOUrl,
|
||||
"vm_name": &b.config.VMName,
|
||||
"vmx_template_path": &b.config.VMXTemplatePath,
|
||||
"remote_type": &b.config.RemoteType,
|
||||
"remote_host": &b.config.RemoteHost,
|
||||
"remote_datastore": &b.config.RemoteDatastore,
|
||||
"remote_cache_datastore": &b.config.RemoteCacheDatastore,
|
||||
"remote_cache_directory": &b.config.RemoteCacheDirectory,
|
||||
"remote_user": &b.config.RemoteUser,
|
||||
"remote_password": &b.config.RemotePassword,
|
||||
}
|
||||
|
||||
for n, ptr := range templates {
|
||||
var err error
|
||||
*ptr, err = b.config.tpl.Process(*ptr, nil)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Error processing %s: %s", n, err))
|
||||
}
|
||||
}
|
||||
|
||||
for i, url := range b.config.ISOUrls {
|
||||
var err error
|
||||
b.config.ISOUrls[i], err = b.config.tpl.Process(url, nil)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Error processing iso_urls[%d]: %s", i, err))
|
||||
}
|
||||
}
|
||||
|
||||
for i, command := range b.config.BootCommand {
|
||||
if err := b.config.tpl.Validate(command); err != nil {
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
fmt.Errorf("Error processing boot_command[%d]: %s", i, err))
|
||||
}
|
||||
}
|
||||
|
||||
for i, file := range b.config.FloppyFiles {
|
||||
var err error
|
||||
b.config.FloppyFiles[i], err = b.config.tpl.Process(file, nil)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
fmt.Errorf("Error processing floppy_files[%d]: %s",
|
||||
i, err))
|
||||
}
|
||||
}
|
||||
|
||||
if b.config.ISOChecksumType == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("The iso_checksum_type must be specified."))
|
||||
|
|
@ -343,7 +295,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
&vmwcommon.StepTypeBootCommand{
|
||||
BootCommand: b.config.BootCommand,
|
||||
VMName: b.config.VMName,
|
||||
Tpl: b.config.tpl,
|
||||
Ctx: b.config.ctx,
|
||||
},
|
||||
&common.StepConnectSSH{
|
||||
SSHAddress: driver.SSHAddress,
|
||||
|
|
@ -355,7 +307,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
RemoteType: b.config.RemoteType,
|
||||
ToolsUploadFlavor: b.config.ToolsUploadFlavor,
|
||||
ToolsUploadPath: b.config.ToolsUploadPath,
|
||||
Tpl: b.config.tpl,
|
||||
Ctx: b.config.ctx,
|
||||
},
|
||||
&common.StepProvision{},
|
||||
&vmwcommon.StepShutdown{
|
||||
|
|
@ -369,7 +321,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
|||
},
|
||||
&vmwcommon.StepCleanVMX{},
|
||||
&StepUploadVMX{
|
||||
RemoteType: b.config.RemoteType,
|
||||
RemoteType: b.config.RemoteType,
|
||||
},
|
||||
&vmwcommon.StepCompactDisk{
|
||||
Skip: b.config.SkipCompaction,
|
||||
|
|
@ -440,5 +392,5 @@ func (b *Builder) validateVMXTemplatePath() error {
|
|||
return err
|
||||
}
|
||||
|
||||
return b.config.tpl.Validate(string(data))
|
||||
return interpolate.Validate(string(data), &b.config.ctx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// NewDriver returns a new driver implementation for this operating
|
||||
// system, or an error if the driver couldn't be initialized.
|
||||
func NewDriver(config *config) (vmwcommon.Driver, error) {
|
||||
func NewDriver(config *Config) (vmwcommon.Driver, error) {
|
||||
drivers := []vmwcommon.Driver{}
|
||||
|
||||
if config.RemoteType == "" {
|
||||
|
|
|
|||
|
|
@ -3,13 +3,9 @@ package iso
|
|||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
gossh "code.google.com/p/go.crypto/ssh"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/communicator/ssh"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
|
|
@ -17,6 +13,11 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
gossh "code.google.com/p/go.crypto/ssh"
|
||||
"github.com/mitchellh/multistep"
|
||||
"github.com/mitchellh/packer/communicator/ssh"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
)
|
||||
|
||||
// ESX5 driver talks to an ESXi5 hypervisor remotely over SSH to build
|
||||
|
|
@ -218,7 +219,7 @@ func (d *ESX5Driver) VNCAddress(portMin, portMax uint) (string, uint, error) {
|
|||
}
|
||||
|
||||
func (d *ESX5Driver) SSHAddress(state multistep.StateBag) (string, error) {
|
||||
config := state.Get("config").(*config)
|
||||
config := state.Get("config").(*Config)
|
||||
|
||||
if address, ok := state.GetOk("vm_address"); ok {
|
||||
return address.(string), nil
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import (
|
|||
type stepCreateDisk struct{}
|
||||
|
||||
func (stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*config)
|
||||
config := state.Get("config").(*Config)
|
||||
driver := state.Get("driver").(vmwcommon.Driver)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,12 +2,14 @@ package iso
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/multistep"
|
||||
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/mitchellh/multistep"
|
||||
vmwcommon "github.com/mitchellh/packer/builder/vmware/common"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"github.com/mitchellh/packer/template/interpolate"
|
||||
)
|
||||
|
||||
type vmxTemplateData struct {
|
||||
|
|
@ -32,13 +34,14 @@ type stepCreateVMX struct {
|
|||
}
|
||||
|
||||
func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(*config)
|
||||
config := state.Get("config").(*Config)
|
||||
isoPath := state.Get("iso_path").(string)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Building and writing VMX file")
|
||||
|
||||
tplData := &vmxTemplateData{
|
||||
ctx := config.ctx
|
||||
ctx.Data = &vmxTemplateData{
|
||||
Name: config.VMName,
|
||||
GuestOS: config.GuestOSType,
|
||||
DiskName: config.DiskName,
|
||||
|
|
@ -68,7 +71,7 @@ func (s *stepCreateVMX) Run(state multistep.StateBag) multistep.StepAction {
|
|||
vmxTemplate = string(rawBytes)
|
||||
}
|
||||
|
||||
vmxContents, err := config.tpl.Process(vmxTemplate, tplData)
|
||||
vmxContents, err := interpolate.Render(vmxTemplate, &ctx)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error procesing VMX template: %s", err)
|
||||
state.Put("error", err)
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ func (s *stepRemoteUpload) Run(state multistep.StateBag) multistep.StepAction {
|
|||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
config := state.Get("config").(*config)
|
||||
config := state.Get("config").(*Config)
|
||||
checksum := config.ISOChecksum
|
||||
checksumType := config.ISOChecksumType
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,11 @@ func Render(v string, ctx *Context) (string, error) {
|
|||
return (&I{Value: v}).Render(ctx)
|
||||
}
|
||||
|
||||
// Validate is shorthand for constructing an I and calling Validate.
|
||||
func Validate(v string, ctx *Context) error {
|
||||
return (&I{Value: v}).Validate(ctx)
|
||||
}
|
||||
|
||||
// I stands for "interpolation" and is the main interpolation struct
|
||||
// in order to render values.
|
||||
type I struct {
|
||||
|
|
@ -52,6 +57,12 @@ func (i *I) Render(ctx *Context) (string, error) {
|
|||
return result.String(), nil
|
||||
}
|
||||
|
||||
// Validate validates that the template is syntactically valid.
|
||||
func (i *I) Validate(ctx *Context) error {
|
||||
_, err := i.template(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (i *I) template(ctx *Context) (*template.Template, error) {
|
||||
return template.New("root").Funcs(Funcs(ctx)).Parse(i.Value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ func RenderMap(v interface{}, ctx *Context, f *RenderFilter) (map[string]interfa
|
|||
|
||||
// Now go through each value and render it
|
||||
for k, raw := range m {
|
||||
// Always validate every field
|
||||
if err := ValidateInterface(raw, ctx); err != nil {
|
||||
return nil, fmt.Errorf("invalid '%s': %s", k, err)
|
||||
}
|
||||
|
||||
if !f.include(k) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -70,6 +75,24 @@ func RenderInterface(v interface{}, ctx *Context) (interface{}, error) {
|
|||
return v, nil
|
||||
}
|
||||
|
||||
// ValidateInterface renders any value and returns the resulting value.
|
||||
func ValidateInterface(v interface{}, ctx *Context) error {
|
||||
f := func(v string) (string, error) {
|
||||
return v, Validate(v, ctx)
|
||||
}
|
||||
|
||||
walker := &renderWalker{
|
||||
F: f,
|
||||
Replace: false,
|
||||
}
|
||||
err := reflectwalk.Walk(v, walker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Include checks whether a key should be included.
|
||||
func (f *RenderFilter) include(k string) bool {
|
||||
if f == nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue