mirror of https://github.com/docker/docs.git
Merge pull request #2951 from dgageot/2949-remove-stopped-vbox-vm
FIX #2949 Cannot remove stopped vbox VM
This commit is contained in:
commit
35054c5c71
|
@ -615,19 +615,20 @@ func (d *Driver) Kill() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Driver) Remove() error {
|
func (d *Driver) Remove() error {
|
||||||
_, err := d.GetState()
|
s, err := d.GetState()
|
||||||
|
if err == ErrMachineNotExist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == ErrMachineNotExist {
|
return err
|
||||||
log.Infof("machine does not exist, assuming it has been removed already")
|
}
|
||||||
return nil
|
|
||||||
|
if s != state.Stopped && s != state.Saved {
|
||||||
|
if err := d.Kill(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
if err := d.Kill(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// vbox will not release it's lock immediately after the stop
|
|
||||||
d.sleeper.Sleep(1 * time.Second)
|
|
||||||
return d.vbm("unregistervm", "--delete", d.MachineName)
|
return d.vbm("unregistervm", "--delete", d.MachineName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -300,38 +300,42 @@ func (v *MockCreateOperations) doCall(callSignature string) (string, error) {
|
||||||
return call.output, call.err
|
return call.output, call.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mockCalls(t *testing.T, driver *Driver, expectedCalls []Call) {
|
||||||
|
mockOperations := &MockCreateOperations{
|
||||||
|
test: t,
|
||||||
|
expectedCalls: expectedCalls,
|
||||||
|
}
|
||||||
|
|
||||||
|
driver.Boot2DockerURL = "http://b2d.org"
|
||||||
|
driver.VBoxManager = mockOperations
|
||||||
|
driver.b2dUpdater = mockOperations
|
||||||
|
driver.sshKeyGenerator = mockOperations
|
||||||
|
driver.diskCreator = mockOperations
|
||||||
|
driver.logsReader = mockOperations
|
||||||
|
driver.ipWaiter = mockOperations
|
||||||
|
driver.randomInter = mockOperations
|
||||||
|
driver.sleeper = mockOperations
|
||||||
|
}
|
||||||
|
|
||||||
func TestCreateVM(t *testing.T) {
|
func TestCreateVM(t *testing.T) {
|
||||||
shareName, shareDir := getShareDriveAndName()
|
shareName, shareDir := getShareDriveAndName()
|
||||||
|
|
||||||
operations := &MockCreateOperations{
|
|
||||||
test: t,
|
|
||||||
expectedCalls: []Call{
|
|
||||||
{"CopyIsoToMachineDir path default http://b2d.org", "", nil},
|
|
||||||
{"Generate path/machines/default/id_rsa", "", nil},
|
|
||||||
{"Create 20000 path/machines/default/id_rsa.pub path/machines/default/disk.vmdk", "", nil},
|
|
||||||
{"vbm createvm --basefolder path/machines/default --name default --register", "", nil},
|
|
||||||
{"vbm modifyvm default --firmware bios --bioslogofadein off --bioslogofadeout off --bioslogodisplaytime 0 --biosbootmenu disabled --ostype Linux26_64 --cpus 1 --memory 1024 --acpi on --ioapic on --rtcuseutc on --natdnshostresolver1 off --natdnsproxy1 off --cpuhotplug off --pae on --hpet on --hwvirtex on --nestedpaging on --largepages on --vtxvpid on --accelerate3d off --boot1 dvd", "", nil},
|
|
||||||
{"vbm modifyvm default --nic1 nat --nictype1 82540EM --cableconnected1 on", "", nil},
|
|
||||||
{"vbm storagectl default --name SATA --add sata --hostiocache on", "", nil},
|
|
||||||
{"vbm storageattach default --storagectl SATA --port 0 --device 0 --type dvddrive --medium path/machines/default/boot2docker.iso", "", nil},
|
|
||||||
{"vbm storageattach default --storagectl SATA --port 1 --device 0 --type hdd --medium path/machines/default/disk.vmdk", "", nil},
|
|
||||||
{"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountPrefix /", "", nil},
|
|
||||||
{"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountDir /", "", nil},
|
|
||||||
{"vbm sharedfolder add default --name " + shareName + " --hostpath " + shareDir + " --automount", "", nil},
|
|
||||||
{"vbm setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/" + shareName + " 1", "", nil},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
driver := NewDriver("default", "path")
|
driver := NewDriver("default", "path")
|
||||||
driver.Boot2DockerURL = "http://b2d.org"
|
mockCalls(t, driver, []Call{
|
||||||
driver.VBoxManager = operations
|
{"CopyIsoToMachineDir path default http://b2d.org", "", nil},
|
||||||
driver.b2dUpdater = operations
|
{"Generate path/machines/default/id_rsa", "", nil},
|
||||||
driver.sshKeyGenerator = operations
|
{"Create 20000 path/machines/default/id_rsa.pub path/machines/default/disk.vmdk", "", nil},
|
||||||
driver.diskCreator = operations
|
{"vbm createvm --basefolder path/machines/default --name default --register", "", nil},
|
||||||
driver.logsReader = operations
|
{"vbm modifyvm default --firmware bios --bioslogofadein off --bioslogofadeout off --bioslogodisplaytime 0 --biosbootmenu disabled --ostype Linux26_64 --cpus 1 --memory 1024 --acpi on --ioapic on --rtcuseutc on --natdnshostresolver1 off --natdnsproxy1 off --cpuhotplug off --pae on --hpet on --hwvirtex on --nestedpaging on --largepages on --vtxvpid on --accelerate3d off --boot1 dvd", "", nil},
|
||||||
driver.ipWaiter = operations
|
{"vbm modifyvm default --nic1 nat --nictype1 82540EM --cableconnected1 on", "", nil},
|
||||||
driver.randomInter = operations
|
{"vbm storagectl default --name SATA --add sata --hostiocache on", "", nil},
|
||||||
driver.sleeper = operations
|
{"vbm storageattach default --storagectl SATA --port 0 --device 0 --type dvddrive --medium path/machines/default/boot2docker.iso", "", nil},
|
||||||
|
{"vbm storageattach default --storagectl SATA --port 1 --device 0 --type hdd --medium path/machines/default/disk.vmdk", "", nil},
|
||||||
|
{"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountPrefix /", "", nil},
|
||||||
|
{"vbm guestproperty set default /VirtualBox/GuestAdd/SharedFolders/MountDir /", "", nil},
|
||||||
|
{"vbm sharedfolder add default --name " + shareName + " --hostpath " + shareDir + " --automount", "", nil},
|
||||||
|
{"vbm setextradata default VBoxInternal2/SharedFoldersEnableSymlinksCreate/" + shareName + " 1", "", nil},
|
||||||
|
})
|
||||||
|
|
||||||
err := driver.CreateVM()
|
err := driver.CreateVM()
|
||||||
|
|
||||||
|
@ -339,59 +343,46 @@ func TestCreateVM(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStart(t *testing.T) {
|
func TestStart(t *testing.T) {
|
||||||
operations := &MockCreateOperations{
|
|
||||||
test: t,
|
|
||||||
expectedCalls: []Call{
|
|
||||||
{"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil},
|
|
||||||
{"vbm list hostonlyifs", "", nil},
|
|
||||||
{"vbm hostonlyif create", "Interface 'VirtualBox Host-Only Ethernet Adapter' was successfully created", nil},
|
|
||||||
{"vbm list hostonlyifs", `
|
|
||||||
Name: VirtualBox Host-Only Ethernet Adapter
|
|
||||||
GUID: 786f6276-656e-4074-8000-0a0027000000
|
|
||||||
DHCP: Disabled
|
|
||||||
IPAddress: 192.168.99.1
|
|
||||||
NetworkMask: 255.255.255.0
|
|
||||||
IPV6Address:
|
|
||||||
IPV6NetworkMaskPrefixLength: 0
|
|
||||||
HardwareAddress: 0a:00:27:00:00:00
|
|
||||||
MediumType: Ethernet
|
|
||||||
Status: Up
|
|
||||||
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
|
||||||
{"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil},
|
|
||||||
{"vbm list dhcpservers", "", nil},
|
|
||||||
{"vbm list dhcpservers", "", nil},
|
|
||||||
{"vbm dhcpserver add --netname HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.6 --netmask 255.255.255.0 --lowerip 192.168.99.100 --upperip 192.168.99.254 --enable", "", nil},
|
|
||||||
{"vbm modifyvm default --nic2 hostonly --nictype2 82540EM --nicpromisc2 deny --hostonlyadapter2 VirtualBox Host-Only Ethernet Adapter --cableconnected2 on", "", nil},
|
|
||||||
{"IGNORE CALL", "", nil},
|
|
||||||
{"IGNORE CALL", "", nil},
|
|
||||||
{"vbm startvm default --type headless", "", nil},
|
|
||||||
{"Read path/machines/default/default/Logs/VBox.log", "", nil},
|
|
||||||
{"WaitIP", "", nil},
|
|
||||||
{"vbm list hostonlyifs", `
|
|
||||||
Name: VirtualBox Host-Only Ethernet Adapter
|
|
||||||
GUID: 786f6276-656e-4074-8000-0a0027000000
|
|
||||||
DHCP: Disabled
|
|
||||||
IPAddress: 192.168.99.1
|
|
||||||
NetworkMask: 255.255.255.0
|
|
||||||
IPV6Address:
|
|
||||||
IPV6NetworkMaskPrefixLength: 0
|
|
||||||
HardwareAddress: 0a:00:27:00:00:00
|
|
||||||
MediumType: Ethernet
|
|
||||||
Status: Up
|
|
||||||
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
driver := NewDriver("default", "path")
|
driver := NewDriver("default", "path")
|
||||||
driver.Boot2DockerURL = "http://b2d.org"
|
mockCalls(t, driver, []Call{
|
||||||
driver.VBoxManager = operations
|
{"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil},
|
||||||
driver.b2dUpdater = operations
|
{"vbm list hostonlyifs", "", nil},
|
||||||
driver.sshKeyGenerator = operations
|
{"vbm hostonlyif create", "Interface 'VirtualBox Host-Only Ethernet Adapter' was successfully created", nil},
|
||||||
driver.diskCreator = operations
|
{"vbm list hostonlyifs", `
|
||||||
driver.logsReader = operations
|
Name: VirtualBox Host-Only Ethernet Adapter
|
||||||
driver.ipWaiter = operations
|
GUID: 786f6276-656e-4074-8000-0a0027000000
|
||||||
driver.randomInter = operations
|
DHCP: Disabled
|
||||||
driver.sleeper = operations
|
IPAddress: 192.168.99.1
|
||||||
|
NetworkMask: 255.255.255.0
|
||||||
|
IPV6Address:
|
||||||
|
IPV6NetworkMaskPrefixLength: 0
|
||||||
|
HardwareAddress: 0a:00:27:00:00:00
|
||||||
|
MediumType: Ethernet
|
||||||
|
Status: Up
|
||||||
|
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
||||||
|
{"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil},
|
||||||
|
{"vbm list dhcpservers", "", nil},
|
||||||
|
{"vbm list dhcpservers", "", nil},
|
||||||
|
{"vbm dhcpserver add --netname HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.6 --netmask 255.255.255.0 --lowerip 192.168.99.100 --upperip 192.168.99.254 --enable", "", nil},
|
||||||
|
{"vbm modifyvm default --nic2 hostonly --nictype2 82540EM --nicpromisc2 deny --hostonlyadapter2 VirtualBox Host-Only Ethernet Adapter --cableconnected2 on", "", nil},
|
||||||
|
{"IGNORE CALL", "", nil},
|
||||||
|
{"IGNORE CALL", "", nil},
|
||||||
|
{"vbm startvm default --type headless", "", nil},
|
||||||
|
{"Read path/machines/default/default/Logs/VBox.log", "", nil},
|
||||||
|
{"WaitIP", "", nil},
|
||||||
|
{"vbm list hostonlyifs", `
|
||||||
|
Name: VirtualBox Host-Only Ethernet Adapter
|
||||||
|
GUID: 786f6276-656e-4074-8000-0a0027000000
|
||||||
|
DHCP: Disabled
|
||||||
|
IPAddress: 192.168.99.1
|
||||||
|
NetworkMask: 255.255.255.0
|
||||||
|
IPV6Address:
|
||||||
|
IPV6NetworkMaskPrefixLength: 0
|
||||||
|
HardwareAddress: 0a:00:27:00:00:00
|
||||||
|
MediumType: Ethernet
|
||||||
|
Status: Up
|
||||||
|
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
||||||
|
})
|
||||||
|
|
||||||
err := driver.Start()
|
err := driver.Start()
|
||||||
|
|
||||||
|
@ -399,14 +390,13 @@ VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`,
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStartWithHostOnlyAdapterCreationBug(t *testing.T) {
|
func TestStartWithHostOnlyAdapterCreationBug(t *testing.T) {
|
||||||
operations := &MockCreateOperations{
|
driver := NewDriver("default", "path")
|
||||||
test: t,
|
mockCalls(t, driver, []Call{
|
||||||
expectedCalls: []Call{
|
{"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil},
|
||||||
{"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil},
|
{"vbm list hostonlyifs", "", nil},
|
||||||
{"vbm list hostonlyifs", "", nil},
|
{"vbm hostonlyif create", "", errors.New("error: Failed to create the host-only adapter")},
|
||||||
{"vbm hostonlyif create", "", errors.New("error: Failed to create the host-only adapter")},
|
{"vbm list hostonlyifs", "", nil},
|
||||||
{"vbm list hostonlyifs", "", nil},
|
{"vbm list hostonlyifs", `
|
||||||
{"vbm list hostonlyifs", `
|
|
||||||
Name: VirtualBox Host-Only Ethernet Adapter
|
Name: VirtualBox Host-Only Ethernet Adapter
|
||||||
GUID: 786f6276-656e-4074-8000-0a0027000000
|
GUID: 786f6276-656e-4074-8000-0a0027000000
|
||||||
DHCP: Disabled
|
DHCP: Disabled
|
||||||
|
@ -418,17 +408,17 @@ HardwareAddress: 0a:00:27:00:00:00
|
||||||
MediumType: Ethernet
|
MediumType: Ethernet
|
||||||
Status: Up
|
Status: Up
|
||||||
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
||||||
{"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil},
|
{"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil},
|
||||||
{"vbm list dhcpservers", "", nil},
|
{"vbm list dhcpservers", "", nil},
|
||||||
{"vbm list dhcpservers", "", nil},
|
{"vbm list dhcpservers", "", nil},
|
||||||
{"vbm dhcpserver add --netname HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.6 --netmask 255.255.255.0 --lowerip 192.168.99.100 --upperip 192.168.99.254 --enable", "", nil},
|
{"vbm dhcpserver add --netname HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.6 --netmask 255.255.255.0 --lowerip 192.168.99.100 --upperip 192.168.99.254 --enable", "", nil},
|
||||||
{"vbm modifyvm default --nic2 hostonly --nictype2 82540EM --nicpromisc2 deny --hostonlyadapter2 VirtualBox Host-Only Ethernet Adapter --cableconnected2 on", "", nil},
|
{"vbm modifyvm default --nic2 hostonly --nictype2 82540EM --nicpromisc2 deny --hostonlyadapter2 VirtualBox Host-Only Ethernet Adapter --cableconnected2 on", "", nil},
|
||||||
{"IGNORE CALL", "", nil},
|
{"IGNORE CALL", "", nil},
|
||||||
{"IGNORE CALL", "", nil},
|
{"IGNORE CALL", "", nil},
|
||||||
{"vbm startvm default --type headless", "", nil},
|
{"vbm startvm default --type headless", "", nil},
|
||||||
{"Read path/machines/default/default/Logs/VBox.log", "", nil},
|
{"Read path/machines/default/default/Logs/VBox.log", "", nil},
|
||||||
{"WaitIP", "", nil},
|
{"WaitIP", "", nil},
|
||||||
{"vbm list hostonlyifs", `
|
{"vbm list hostonlyifs", `
|
||||||
Name: VirtualBox Host-Only Ethernet Adapter
|
Name: VirtualBox Host-Only Ethernet Adapter
|
||||||
GUID: 786f6276-656e-4074-8000-0a0027000000
|
GUID: 786f6276-656e-4074-8000-0a0027000000
|
||||||
DHCP: Disabled
|
DHCP: Disabled
|
||||||
|
@ -440,29 +430,67 @@ HardwareAddress: 0a:00:27:00:00:00
|
||||||
MediumType: Ethernet
|
MediumType: Ethernet
|
||||||
Status: Up
|
Status: Up
|
||||||
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter`, nil},
|
||||||
{"vbm showvminfo default --machinereadable", `VMState="running"`, nil},
|
{"vbm showvminfo default --machinereadable", `VMState="running"`, nil},
|
||||||
{"vbm controlvm default acpipowerbutton", "", nil},
|
{"vbm controlvm default acpipowerbutton", "", nil},
|
||||||
{"vbm showvminfo default --machinereadable", `VMState="stopped"`, nil},
|
{"vbm showvminfo default --machinereadable", `VMState="stopped"`, nil},
|
||||||
{"Sleep 5s", "", nil},
|
{"Sleep 5s", "", nil},
|
||||||
{"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil},
|
{"vbm hostonlyif ipconfig VirtualBox Host-Only Ethernet Adapter --ip 192.168.99.1 --netmask 255.255.255.0", "", nil},
|
||||||
{"Sleep 5s", "", nil},
|
{"Sleep 5s", "", nil},
|
||||||
{"vbm startvm default --type headless", "", nil},
|
{"vbm startvm default --type headless", "", nil},
|
||||||
{"WaitIP", "", nil},
|
{"WaitIP", "", nil},
|
||||||
},
|
})
|
||||||
}
|
|
||||||
|
|
||||||
driver := NewDriver("default", "path")
|
|
||||||
driver.Boot2DockerURL = "http://b2d.org"
|
|
||||||
driver.VBoxManager = operations
|
|
||||||
driver.b2dUpdater = operations
|
|
||||||
driver.sshKeyGenerator = operations
|
|
||||||
driver.diskCreator = operations
|
|
||||||
driver.logsReader = operations
|
|
||||||
driver.ipWaiter = operations
|
|
||||||
driver.randomInter = operations
|
|
||||||
driver.sleeper = operations
|
|
||||||
|
|
||||||
err := driver.Start()
|
err := driver.Start()
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRemoveStopped(t *testing.T) {
|
||||||
|
driver := NewDriver("default", "path")
|
||||||
|
mockCalls(t, driver, []Call{
|
||||||
|
{"vbm showvminfo default --machinereadable", `VMState="poweroff"`, nil},
|
||||||
|
{"vbm unregistervm --delete default", "", nil},
|
||||||
|
})
|
||||||
|
|
||||||
|
err := driver.Remove()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveStarted(t *testing.T) {
|
||||||
|
driver := NewDriver("default", "path")
|
||||||
|
mockCalls(t, driver, []Call{
|
||||||
|
{"vbm showvminfo default --machinereadable", `VMState="running"`, nil},
|
||||||
|
{"vbm controlvm default poweroff", "", nil},
|
||||||
|
{"vbm unregistervm --delete default", "", nil},
|
||||||
|
})
|
||||||
|
|
||||||
|
err := driver.Remove()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveSaved(t *testing.T) {
|
||||||
|
driver := NewDriver("default", "path")
|
||||||
|
mockCalls(t, driver, []Call{
|
||||||
|
{"vbm showvminfo default --machinereadable", `VMState="saved"`, nil},
|
||||||
|
{"vbm unregistervm --delete default", "", nil},
|
||||||
|
})
|
||||||
|
|
||||||
|
err := driver.Remove()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemovePaused(t *testing.T) {
|
||||||
|
driver := NewDriver("default", "path")
|
||||||
|
mockCalls(t, driver, []Call{
|
||||||
|
{"vbm showvminfo default --machinereadable", `VMState="running"`, nil},
|
||||||
|
{"vbm controlvm default poweroff", "", nil},
|
||||||
|
{"vbm unregistervm --delete default", "", nil},
|
||||||
|
})
|
||||||
|
|
||||||
|
err := driver.Remove()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue