Work around bug in Python subprocess for remctl
[invirt/packages/invirt-autoinstaller.git] / files / usr / sbin / sipb-xen-lvcopy
1 #!/usr/bin/env python2.5
2
3 import sys
4 import os
5 import shutil
6 import tempfile
7 import time
8 from subprocess import call, check_call, Popen, PIPE
9
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
15 def losetup(source, offset=0):
16   p = Popen(['sipb-xen-losetup', source, str(offset)], stdout=PIPE)
17   return p.communicate()[0].strip()
18
19 def frob_copy_in_vm(target, *args):
20   '''UNUSED: maybe we'll use this someday; it does isolate the frobber.'''
21   # 1. prepare arguments volume
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
27   # 2. invoke frobber vm
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
35   # XXX should check_call(['/sbin/lvremove', '-f', 'xenvg/'+args_volume])
36
37 def frob_copy(target, hostname, rootpw):
38   """target should be an LV device filename"""
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
44   call(['/usr/sbin/chroot', mntdir, '/post-copy', hostname, rootpw])
45   # 3: clean up
46   call(['umount', mntdir])
47   os.rmdir(mntdir)
48   call(['losetup', '-d', fs])
49
50 def duplicate_by_vm(source, target, rootpw, nodd=False, nofrob=False):
51   # source, target should be machine names
52   prefix = 'd_'
53   # 1. copy (by dd) source to target
54   source_device = '/dev/xenvg/' + prefix + source + '_hda'
55   target_device = '/dev/xenvg/' + prefix + target + '_hda'
56   if not nodd:
57     check_call(['/bin/dd', 'bs=1M', 'conv=nocreat',
58                 'if='+source_device, 'of='+target_device])
59   # 2. frob target
60   if not nofrob:
61     frob_copy(target_device, target, rootpw)
62
63 def main(*argv):
64   subcommand = argv[1]
65   args = argv[2:]
66   os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
67   if subcommand == 'lvcopy':
68     kwargs = {}
69     while True:
70       if args[0].startswith('--'):
71         kwargs[args[0][2:]] = True
72         args = args[1:]
73         continue
74       if len(args) != 3:
75         print >>sys.stderr, argv[0]+': bad argument list'
76         return 2
77       break
78     duplicate_by_vm(*args, **kwargs)
79   elif subcommand == 'test':
80     pass
81   else:
82     print >>sys.stderr, argv[0]+": unknown subcommand: "+subcommand
83     return 2
84   return 0
85
86 if __name__ == '__main__':
87   sys.exit(main(*sys.argv))