Revision 1dfa7776 util/vm/build.py
util/vm/build.py | ||
---|---|---|
150 | 150 |
|
151 | 151 |
|
152 | 152 |
def extractKernel( image, flavor ): |
153 |
"Extract kernel from base image" |
|
153 |
"Extract kernel and initrd from base image"
|
|
154 | 154 |
kernel = path.join( VMImageDir, flavor + '-vmlinuz' ) |
155 |
initrd = path.join( VMImageDir, flavor + '-initrd' ) |
|
155 | 156 |
if path.exists( kernel ) and ( stat( image )[ ST_MODE ] & 0777 ) == 0444: |
156 |
return kernel |
|
157 |
# If kernel is there, then initrd should also be there |
|
158 |
return kernel, initrd |
|
157 | 159 |
log( '* Extracting kernel to', kernel ) |
158 | 160 |
nbd = attachNBD( image, flags='-r' ) |
159 | 161 |
print srun( 'partx ' + nbd ) |
160 | 162 |
# Assume kernel is in partition 1/boot/vmlinuz*generic for now |
161 | 163 |
part = nbd + 'p1' |
162 | 164 |
mnt = mkdtemp() |
163 |
srun( 'mount %s %s' % ( part, mnt ) ) |
|
165 |
srun( 'mount -o ro %s %s' % ( part, mnt ) )
|
|
164 | 166 |
kernsrc = glob( '%s/boot/vmlinuz*generic' % mnt )[ 0 ] |
165 |
run( 'sudo cp %s %s' % ( kernsrc, kernel ) ) |
|
166 |
run( 'sudo chmod 0444 ' + kernel ) |
|
167 |
initrdsrc = glob( '%s/boot/initrd*generic' % mnt )[ 0 ] |
|
168 |
srun( 'cp %s %s' % ( initrdsrc, initrd ) ) |
|
169 |
srun( 'chmod 0444 ' + initrd ) |
|
170 |
srun( 'cp %s %s' % ( kernsrc, kernel ) ) |
|
171 |
srun( 'chmod 0444 ' + kernel ) |
|
167 | 172 |
srun( 'umount ' + mnt ) |
168 | 173 |
run( 'rmdir ' + mnt ) |
169 | 174 |
detachNBD( nbd ) |
170 |
return kernel |
|
175 |
return kernel, initrd
|
|
171 | 176 |
|
172 | 177 |
|
173 | 178 |
def findBaseImage( flavor, size='8G' ): |
... | ... | |
189 | 194 |
# Write-protect image, also signaling it is complete |
190 | 195 |
log( '* Write-protecting image', image) |
191 | 196 |
os.chmod( image, 0444 ) |
192 |
kernel = extractKernel( image, flavor ) |
|
197 |
kernel, initrd = extractKernel( image, flavor )
|
|
193 | 198 |
log( '* Using base image', image, 'and kernel', kernel ) |
194 |
return image, kernel |
|
199 |
return image, kernel, initrd
|
|
195 | 200 |
|
196 | 201 |
|
197 | 202 |
# Kickstart and Preseed files for Ubuntu/Debian installer |
... | ... | |
279 | 284 |
return floppy, kickstart, preseed |
280 | 285 |
|
281 | 286 |
|
282 |
def kvmFor( path ): |
|
287 |
def kvmFor( filepath ):
|
|
283 | 288 |
"Guess kvm version for file path" |
284 |
name = path.basename( path ) |
|
289 |
name = path.basename( filepath )
|
|
285 | 290 |
if '64' in name: |
286 | 291 |
kvm = 'qemu-system-x86_64' |
287 | 292 |
elif 'i386' in name or '32' in name: |
... | ... | |
335 | 340 |
log( '* Ubuntu installation completed in %.2f seconds ' % elapsed ) |
336 | 341 |
|
337 | 342 |
|
338 |
def boot( cow, kernel, logfile ): |
|
343 |
def boot( cow, kernel, initrd, logfile ):
|
|
339 | 344 |
"""Boot qemu/kvm with a COW disk and local/user data store |
340 | 345 |
cow: COW disk path |
341 | 346 |
kernel: kernel path |
... | ... | |
353 | 358 |
'-m 1024', |
354 | 359 |
'-k en-us', |
355 | 360 |
'-kernel', kernel, |
361 |
'-initrd', initrd, |
|
356 | 362 |
'-drive file=%s,if=virtio' % cow, |
357 | 363 |
'-append "root=/dev/vda1 init=/sbin/init console=ttyS0" ' ] |
358 | 364 |
cmd = ' '.join( cmd ) |
... | ... | |
432 | 438 |
def build( flavor='raring32server' ): |
433 | 439 |
"Build a Mininet VM" |
434 | 440 |
start = time() |
435 |
date = time.strftime( '%y%m%d-%H:%M:%S', time.localtime()) |
|
436 |
dir = os.mkdir( 'mn-' + flavor + date ) |
|
441 |
date = strftime( '%y%m%d-%H-%M-%S', localtime()) |
|
442 |
dir = 'mn-%s-%s' % ( flavor, date ) |
|
443 |
try: |
|
444 |
os.mkdir( dir ) |
|
445 |
except: |
|
446 |
raise Exception( "Failed to create build directory %s" % dir ) |
|
437 | 447 |
os.chdir( dir ) |
438 | 448 |
log( '* Created working directory', dir ) |
439 |
image, kernel = findBaseImage( flavor ) |
|
449 |
image, kernel, initrd = findBaseImage( flavor )
|
|
440 | 450 |
volume = flavor + '.qcow2' |
441 | 451 |
run( 'qemu-img create -f qcow2 -b %s %s' % ( image, volume ) ) |
442 | 452 |
log( '* VM image for', flavor, 'created as', volume ) |
443 | 453 |
logfile = open( flavor + '.log', 'w+' ) |
444 | 454 |
log( '* Logging results to', abspath( logfile.name ) ) |
445 |
vm = boot( volume, kernel, logfile ) |
|
455 |
vm = boot( volume, kernel, initrd, logfile )
|
|
446 | 456 |
interact( vm ) |
447 | 457 |
vmdk = convert( volume, basename=flavor ) |
448 | 458 |
log( '* Converted VM image stored as', abspath( vmdk ) ) |
... | ... | |
463 | 473 |
"Parse command line arguments and run" |
464 | 474 |
parser = argparse.ArgumentParser( description='Mininet VM build script' ) |
465 | 475 |
parser.add_argument( '--depend', action='store_true', |
466 |
help='Install dependencies for this script' )
|
|
476 |
help='install dependencies for this script' )
|
|
467 | 477 |
parser.add_argument( '--list', action='store_true', |
468 | 478 |
help='list valid build flavors' ) |
469 | 479 |
parser.add_argument( '--clean', action='store_true', |
Also available in: Unified diff