mirror of
https://github.com/kevingruesser/bootstrap-vz.git
synced 2025-08-24 15:36:27 +00:00
Refactor. Locking a vbox is now quite a bit easier
This commit is contained in:
parent
6f23bcaafc
commit
6a0bef147a
7 changed files with 165 additions and 115 deletions
10
tests/integration/images/__init__.py
Normal file
10
tests/integration/images/__init__.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
class Image(object):
|
||||||
|
|
||||||
|
def __init__(self, manifest):
|
||||||
|
self.manifest = manifest
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
pass
|
||||||
|
|
18
tests/integration/images/virtualbox.py
Normal file
18
tests/integration/images/virtualbox.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from . import Image
|
||||||
|
import virtualbox as vboxapi
|
||||||
|
|
||||||
|
|
||||||
|
class VirtualBoxImage(Image):
|
||||||
|
|
||||||
|
def __init__(self, manifest, image_path):
|
||||||
|
super(VirtualBoxImage, self).__init__(manifest)
|
||||||
|
self.image_path = image_path
|
||||||
|
self.vbox = vboxapi.VirtualBox()
|
||||||
|
self.medium = self.vbox.open_medium(self.image_path, # location
|
||||||
|
vboxapi.library.DeviceType.hard_disk, # decive_type
|
||||||
|
vboxapi.library.AccessMode.read_only, # access_mode
|
||||||
|
False) # force_new_uuid
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
self.medium.close()
|
16
tests/integration/instances/__init__.py
Normal file
16
tests/integration/instances/__init__.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
|
||||||
|
class Instance(object):
|
||||||
|
|
||||||
|
def __init__(self, name, image):
|
||||||
|
self.name = name
|
||||||
|
self.image = image
|
||||||
|
|
||||||
|
def boot(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
pass
|
95
tests/integration/instances/virtualbox.py
Normal file
95
tests/integration/instances/virtualbox.py
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from . import Instance
|
||||||
|
import virtualbox as vboxapi
|
||||||
|
|
||||||
|
|
||||||
|
class VirtualBoxInstance(Instance):
|
||||||
|
|
||||||
|
cpus = 1
|
||||||
|
memory = 256
|
||||||
|
|
||||||
|
def __init__(self, name, image):
|
||||||
|
super(VirtualBoxInstance, self).__init__(name, image)
|
||||||
|
self.vbox = vboxapi.VirtualBox()
|
||||||
|
manager = vboxapi.Manager()
|
||||||
|
self.session = manager.get_session()
|
||||||
|
|
||||||
|
def create(self):
|
||||||
|
# create machine
|
||||||
|
os_type = {'x86': 'Debian',
|
||||||
|
'amd64': 'Debian_64'}.get(self.image.manifest.system['architecture'])
|
||||||
|
self.machine = self.vbox.create_machine(settings_file='', name=self.name,
|
||||||
|
groups=[], os_type_id=os_type, flags='')
|
||||||
|
self.machine.cpu_count = self.cpus
|
||||||
|
self.machine.memory_size = self.memory
|
||||||
|
self.machine.save_settings() # save settings, so that we can register it
|
||||||
|
self.vbox.register_machine(self.machine)
|
||||||
|
|
||||||
|
# attach image
|
||||||
|
with self.Lock(self.machine, self.session) as machine:
|
||||||
|
strg_ctrl = machine.add_storage_controller('SATA Controller',
|
||||||
|
vboxapi.library.StorageBus.sata)
|
||||||
|
strg_ctrl.port_count = 1
|
||||||
|
machine.attach_device(name='SATA Controller', controller_port=0, device=0,
|
||||||
|
type_p=vboxapi.library.DeviceType.hard_disk,
|
||||||
|
medium=self.image.medium)
|
||||||
|
machine.save_settings()
|
||||||
|
|
||||||
|
# redirect serial port
|
||||||
|
with self.Lock(self.machine, self.session) as machine:
|
||||||
|
serial_port = machine.get_serial_port(0)
|
||||||
|
serial_port.enabled = True
|
||||||
|
import tempfile
|
||||||
|
handle, self.serial_port_path = tempfile.mkstemp()
|
||||||
|
import os
|
||||||
|
os.close(handle)
|
||||||
|
serial_port.path = self.serial_port_path
|
||||||
|
serial_port.host_mode = vboxapi.library.PortMode.host_pipe
|
||||||
|
# serial_port.server = True
|
||||||
|
machine.save_settings()
|
||||||
|
|
||||||
|
def boot(self):
|
||||||
|
self.machine.launch_vm_process(self.session, 'headless').wait_for_completion(-1)
|
||||||
|
|
||||||
|
def shutdown(self):
|
||||||
|
self.session.console.power_down().wait_for_completion(-1)
|
||||||
|
self.Lock(self.machine, self.session).unlock()
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
if hasattr(self, 'machine'):
|
||||||
|
try:
|
||||||
|
with self.Lock(self.machine, self.session) as machine:
|
||||||
|
machine.detach_device(name='SATA Controller', controller_port=0, device=0)
|
||||||
|
machine.save_settings()
|
||||||
|
except vboxapi.library.VBoxErrorObjectNotFound:
|
||||||
|
pass
|
||||||
|
self.machine.unregister(vboxapi.library.CleanupMode.unregister_only)
|
||||||
|
self.machine.remove(delete=True)
|
||||||
|
|
||||||
|
class Lock(object):
|
||||||
|
def __init__(self, machine, session):
|
||||||
|
self.machine = machine
|
||||||
|
self.session = session
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self.lock()
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
return self.unlock()
|
||||||
|
|
||||||
|
def lock(self):
|
||||||
|
self.unlock()
|
||||||
|
self.machine.lock_machine(self.session, vboxapi.library.LockType.write)
|
||||||
|
return self.session.machine
|
||||||
|
|
||||||
|
def unlock(self):
|
||||||
|
from ..tools import waituntil
|
||||||
|
if self.machine.session_state == vboxapi.library.SessionState.unlocked:
|
||||||
|
return
|
||||||
|
if self.machine.session_state == vboxapi.library.SessionState.unlocking:
|
||||||
|
waituntil(lambda: self.machine.session_state == vboxapi.library.SessionState.unlocked)
|
||||||
|
return
|
||||||
|
if self.machine.session_state == vboxapi.library.SessionState.spawning:
|
||||||
|
waituntil(lambda: self.machine.session_state == vboxapi.library.SessionState.locked)
|
||||||
|
self.session.unlock_machine()
|
||||||
|
waituntil(lambda: self.machine.session_state == vboxapi.library.SessionState.unlocked)
|
|
@ -1,25 +0,0 @@
|
||||||
import virtualbox
|
|
||||||
|
|
||||||
|
|
||||||
class Image(object):
|
|
||||||
|
|
||||||
def __init__(self, manifest):
|
|
||||||
self.manifest = manifest
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualBoxImage(Image):
|
|
||||||
|
|
||||||
def __init__(self, manifest, image_path):
|
|
||||||
super(VirtualBoxImage, self).__init__(manifest)
|
|
||||||
self.image_path = image_path
|
|
||||||
self.vbox = virtualbox.VirtualBox()
|
|
||||||
self.medium = self.vbox.open_medium(self.image_path, # location
|
|
||||||
virtualbox.library.DeviceType.hard_disk, # decive_type
|
|
||||||
virtualbox.library.AccessMode.read_only, # access_mode
|
|
||||||
False) # force_new_uuid
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
self.medium.close()
|
|
|
@ -1,71 +0,0 @@
|
||||||
import virtualbox
|
|
||||||
|
|
||||||
|
|
||||||
class Instance(object):
|
|
||||||
|
|
||||||
def __init__(self, name, image):
|
|
||||||
self.name = name
|
|
||||||
self.image = image
|
|
||||||
|
|
||||||
def boot(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class VirtualBoxInstance(Instance):
|
|
||||||
|
|
||||||
cpus = 1
|
|
||||||
memory = 256
|
|
||||||
|
|
||||||
def __init__(self, name, image):
|
|
||||||
super(VirtualBoxInstance, self).__init__(name, image)
|
|
||||||
self.vbox = virtualbox.VirtualBox()
|
|
||||||
manager = virtualbox.Manager()
|
|
||||||
self.session = manager.get_session()
|
|
||||||
|
|
||||||
def create(self):
|
|
||||||
if self.image.manifest.system['architecture'] == 'x86':
|
|
||||||
os_type = 'Debian'
|
|
||||||
else:
|
|
||||||
os_type = 'Debian_64'
|
|
||||||
self.machine = self.vbox.create_machine(settings_file='', name=self.name,
|
|
||||||
groups=[], os_type_id=os_type, flags='')
|
|
||||||
self.machine.cpu_count = self.cpus
|
|
||||||
self.machine.memory_size = self.memory
|
|
||||||
self.machine.save_settings() # save settings, so that we can register it
|
|
||||||
self.vbox.register_machine(self.machine)
|
|
||||||
self.machine.lock_machine(self.session, virtualbox.library.LockType.write)
|
|
||||||
strg_ctrl = self.session.machine.add_storage_controller('SATA Controller',
|
|
||||||
virtualbox.library.StorageBus.sata)
|
|
||||||
strg_ctrl.port_count = 1
|
|
||||||
self.session.machine.attach_device(name='SATA Controller', controller_port=0, device=0,
|
|
||||||
type_p=virtualbox.library.DeviceType.hard_disk,
|
|
||||||
medium=self.image.medium)
|
|
||||||
self.session.machine.save_settings() # save changes to the controller
|
|
||||||
self._unlock_machine()
|
|
||||||
|
|
||||||
def boot(self):
|
|
||||||
self.machine.launch_vm_process(self.session, 'headless').wait_for_completion(-1)
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
self.session.console.power_down().wait_for_completion(-1)
|
|
||||||
self._unlock_machine()
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
if hasattr(self, 'machine'):
|
|
||||||
self.machine.lock_machine(self.session, virtualbox.library.LockType.shared)
|
|
||||||
self.session.machine.detach_device(name='SATA Controller', controller_port=0, device=0)
|
|
||||||
self.session.machine.save_settings()
|
|
||||||
self._unlock_machine()
|
|
||||||
self.machine.unregister(virtualbox.library.CleanupMode.unregister_only)
|
|
||||||
self.machine.remove(delete=True)
|
|
||||||
|
|
||||||
def _unlock_machine(self):
|
|
||||||
from . import waituntil
|
|
||||||
self.session.unlock_machine()
|
|
||||||
waituntil(lambda: self.machine.session_state != virtualbox.library.SessionState.locked)
|
|
|
@ -1,10 +1,10 @@
|
||||||
import tools
|
import tools
|
||||||
import tools.images
|
|
||||||
import tools.instances
|
|
||||||
from manifests import partials
|
from manifests import partials
|
||||||
from bootstrapvz.base.manifest import Manifest
|
from bootstrapvz.base.manifest import Manifest
|
||||||
from bootstrapvz.remote.build_servers import pick_build_server
|
from bootstrapvz.remote.build_servers import pick_build_server
|
||||||
from . import build_servers
|
from . import build_servers
|
||||||
|
from images.virtualbox import VirtualBoxImage
|
||||||
|
from instances.virtualbox import VirtualBoxInstance
|
||||||
|
|
||||||
|
|
||||||
def test_virtualbox_unpartitioned_extlinux():
|
def test_virtualbox_unpartitioned_extlinux():
|
||||||
|
@ -19,42 +19,49 @@ volume:
|
||||||
partitions:
|
partitions:
|
||||||
type: msdos
|
type: msdos
|
||||||
""")
|
""")
|
||||||
manifest_data = tools.merge_dicts(partials['base'], partials['stable64'],
|
manifest_data = tools.merge_dicts(partials['base'], partials['stable64'], partials['unpartitioned'],
|
||||||
partials['unpartitioned'], partials['root_password'],
|
partials['root_password'], partials['apt_proxy'],
|
||||||
manifest_data)
|
manifest_data)
|
||||||
|
|
||||||
build_server = pick_build_server(build_servers, manifest_data)
|
build_server = pick_build_server(build_servers, manifest_data)
|
||||||
manifest_data = build_server.apply_build_settings(manifest_data)
|
manifest_data = build_server.apply_build_settings(manifest_data)
|
||||||
manifest = Manifest(data=manifest_data)
|
manifest = Manifest(data=manifest_data)
|
||||||
|
|
||||||
bootstrap_info = tools.bootstrap(manifest, build_server)
|
# bootstrap_info = tools.bootstrap(manifest, build_server)
|
||||||
|
from bootstrapvz.base.bootstrapinfo import BootstrapInformation
|
||||||
|
bootstrap_info = BootstrapInformation(manifest)
|
||||||
|
bootstrap_info.volume.image_path = '/target/debian-wheezy-amd64-141218.vdi'
|
||||||
|
|
||||||
from bootstrapvz.remote.build_servers import LocalBuildServer
|
from bootstrapvz.remote.build_servers import LocalBuildServer
|
||||||
if isinstance(build_server, LocalBuildServer):
|
if isinstance(build_server, LocalBuildServer):
|
||||||
image_path = bootstrap_info.volume.image_path
|
image_path = bootstrap_info.volume.image_path
|
||||||
else:
|
else:
|
||||||
import tempfile
|
# import tempfile
|
||||||
handle, image_path = tempfile.mkstemp()
|
# handle, image_path = tempfile.mkstemp()
|
||||||
import os
|
# import os
|
||||||
os.close(handle)
|
# os.close(handle)
|
||||||
build_server.download(bootstrap_info.volume.image_path, image_path)
|
# build_server.download(bootstrap_info.volume.image_path, image_path)
|
||||||
build_server.delete(bootstrap_info.volume.image_path)
|
# build_server.delete(bootstrap_info.volume.image_path)
|
||||||
|
image_path = '/Users/anders/Workspace/cloud/images/debian-wheezy-amd64-141130.vmdk'
|
||||||
|
|
||||||
|
image = VirtualBoxImage(manifest, image_path)
|
||||||
|
lines = []
|
||||||
try:
|
try:
|
||||||
image = tools.images.VirtualBoxImage(manifest, image_path)
|
instance = VirtualBoxInstance('unpartitioned_extlinux', image)
|
||||||
try:
|
try:
|
||||||
instance = tools.instances.VirtualBoxInstance('unpartitioned_extlinux', image)
|
|
||||||
instance.create()
|
instance.create()
|
||||||
try:
|
try:
|
||||||
instance.boot()
|
instance.boot()
|
||||||
|
lines = instance.get_console_output()
|
||||||
# tools.reachable_with_ssh(instance)
|
# tools.reachable_with_ssh(instance)
|
||||||
finally:
|
finally:
|
||||||
instance.shutdown()
|
instance.shutdown()
|
||||||
finally:
|
finally:
|
||||||
if 'instance' in locals():
|
instance.destroy()
|
||||||
instance.destroy()
|
|
||||||
finally:
|
finally:
|
||||||
if 'image' in locals():
|
# pass
|
||||||
image.destroy()
|
if len(lines) > 0:
|
||||||
import os
|
raise Exception('\n'.join(lines))
|
||||||
os.remove(image_path)
|
# image.destroy()
|
||||||
|
# import os
|
||||||
|
# os.remove(image_path)
|
||||||
|
|
Loading…
Add table
Reference in a new issue