| [245] | 1 | #!/usr/bin/env python2.5 | 
|---|
| [231] | 2 |  | 
|---|
 | 3 | import sys | 
|---|
 | 4 | import os | 
|---|
 | 5 | import shutil | 
|---|
 | 6 | import tempfile | 
|---|
| [336] | 7 | import time | 
|---|
 | 8 | from subprocess import call, check_call, Popen, PIPE | 
|---|
| [231] | 9 |  | 
|---|
| [528] | 10 | # Make sure to use up fd 0 to avoid a bug in subprocess in Python <= 2.5.1 | 
|---|
 | 11 | # NB we need to do this on every Python remctl script. | 
|---|
 | 12 | # See r53624 in Python svn. | 
|---|
 | 13 | sys.stdin = open('/dev/null') | 
|---|
 | 14 |  | 
|---|
| [231] | 15 | def losetup(source, offset=0): | 
|---|
| [449] | 16 |   p = Popen(['sipb-xen-losetup', source, str(offset)], stdout=PIPE) | 
|---|
 | 17 |   return p.communicate()[0].strip() | 
|---|
| [231] | 18 |  | 
|---|
| [405] | 19 | def frob_copy_in_vm(target, *args): | 
|---|
| [338] | 20 |   '''UNUSED: maybe we'll use this someday; it does isolate the frobber.''' | 
|---|
| [336] | 21 |   # 1. prepare arguments volume | 
|---|
| [245] | 22 |   args_volume = prefix+target+'_args' | 
|---|
 | 23 |   args_device = '/dev/xenvg/' + args_volume | 
|---|
 | 24 |   check_call(['/sbin/lvcreate', 'xenvg', '--name', args_volume, '--size', '4K']) | 
|---|
 | 25 |   file(args_device, 'w').write('\n'.join(args) + '\n') | 
|---|
 | 26 |  | 
|---|
| [336] | 27 |   # 2. invoke frobber vm | 
|---|
| [245] | 28 |   copier_device = '/dev/xenvg/d_wert_hda' | 
|---|
 | 29 |   check_call(['/usr/sbin/xm', 'create', 'sipb-database', | 
|---|
 | 30 |               'machine_name='+target, | 
|---|
 | 31 |               'disks=' + ' '.join(['phy:'+copier_device+',hda,w', | 
|---|
 | 32 |                                    'phy:'+target_device+',hdc,w', | 
|---|
 | 33 |                                    'phy:'+args_device+',hdd,w'])]) | 
|---|
 | 34 |  | 
|---|
| [336] | 35 |   # XXX should check_call(['/sbin/lvremove', '-f', 'xenvg/'+args_volume]) | 
|---|
| [245] | 36 |  | 
|---|
| [405] | 37 | def frob_copy(target, hostname, rootpw): | 
|---|
 | 38 |   """target should be an LV device filename""" | 
|---|
| [336] | 39 |   # 1: mount filesystem | 
|---|
 | 40 |   fs = losetup(target, 32256) | 
|---|
 | 41 |   mntdir = tempfile.mkdtemp('', 'auto-install.frob.', '/tmp') | 
|---|
 | 42 |   call(['mount', '-t', 'ext3', fs, mntdir]) | 
|---|
 | 43 |   # 2: do frobbing | 
|---|
| [405] | 44 |   call(['/usr/sbin/chroot', mntdir, '/post-copy', hostname, rootpw]) | 
|---|
| [336] | 45 |   # 3: clean up | 
|---|
 | 46 |   call(['umount', mntdir]) | 
|---|
| [338] | 47 |   os.rmdir(mntdir) | 
|---|
| [336] | 48 |   call(['losetup', '-d', fs]) | 
|---|
 | 49 |  | 
|---|
| [405] | 50 | def duplicate_by_vm(source, target, rootpw, nodd=False, nofrob=False): | 
|---|
| [542] | 51 |   if source != "ice3": | 
|---|
 | 52 |      print "Error: can't clone that VM" | 
|---|
 | 53 |      sys.exit(1) | 
|---|
| [336] | 54 |   # source, target should be machine names | 
|---|
 | 55 |   prefix = 'd_' | 
|---|
 | 56 |   # 1. copy (by dd) source to target | 
|---|
 | 57 |   source_device = '/dev/xenvg/' + prefix + source + '_hda' | 
|---|
 | 58 |   target_device = '/dev/xenvg/' + prefix + target + '_hda' | 
|---|
| [338] | 59 |   if not nodd: | 
|---|
 | 60 |     check_call(['/bin/dd', 'bs=1M', 'conv=nocreat', | 
|---|
 | 61 |                 'if='+source_device, 'of='+target_device]) | 
|---|
| [336] | 62 |   # 2. frob target | 
|---|
| [405] | 63 |   if not nofrob: | 
|---|
 | 64 |     frob_copy(target_device, target, rootpw) | 
|---|
| [336] | 65 |  | 
|---|
| [338] | 66 | def main(*argv): | 
|---|
 | 67 |   subcommand = argv[1] | 
|---|
 | 68 |   args = argv[2:] | 
|---|
 | 69 |   os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin' | 
|---|
 | 70 |   if subcommand == 'lvcopy': | 
|---|
 | 71 |     kwargs = {} | 
|---|
| [405] | 72 |     while True: | 
|---|
 | 73 |       if args[0].startswith('--'): | 
|---|
 | 74 |         kwargs[args[0][2:]] = True | 
|---|
 | 75 |         args = args[1:] | 
|---|
 | 76 |         continue | 
|---|
 | 77 |       if len(args) != 3: | 
|---|
 | 78 |         print >>sys.stderr, argv[0]+': bad argument list' | 
|---|
 | 79 |         return 2 | 
|---|
 | 80 |       break | 
|---|
| [338] | 81 |     duplicate_by_vm(*args, **kwargs) | 
|---|
| [405] | 82 |   elif subcommand == 'test': | 
|---|
 | 83 |     pass | 
|---|
| [338] | 84 |   else: | 
|---|
 | 85 |     print >>sys.stderr, argv[0]+": unknown subcommand: "+subcommand | 
|---|
 | 86 |     return 2 | 
|---|
 | 87 |   return 0 | 
|---|
 | 88 |  | 
|---|
| [231] | 89 | if __name__ == '__main__': | 
|---|
| [338] | 90 |   sys.exit(main(*sys.argv)) | 
|---|