-
Notifications
You must be signed in to change notification settings - Fork 4
/
MakeDebianVB.py
executable file
·239 lines (217 loc) · 11.6 KB
/
MakeDebianVB.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import time
__author__ = 'Andreas Bader'
__version__ = "0.01"
import argparse
import logging
import Util
import os
import shutil
from fabric.api import *
import re
neededTools = ["which", "VBoxManage", "vagrant"]
creation_commands = [
"VBoxManage createvm --name \"{name}\" --register",
"VBoxManage modifyvm \"{name}\" --ostype Debian_64",
"VBoxManage modifyvm \"{name}\" --memory 1024",
"VBoxManage modifyvm \"{name}\" --vram 8",
"VBoxManage modifyvm \"{name}\" --acpi on",
"VBoxManage modifyvm \"{name}\" --ioapic on",
"VBoxManage modifyvm \"{name}\" --boot1 dvd",
"VBoxManage modifyvm \"{name}\" --pae on",
"VBoxManage modifyvm \"{name}\" --longmode on",
"VBoxManage modifyvm \"{name}\" --hwvirtex on",
"VBoxManage modifyvm \"{name}\" --nestedpaging on",
"VBoxManage modifyvm \"{name}\" --largepages off",
"VBoxManage modifyvm \"{name}\" --vtxvpid on",
"VBoxManage modifyvm \"{name}\" --vtxux on",
"VBoxManage modifyvm \"{name}\" --accelerate3d off",
"VBoxManage modifyvm \"{name}\" --accelerate2dvideo off",
"VBoxManage modifyvm \"{name}\" --chipset piix3",
"VBoxManage modifyvm \"{name}\" --biossystemtimeoffset 0",
"VBoxManage modifyvm \"{name}\" --firmware bios",
"VBoxManage modifyvm \"{name}\" --monitorcount 1",
"VBoxManage modifyvm \"{name}\" --cpus 2",
"VBoxManage modifyvm \"{name}\" --rtcuseutc on",
"VBoxManage modifyvm \"{name}\" --nic1 nat",
"VBoxManage modifyvm \"{name}\" --cableconnected1 on",
"VBoxManage createhd --filename \"{path}/{name}.vdi\" --size \"{size}\" --format VDI --variant Standard",
"VBoxManage storagectl \"{name}\" --name \"IDE Controller\" --add ide",
"VBoxManage storagectl \"{name}\" --name \"SATA Controller\" --add sata",
"VBoxManage storageattach \"{name}\" --storagectl \"SATA Controller\" --port 0 --device 0 --type hdd --medium \"{path}/{name}.vdi\"",
"VBoxManage storageattach \"{name}\" --storagectl \"IDE Controller\" --port 0 --device 0 --type dvddrive --medium \"{iso}\""
]
timeout = 3600 # 1 hour should be enough
def delete_vm(name, logger):
with settings(warn_only=True), hide('output','running','warnings'):
ret = local("VBoxManage list vms", capture=True)
if base_box_name in ret.stdout:
uuid = re.search("^\"%s\"\s+\{[a-z0-9\-]+\}" % name,ret,re.MULTILINE)
if uuid is None:
logger.error("uuid of VM %s can't be found." %(name))
return False
uuid = re.search("\{[a-z0-9\-]+\}", uuid.group())
if uuid is None:
logger.error("uuid of VM %s can't be extracted from '%s'." %(name, uuid.group()))
return False
uuid = uuid.group().replace("{","").replace("}","")
# deleting all drives without iso files
# not necessary, --delete for unrgeistervm does it already
# drives = local("VBoxManage showvminfo %s" % uuid, capture=True)
# for res in re.findall("^IDE-Controller.+$|^SATA-Controller.+$", drives, re.MULTILINE):
# if ".iso" in res.lower():
# continue
# hdd_uuid = re.search("\(UUID:\s+[a-z0-9\-]+\)$",res)
# if hdd_uuid == None:
# logger.warning("Can't find UUID for hdd in '%s'. Please delete it by hand." %(hdd_uuid))
# continue
# hdd_uuid = hdd_uuid.group().replace("(UUID: ","").replace(")","")
if status_vm(uuid, logger):
logger.info("VM %s is running, stopping it..." %(name))
stop_vm(uuid, logger)
deleted = local("VBoxManage unregistervm %s --delete" % uuid)
if deleted.return_code != 0:
logger.error("Error while deleting VM %s with UUID %s. Please delete by hand!" %(name, uuid))
else:
logger.error("VM %s can't be found." %(name))
return False
return True
def create_vm(name, size, path, iso, logger):
with settings(warn_only=True), hide('output','running','warnings'):
for command in creation_commands:
ret = local(command.format(name=name, size=size, path=path, iso=iso), capture=True)
logger.info("Executing '%s'." % (command.format(name=name, size=size, path=path, iso=iso)))
if ret.return_code != 0:
logger.error("Command '%s' failed and returned with error code %s and stdout '%s' and stderr '%s'." %
(command.format(name=name, size=size, path=path, iso=iso), ret.return_code, ret.stdout, ret.stderr))
return False
logger.info("Command '%s' returned 0." % (command.format(name=name, size=size, path=path, iso=iso)))
return True
def start_vm(name, graphic, logger):
with settings(warn_only=True), hide('output','running','warnings'):
headless_arg=""
if not graphic:
headless_arg = " --type headless"
ret = local("VBoxManage startvm \"%s\"%s" %(name, headless_arg), capture=True)
logger.info("Executing 'VBoxHeadless --startvm \"%s\"%s'." % (name, headless_arg))
if ret.return_code != 0:
logger.error("Command 'VBoxHeadless --startvm \"%s\"%s' failed and returned with error "
"code %s and stdout '%s' and stderr '%s'." %
(name, headless_arg, ret.return_code, ret.stdout, ret.stderr))
return False
logger.info("Command 'VBoxHeadless --startvm \"%s\"%s' returned 0." % (name, headless_arg))
return True
def stop_vm(name, logger):
with settings(warn_only=True), hide('output','running','warnings'):
if status_vm(name, logger):
logger.info("Trying soft poweroff...")
ret = local("vboxmanage controlvm \"%s\" poweroff soft" % (name))
logger.info("Command 'vboxmanage controlvm \"%s\" poweroff soft' returned %s." % (name, ret.return_code))
if ret.return_code != 0:
logger.info("Soft poweroff failed, trying (hard) poweroff...")
ret = local("vboxmanage controlvm \"%s\" poweroff" % (name))
logger.info("Command 'vboxmanage controlvm \"%s\" poweroff' returned %s." % (name, ret.return_code))
if ret.return_code != 0:
return False
return True
def status_vm(name, logger):
with settings(warn_only=True), hide('output','running','warnings'):
ret = local("VBoxManage showvminfo \"%s\"" % name, capture=True)
if ret.return_code == 0:
state = re.search("State:\s+running", ret.stdout)
if state == None:
return False
else:
return True
else:
logger.error("Error while checking of VM %s, can't determine state." %(name))
return False
def exist_vm(name, logger):
with settings(warn_only=True), hide('output','running','warnings'):
ret = local("VBoxManage list vms", capture=True)
if ret.return_code == 0:
if name in ret.stdout:
return True
else:
return False
else:
logger.error("Error while checking of VM %s, can't determine existence." %(name))
return True
def package_vm(name, output_file, logger):
with settings(warn_only=True), hide('output','running','warnings'):
logger.info("Packaging vm with 'vagrant package --base \"%s\"'." %(name))
ret = local("vagrant package --base \"%s\" --output \"%s\"" %(name, output_file), capture=True)
if ret.return_code == 0:
logger.info("Packaging of VM %s returned 0." %(name))
return True
else:
logger.error("Packaging of VM %s returned %s with stdout '%s' and stderr '%s'."
% (name, ret.return_code, ret.stdout, ret.stderr))
return False
# Configure ArgumentParser
parser = argparse.ArgumentParser(prog="MakeDebianVB.py",version=__version__,description="Creates an Vagrant Box with/for VirtualBox for use with TSDBBench.", formatter_class=argparse.RawDescriptionHelpFormatter, epilog="")
parser.add_argument("-i", "--isofile", metavar="ISOFILE", required=True, help="path to Debian Autoinstall Iso")
parser.add_argument("-f", "--outputfolder", metavar="OUTPUTFOLDER", required=True, help="path to outputfolder (will be created if not existent) (> 5 gb)")
parser.add_argument("-g", "--graphic", action="store_true", help="show graphic output, normally -nographic is used. Useful if you don't use a preseeded iso.")
parser.add_argument("-o", "--overwrite", action="store_true", help="overwrite if VM is existing")
parser.add_argument("-l", "--log", action='store_true', help="Be more verbose, log vagrant output.")
parser.add_argument("-s", "--size", metavar="SIZE", type=int, default=50, help="Size in Gigabyte (50 is default), e.g. 50 for 50G (will be compressed, Qcow2 file size will be much lesser!)")
args = parser.parse_args()
# Configure Logging
logLevel = logging.WARN
if args.log:
logLevel = logging.DEBUG
logging.basicConfig(level=logLevel)
logger = logging.getLogger(__name__)
# Check ob alle Tools da sind
for tool in neededTools:
with settings(warn_only=True), hide('output','running','warnings'):
ret=local("which '%s'" %(tool))
if ret.return_code != 0:
logger.error("'%s' not found, please install." %(tool))
exit(-1)
if not (Util.check_file_exists(args.isofile) and Util.check_file_readable(args.isofile)):
logger.error("Isofile %s does not exist or is not readable." %(args.isofile))
exit(-1)
if not Util.check_folder(args.outputfolder,logger,False,True):
if not Util.create_folder(args.outputfolder) or not Util.check_folder(args.outputfolder,logger):
logger.error("Can't create %s." %(args.outputfolder))
exit(-1)
isoFileName=os.path.basename(args.isofile)
base_box_name="default"
if len(os.path.splitext(args.isofile)) > 0:
base_box_name=os.path.splitext(isoFileName)[0]
outputFileName="%s.box" %(base_box_name)
## Checking if Virtualbox exists
if exist_vm(base_box_name, logger):
if not args.overwrite:
logger.error("Error: VM %s already exists." % base_box_name)
else:
if not delete_vm(base_box_name, logger):
logger.error("Error: VM %s already exists and can't be deleted." % base_box_name)
exit(-1)
if create_vm(base_box_name, int(round(args.size*953.674)), args.outputfolder, args.isofile, logger):
if start_vm(base_box_name, args.graphic, logger):
logger.info("Waiting for Installation to finish...")
start_time = time.time()
while status_vm(base_box_name, logger) and time.time()-start_time <= timeout:
time.sleep(1)
if time.time()-start_time > timeout:
logger.error("VM took more than %s seconds. Timeout activated." % timeout)
else:
logger.info("VM is now powered off.")
logger.info("Packaging VM with Vagrant.")
if package_vm(base_box_name, os.path.join(args.outputfolder, outputFileName), logger):
print "Packaging was successful. You can now import your new base box with" \
" 'vagrant box add tsdbbench-debian %s'" %(os.path.join(args.outputfolder, outputFileName))
logger.info("Deleting VM.")
if not delete_vm(base_box_name, logger):
logger.warning("Error: VM %s can't be deleted, please delete by hand." % base_box_name)
else:
logger.error("Error: VM %s can't be started." % base_box_name)
exit(-1)
else:
logger.error("Error: VM %s can't be created." % base_box_name)
exit(-1)
exit(0)