#!/usr/bin/env python
# coding: utf-8
import os
import re
import logging # for logging mode/level
# Local Import
from linuxiso.ressources.tools import run_cmd
[docs]class Virtualbox(object):
"""
Class manage virtualbox with VBoxManage command
The typical use is:
- chose a config that containt all info about iso
- **list** iso managed
- get the **status** of one or all iso (**status_all**)
- do operation on iso like **download**, **download_all**,
**remove** or **remove_all**
>>> virtualbox = Virtualbox(conf)
>>> virtualbox.list_vms()
>>> virtualbox.create(
... hostname=hostname,
... recipe='Debian-amd64-standard',
... iso=./path/iso/debian.iso)
>>> virtualbox.run('Debian VM')
"""
def __init__(self, conf=None):
self.conf = conf
[docs] @staticmethod
def list_vms():
"""
Get list vms
return l_vm : dict result
"""
logging.info('Get list vms')
# == Command
l_vm_raw = run_cmd('VBoxManage list vms')
l_vm = []
# == Extract information with RegEX
regex = r"^\"(?P<hostname>[\w ]+)\" +\{(?P<id>[0-9a-f-]+)\}"
for ligne in l_vm_raw.split('\n'):
m = re.search(regex, ligne)
if m:
l_vm.append({
'name': m.group('hostname'),
'uid': m.group('id')})
return l_vm
[docs] @staticmethod
def list_ostypes():
"""
Get list ostypes
return l_ostypes : dict result
"""
logging.info('Get list ostypes')
# == Command
l_ostypes_raw = run_cmd("VBoxManage list ostypes")
l_ostypes = {}
logging.debug('Extract information with RegEX')
m_iter = re.finditer(r"ID:\s+(?P<id>\w*)\nDescription:\s+(?P<description>.*)\nFamily ID:\s+(?P<family_id>.*)\nFamily Desc:\s+(?P<family_desc>.*)\n64 bit:\s+(?P<b_64_bit>.*)",l_ostypes_raw,re.MULTILINE)
for match in m_iter:
l_ostypes[match.group("id")] = {
"description": match.group("description"),
"family_id": match.group("family_id"),
"family_desc": match.group("family_desc"),
"b_64_bit": match.group("b_64_bit")}
return l_ostypes
[docs] @staticmethod
def get_machine_folder():
"""Get machine folder"""
logging.info('Get machine folder')
ligne = run_cmd(
'VBoxManage list systemproperties |'
' grep \"Default machine folder:\"')
logging.debug('Extract information with RegEX')
m = re.search(r"^[^:]+:\s*(?P<dir_vm>.*)$", ligne)
return m.group("dir_vm")
[docs] @staticmethod
def run(hostname):
""" Run existing vm
>>> virtualbox = Virtualbox(conf)
>>> virtualbox.run('Debian VM')
"""
logging.info('Run existing vm')
run_cmd("VBoxManage startvm "+hostname)
[docs] def create(self, vm_name):
"""Create virtualbox vm
>>> from linuxiso.virtualbox import Virtualbox
>>> virtualbox = Virtualbox(conf)
>>> virtualbox.run('Debian VM')
>>> virtualbox.create(
... hostname=hostname,
... recipe='Debian-amd64-standard',
... iso=./path/iso/debian.iso)
"""
sub_conf = self.conf['virtualbox']['vms'][vm_name]
hostname = vm_name
dir_isocustom = self.conf['general']['dir_isocustom']
if 'install' in sub_conf.keys() and sub_conf['install']:
iso = os.path.join(dir_isocustom, sub_conf['install'])
else:
iso = None
logging.info('Create virtualbox vm')
l_vm = self.list_vms()
isexist = [x['name'] for x in l_vm if hostname == x['name']]
assert isexist == [], "Error : la vm '"+hostname+"' existe déjà"
# msg = "Error : la recipe '"+recipe+"' n'existe pas"
# assert recipe in self.conf['virtualbox']['recipes'].keys(), msg
# dir1 = conf['disk-dir']+'/'+conf['hostname']
# assert(not os.path.exists(dir1)), "Le dossier "+dir1+" existe déjà !"
# dir_iso = self.conf['general']['dir_input']
# dir_isocustom = self.conf['general']['dir_isocustom']
os_type = sub_conf['os_type']
file_disk_type = sub_conf['file_disk_type']
ram = str(sub_conf['ram'])
vram = str(sub_conf['vram'])
disk_size = sub_conf['disk_size']
interface_name = sub_conf['interface_name']
interface_type = sub_conf['interface_type']
dir_vm = self.get_machine_folder()
if not os.path.isdir(dir_vm):
os.mkdir(dir_vm)
os.chdir(dir_vm)
os.mkdir(dir_vm+os.sep+hostname)
os.chdir(dir_vm+os.sep+hostname)
# Create vm
run_cmd(
'VBoxManage createvm '
'--name "'+hostname+'" '
'--ostype "'+os_type+'" ' # Ex: "Debian_64"
'--register')
# Add SATA controller
run_cmd(
'VBoxManage storagectl "'+hostname+'" '
'--name "SATA Controller" '
'--add sata '
'--controller IntelAHCI')
# Add disks SATA controller
if isinstance(disk_size, int):
disk_size = [disk_size]
run_cmd(
'VBoxManage storagectl '+hostname+' '
'--name "SATA Controller" '
'--portcount '+str(len(disk_size))) # Number of disque
i = 0
for on_disk_size in disk_size:
ds = str(on_disk_size)
it = str(i)
disk_name = hostname+'_'+it+'.'+file_disk_type
# Create one disk
run_cmd(
'VBoxManage createhd '
'--filename "'+disk_name+'" ' # Ex:test_0.vmdk
'--size '+ds) # Disk size in Mo
# Attach one disk to SATA controller
run_cmd(
'VBoxManage storageattach "'+hostname+'" '
'--storagectl "SATA Controller" '
'--port '+it+' '
'--device 0 '
'--type hdd '
'--medium "'+disk_name+'"') # Ex:test_0.vmdk
i += 1
# Add IDE Controller
run_cmd(
'VBoxManage storagectl "'+hostname+'" '
'--name "IDE Controller" '
'--add ide')
# Mount the iso to the IDE controller
if iso:
run_cmd(
'VBoxManage storageattach "'+hostname+'" '
'--storagectl "IDE Controller" '
'--port 0 '
'--device 0 '
'--type dvddrive '
'--medium "'+iso+'"')
# Enable Input/Output (mouse, keyboard, ...)
run_cmd(
'VBoxManage modifyvm "'+hostname+'" '
'--ioapic on')
# Define boot order
run_cmd(
'VBoxManage modifyvm "'+hostname+'" '
'--boot1 dvd '
'--boot2 disk '
'--boot3 none '
'--boot4 none')
# Define RAM and VRAM(video)
run_cmd(
'VBoxManage modifyvm "'+hostname+'" '
'--memory '+ram+' '
'--vram '+vram)
# Connect network bridge interface
run_cmd(
'VBoxManage modifyvm "'+hostname+'" '
'--nic1 '+interface_type+' '
'--bridgeadapter1 '+interface_name)
[docs] def remove(self, name_or_uid):
"""Remove virtualbox vm
>>> virtualbox = Virtualbox(conf)
>>> virtualbox.remove('Debian VM')
"""
logging.info('Remove virtualbox vm')
# Remove vm
run_cmd(
'VBoxManage unregistervm "'+name_or_uid+'" '
'--delete')