func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error { if c.SSHPort == 0 { c.SSHPort = 22 } if c.RawSSHWaitTimeout == "" { c.RawSSHWaitTimeout = "20m" } 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)) } else if _, err := commonssh.FileSigner(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } } if c.SSHUser == "" { errs = append(errs, errors.New("An ssh_username must be specified.")) } var err error c.SSHWaitTimeout, err = time.ParseDuration(c.RawSSHWaitTimeout) if err != nil { errs = append(errs, fmt.Errorf("Failed parsing ssh_wait_timeout: %s", err)) } return errs }
func (d *ESX5Driver) connect() error { address := fmt.Sprintf("%s:%d", d.Host, d.Port) auth := []gossh.AuthMethod{ gossh.Password(d.Password), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(d.Password)), } if d.PrivateKey != "" { signer, err := commonssh.FileSigner(d.PrivateKey) if err != nil { return err } auth = append(auth, gossh.PublicKeys(signer)) } sshConfig := &ssh.Config{ Connection: ssh.ConnectFunc("tcp", address), SSHConfig: &gossh.ClientConfig{ User: d.Username, Auth: auth, }, } comm, err := ssh.New(address, sshConfig) if err != nil { return err } d.comm = comm return nil }
func (c *SSHConfig) Prepare(t *packer.ConfigTemplate) []error { if c.SSHHostPortMin == 0 { c.SSHHostPortMin = 2222 } if c.SSHHostPortMax == 0 { c.SSHHostPortMax = 4444 } if c.SSHPort == 0 { c.SSHPort = 22 } if c.RawSSHWaitTimeout == "" { c.RawSSHWaitTimeout = "20m" } templates := map[string]*string{ "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)) } } if c.SSHKeyPath != "" { if _, err := os.Stat(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } else if _, err := commonssh.FileSigner(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } } if c.SSHHostPortMin > c.SSHHostPortMax { errs = append(errs, errors.New("ssh_host_port_min must be less than ssh_host_port_max")) } if c.SSHUser == "" { errs = append(errs, errors.New("An ssh_username must be specified.")) } var err error c.SSHWaitTimeout, err = time.ParseDuration(c.RawSSHWaitTimeout) if err != nil { errs = append(errs, fmt.Errorf("Failed parsing ssh_wait_timeout: %s", err)) } return errs }
func SSHConfig(state multistep.StateBag) (*gossh.ClientConfig, error) { config := state.Get("commonconfig").(CommonConfig) auth := []gossh.AuthMethod{ gossh.Password(config.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHPassword)), } if config.SSHKeyPath != "" { signer, err := commonssh.FileSigner(config.SSHKeyPath) if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.SSHUser, Auth: auth, }, nil }
func sshBastionConfig(config *Config) (*gossh.ClientConfig, error) { auth := make([]gossh.AuthMethod, 0, 2) if config.SSHBastionPassword != "" { auth = append(auth, gossh.Password(config.SSHBastionPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.SSHBastionPassword))) } if config.SSHBastionPrivateKey != "" { signer, err := commonssh.FileSigner(config.SSHBastionPrivateKey) if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.SSHBastionUsername, Auth: auth, }, nil }
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*gossh.ClientConfig, error) { return func(state multistep.StateBag) (*gossh.ClientConfig, error) { auth := []gossh.AuthMethod{ gossh.Password(config.Comm.SSHPassword), gossh.KeyboardInteractive( ssh.PasswordKeyboardInteractive(config.Comm.SSHPassword)), } if config.SSHKeyPath != "" { signer, err := commonssh.FileSigner(config.Comm.SSHPrivateKey) if err != nil { return nil, err } auth = append(auth, gossh.PublicKeys(signer)) } return &gossh.ClientConfig{ User: config.Comm.SSHUsername, Auth: auth, }, nil } }
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { err := config.Decode(&b.config, &config.DecodeOpts{ Interpolate: true, InterpolateFilter: &interpolate.RenderFilter{ Exclude: []string{ "boot_command", "qemuargs", }, }, }, raws...) if err != nil { return nil, err } var errs *packer.MultiError warnings := make([]string, 0) if b.config.DiskSize == 0 { b.config.DiskSize = 40000 } if b.config.DiskCache == "" { b.config.DiskCache = "writeback" } if b.config.DiskDiscard == "" { b.config.DiskDiscard = "ignore" } if b.config.Accelerator == "" { b.config.Accelerator = "kvm" } if b.config.HTTPPortMin == 0 { b.config.HTTPPortMin = 8000 } if b.config.HTTPPortMax == 0 { b.config.HTTPPortMax = 9000 } if b.config.MachineType == "" { b.config.MachineType = "pc" } if b.config.OutputDir == "" { b.config.OutputDir = fmt.Sprintf("output-%s", b.config.PackerBuildName) } if b.config.QemuBinary == "" { b.config.QemuBinary = "qemu-system-x86_64" } if b.config.RawBootWait == "" { b.config.RawBootWait = "10s" } if b.config.SSHHostPortMin == 0 { b.config.SSHHostPortMin = 2222 } if b.config.SSHHostPortMax == 0 { b.config.SSHHostPortMax = 4444 } if b.config.SSHPort == 0 { b.config.SSHPort = 22 } if b.config.VNCPortMin == 0 { b.config.VNCPortMin = 5900 } if b.config.VNCPortMax == 0 { b.config.VNCPortMax = 6000 } if b.config.VMName == "" { b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName) } if b.config.Format == "" { b.config.Format = "qcow2" } if b.config.FloppyFiles == nil { b.config.FloppyFiles = make([]string, 0) } if b.config.NetDevice == "" { b.config.NetDevice = "virtio-net" } if b.config.DiskInterface == "" { b.config.DiskInterface = "virtio" } if !(b.config.Format == "qcow2" || b.config.Format == "raw") { errs = packer.MultiErrorAppend( errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed")) } if _, ok := accels[b.config.Accelerator]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed")) } if _, ok := netDevice[b.config.NetDevice]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("unrecognized network device type")) } if _, ok := diskInterface[b.config.DiskInterface]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("unrecognized disk interface type")) } if _, ok := diskCache[b.config.DiskCache]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("unrecognized disk cache type")) } if _, ok := diskDiscard[b.config.DiskDiscard]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("unrecognized disk cache type")) } if b.config.HTTPPortMin > b.config.HTTPPortMax { errs = packer.MultiErrorAppend( errs, errors.New("http_port_min must be less than http_port_max")) } if b.config.ISOChecksumType == "" { errs = packer.MultiErrorAppend( errs, errors.New("The iso_checksum_type must be specified.")) } else { b.config.ISOChecksumType = strings.ToLower(b.config.ISOChecksumType) if b.config.ISOChecksumType != "none" { if b.config.ISOChecksum == "" { errs = packer.MultiErrorAppend( errs, errors.New("Due to large file sizes, an iso_checksum is required")) } else { b.config.ISOChecksum = strings.ToLower(b.config.ISOChecksum) } if h := common.HashForType(b.config.ISOChecksumType); h == nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Unsupported checksum type: %s", b.config.ISOChecksumType)) } } } if b.config.RawSingleISOUrl == "" && len(b.config.ISOUrls) == 0 { errs = packer.MultiErrorAppend( errs, errors.New("One of iso_url or iso_urls must be specified.")) } else if b.config.RawSingleISOUrl != "" && len(b.config.ISOUrls) > 0 { errs = packer.MultiErrorAppend( errs, errors.New("Only one of iso_url or iso_urls may be specified.")) } else if b.config.RawSingleISOUrl != "" { b.config.ISOUrls = []string{b.config.RawSingleISOUrl} } for i, url := range b.config.ISOUrls { b.config.ISOUrls[i], err = common.DownloadableURL(url) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed to parse iso_url %d: %s", i+1, err)) } } if !b.config.PackerForce { if _, err := os.Stat(b.config.OutputDir); err == nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Output directory '%s' already exists. It must not exist.", b.config.OutputDir)) } } b.config.bootWait, err = time.ParseDuration(b.config.RawBootWait) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) } if b.config.RawShutdownTimeout == "" { b.config.RawShutdownTimeout = "5m" } if b.config.RawSSHWaitTimeout == "" { b.config.RawSSHWaitTimeout = "20m" } b.config.shutdownTimeout, err = time.ParseDuration(b.config.RawShutdownTimeout) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err)) } if b.config.SSHKeyPath != "" { if _, err := os.Stat(b.config.SSHKeyPath); err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } else if _, err := commonssh.FileSigner(b.config.SSHKeyPath); err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } } if b.config.SSHHostPortMin > b.config.SSHHostPortMax { errs = packer.MultiErrorAppend( errs, errors.New("ssh_host_port_min must be less than ssh_host_port_max")) } if b.config.SSHUser == "" { errs = packer.MultiErrorAppend( errs, errors.New("An ssh_username must be specified.")) } b.config.sshWaitTimeout, err = time.ParseDuration(b.config.RawSSHWaitTimeout) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed parsing ssh_wait_timeout: %s", err)) } if b.config.VNCPortMin > b.config.VNCPortMax { errs = packer.MultiErrorAppend( errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) } if b.config.QemuArgs == nil { b.config.QemuArgs = make([][]string, 0) } if b.config.ISOChecksumType == "none" { warnings = append(warnings, "A checksum type of 'none' was specified. Since ISO files are so big,\n"+ "a checksum is highly recommended.") } if errs != nil && len(errs.Errors) > 0 { return warnings, errs } return warnings, nil }
func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { md, err := common.DecodeConfig(&b.config, 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) if b.config.DiskSize == 0 { b.config.DiskSize = 40000 } if b.config.Accelerator == "" { b.config.Accelerator = "kvm" } if b.config.HTTPPortMin == 0 { b.config.HTTPPortMin = 8000 } if b.config.HTTPPortMax == 0 { b.config.HTTPPortMax = 9000 } if b.config.MachineType == "" { b.config.MachineType = "pc-1.0" } if b.config.OutputDir == "" { b.config.OutputDir = fmt.Sprintf("output-%s", b.config.PackerBuildName) } if b.config.QemuBinary == "" { b.config.QemuBinary = "qemu-system-x86_64" } if b.config.RawBootWait == "" { b.config.RawBootWait = "10s" } if b.config.SSHHostPortMin == 0 { b.config.SSHHostPortMin = 2222 } if b.config.SSHHostPortMax == 0 { b.config.SSHHostPortMax = 4444 } if b.config.SSHPort == 0 { b.config.SSHPort = 22 } if b.config.VNCPortMin == 0 { b.config.VNCPortMin = 5900 } if b.config.VNCPortMax == 0 { b.config.VNCPortMax = 6000 } for i, args := range b.config.QemuArgs { for j, arg := range args { if err := b.config.tpl.Validate(arg); err != nil { errs = packer.MultiErrorAppend(errs, fmt.Errorf("Error processing qemu-system_x86-64[%d][%d]: %s", i, j, err)) } } } if b.config.VMName == "" { b.config.VMName = fmt.Sprintf("packer-%s", b.config.PackerBuildName) } if b.config.Format == "" { b.config.Format = "qcow2" } if b.config.FloppyFiles == nil { b.config.FloppyFiles = make([]string, 0) } if b.config.NetDevice == "" { b.config.NetDevice = "virtio-net" } if b.config.DiskInterface == "" { b.config.DiskInterface = "virtio" } // Errors templates := map[string]*string{ "http_directory": &b.config.HTTPDir, "iso_checksum": &b.config.ISOChecksum, "iso_checksum_type": &b.config.ISOChecksumType, "iso_url": &b.config.RawSingleISOUrl, "output_directory": &b.config.OutputDir, "shutdown_command": &b.config.ShutdownCommand, "ssh_key_path": &b.config.SSHKeyPath, "ssh_password": &b.config.SSHPassword, "ssh_username": &b.config.SSHUser, "vm_name": &b.config.VMName, "format": &b.config.Format, "boot_wait": &b.config.RawBootWait, "shutdown_timeout": &b.config.RawShutdownTimeout, "ssh_wait_timeout": &b.config.RawSSHWaitTimeout, "accelerator": &b.config.Accelerator, "machine_type": &b.config.MachineType, "net_device": &b.config.NetDevice, "disk_interface": &b.config.DiskInterface, } 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.Format == "qcow2" || b.config.Format == "raw") { errs = packer.MultiErrorAppend( errs, errors.New("invalid format, only 'qcow2' or 'raw' are allowed")) } if _, ok := accels[b.config.Accelerator]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("invalid accelerator, only 'kvm', 'tcg', 'xen', or 'none' are allowed")) } if _, ok := netDevice[b.config.NetDevice]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("unrecognized network device type")) } if _, ok := diskInterface[b.config.DiskInterface]; !ok { errs = packer.MultiErrorAppend( errs, errors.New("unrecognized disk interface type")) } if b.config.HTTPPortMin > b.config.HTTPPortMax { errs = packer.MultiErrorAppend( errs, errors.New("http_port_min must be less than http_port_max")) } if b.config.ISOChecksum == "" { errs = packer.MultiErrorAppend( errs, errors.New("Due to large file sizes, an iso_checksum is required")) } else { b.config.ISOChecksum = strings.ToLower(b.config.ISOChecksum) } if b.config.ISOChecksumType == "" { errs = packer.MultiErrorAppend( errs, errors.New("The iso_checksum_type must be specified.")) } else { b.config.ISOChecksumType = strings.ToLower(b.config.ISOChecksumType) if h := common.HashForType(b.config.ISOChecksumType); h == nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Unsupported checksum type: %s", b.config.ISOChecksumType)) } } if b.config.RawSingleISOUrl == "" && len(b.config.ISOUrls) == 0 { errs = packer.MultiErrorAppend( errs, errors.New("One of iso_url or iso_urls must be specified.")) } else if b.config.RawSingleISOUrl != "" && len(b.config.ISOUrls) > 0 { errs = packer.MultiErrorAppend( errs, errors.New("Only one of iso_url or iso_urls may be specified.")) } else if b.config.RawSingleISOUrl != "" { b.config.ISOUrls = []string{b.config.RawSingleISOUrl} } for i, url := range b.config.ISOUrls { b.config.ISOUrls[i], err = common.DownloadableURL(url) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed to parse iso_url %d: %s", i+1, err)) } } if !b.config.PackerForce { if _, err := os.Stat(b.config.OutputDir); err == nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Output directory '%s' already exists. It must not exist.", b.config.OutputDir)) } } b.config.bootWait, err = time.ParseDuration(b.config.RawBootWait) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed parsing boot_wait: %s", err)) } if b.config.RawShutdownTimeout == "" { b.config.RawShutdownTimeout = "5m" } if b.config.RawSSHWaitTimeout == "" { b.config.RawSSHWaitTimeout = "20m" } b.config.shutdownTimeout, err = time.ParseDuration(b.config.RawShutdownTimeout) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed parsing shutdown_timeout: %s", err)) } if b.config.SSHKeyPath != "" { if _, err := os.Stat(b.config.SSHKeyPath); err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } else if _, err := commonssh.FileSigner(b.config.SSHKeyPath); err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } } if b.config.SSHHostPortMin > b.config.SSHHostPortMax { errs = packer.MultiErrorAppend( errs, errors.New("ssh_host_port_min must be less than ssh_host_port_max")) } if b.config.SSHUser == "" { errs = packer.MultiErrorAppend( errs, errors.New("An ssh_username must be specified.")) } b.config.sshWaitTimeout, err = time.ParseDuration(b.config.RawSSHWaitTimeout) if err != nil { errs = packer.MultiErrorAppend( errs, fmt.Errorf("Failed parsing ssh_wait_timeout: %s", err)) } if b.config.VNCPortMin > b.config.VNCPortMax { errs = packer.MultiErrorAppend( errs, fmt.Errorf("vnc_port_min must be less than vnc_port_max")) } if b.config.QemuArgs == nil { b.config.QemuArgs = make([][]string, 0) } if errs != nil && len(errs.Errors) > 0 { return nil, errs } return nil, nil }
func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error { var err error var errs []error // Set default values if c.HostPortMin == 0 { c.HostPortMin = 5900 } if c.HostPortMax == 0 { c.HostPortMax = 6000 } if c.RawBootWait == "" { c.RawBootWait = "5s" } if c.ToolsIsoName == "" { c.ToolsIsoName = "xs-tools.iso" } if c.HTTPPortMin == 0 { c.HTTPPortMin = 8000 } if c.HTTPPortMax == 0 { c.HTTPPortMax = 9000 } if c.RawSSHWaitTimeout == "" { c.RawSSHWaitTimeout = "200m" } if c.FloppyFiles == nil { c.FloppyFiles = make([]string, 0) } /* if c.SSHHostPortMin == 0 { c.SSHHostPortMin = 2222 } if c.SSHHostPortMax == 0 { c.SSHHostPortMax = 4444 } */ if c.SSHPort == 0 { c.SSHPort = 22 } if c.RawSSHWaitTimeout == "" { c.RawSSHWaitTimeout = "20m" } if c.OutputDir == "" { c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName) } if c.VMName == "" { c.VMName = fmt.Sprintf("packer-%s-{{timestamp}}", pc.PackerBuildName) } if c.Format == "" { c.Format = "xva" } if c.KeepVM == "" { c.KeepVM = "never" } if c.IPGetter == "" { c.IPGetter = "auto" } // Validation if c.Username == "" { errs = append(errs, errors.New("remote_username must be specified.")) } if c.Password == "" { errs = append(errs, errors.New("remote_password must be specified.")) } if c.HostIp == "" { errs = append(errs, errors.New("remote_host must be specified.")) } if c.HostPortMin > c.HostPortMax { errs = append(errs, errors.New("the host min port must be less than the max")) } if c.HTTPPortMin > c.HTTPPortMax { errs = append(errs, errors.New("the HTTP min port must be less than the max")) } c.BootWait, err = time.ParseDuration(c.RawBootWait) if err != nil { errs = append(errs, fmt.Errorf("Failed to parse boot_wait: %s", err)) } if c.SSHKeyPath != "" { if _, err := os.Stat(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } else if _, err := commonssh.FileSigner(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } } /* if c.SSHHostPortMin > c.SSHHostPortMax { errs = append(errs, errors.New("ssh_host_port_min must be less than ssh_host_port_max")) } */ if c.SSHUser == "" { errs = append(errs, errors.New("An ssh_username must be specified.")) } c.SSHWaitTimeout, err = time.ParseDuration(c.RawSSHWaitTimeout) if err != nil { errs = append(errs, fmt.Errorf("Failed to parse ssh_wait_timeout: %s", err)) } switch c.Format { case "template", "xva", "vdi_raw", "vdi_vhd", "none": default: errs = append(errs, errors.New("format must be one of 'template', 'xva', 'vdi_raw', 'vdi_vhd', 'none'")) } switch c.KeepVM { case "always", "never", "on_success": default: errs = append(errs, errors.New("keep_vm must be one of 'always', 'never', 'on_success'")) } switch c.IPGetter { case "auto", "tools", "http": default: errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http'")) } return errs }
func (c *CommonConfig) Prepare(t *packer.ConfigTemplate, pc *common.PackerConfig) []error { var err error // Set default values if c.HostPortMin == 0 { c.HostPortMin = 5900 } if c.HostPortMax == 0 { c.HostPortMax = 6000 } if c.RawBootWait == "" { c.RawBootWait = "5s" } if c.ToolsIsoName == "" { c.ToolsIsoName = "xs-tools.iso" } if c.HTTPPortMin == 0 { c.HTTPPortMin = 8000 } if c.HTTPPortMax == 0 { c.HTTPPortMax = 9000 } if c.RawSSHWaitTimeout == "" { c.RawSSHWaitTimeout = "200m" } if c.FloppyFiles == nil { c.FloppyFiles = make([]string, 0) } /* if c.SSHHostPortMin == 0 { c.SSHHostPortMin = 2222 } if c.SSHHostPortMax == 0 { c.SSHHostPortMax = 4444 } */ if c.SSHPort == 0 { c.SSHPort = 22 } if c.RawSSHWaitTimeout == "" { c.RawSSHWaitTimeout = "20m" } if c.OutputDir == "" { c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName) } if c.VMName == "" { c.VMName = fmt.Sprintf("packer-%s-{{timestamp}}", pc.PackerBuildName) } if c.Format == "" { c.Format = "xva" } if c.KeepVM == "" { c.KeepVM = "never" } if c.IPGetter == "" { c.IPGetter = "auto" } // Template substitution templates := map[string]*string{ "remote_username": &c.Username, "remote_password": &c.Password, "remote_host": &c.HostIp, "vm_name": &c.VMName, "vm_description": &c.VMDescription, "sr_name": &c.SrName, "shutdown_command": &c.ShutdownCommand, "boot_wait": &c.RawBootWait, "tools_iso_name": &c.ToolsIsoName, "http_directory": &c.HTTPDir, "ssh_key_path": &c.SSHKeyPath, "ssh_password": &c.SSHPassword, "ssh_username": &c.SSHUser, "ssh_wait_timeout": &c.RawSSHWaitTimeout, "output_directory": &c.OutputDir, "format": &c.Format, "keep_vm": &c.KeepVM, "ip_getter": &c.IPGetter, } for i := range c.FloppyFiles { templates[fmt.Sprintf("floppy_files[%d]", i)] = &c.FloppyFiles[i] } 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)) } } // Validation if c.Username == "" { errs = append(errs, errors.New("remote_username must be specified.")) } if c.Password == "" { errs = append(errs, errors.New("remote_password must be specified.")) } if c.HostIp == "" { errs = append(errs, errors.New("remote_host must be specified.")) } if c.HostPortMin > c.HostPortMax { errs = append(errs, errors.New("the host min port must be less than the max")) } if c.HTTPPortMin > c.HTTPPortMax { errs = append(errs, errors.New("the HTTP min port must be less than the max")) } c.BootWait, err = time.ParseDuration(c.RawBootWait) if err != nil { errs = append(errs, fmt.Errorf("Failed to parse boot_wait: %s", err)) } for i, command := range c.BootCommand { if err := t.Validate(command); err != nil { errs = append(errs, fmt.Errorf("Error processing boot_command[%d]: %s", i, err)) } } if c.SSHKeyPath != "" { if _, err := os.Stat(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } else if _, err := commonssh.FileSigner(c.SSHKeyPath); err != nil { errs = append(errs, fmt.Errorf("ssh_key_path is invalid: %s", err)) } } /* if c.SSHHostPortMin > c.SSHHostPortMax { errs = append(errs, errors.New("ssh_host_port_min must be less than ssh_host_port_max")) } */ if c.SSHUser == "" { errs = append(errs, errors.New("An ssh_username must be specified.")) } c.SSHWaitTimeout, err = time.ParseDuration(c.RawSSHWaitTimeout) if err != nil { errs = append(errs, fmt.Errorf("Failed to parse ssh_wait_timeout: %s", err)) } switch c.Format { case "xva", "vdi_raw", "vdi_vhd", "none": default: errs = append(errs, errors.New("format must be one of 'xva', 'vdi_raw', 'vdi_vhd', 'none'")) } switch c.KeepVM { case "always", "never", "on_success": default: errs = append(errs, errors.New("keep_vm must be one of 'always', 'never', 'on_success'")) } switch c.IPGetter { case "auto", "tools", "http": default: errs = append(errs, errors.New("ip_getter must be one of 'auto', 'tools', 'http'")) } return errs }