Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Kent Holloway 2014-10-06 10:14:08 -05:00
commit a3e4554a15
16 changed files with 242 additions and 292 deletions

View File

@ -1,8 +1,15 @@
## 0.7.2 (unreleased)
FEATURES:
* builder/parallels: Don't depend on _prl-utils_ [GH-1499]
BUG FIXES:
* builder/vmware-vmx: Fix issue with order of boot command support [GH-1492]
* builder/parallels: Ignore 'The fdd0 device does not exist' [GH-1501]
* builder/parallels: Rely on Cleanup functions to detach devices [GH-1502]
* builder/parallels: Create VM without hdd and then add it later [GH-1548]
## 0.7.1 (September 10, 2014)

View File

@ -15,6 +15,9 @@ import (
// versions out of the builder steps, so sometimes the methods are
// extremely specific.
type Driver interface {
// Adds new CD/DVD drive to the VM and returns name of this device
DeviceAddCdRom(string, string) (string, error)
// Import a VM
Import(string, string, string, bool) error

View File

@ -95,6 +95,29 @@ func getAppPath(bundleId string) (string, error) {
return pathOutput, nil
}
func (d *Parallels9Driver) DeviceAddCdRom(name string, image string) (string, error) {
command := []string{
"set", name,
"--device-add", "cdrom",
"--image", image,
}
out, err := exec.Command(d.PrlctlPath, command...).Output()
if err != nil {
return "", err
}
deviceRe := regexp.MustCompile(`\s+(cdrom\d+)\s+`)
matches := deviceRe.FindStringSubmatch(string(out))
if matches == nil {
return "", fmt.Errorf(
"Could not determine cdrom device name in the output:\n%s", string(out))
}
device_name := matches[1]
return device_name, nil
}
func (d *Parallels9Driver) IsRunning(name string) (bool, error) {
var stdout bytes.Buffer

View File

@ -5,6 +5,12 @@ import "sync"
type DriverMock struct {
sync.Mutex
DeviceAddCdRomCalled bool
DeviceAddCdRomName string
DeviceAddCdRomImage string
DeviceAddCdRomResult string
DeviceAddCdRomErr error
ImportCalled bool
ImportName string
ImportSrcPath string
@ -45,6 +51,13 @@ type DriverMock struct {
IpAddressError error
}
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) Import(name, srcPath, dstPath string, reassignMac bool) error {
d.ImportCalled = true
d.ImportName = name

View File

@ -39,11 +39,10 @@ func (s *StepAttachFloppy) Run(state multistep.StateBag) multistep.StepAction {
"set", vmName,
"--device-del", "fdd0",
}
if err := driver.Prlctl(del_command...); err != nil {
state.Put("error", fmt.Errorf("Error deleting floppy: %s", err))
}
ui.Say("Attaching floppy disk...")
// This will almost certainly fail with 'The fdd0 device does not exist.'
driver.Prlctl(del_command...)
ui.Say("Attaching floppy disk...")
// Attaching the floppy disk
add_command := []string{
"set", vmName,

View File

@ -17,8 +17,8 @@ import (
// vmName string
//
// Produces:
// attachedToolsIso boolean
type StepAttachParallelsTools struct {
cdromDevice string
ParallelsToolsMode string
}
@ -37,27 +37,25 @@ func (s *StepAttachParallelsTools) Run(state multistep.StateBag) multistep.StepA
parallelsToolsPath := state.Get("parallels_tools_path").(string)
// Attach the guest additions to the computer
ui.Say("Attaching Parallels Tools ISO onto IDE controller...")
command := []string{
"set", vmName,
"--device-add", "cdrom",
"--image", parallelsToolsPath,
}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error attaching Parallels Tools: %s", err)
ui.Say("Attaching Parallels Tools ISO to the new CD/DVD drive...")
cdrom, err := driver.DeviceAddCdRom(vmName, parallelsToolsPath)
if err != nil {
err := fmt.Errorf("Error attaching Parallels Tools ISO: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Set some state so we know to remove
state.Put("attachedToolsIso", true)
// Track the device name so that we can can delete later
s.cdromDevice = cdrom
return multistep.ActionContinue
}
func (s *StepAttachParallelsTools) Cleanup(state multistep.StateBag) {
if _, ok := state.GetOk("attachedToolsIso"); !ok {
if s.cdromDevice == "" {
return
}
@ -66,14 +64,10 @@ func (s *StepAttachParallelsTools) Cleanup(state multistep.StateBag) {
vmName := state.Get("vmName").(string)
log.Println("Detaching Parallels Tools ISO...")
cdDevice := "cdrom0"
if _, ok := state.GetOk("attachedIso"); ok {
cdDevice = "cdrom1"
}
command := []string{
"set", vmName,
"--device-del", cdDevice,
"--device-del", s.cdromDevice,
}
if err := driver.Prlctl(command...); err != nil {

View File

@ -1,67 +0,0 @@
package common
import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
)
// This step removes any devices (floppy disks, ISOs, etc.) from the
// machine that we may have added.
//
// Uses:
// driver Driver
// ui packer.Ui
// vmName string
//
// Produces:
type StepRemoveDevices struct{}
func (s *StepRemoveDevices) Run(state multistep.StateBag) multistep.StepAction {
driver := state.Get("driver").(Driver)
ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string)
// Remove the attached floppy disk, if it exists
if _, ok := state.GetOk("floppy_path"); ok {
ui.Message("Removing floppy drive...")
command := []string{"set", vmName, "--device-del", "fdd0"}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error removing floppy: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
if _, ok := state.GetOk("attachedIso"); ok {
command := []string{
"set", vmName,
"--device-set", "cdrom0",
"--device", "Default CD/DVD-ROM",
}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error detaching ISO: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
if _, ok := state.GetOk("attachedToolsIso"); ok {
command := []string{"set", vmName, "--device-del", "cdrom1"}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error detaching ISO: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
}
return multistep.ActionContinue
}
func (s *StepRemoveDevices) Cleanup(state multistep.StateBag) {
}

View File

@ -1,93 +0,0 @@
package common
import (
"github.com/mitchellh/multistep"
"testing"
)
func TestStepRemoveDevices_impl(t *testing.T) {
var _ multistep.Step = new(StepRemoveDevices)
}
func TestStepRemoveDevices(t *testing.T) {
state := testState(t)
step := new(StepRemoveDevices)
state.Put("vmName", "foo")
driver := state.Get("driver").(*DriverMock)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test that ISO was removed
if len(driver.PrlctlCalls) != 0 {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
}
func TestStepRemoveDevices_attachedIso(t *testing.T) {
state := testState(t)
step := new(StepRemoveDevices)
state.Put("attachedIso", true)
state.Put("vmName", "foo")
driver := state.Get("driver").(*DriverMock)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test that ISO was detached
if len(driver.PrlctlCalls) != 1 {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
if driver.PrlctlCalls[0][2] != "--device-set" {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
if driver.PrlctlCalls[0][3] != "cdrom0" {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
if driver.PrlctlCalls[0][5] != "Default CD/DVD-ROM" {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
}
func TestStepRemoveDevices_floppyPath(t *testing.T) {
state := testState(t)
step := new(StepRemoveDevices)
state.Put("floppy_path", "foo")
state.Put("vmName", "foo")
driver := state.Get("driver").(*DriverMock)
// Test the run
if action := step.Run(state); action != multistep.ActionContinue {
t.Fatalf("bad action: %#v", action)
}
if _, ok := state.GetOk("error"); ok {
t.Fatal("should NOT have error")
}
// Test that both were removed
if len(driver.PrlctlCalls) != 1 {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
if driver.PrlctlCalls[0][2] != "--device-del" {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
if driver.PrlctlCalls[0][3] != "fdd0" {
t.Fatalf("bad: %#v", driver.PrlctlCalls)
}
}

View File

@ -294,7 +294,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout,
},
new(parallelscommon.StepRemoveDevices),
}
// Setup the state bag

View File

@ -11,10 +11,14 @@ import (
// This step attaches the ISO to the virtual machine.
//
// Uses:
// driver Driver
// isoPath string
// ui packer.Ui
// vmName string
//
// Produces:
type stepAttachISO struct {
diskPath string
cdromDevice string
}
func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction {
@ -24,41 +28,78 @@ func (s *stepAttachISO) Run(state multistep.StateBag) multistep.StepAction {
vmName := state.Get("vmName").(string)
// Attach the disk to the controller
ui.Say("Attaching ISO onto IDE controller...")
command := []string{
"set", vmName,
"--device-set", "cdrom0",
"--image", isoPath,
"--enable", "--connect",
}
if err := driver.Prlctl(command...); err != nil {
ui.Say("Attaching ISO to the new CD/DVD drive...")
cdrom, err := driver.DeviceAddCdRom(vmName, isoPath)
if err != nil {
err := fmt.Errorf("Error attaching ISO: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Set some state so we know to remove
state.Put("attachedIso", true)
// Set new boot order
ui.Say("Setting the boot order...")
command := []string{
"set", vmName,
"--device-bootorder", fmt.Sprintf("hdd0 %s cdrom0 net0", cdrom),
}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error setting the boot order: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Disable 'cdrom0' device
ui.Say("Disabling default CD/DVD drive...")
command = []string{
"set", vmName,
"--device-set", "cdrom0", "--disable",
}
if err := driver.Prlctl(command...); err != nil {
err := fmt.Errorf("Error disabling default CD/DVD drive: %s", err)
state.Put("error", err)
ui.Error(err.Error())
return multistep.ActionHalt
}
// Track the device name so that we can can delete later
s.cdromDevice = cdrom
return multistep.ActionContinue
}
func (s *stepAttachISO) Cleanup(state multistep.StateBag) {
if _, ok := state.GetOk("attachedIso"); !ok {
driver := state.Get("driver").(parallelscommon.Driver)
ui := state.Get("ui").(packer.Ui)
vmName := state.Get("vmName").(string)
// Enable 'cdrom0' device back
log.Println("Enabling default CD/DVD drive...")
command := []string{
"set", vmName,
"--device-set", "cdrom0", "--enable",
}
if err := driver.Prlctl(command...); err != nil {
ui.Error(fmt.Sprintf("Error enabling default CD/DVD drive: %s", err))
}
// Detach ISO
if s.cdromDevice == "" {
return
}
driver := state.Get("driver").(parallelscommon.Driver)
vmName := state.Get("vmName").(string)
command := []string{
log.Println("Detaching ISO...")
command = []string{
"set", vmName,
"--device-set", "cdrom0",
"--enable", "--disconnect",
"--device-del", s.cdromDevice,
}
// Remove the ISO, ignore errors
log.Println("Detaching ISO...")
driver.Prlctl(command...)
if err := driver.Prlctl(command...); err != nil {
ui.Error(fmt.Sprintf("Error detaching ISO: %s", err))
}
}

View File

@ -20,7 +20,7 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction {
command := []string{
"set", vmName,
"--device-set", "hdd0",
"--device-add", "hdd",
"--size", strconv.FormatUint(uint64(config.DiskSize), 10),
"--iface", config.HardDriveInterface,
}

View File

@ -29,6 +29,7 @@ func (s *stepCreateVM) Run(state multistep.StateBag) multistep.StepAction {
"--distribution", config.GuestOSType,
"--dst", config.OutputDir,
"--vmtype", "vm",
"--no-hdd",
}
commands[1] = []string{"set", name, "--cpus", "1"}
commands[2] = []string{"set", name, "--memsize", "512"}

View File

@ -99,7 +99,6 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
Command: b.config.ShutdownCommand,
Timeout: b.config.ShutdownTimeout,
},
new(parallelscommon.StepRemoveDevices),
}
// Run the steps.

View File

@ -1,12 +1,13 @@
source 'https://rubygems.org'
source "https://rubygems.org"
gem "middleman", "~> 3.1.5"
gem "middleman-minify-html", "~> 3.1.1"
gem "rack-contrib", "~> 1.1.0"
gem "redcarpet", "~> 3.0.0"
gem "therubyracer", "~> 0.12.0"
gem "thin", "~> 1.5.0"
gem "less", "~> 2.6"
gem "middleman", "~> 3.3"
gem "middleman-minify-html", "~> 3.4"
gem "rack-contrib", "~> 1.1"
gem "redcarpet", "~> 3.1"
gem "therubyracer", "~> 0.12"
gem "thin", "~> 1.6"
group :development do
gem "highline", "~> 1.6.15"
gem "highline", "~> 1.6"
end

View File

@ -1,109 +1,143 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (3.2.15)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
chunky_png (1.2.9)
coffee-script (2.2.0)
activesupport (4.1.6)
i18n (~> 0.6, >= 0.6.9)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
celluloid (0.16.0)
timers (~> 4.0.0)
chunky_png (1.3.1)
coffee-script (2.3.0)
coffee-script-source
execjs
coffee-script-source (1.6.3)
compass (0.12.2)
coffee-script-source (1.8.0)
commonjs (0.2.7)
compass (1.0.1)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
daemons (1.1.9)
eventmachine (1.0.3)
execjs (1.4.0)
multi_json (~> 1.0)
ffi (1.9.0)
fssm (0.2.10)
haml (4.0.3)
tilt
highline (1.6.20)
hike (1.2.3)
i18n (0.6.5)
kramdown (1.2.0)
libv8 (3.16.14.3)
listen (1.3.1)
compass-core (~> 1.0.1)
compass-import-once (~> 1.0.5)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
rb-kqueue (>= 0.2)
middleman (3.1.6)
coffee-script (~> 2.2.0)
compass (>= 0.12.2)
execjs (~> 1.4.0)
haml (>= 3.1.6)
sass (>= 3.3.13, < 3.5)
compass-core (1.0.1)
multi_json (~> 1.0)
sass (>= 3.3.0, < 3.5)
compass-import-once (1.0.5)
sass (>= 3.2, < 3.5)
daemons (1.1.9)
erubis (2.7.0)
eventmachine (1.0.3)
execjs (2.2.1)
ffi (1.9.5)
haml (4.0.5)
tilt
highline (1.6.21)
hike (1.2.3)
hitimes (1.2.2)
hooks (0.4.0)
uber (~> 0.0.4)
htmlcompressor (0.1.2)
i18n (0.6.11)
json (1.8.1)
kramdown (1.4.2)
less (2.6.0)
commonjs (~> 0.2.7)
libv8 (3.16.14.7)
listen (2.7.11)
celluloid (>= 0.15.2)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
middleman (3.3.6)
coffee-script (~> 2.2)
compass (>= 1.0.0, < 2.0.0)
compass-import-once (= 1.0.5)
execjs (~> 2.0)
haml (>= 4.0.5)
kramdown (~> 1.2)
middleman-core (= 3.1.6)
middleman-more (= 3.1.6)
middleman-core (= 3.3.6)
middleman-sprockets (>= 3.1.2)
sass (>= 3.1.20)
uglifier (~> 2.1.0)
middleman-core (3.1.6)
activesupport (~> 3.2.6)
sass (>= 3.4.0, < 4.0)
uglifier (~> 2.5)
middleman-core (3.3.6)
activesupport (~> 4.1.0)
bundler (~> 1.1)
i18n (~> 0.6.1)
listen (~> 1.1)
rack (>= 1.4.5)
rack-test (~> 0.6.1)
erubis
hooks (~> 0.3)
i18n (~> 0.6.9)
listen (>= 2.7.9, < 3.0)
padrino-helpers (~> 0.12.3)
rack (>= 1.4.5, < 2.0)
rack-test (~> 0.6.2)
thor (>= 0.15.2, < 2.0)
tilt (~> 1.3.6)
middleman-minify-html (3.1.1)
middleman-core (~> 3.0)
middleman-more (3.1.6)
middleman-sprockets (3.1.4)
middleman-core (>= 3.0.14)
middleman-more (>= 3.0.14)
sprockets (~> 2.1)
sprockets-helpers (~> 1.0.0)
sprockets-sass (~> 1.0.0)
multi_json (1.8.2)
tilt (~> 1.4.1, < 2.0)
middleman-minify-html (3.4.0)
htmlcompressor (~> 0.1.0)
middleman-core (>= 3.2)
middleman-sprockets (3.3.10)
middleman-core (~> 3.3)
sprockets (~> 2.12.1)
sprockets-helpers (~> 1.1.0)
sprockets-sass (~> 1.2.0)
minitest (5.4.2)
multi_json (1.10.1)
padrino-helpers (0.12.3)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.12.3)
tilt (~> 1.4.1)
padrino-support (0.12.3)
activesupport (>= 3.1)
rack (1.5.2)
rack-contrib (1.1.0)
rack (>= 0.9.1)
rack-test (0.6.2)
rack (>= 1.0)
rb-fsevent (0.9.3)
rb-inotify (0.9.2)
rb-fsevent (0.9.4)
rb-inotify (0.9.5)
ffi (>= 0.5.0)
rb-kqueue (0.2.0)
ffi (>= 0.5.0)
redcarpet (3.0.0)
redcarpet (3.1.2)
ref (1.0.5)
sass (3.2.12)
sprockets (2.10.0)
sass (3.4.5)
sprockets (2.12.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-helpers (1.0.1)
sprockets-helpers (1.1.0)
sprockets (~> 2.0)
sprockets-sass (1.0.2)
sprockets-sass (1.2.0)
sprockets (~> 2.0)
tilt (~> 1.1)
therubyracer (0.12.0)
therubyracer (0.12.1)
libv8 (~> 3.16.14.0)
ref
thin (1.5.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.18.1)
tilt (1.3.7)
uglifier (2.1.2)
thin (1.6.3)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0)
rack (~> 1.0)
thor (0.19.1)
thread_safe (0.3.4)
tilt (1.4.1)
timers (4.0.1)
hitimes
tzinfo (1.2.2)
thread_safe (~> 0.1)
uber (0.0.8)
uglifier (2.5.3)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
json (>= 1.8.0)
PLATFORMS
ruby
DEPENDENCIES
highline (~> 1.6.15)
middleman (~> 3.1.5)
middleman-minify-html (~> 3.1.1)
rack-contrib (~> 1.1.0)
redcarpet (~> 3.0.0)
therubyracer (~> 0.12.0)
thin (~> 1.5.0)
highline (~> 1.6)
less (~> 2.6)
middleman (~> 3.3)
middleman-minify-html (~> 3.4)
rack-contrib (~> 1.1)
redcarpet (~> 3.1)
therubyracer (~> 0.12)
thin (~> 1.6)

View File

@ -1,4 +0,0 @@
Just update this if you want to force a website push and it isn't
working:
1