Merge pull request #4292 from legal90/prl-fix-style

Parallels: Fix style warnings
This commit is contained in:
Rickard von Essen 2016-12-17 19:50:23 +01:00 committed by GitHub
commit bbe3f26ed2
46 changed files with 277 additions and 177 deletions

View File

@ -2,13 +2,14 @@ package common
import (
"fmt"
"github.com/mitchellh/packer/packer"
"os"
"path/filepath"
"regexp"
"github.com/mitchellh/packer/packer"
)
// This is the common builder ID to all of these artifacts.
// BuilderId is the common builder ID to all of these artifacts.
const BuilderId = "packer.parallels"
// These are the extensions of files and directories that are unnecessary for the function

View File

@ -25,7 +25,7 @@ func TestNewArtifact(t *testing.T) {
t.Fatalf("err: %s", err)
}
if err := os.Mkdir(filepath.Join(td, "b"), 0755); err != nil {
if err = os.Mkdir(filepath.Join(td, "b"), 0755); err != nil {
t.Fatalf("err: %s", err)
}

View File

@ -9,7 +9,7 @@ import (
"strings"
)
// A driver is able to talk to Parallels and perform certain
// Driver is the interface that talks to Parallels and performs certain
// operations with it. Some of the operations on here may seem overly
// specific, but they were built specifically in mind to handle features
// of the Parallels builder for Packer, and to abstract differences in
@ -20,7 +20,7 @@ type Driver interface {
CompactDisk(string) error
// Adds new CD/DVD drive to the VM and returns name of this device
DeviceAddCdRom(string, string) (string, error)
DeviceAddCDROM(string, string) (string, error)
// Get path to the first virtual disk image
DiskPath(string) (string, error)
@ -38,7 +38,7 @@ type Driver interface {
Prlctl(...string) error
// Get the path to the Parallels Tools ISO for the given flavor.
ToolsIsoPath(string) (string, error)
ToolsISOPath(string) (string, error)
// Verify checks to make sure that this driver should function
// properly. If there is any indication the driver can't function,
@ -55,18 +55,20 @@ type Driver interface {
SetDefaultConfiguration(string) error
// Finds the MAC address of the NIC nic0
Mac(string) (string, error)
MAC(string) (string, error)
// Finds the IP address of a VM connected that uses DHCP by its MAC address
IpAddress(string) (string, error)
IPAddress(string) (string, error)
}
// NewDriver returns a new driver implementation for this version of Parallels
// Desktop, or an error if the driver couldn't be initialized.
func NewDriver() (Driver, error) {
var drivers map[string]Driver
var prlctlPath string
var prlsrvctlPath string
var supportedVersions []string
dhcp_lease_file := "/Library/Preferences/Parallels/parallels_dhcp_leases"
DHCPLeaseFile := "/Library/Preferences/Parallels/parallels_dhcp_leases"
if runtime.GOOS != "darwin" {
return nil, fmt.Errorf(
@ -98,20 +100,20 @@ func NewDriver() (Driver, error) {
Parallels9Driver: Parallels9Driver{
PrlctlPath: prlctlPath,
PrlsrvctlPath: prlsrvctlPath,
dhcp_lease_file: dhcp_lease_file,
dhcpLeaseFile: DHCPLeaseFile,
},
},
"10": &Parallels10Driver{
Parallels9Driver: Parallels9Driver{
PrlctlPath: prlctlPath,
PrlsrvctlPath: prlsrvctlPath,
dhcp_lease_file: dhcp_lease_file,
dhcpLeaseFile: DHCPLeaseFile,
},
},
"9": &Parallels9Driver{
PrlctlPath: prlctlPath,
PrlsrvctlPath: prlsrvctlPath,
dhcp_lease_file: dhcp_lease_file,
dhcpLeaseFile: DHCPLeaseFile,
},
}

View File

@ -1,11 +1,11 @@
package common
// Parallels10Driver are inherited from Parallels9Driver.
// Used for Parallels v 10 & 11
type Parallels10Driver struct {
Parallels9Driver
}
// SetDefaultConfiguration applies pre-defined default settings to the VM config.
func (d *Parallels10Driver) SetDefaultConfiguration(vmName string) error {
commands := make([][]string, 12)
commands[0] = []string{"set", vmName, "--cpus", "1"}

View File

@ -12,6 +12,7 @@ type Parallels11Driver struct {
Parallels9Driver
}
// Verify raises an error if the builder could not be used on that host machine.
func (d *Parallels11Driver) Verify() error {
stdout, err := exec.Command(d.PrlsrvctlPath, "info", "--license").Output()
@ -24,18 +25,18 @@ func (d *Parallels11Driver) Verify() error {
if matches == nil {
return fmt.Errorf(
"Could not determine your Parallels Desktop edition using: %s info --license", d.PrlsrvctlPath)
} else {
}
switch matches[1] {
case "pro", "business":
break
default:
return fmt.Errorf("Packer can be used only with Parallels Desktop 11 Pro or Business edition. You use: %s edition", matches[1])
}
}
return nil
}
// SetDefaultConfiguration applies pre-defined default settings to the VM config.
func (d *Parallels11Driver) SetDefaultConfiguration(vmName string) error {
commands := make([][]string, 12)
commands[0] = []string{"set", vmName, "--cpus", "1"}

View File

@ -16,6 +16,7 @@ import (
"gopkg.in/xmlpath.v2"
)
// Parallels9Driver is a base type for Parallels builders.
type Parallels9Driver struct {
// This is the path to the "prlctl" application.
PrlctlPath string
@ -24,48 +25,51 @@ type Parallels9Driver struct {
PrlsrvctlPath string
// The path to the parallels_dhcp_leases file
dhcp_lease_file string
dhcpLeaseFile string
}
func (d *Parallels9Driver) Import(name, srcPath, dstDir string, reassignMac bool) error {
// Import creates a clone of the source VM and reassigns the MAC address if needed.
func (d *Parallels9Driver) Import(name, srcPath, dstDir string, reassignMAC bool) error {
err := d.Prlctl("register", srcPath, "--preserve-uuid")
if err != nil {
return err
}
srcId, err := getVmId(srcPath)
srcID, err := getVMID(srcPath)
if err != nil {
return err
}
srcMac := "auto"
if !reassignMac {
srcMac, err = getFirtsMacAddress(srcPath)
srcMAC := "auto"
if !reassignMAC {
srcMAC, err = getFirtsMACAddress(srcPath)
if err != nil {
return err
}
}
err = d.Prlctl("clone", srcId, "--name", name, "--dst", dstDir)
err = d.Prlctl("clone", srcID, "--name", name, "--dst", dstDir)
if err != nil {
return err
}
err = d.Prlctl("unregister", srcId)
err = d.Prlctl("unregister", srcID)
if err != nil {
return err
}
err = d.Prlctl("set", name, "--device-set", "net0", "--mac", srcMac)
err = d.Prlctl("set", name, "--device-set", "net0", "--mac", srcMAC)
if err != nil {
return err
}
return nil
}
func getVmId(path string) (string, error) {
func getVMID(path string) (string, error) {
return getConfigValueFromXpath(path, "/ParallelsVirtualMachine/Identification/VmUuid")
}
func getFirtsMacAddress(path string) (string, error) {
func getFirtsMACAddress(path string) (string, error) {
return getConfigValueFromXpath(path, "/ParallelsVirtualMachine/Hardware/NetworkAdapter[@id='0']/MAC")
}
@ -84,10 +88,10 @@ func getConfigValueFromXpath(path, xpath string) (string, error) {
}
// Finds an application bundle by identifier (for "darwin" platform only)
func getAppPath(bundleId string) (string, error) {
func getAppPath(bundleID string) (string, error) {
var stdout bytes.Buffer
cmd := exec.Command("mdfind", "kMDItemCFBundleIdentifier ==", bundleId)
cmd := exec.Command("mdfind", "kMDItemCFBundleIdentifier ==", bundleID)
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
return "", err
@ -108,6 +112,7 @@ func getAppPath(bundleId string) (string, error) {
return pathOutput, nil
}
// CompactDisk performs the compation of the specified virtual disk image.
func (d *Parallels9Driver) CompactDisk(diskPath string) error {
prlDiskToolPath, err := exec.LookPath("prl_disk_tool")
if err != nil {
@ -135,7 +140,8 @@ func (d *Parallels9Driver) CompactDisk(diskPath string) error {
return nil
}
func (d *Parallels9Driver) DeviceAddCdRom(name string, image string) (string, error) {
// DeviceAddCDROM adds a virtual CDROM device and attaches the specified image.
func (d *Parallels9Driver) DeviceAddCDROM(name string, image string) (string, error) {
command := []string{
"set", name,
"--device-add", "cdrom",
@ -154,27 +160,29 @@ func (d *Parallels9Driver) DeviceAddCdRom(name string, image string) (string, er
"Could not determine cdrom device name in the output:\n%s", string(out))
}
device_name := matches[1]
return device_name, nil
deviceName := matches[1]
return deviceName, nil
}
// DiskPath returns a full path to the first virtual disk drive.
func (d *Parallels9Driver) DiskPath(name string) (string, error) {
out, err := exec.Command(d.PrlctlPath, "list", "-i", name).Output()
if err != nil {
return "", err
}
hddRe := regexp.MustCompile("hdd0.* image='(.*)' type=*")
matches := hddRe.FindStringSubmatch(string(out))
HDDRe := regexp.MustCompile("hdd0.* image='(.*)' type=*")
matches := HDDRe.FindStringSubmatch(string(out))
if matches == nil {
return "", fmt.Errorf(
"Could not determine hdd image path in the output:\n%s", string(out))
}
hdd_path := matches[1]
return hdd_path, nil
HDDPath := matches[1]
return HDDPath, nil
}
// IsRunning determines whether the VM is running or not.
func (d *Parallels9Driver) IsRunning(name string) (bool, error) {
var stdout bytes.Buffer
@ -205,6 +213,7 @@ func (d *Parallels9Driver) IsRunning(name string) (bool, error) {
return false, nil
}
// Stop forcibly stops the VM.
func (d *Parallels9Driver) Stop(name string) error {
if err := d.Prlctl("stop", name); err != nil {
return err
@ -216,6 +225,7 @@ func (d *Parallels9Driver) Stop(name string) error {
return nil
}
// Prlctl executes the specified "prlctl" command.
func (d *Parallels9Driver) Prlctl(args ...string) error {
var stdout, stderr bytes.Buffer
@ -238,10 +248,12 @@ func (d *Parallels9Driver) Prlctl(args ...string) error {
return err
}
// Verify raises an error if the builder could not be used on that host machine.
func (d *Parallels9Driver) Verify() error {
return nil
}
// Version returns the version of Parallels Desktop installed on that host.
func (d *Parallels9Driver) Version() (string, error) {
out, err := exec.Command(d.PrlctlPath, "--version").Output()
if err != nil {
@ -260,6 +272,8 @@ func (d *Parallels9Driver) Version() (string, error) {
return version, nil
}
// SendKeyScanCodes sends the specified scancodes as key events to the VM.
// It is performed using "Prltype" script (refer to "prltype.go").
func (d *Parallels9Driver) SendKeyScanCodes(vmName string, codes ...string) error {
var stdout, stderr bytes.Buffer
@ -309,6 +323,7 @@ func prepend(head string, tail []string) []string {
return tmp
}
// SetDefaultConfiguration applies pre-defined default settings to the VM config.
func (d *Parallels9Driver) SetDefaultConfiguration(vmName string) error {
commands := make([][]string, 7)
commands[0] = []string{"set", vmName, "--cpus", "1"}
@ -328,7 +343,8 @@ func (d *Parallels9Driver) SetDefaultConfiguration(vmName string) error {
return nil
}
func (d *Parallels9Driver) Mac(vmName string) (string, error) {
// MAC returns the MAC address of the VM's first network interface.
func (d *Parallels9Driver) MAC(vmName string) (string, error) {
var stdout bytes.Buffer
cmd := exec.Command(d.PrlctlPath, "list", "-i", vmName)
@ -351,26 +367,26 @@ func (d *Parallels9Driver) Mac(vmName string) (string, error) {
return mac, nil
}
// Finds the IP address of a VM connected that uses DHCP by its MAC address
// IPAddress finds the IP address of a VM connected that uses DHCP by its MAC address
//
// Parses the file /Library/Preferences/Parallels/parallels_dhcp_leases
// file contain a list of DHCP leases given by Parallels Desktop
// Example line:
// 10.211.55.181="1418921112,1800,001c42f593fb,ff42f593fb000100011c25b9ff001c42f593fb"
// IP Address ="Lease expiry, Lease time, MAC, MAC or DUID"
func (d *Parallels9Driver) IpAddress(mac string) (string, error) {
func (d *Parallels9Driver) IPAddress(mac string) (string, error) {
if len(mac) != 12 {
return "", fmt.Errorf("Not a valid MAC address: %s. It should be exactly 12 digits.", mac)
}
leases, err := ioutil.ReadFile(d.dhcp_lease_file)
leases, err := ioutil.ReadFile(d.dhcpLeaseFile)
if err != nil {
return "", err
}
re := regexp.MustCompile("(.*)=\"(.*),(.*)," + strings.ToLower(mac) + ",.*\"")
mostRecentIp := ""
mostRecentIP := ""
mostRecentLease := uint64(0)
for _, l := range re.FindAllStringSubmatch(string(leases), -1) {
ip := l[1]
@ -378,20 +394,22 @@ func (d *Parallels9Driver) IpAddress(mac string) (string, error) {
leaseTime, _ := strconv.ParseUint(l[3], 10, 32)
log.Printf("Found lease: %s for MAC: %s, expiring at %d, leased for %d s.\n", ip, mac, expiry, leaseTime)
if mostRecentLease <= expiry-leaseTime {
mostRecentIp = ip
mostRecentIP = ip
mostRecentLease = expiry - leaseTime
}
}
if len(mostRecentIp) == 0 {
return "", fmt.Errorf("IP lease not found for MAC address %s in: %s\n", mac, d.dhcp_lease_file)
if len(mostRecentIP) == 0 {
return "", fmt.Errorf("IP lease not found for MAC address %s in: %s\n", mac, d.dhcpLeaseFile)
}
log.Printf("Found IP lease: %s for MAC address %s\n", mostRecentIp, mac)
return mostRecentIp, nil
log.Printf("Found IP lease: %s for MAC address %s\n", mostRecentIP, mac)
return mostRecentIP, nil
}
func (d *Parallels9Driver) ToolsIsoPath(k string) (string, error) {
// ToolsISOPath returns a full path to the Parallels Tools ISO for the specified guest
// OS type. The following OS types are supported: "win", "lin", "mac", "other".
func (d *Parallels9Driver) ToolsISOPath(k string) (string, error) {
appPath, err := getAppPath("com.parallels.desktop.console")
if err != nil {
return "", err

View File

@ -10,7 +10,7 @@ func TestParallels9Driver_impl(t *testing.T) {
var _ Driver = new(Parallels9Driver)
}
func TestIpAddress(t *testing.T) {
func TestIPAddress(t *testing.T) {
tf, err := ioutil.TempFile("", "packer")
if err != nil {
t.Fatalf("err: %s", err)
@ -18,11 +18,11 @@ func TestIpAddress(t *testing.T) {
defer os.Remove(tf.Name())
d := Parallels9Driver{
dhcp_lease_file: tf.Name(),
dhcpLeaseFile: tf.Name(),
}
// No lease should be found in an empty file
ip, err := d.IpAddress("123456789012")
ip, err := d.IPAddress("123456789012")
if err == nil {
t.Fatalf("Found IP: \"%v\". No IP should be found!\n", ip)
}
@ -35,7 +35,7 @@ func TestIpAddress(t *testing.T) {
10.211.55.254="1411712008,1800,001c42a51419,01001c42a51419"
`)
ioutil.WriteFile(tf.Name(), c, 0666)
ip, err = d.IpAddress("001C4235240c")
ip, err = d.IPAddress("001C4235240c")
if err != nil {
t.Fatalf("Error: %v\n", err)
}
@ -50,7 +50,7 @@ func TestIpAddress(t *testing.T) {
10.211.55.254="1411712008,1800,001c42a51419,01001c42a51419"
`)
ioutil.WriteFile(tf.Name(), c, 0666)
ip, err = d.IpAddress("001c4235240c")
ip, err = d.IPAddress("001c4235240c")
if err != nil {
t.Fatalf("Error: %v\n", err)
}

View File

@ -9,11 +9,11 @@ type DriverMock struct {
CompactDiskPath string
CompactDiskErr error
DeviceAddCdRomCalled bool
DeviceAddCdRomName string
DeviceAddCdRomImage string
DeviceAddCdRomResult string
DeviceAddCdRomErr error
DeviceAddCDROMCalled bool
DeviceAddCDROMName string
DeviceAddCDROMImage string
DeviceAddCDROMResult string
DeviceAddCDROMErr error
DiskPathCalled bool
DiskPathName string
@ -49,18 +49,18 @@ type DriverMock struct {
SetDefaultConfigurationCalled bool
SetDefaultConfigurationError error
ToolsIsoPathCalled bool
ToolsIsoPathFlavor string
ToolsIsoPathResult string
ToolsIsoPathErr error
ToolsISOPathCalled bool
ToolsISOPathFlavor string
ToolsISOPathResult string
ToolsISOPathErr error
MacName string
MacReturn string
MacError error
MACName string
MACReturn string
MACError error
IpAddressMac string
IpAddressReturn string
IpAddressError error
IPAddressMAC string
IPAddressReturn string
IPAddressError error
}
func (d *DriverMock) CompactDisk(path string) error {
@ -69,11 +69,11 @@ func (d *DriverMock) CompactDisk(path string) error {
return d.CompactDiskErr
}
func (d *DriverMock) DeviceAddCdRom(name string, image string) (string, error) {
d.DeviceAddCdRomCalled = true
d.DeviceAddCdRomName = name
d.DeviceAddCdRomImage = image
return d.DeviceAddCdRomResult, d.DeviceAddCdRomErr
func (d *DriverMock) DeviceAddCDROM(name string, image string) (string, error) {
d.DeviceAddCDROMCalled = true
d.DeviceAddCDROMName = name
d.DeviceAddCDROMImage = image
return d.DeviceAddCDROMResult, d.DeviceAddCDROMErr
}
func (d *DriverMock) DiskPath(name string) (string, error) {
@ -82,7 +82,7 @@ func (d *DriverMock) DiskPath(name string) (string, error) {
return d.DiskPathResult, d.DiskPathErr
}
func (d *DriverMock) Import(name, srcPath, dstPath string, reassignMac bool) error {
func (d *DriverMock) Import(name, srcPath, dstPath string, reassignMAC bool) error {
d.ImportCalled = true
d.ImportName = name
d.ImportSrcPath = srcPath
@ -136,18 +136,18 @@ func (d *DriverMock) SetDefaultConfiguration(name string) error {
return d.SetDefaultConfigurationError
}
func (d *DriverMock) Mac(name string) (string, error) {
d.MacName = name
return d.MacReturn, d.MacError
func (d *DriverMock) MAC(name string) (string, error) {
d.MACName = name
return d.MACReturn, d.MACError
}
func (d *DriverMock) IpAddress(mac string) (string, error) {
d.IpAddressMac = mac
return d.IpAddressReturn, d.IpAddressError
func (d *DriverMock) IPAddress(mac string) (string, error) {
d.IPAddressMAC = mac
return d.IPAddressReturn, d.IPAddressError
}
func (d *DriverMock) ToolsIsoPath(flavor string) (string, error) {
d.ToolsIsoPathCalled = true
d.ToolsIsoPathFlavor = flavor
return d.ToolsIsoPathResult, d.ToolsIsoPathErr
func (d *DriverMock) ToolsISOPath(flavor string) (string, error) {
d.ToolsISOPathCalled = true
d.ToolsISOPathFlavor = flavor
return d.ToolsISOPathResult, d.ToolsISOPathErr
}

View File

@ -1,6 +1,6 @@
package common
// Interface to help find the host IP that is available from within
// HostIPFinder allows to find the host IP that is available from within
// the Parallels virtual machines.
type HostIPFinder interface {
HostIP() (string, error)

View File

@ -13,6 +13,8 @@ type IfconfigIPFinder struct {
Devices []string
}
// HostIP returns the host's IP address or an error if it could not be found
// from the `ifconfig` output.
func (f *IfconfigIPFinder) HostIP() (string, error) {
var ifconfigPath string
@ -50,5 +52,5 @@ func (f *IfconfigIPFinder) HostIP() (string, error) {
}
}
}
return "", errors.New("IP not found in ifconfig output...")
return "", errors.New("IP not found in ifconfig output")
}

View File

@ -9,10 +9,12 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// OutputConfig contains the configuration for builder's output.
type OutputConfig struct {
OutputDir string `mapstructure:"output_directory"`
}
// Prepare configures the output directory or returns an error if it already exists.
func (c *OutputConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig) []error {
if c.OutputDir == "" {
c.OutputDir = fmt.Sprintf("output-%s", pc.PackerBuildName)

View File

@ -1,10 +1,11 @@
package common
import (
"github.com/mitchellh/packer/common"
"io/ioutil"
"os"
"testing"
"github.com/mitchellh/packer/common"
)
func TestOutputConfigPrepare(t *testing.T) {

View File

@ -4,10 +4,13 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// PrlctlConfig contains the configuration for running "prlctl" commands
// before the VM start.
type PrlctlConfig struct {
Prlctl [][]string `mapstructure:"prlctl"`
}
// Prepare sets the default value of "Prlctl" property.
func (c *PrlctlConfig) Prepare(ctx *interpolate.Context) []error {
if c.Prlctl == nil {
c.Prlctl = make([][]string, 0)

View File

@ -4,10 +4,13 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// PrlctlPostConfig contains the configuration for running "prlctl" commands
// in the end of artifact build.
type PrlctlPostConfig struct {
PrlctlPost [][]string `mapstructure:"prlctl_post"`
}
// Prepare sets the default value of "PrlctlPost" property.
func (c *PrlctlPostConfig) Prepare(ctx *interpolate.Context) []error {
if c.PrlctlPost == nil {
c.PrlctlPost = make([][]string, 0)

View File

@ -4,10 +4,12 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// PrlctlVersionConfig contains the configuration for `prlctl` version.
type PrlctlVersionConfig struct {
PrlctlVersionFile string `mapstructure:"prlctl_version_file"`
}
// Prepare sets the default value of "PrlctlVersionFile" property.
func (c *PrlctlVersionConfig) Prepare(ctx *interpolate.Context) []error {
if c.PrlctlVersionFile == "" {
c.PrlctlVersionFile = ".prlctl_version"

View File

@ -1,5 +1,7 @@
package common
// Prltype is a Python scrypt allowin to send scancodes to the VM. It requires
// the module "prlsdkapi", which is bundled to Parallels Virtualization SDK.
const Prltype string = `
import sys
import prlsdkapi

View File

@ -7,12 +7,14 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// RunConfig contains the configuration for VM run.
type RunConfig struct {
RawBootWait string `mapstructure:"boot_wait"`
BootWait time.Duration ``
}
// Prepare sets the configuration for VM run.
func (c *RunConfig) Prepare(ctx *interpolate.Context) []error {
if c.RawBootWait == "" {
c.RawBootWait = "10s"

View File

@ -7,6 +7,7 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// ShutdownConfig contains the configuration for VM shutdown.
type ShutdownConfig struct {
ShutdownCommand string `mapstructure:"shutdown_command"`
RawShutdownTimeout string `mapstructure:"shutdown_timeout"`
@ -14,6 +15,7 @@ type ShutdownConfig struct {
ShutdownTimeout time.Duration ``
}
// Prepare sets default values to the VM shutdown configuration.
func (c *ShutdownConfig) Prepare(ctx *interpolate.Context) []error {
if c.RawShutdownTimeout == "" {
c.RawShutdownTimeout = "5m"

View File

@ -7,16 +7,17 @@ import (
"golang.org/x/crypto/ssh"
)
// CommHost returns the VM's IP address which should be used to access it by SSH.
func CommHost(state multistep.StateBag) (string, error) {
vmName := state.Get("vmName").(string)
driver := state.Get("driver").(Driver)
mac, err := driver.Mac(vmName)
mac, err := driver.MAC(vmName)
if err != nil {
return "", err
}
ip, err := driver.IpAddress(mac)
ip, err := driver.IPAddress(mac)
if err != nil {
return "", err
}
@ -24,6 +25,7 @@ func CommHost(state multistep.StateBag) (string, error) {
return ip, nil
}
// SSHConfigFunc returns SSH credentials to access the VM by SSH.
func SSHConfigFunc(config SSHConfig) func(multistep.StateBag) (*ssh.ClientConfig, error) {
return func(state multistep.StateBag) (*ssh.ClientConfig, error) {
auth := []ssh.AuthMethod{

View File

@ -7,6 +7,7 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
// SSHConfig contains the configuration for SSH communicator.
type SSHConfig struct {
Comm communicator.Config `mapstructure:",squash"`
@ -15,6 +16,7 @@ type SSHConfig struct {
SSHWaitTimeout time.Duration `mapstructure:"ssh_wait_timeout"`
}
// Prepare sets the default values for SSH communicator properties.
func (c *SSHConfig) Prepare(ctx *interpolate.Context) []error {
// TODO: backwards compatibility, write fixer instead
if c.SSHWaitTimeout != 0 {

View File

@ -2,12 +2,13 @@ package common
import (
"fmt"
"log"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"log"
)
// This step attaches a floppy to the virtual machine.
// StepAttachFloppy is a step that attaches a floppy to the virtual machine.
//
// Uses:
// driver Driver
@ -19,6 +20,8 @@ type StepAttachFloppy struct {
floppyPath string
}
// Run adds a virtual FDD device to the VM and attaches the image.
// If the image is not specified, then this step will be skipped.
func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction {
// Determine if we even have a floppy disk to attach
var floppyPath string
@ -35,22 +38,22 @@ func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Deleting any current floppy disk...")
// Delete the floppy disk controller
del_command := []string{
delCommand := []string{
"set", vmName,
"--device-del", "fdd0",
}
// This will almost certainly fail with 'The fdd0 device does not exist.'
driver.Prlctl(del_command...)
driver.Prlctl(delCommand...)
ui.Say("Attaching floppy disk...")
// Attaching the floppy disk
add_command := []string{
addCommand := []string{
"set", vmName,
"--device-add", "fdd",
"--image", floppyPath,
"--connect",
}
if err := driver.Prlctl(add_command...); err != nil {
if err := driver.Prlctl(addCommand...); err != nil {
state.Put("error", fmt.Errorf("Error adding floppy: %s", err))
return multistep.ActionHalt
}
@ -61,6 +64,7 @@ func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup removes the virtual FDD device attached to the VM.
func (s *StepAttachFloppy) Cleanup(state multistep.StateBag) {
driver := state.Get("driver").(Driver)
vmName := state.Get("vmName").(string)

View File

@ -1,10 +1,11 @@
package common
import (
"github.com/mitchellh/multistep"
"io/ioutil"
"os"
"testing"
"github.com/mitchellh/multistep"
)
func TestStepAttachFloppy_impl(t *testing.T) {

View File

@ -2,13 +2,14 @@ package common
import (
"fmt"
"log"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"log"
)
// This step attaches the Parallels Tools as an inserted CD onto
// the virtual machine.
// StepAttachParallelsTools is a step that attaches Parallels Tools ISO image
// as an inserted CD onto the virtual machine.
//
// Uses:
// driver Driver
@ -22,6 +23,8 @@ type StepAttachParallelsTools struct {
ParallelsToolsMode string
}
// Run adds a virtual CD-ROM device to the VM and attaches Parallels Tools ISO image.
// If ISO image is not specified, then this step will be skipped.
func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
@ -39,10 +42,10 @@ func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepA
// Attach the guest additions to the computer
ui.Say("Attaching Parallels Tools ISO to the new CD/DVD drive...")
cdrom, err := driver.DeviceAddCdRom(vmName, parallelsToolsPath)
cdrom, err := driver.DeviceAddCDROM(vmName, parallelsToolsPath)
if err != nil {
err := fmt.Errorf("Error attaching Parallels Tools ISO: %s", err)
err = fmt.Errorf("Error attaching Parallels Tools ISO: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -54,6 +57,7 @@ func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepA
return multistep.ActionContinue
}
// Cleanup removes the virtual CD-ROM device attached to the VM.
func (s *StepAttachParallelsTools) Cleanup(state multistep.StateBag) {
if s.cdromDevice == "" {
return

View File

@ -2,12 +2,13 @@ package common
import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
// This step removes all empty blocks from expanding Parallels virtual disks
// and reduces the result disk size
// StepCompactDisk is a step that removes all empty blocks from expanding
// Parallels virtual disks and reduces the result disk size
//
// Uses:
// driver Driver
@ -20,6 +21,7 @@ type StepCompactDisk struct {
Skip bool
}
// Run runs the compaction of the virtual disk attached to the VM.
func (s *StepCompactDisk) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
vmName := state.Get("vmName").(string)
@ -33,7 +35,7 @@ func (s *StepCompactDisk) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Compacting the disk image")
diskPath, err := driver.DiskPath(vmName)
if err != nil {
err := fmt.Errorf("Error detecting virtual disk path: %s", err)
err = fmt.Errorf("Error detecting virtual disk path: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -48,4 +50,5 @@ func (s *StepCompactDisk) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup does nothing.
func (*StepCompactDisk) Cleanup(multistep.StateBag) {}

View File

@ -20,6 +20,7 @@ type StepOutputDir struct {
success bool
}
// Run sets up the output directory.
func (s *StepOutputDir) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
@ -48,6 +49,7 @@ func (s *StepOutputDir) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup deletes the output directory.
func (s *StepOutputDir) Cleanup(state multistep.StateBag) {
_, cancelled := state.GetOk(multistep.StateCancelled)
_, halted := state.GetOk(multistep.StateHalted)

View File

@ -1,10 +1,11 @@
package common
import (
"github.com/mitchellh/multistep"
"io/ioutil"
"os"
"testing"
"github.com/mitchellh/multistep"
)
func testStepOutputDir(t *testing.T) *StepOutputDir {

View File

@ -2,11 +2,13 @@ package common
import (
"fmt"
"github.com/mitchellh/multistep"
"os"
"github.com/mitchellh/multistep"
)
// This step prepares parameters related to Parallels Tools.
// StepPrepareParallelsTools is a step that prepares parameters related
// to Parallels Tools.
//
// Uses:
// driver Driver
@ -18,6 +20,7 @@ type StepPrepareParallelsTools struct {
ParallelsToolsMode string
}
// Run sets the value of "parallels_tools_path".
func (s *StepPrepareParallelsTools) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
@ -25,7 +28,7 @@ func (s *StepPrepareParallelsTools) Run(state multistep.StateBag) multistep.Step
return multistep.ActionContinue
}
path, err := driver.ToolsIsoPath(s.ParallelsToolsFlavor)
path, err := driver.ToolsISOPath(s.ParallelsToolsFlavor)
if err != nil {
state.Put("error", err)
@ -44,4 +47,5 @@ func (s *StepPrepareParallelsTools) Run(state multistep.StateBag) multistep.Step
return multistep.ActionContinue
}
// Cleanup does nothing.
func (s *StepPrepareParallelsTools) Cleanup(multistep.StateBag) {}

View File

@ -29,7 +29,7 @@ func TestStepPrepareParallelsTools(t *testing.T) {
driver := state.Get("driver").(*DriverMock)
// Mock results
driver.ToolsIsoPathResult = tf.Name()
driver.ToolsISOPathResult = tf.Name()
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
@ -40,11 +40,11 @@ func TestStepPrepareParallelsTools(t *testing.T) {
}
// Test the driver
if !driver.ToolsIsoPathCalled {
if !driver.ToolsISOPathCalled {
t.Fatal("tools iso path should be called")
}
if driver.ToolsIsoPathFlavor != "foo" {
t.Fatalf("bad: %#v", driver.ToolsIsoPathFlavor)
if driver.ToolsISOPathFlavor != "foo" {
t.Fatalf("bad: %#v", driver.ToolsISOPathFlavor)
}
// Test the resulting state
@ -75,8 +75,8 @@ func TestStepPrepareParallelsTools_disabled(t *testing.T) {
}
// Test the driver
if driver.ToolsIsoPathCalled {
t.Fatal("tools iso path should NOT be called")
if driver.ToolsISOPathCalled {
t.Fatal("tools ISO path should NOT be called")
}
}
@ -90,7 +90,7 @@ func TestStepPrepareParallelsTools_nonExist(t *testing.T) {
driver := state.Get("driver").(*DriverMock)
// Mock results
driver.ToolsIsoPathResult = "foo"
driver.ToolsISOPathResult = "foo"
// Test the run
if action := step.Run(state); action != multistep.ActionHalt {
@ -101,11 +101,11 @@ func TestStepPrepareParallelsTools_nonExist(t *testing.T) {
}
// Test the driver
if !driver.ToolsIsoPathCalled {
if !driver.ToolsISOPathCalled {
t.Fatal("tools iso path should be called")
}
if driver.ToolsIsoPathFlavor != "foo" {
t.Fatalf("bad: %#v", driver.ToolsIsoPathFlavor)
if driver.ToolsISOPathFlavor != "foo" {
t.Fatalf("bad: %#v", driver.ToolsISOPathFlavor)
}
// Test the resulting state

View File

@ -13,8 +13,8 @@ type commandTemplate struct {
Name string
}
// This step executes additional prlctl commands as specified by the
// template.
// StepPrlctl is a step that executes additional `prlctl` commands as specified.
// by the template.
//
// Uses:
// driver Driver
@ -27,6 +27,7 @@ type StepPrlctl struct {
Ctx interpolate.Context
}
// Run executes `prlctl` commands.
func (s *StepPrlctl) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
@ -48,7 +49,7 @@ func (s *StepPrlctl) Run(state multistep.StateBag) multistep.StepAction {
var err error
command[i], err = interpolate.Render(arg, &s.Ctx)
if err != nil {
err := fmt.Errorf("Error preparing prlctl command: %s", err)
err = fmt.Errorf("Error preparing prlctl command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -57,7 +58,7 @@ func (s *StepPrlctl) Run(state multistep.StateBag) multistep.StepAction {
ui.Message(fmt.Sprintf("Executing: prlctl %s", strings.Join(command, " ")))
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error executing command: %s", err)
err = fmt.Errorf("Error executing command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -67,4 +68,5 @@ func (s *StepPrlctl) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup does nothing.
func (s *StepPrlctl) Cleanup(state multistep.StateBag) {}

View File

@ -2,12 +2,13 @@ package common
import (
"fmt"
"time"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"time"
)
// This step starts the virtual machine.
// StepRun is a step that starts the virtual machine.
//
// Uses:
// driver Driver
@ -21,6 +22,7 @@ type StepRun struct {
vmName string
}
// Run starts the VM.
func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
@ -29,7 +31,7 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
ui.Say("Starting the virtual machine...")
command := []string{"start", vmName}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error starting VM: %s", err)
err = fmt.Errorf("Error starting VM: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -56,6 +58,7 @@ func (s *StepRun) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup stops the VM.
func (s *StepRun) Cleanup(state multistep.StateBag) {
if s.vmName == "" {
return

View File

@ -3,14 +3,15 @@ package common
import (
"errors"
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"log"
"time"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
// This step shuts down the machine. It first attempts to do so gracefully,
// but ultimately forcefully shuts it down if that fails.
// StepShutdown is a step that shuts down the machine. It first attempts to do
// so gracefully, but ultimately forcefully shuts it down if that fails.
//
// Uses:
// communicator packer.Communicator
@ -25,6 +26,7 @@ type StepShutdown struct {
Timeout time.Duration
}
// Run shuts down the VM.
func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
comm := state.Get("communicator").(packer.Communicator)
driver := state.Get("driver").(Driver)
@ -36,7 +38,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
log.Printf("Executing shutdown command: %s", s.Command)
cmd := &packer.RemoteCmd{Command: s.Command}
if err := cmd.StartWithUi(comm, ui); err != nil {
err := fmt.Errorf("Failed to send shutdown command: %s", err)
err = fmt.Errorf("Failed to send shutdown command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -64,7 +66,7 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
} else {
ui.Say("Halting the virtual machine...")
if err := driver.Stop(vmName); err != nil {
err := fmt.Errorf("Error stopping VM: %s", err)
err = fmt.Errorf("Error stopping VM: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -75,4 +77,5 @@ func (s *StepShutdown) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup does nothing.
func (s *StepShutdown) Cleanup(state multistep.StateBag) {}

View File

@ -1,10 +1,11 @@
package common
import (
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"testing"
"time"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
func TestStepShutdown_impl(t *testing.T) {

View File

@ -2,9 +2,10 @@ package common
import (
"bytes"
"testing"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"testing"
)
func testState(t *testing.T) multistep.StateBag {

View File

@ -13,16 +13,14 @@ import (
"github.com/mitchellh/packer/template/interpolate"
)
const KeyLeftShift uint32 = 0xFFE1
type bootCommandTemplateData struct {
HTTPIP string
HTTPPort uint
Name string
}
// This step "types" the boot command into the VM via the prltype script, built on the
// Parallels Virtualization SDK - Python API.
// StepTypeBootCommand is a step that "types" the boot command into the VM via
// the prltype script, built on the Parallels Virtualization SDK - Python API.
//
// Uses:
// driver Driver
@ -39,6 +37,7 @@ type StepTypeBootCommand struct {
Ctx interpolate.Context
}
// Run types the boot command by sending key scancodes into the VM.
func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction {
debug := state.Get("debug").(bool)
httpPort := state.Get("http_port").(uint)
@ -50,7 +49,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
pauseFn = state.Get("pauseFn").(multistep.DebugPauseFn)
}
hostIp := "0.0.0.0"
hostIP := "0.0.0.0"
if len(s.HostInterfaces) > 0 {
// Determine the host IP
@ -58,18 +57,18 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
ip, err := ipFinder.HostIP()
if err != nil {
err := fmt.Errorf("Error detecting host IP: %s", err)
err = fmt.Errorf("Error detecting host IP: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
hostIp = ip
hostIP = ip
}
ui.Say(fmt.Sprintf("Host IP for the Parallels machine: %s", hostIp))
ui.Say(fmt.Sprintf("Host IP for the Parallels machine: %s", hostIP))
s.Ctx.Data = &bootCommandTemplateData{
hostIp,
hostIP,
httpPort,
s.VMName,
}
@ -78,7 +77,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
for i, command := range s.BootCommand {
command, err := interpolate.Render(command, &s.Ctx)
if err != nil {
err := fmt.Errorf("Error preparing boot command: %s", err)
err = fmt.Errorf("Error preparing boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -88,7 +87,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
for _, code := range scancodes(command) {
if code == "wait" {
if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil {
err := fmt.Errorf("Error sending boot command: %s", err)
err = fmt.Errorf("Error sending boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -100,7 +99,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
if code == "wait5" {
if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil {
err := fmt.Errorf("Error sending boot command: %s", err)
err = fmt.Errorf("Error sending boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -112,7 +111,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
if code == "wait10" {
if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil {
err := fmt.Errorf("Error sending boot command: %s", err)
err = fmt.Errorf("Error sending boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -136,7 +135,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
log.Printf("Sending scancodes: %#v", codes)
if err := driver.SendKeyScanCodes(s.VMName, codes...); err != nil {
err := fmt.Errorf("Error sending boot command: %s", err)
err = fmt.Errorf("Error sending boot command: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -146,6 +145,7 @@ func (s *StepTypeBootCommand) Run(state multistep.StateBag) multistep.StepAction
return multistep.ActionContinue
}
// Cleanup does nothing.
func (*StepTypeBootCommand) Cleanup(multistep.StateBag) {}
func scancodes(message string) []string {
@ -208,12 +208,12 @@ func scancodes(message string) []string {
scancodeMap := make(map[rune]uint)
for chars, start := range scancodeIndex {
var i uint = 0
var i uint
for len(chars) > 0 {
r, size := utf8.DecodeRuneInString(chars)
chars = chars[size:]
scancodeMap[r] = start + i
i += 1
i++
}
}

View File

@ -1,10 +1,11 @@
package common
import (
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"strings"
"testing"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
func TestStepTypeBootCommand(t *testing.T) {

View File

@ -22,7 +22,13 @@ type toolsPathTemplate struct {
Flavor string
}
// This step uploads the guest additions ISO to the VM.
// StepUploadParallelsTools is a step that uploads the Parallels Tools ISO
// to the VM.
//
// Uses:
// communicator packer.Communicator
// parallels_tools_path string
// ui packer.Ui
type StepUploadParallelsTools struct {
ParallelsToolsFlavor string
ParallelsToolsGuestPath string
@ -30,6 +36,7 @@ type StepUploadParallelsTools struct {
Ctx interpolate.Context
}
// Run uploads the Parallels Tools ISO to the VM.
func (s *StepUploadParallelsTools) Run(state multistep.StateBag) multistep.StepAction {
comm := state.Get("communicator").(packer.Communicator)
ui := state.Get("ui").(packer.Ui)
@ -56,7 +63,7 @@ func (s *StepUploadParallelsTools) Run(state multistep.StateBag) multistep.StepA
s.ParallelsToolsGuestPath, err = interpolate.Render(s.ParallelsToolsGuestPath, &s.Ctx)
if err != nil {
err := fmt.Errorf("Error preparing Parallels Tools path: %s", err)
err = fmt.Errorf("Error preparing Parallels Tools path: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -65,7 +72,7 @@ func (s *StepUploadParallelsTools) Run(state multistep.StateBag) multistep.StepA
ui.Say(fmt.Sprintf("Uploading Parallels Tools for '%s' to path: '%s'",
s.ParallelsToolsFlavor, s.ParallelsToolsGuestPath))
if err := comm.Upload(s.ParallelsToolsGuestPath, f, nil); err != nil {
err := fmt.Errorf("Error uploading Parallels Tools: %s", err)
err = fmt.Errorf("Error uploading Parallels Tools: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
@ -74,4 +81,5 @@ func (s *StepUploadParallelsTools) Run(state multistep.StateBag) multistep.StepA
return multistep.ActionContinue
}
// Cleanup does nothing.
func (s *StepUploadParallelsTools) Cleanup(state multistep.StateBag) {}

View File

@ -1,9 +1,10 @@
package common
import (
"testing"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"testing"
)
func TestStepUploadParallelsTools_impl(t *testing.T) {

View File

@ -3,17 +3,24 @@ package common
import (
"bytes"
"fmt"
"log"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"log"
)
// This step uploads a file containing the Parallels version, which
// can be useful for various provisioning reasons.
// StepUploadVersion is a step that uploads a file containing the version of
// Parallels Desktop, which can be useful for various provisioning reasons.
//
// Uses:
// communicator packer.Communicator
// driver Driver
// ui packer.Ui
type StepUploadVersion struct {
Path string
}
// Run uploads a file containing the version of Parallels Desktop.
func (s *StepUploadVersion) Run(state multistep.StateBag) multistep.StepAction {
comm := state.Get("communicator").(packer.Communicator)
driver := state.Get("driver").(Driver)
@ -41,4 +48,5 @@ func (s *StepUploadVersion) Run(state multistep.StateBag) multistep.StepAction {
return multistep.ActionContinue
}
// Cleanup does nothing.
func (s *StepUploadVersion) Cleanup(state multistep.StateBag) {}

View File

@ -1,9 +1,10 @@
package common
import (
"testing"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"testing"
)
func TestStepUploadVersion_impl(t *testing.T) {

View File

@ -15,12 +15,14 @@ const (
ParallelsToolsModeUpload = "upload"
)
// ToolsConfig contains the builder configuration related to Parallels Tools.
type ToolsConfig struct {
ParallelsToolsFlavor string `mapstructure:"parallels_tools_flavor"`
ParallelsToolsGuestPath string `mapstructure:"parallels_tools_guest_path"`
ParallelsToolsMode string `mapstructure:"parallels_tools_mode"`
}
// Prepare validates & sets up configuration options related to Parallels Tools.
func (c *ToolsConfig) Prepare(ctx *interpolate.Context) []error {
if c.ParallelsToolsMode == "" {
c.ParallelsToolsMode = ParallelsToolsModeUpload
@ -53,7 +55,7 @@ func (c *ToolsConfig) Prepare(ctx *interpolate.Context) []error {
if c.ParallelsToolsFlavor == "" {
if c.ParallelsToolsMode != ParallelsToolsModeDisable {
errs = append(errs, errors.New("parallels_tools_flavor must be specified."))
errs = append(errs, errors.New("parallels_tools_flavor must be specified"))
}
}

View File

@ -2,17 +2,18 @@ package iso
import (
"fmt"
"log"
"github.com/mitchellh/multistep"
parallelscommon "github.com/mitchellh/packer/builder/parallels/common"
"github.com/mitchellh/packer/packer"
"log"
)
// This step attaches the ISO to the virtual machine.
//
// Uses:
// driver Driver
// isoPath string
// iso_path string
// ui packer.Ui
// vmName string
//

View File

@ -2,10 +2,11 @@ package iso
import (
"fmt"
"strconv"
"github.com/mitchellh/multistep"
parallelscommon "github.com/mitchellh/packer/builder/parallels/common"
"github.com/mitchellh/packer/packer"
"strconv"
)
// This step creates the virtual disk that will be used as the

View File

@ -2,6 +2,7 @@ package iso
import (
"fmt"
"github.com/mitchellh/multistep"
parallelscommon "github.com/mitchellh/packer/builder/parallels/common"
"github.com/mitchellh/packer/packer"

View File

@ -27,7 +27,7 @@ type Config struct {
BootCommand []string `mapstructure:"boot_command"`
SourcePath string `mapstructure:"source_path"`
VMName string `mapstructure:"vm_name"`
ReassignMac bool `mapstructure:"reassign_mac"`
ReassignMAC bool `mapstructure:"reassign_mac"`
ctx interpolate.Context
}

View File

@ -2,6 +2,7 @@ package pvm
import (
"fmt"
"github.com/mitchellh/multistep"
parallelscommon "github.com/mitchellh/packer/builder/parallels/common"
"github.com/mitchellh/packer/packer"
@ -20,7 +21,7 @@ func (s *StepImport) Run(state multistep.StateBag) multistep.StepAction {
config := state.Get("config").(*Config)
ui.Say(fmt.Sprintf("Importing VM: %s", s.SourcePath))
if err := driver.Import(s.Name, s.SourcePath, config.OutputDir, config.ReassignMac); err != nil {
if err := driver.Import(s.Name, s.SourcePath, config.OutputDir, config.ReassignMAC); err != nil {
err := fmt.Errorf("Error importing VM: %s", err)
state.Put("error", err)
ui.Error(err.Error())

View File

@ -2,10 +2,11 @@ package pvm
import (
"bytes"
"testing"
"github.com/mitchellh/multistep"
parallelscommon "github.com/mitchellh/packer/builder/parallels/common"
"github.com/mitchellh/packer/packer"
"testing"
)
func testState(t *testing.T) multistep.StateBag {