Last active
February 10, 2022 16:41
-
-
Save h3ct0r/fd4fd4b7d4a583e71fbf50e35e6e0346 to your computer and use it in GitHub Desktop.
Python script to automatically import an OVA file in VirtualBox and generate several clones
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python | |
# -*- coding: utf-8 -*- | |
"""Import and generate clone of an OVA file in virtualbox | |
""" | |
import re | |
import sys | |
import uuid | |
import random | |
import os.path | |
import argparse | |
import subprocess | |
__author__ = "Héctor Azp (h3ct0r)" | |
def which(program): | |
import os | |
def is_exe(fpath): | |
return os.path.isfile(fpath) and os.access(fpath, os.X_OK) | |
fpath, fname = os.path.split(program) | |
if fpath: | |
if is_exe(program): | |
return program | |
else: | |
for path in os.environ["PATH"].split(os.pathsep): | |
path = path.strip('"') | |
exe_file = os.path.join(path, program) | |
if is_exe(exe_file): | |
return exe_file | |
return None | |
def list_vms(): | |
commandargs = ['VBoxManage', 'list', 'vms'] | |
proc = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | |
output, error = proc.communicate() | |
status = proc.wait() | |
return output | |
def import_vm(ova_path, vm_name): | |
commandargs = ['VBoxManage', 'import', ova_path, "--vsys", "0", "--vmname", vm_name] | |
proc = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | |
output, error = proc.communicate() | |
status = proc.wait() | |
if vm_name in list_vms(): | |
return True, [] | |
return False, [output, error] | |
def list_snapshosts(vm_name): | |
commandargs = ['VBoxManage', 'snapshot', vm_name, 'list'] | |
proc = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | |
output, error = proc.communicate() | |
status = proc.wait() | |
return output | |
def gen_snapshot(vm_name, snapshot_name): | |
#vboxmanage snapshot WinXP_[host]-01 take snap01 | |
commandargs = ['VBoxManage', 'snapshot', vm_name, "take", snapshot_name] | |
proc = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | |
output, error = proc.communicate() | |
status = proc.wait() | |
if snapshot_name in list_snapshosts(vm_name): | |
return True, [] | |
return False, [output, error] | |
def clone_vm(base_vm_name, original_vm_name, snapshot_name, clone_number=1): | |
clone_names = [base_vm_name + "_{:02}".format(i + 2) for i in xrange(clone_number)] | |
group_name = '/' + base_vm_name | |
err_msgs = [] | |
for c_name in clone_names: | |
commandargs = ['VBoxManage', 'clonevm', original_vm_name, "--options", "link", "--name", c_name, '--groups', group_name, '--snapshot', snapshot_name, '--register'] | |
proc = subprocess.Popen(commandargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | |
output, error = proc.communicate() | |
status = proc.wait() | |
result = (c_name in list_vms()) | |
if not result: | |
err_msgs.append([output, error]) | |
print '[INFO] Cloning:{}, result:{}, cmd:{}'.format(c_name, result, ' '.join(commandargs)) | |
if len(err_msgs) > 0: | |
return False, err_msgs | |
return True, err_msgs | |
pass | |
if __name__ == "__main__": | |
if which('VBoxManage') is None: | |
raise ValueError("VBoxManage not installed, please install VirtualBox") | |
parser = argparse.ArgumentParser(description='Automatic import and clone generation from OVA files to VirtualBox') | |
parser.add_argument('-i', '--input', help='Input OVA vile', required=True) | |
parser.add_argument('-name', '--vm_name', help='The name of the new imported VM', required=True) | |
parser.add_argument('-hname', '--hostname', help='The name the current machine', required=True) | |
parser.add_argument('-cn', '--clone_number', help='The number of clones for the imported VM', type=int, required=True) | |
args = vars(parser.parse_args()) | |
ova_filename = args['input'] | |
vm_name = args['vm_name'] | |
clone_number = args['clone_number'] | |
hostname = args['hostname'] | |
vm_name += '_' + hostname | |
first_imported_vm_name = vm_name + '_01' | |
if vm_name in list_vms() or first_imported_vm_name in list_vms(): | |
raise ValueError("This VM name already exist, please choose anoter VM name") | |
if not os.path.exists(ova_filename): | |
raise ValueError("The OVA file does not exist") | |
print '[INFO]', 'Importing:', ova_filename | |
import_result, err_msgs = import_vm(ova_filename, first_imported_vm_name) | |
print '[INFO]', 'Import result:', import_result | |
if not import_result: | |
print err_msgs | |
print '[ERROR]', 'Cannot import VM, please see log' | |
sys.exit(1) | |
snapshot_name = str(uuid.uuid4().get_hex().upper()[0:6]) | |
print '[INFO]', 'Creating snapshot:', snapshot_name | |
snapshot_result, err_msgs = gen_snapshot(first_imported_vm_name, snapshot_name) | |
print '[INFO]', 'Snapshot result:', snapshot_result | |
if not snapshot_result: | |
print err_msgs | |
print '[ERROR]', 'Cannot generate snapshot, please see log' | |
sys.exit(1) | |
print '[INFO]', 'Cloning vm:', first_imported_vm_name, 'into [', clone_number, '] new machines' | |
clone_result, err_msgs = clone_vm(vm_name, first_imported_vm_name, snapshot_name, clone_number=clone_number) | |
print '[INFO]', 'Cloning result:', clone_result | |
if not clone_result: | |
print err_msgs | |
print '[ERROR]', 'There was an error cloning the VM, please look previous debug lines to find the error' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment