93
93
self.add_clean_cmd('rm', log.logfile)
95
def get_version_info(self):
97
info = vcsversion.version_info
104
logging.info("Cleaning up")
105
while len(self._cleanup_cbs) > 0:
106
self._cleanup_cbs.pop(0)()
108
def add_clean_cb(self, cb):
109
self._cleanup_cbs.insert(0, cb)
111
def add_clean_cmd(self, *argv, **kwargs):
112
cb = lambda : util.run_cmd(*argv, **kwargs)
113
self.add_clean_cb(cb)
116
def cancel_cleanup(self, cb):
118
self._cleanup_cbs.remove(cb)
119
except ValueError, e:
120
# Wasn't in there. No worries.
123
95
def distro_help(self):
124
96
return 'Distro. Valid options: %s' % " ".join(VMBuilder.distros.keys())
149
121
self.register_setting('-m', '--mem', type='int', default=128, help='Assign MEM megabytes of memory to the guest vm. [default: %default]')
150
122
self.register_setting('--cpus', type='int', default=1, help='Number of virtual CPU\'s. [default: %default]')
152
group = self.setting_group('Network related options')
153
domainname = '.'.join(socket.gethostbyname_ex(socket.gethostname())[0].split('.')[1:]) or "defaultdomain"
154
group.add_option('--domain', metavar='DOMAIN', default=domainname, help='Set DOMAIN as the domain name of the guest [default: The domain of the machine running this script: %default].')
155
group.add_option('--ip', metavar='ADDRESS', default='dhcp', help='IP address in dotted form [default: %default].')
156
group.add_option('--mac', metavar='VALUE', help='MAC address of the guest [default: one will be automatically generated on first run].')
157
group.add_option('--mask', metavar='VALUE', help='IP mask in dotted form [default: based on ip setting]. Ignored if --ip is not specified.')
158
group.add_option('--net', metavar='ADDRESS', help='IP net address in dotted form [default: based on ip setting]. Ignored if --ip is not specified.')
159
group.add_option('--bcast', metavar='VALUE', help='IP broadcast in dotted form [default: based on ip setting]. Ignored if --ip is not specified.')
160
group.add_option('--gw', metavar='ADDRESS', help='Gateway (router) address in dotted form [default: based on ip setting (first valid address in the network)]. Ignored if --ip is not specified.')
161
group.add_option('--dns', metavar='ADDRESS', help='DNS address in dotted form [default: based on ip setting (first valid address in the network)] Ignored if --ip is not specified.')
162
self.register_setting_group(group)
164
124
def add_disk(self, *args, **kwargs):
165
125
"""Adds a disk image to the virtual machine"""
166
126
disk = Disk(self, *args, **kwargs)
272
232
self.distro.set_defaults()
273
233
self.hypervisor.set_defaults()
276
def ip_defaults(self):
278
is called to validate the ip configuration given and set defaults
281
logging.debug("ip: %s" % self.ip)
284
valid_mac_address = re.compile("([0-9a-f]{2}:){5}([0-9a-f]{2})", re.IGNORECASE)
285
if not valid_mac_address.search(self.mac):
286
raise VMBuilderUserError("Malformed MAC address entered: %s" % self.mac)
288
logging.debug("Valid mac given: %s" % self.mac)
290
if self.ip != 'dhcp':
291
if self.domain == '':
292
raise VMBuilderUserError('Domain is undefined and host has no domain set.')
295
numip = struct.unpack('I', socket.inet_aton(self.ip))[0]
297
raise VMBuilderUserError('%s is not a valid ip address' % self.ip)
300
ipclass = numip & 0xFF
301
if (ipclass > 0) and (ipclass <= 127):
303
elif (ipclass > 128) and (ipclass < 192):
305
elif (ipclass < 224):
308
raise VMBuilderUserError('The class of the ip address specified (%s) does not seem right' % self.ip)
310
mask = struct.unpack('I', socket.inet_aton(self.mask))[0]
312
numnet = numip & mask
315
self.net = socket.inet_ntoa( struct.pack('I', numnet ) )
317
self.bcast = socket.inet_ntoa( struct.pack('I', numnet + (mask ^ 0xFFFFFFFF)))
319
self.gw = socket.inet_ntoa( struct.pack('I', numnet + 0x01000000 ) )
323
self.mask = socket.inet_ntoa( struct.pack('I', mask ) )
325
logging.debug("net: %s" % self.net)
326
logging.debug("netmask: %s" % self.mask)
327
logging.debug("broadcast: %s" % self.bcast)
328
logging.debug("gateway: %s" % self.gw)
329
logging.debug("dns: %s" % self.dns)
331
235
def create_directory_structure(self):
332
236
"""Creates the directory structure where we'll be doing all the work
375
279
"""Creates the working directory for this vm and returns its path"""
376
280
return tempfile.mkdtemp('', 'vmbuilder', self.tmp)
378
def mount_partitions(self):
379
"""Mounts all the vm's partitions and filesystems below .rootmnt"""
380
logging.info('Mounting target filesystems')
381
fss = disk.get_ordered_filesystems(self)
384
self.distro.post_mount(fs)
386
self.fsmounted = True
388
def umount_partitions(self):
389
"""Unmounts all the vm's partitions and filesystems"""
390
logging.info('Unmounting target filesystem')
391
fss = VMBuilder.disk.get_ordered_filesystems(self)
395
for disk in self.disks:
398
self.fsmounted = False
400
282
def install(self):
401
283
if self.in_place:
402
284
self.installdir = self.rootmnt
424
306
raise VMBuilderUserError('You specified a "%s" config option in a config file, but that is not valid. Perhaps you meant "%s"?' % (opt, opt.replace('-', '_')))
427
308
self.call_hooks('preflight_check')
429
310
# Check repository availability
443
def install_file(self, path, contents=None, source=None, mode=None):
444
fullpath = '%s%s' % (self.installdir, path)
445
if source and not contents:
446
shutil.copy(source, fullpath)
448
fp = open(fullpath, 'w')
452
os.chmod(fullpath, mode)
455
324
def create(self):
457
326
The core vm creation method
499
368
logging.debug("Oh, dear, an exception occurred")
502
375
class _MyOptParser(optparse.OptionParser):
503
376
def format_arg_help(self, formatter):