source: trunk/packages/sipb-xen-guest-installer/files/usr/sbin/sipb-xen-lvcopy @ 406

Last change on this file since 406 was 405, checked in by price, 17 years ago

put the post-copy frobbing details in the image

  • Property svn:executable set to *
File size: 3.3 KB
Line 
1#!/usr/bin/env python2.5
2
3import sys
4import os
5import shutil
6import tempfile
7import time
8from subprocess import call, check_call, Popen, PIPE
9
10def losetup(source, offset=0):
11  # XXX we avoid colliding with other instances of ourself,
12  #     but when it comes to other loop-device users we just
13  #     pick a range things don't seem to use and hope...
14  lockfilename = '/tmp/losetup.lock'
15  os.close(os.open(lockfilename, os.O_CREAT+os.O_EXCL)) #lock
16  try:
17    loopdevice = None
18    for i in xrange(32,60): # totally arbitrary, just looks to be unused on black-mesa
19      filename = '/dev/loop%d'%i
20      if 0 == len(file(filename).read(1)):
21        loopdevice = filename # it's empty
22        break
23    if loopdevice is not None:
24      call(['losetup', '-o', str(offset), loopdevice, source])
25    else:
26      raise RuntimeError('out of loop devices for copying VM image: too many at once?')
27  finally:
28    os.unlink(lockfilename) #unlock
29  return loopdevice
30  # XX this means we can duplicate 28 at once.  Since it takes around 30s,
31  # this seems like an adequate capacity.
32
33def frob_copy_in_vm(target, *args):
34  '''UNUSED: maybe we'll use this someday; it does isolate the frobber.'''
35  # 1. prepare arguments volume
36  args_volume = prefix+target+'_args'
37  args_device = '/dev/xenvg/' + args_volume
38  check_call(['/sbin/lvcreate', 'xenvg', '--name', args_volume, '--size', '4K'])
39  file(args_device, 'w').write('\n'.join(args) + '\n')
40
41  # 2. invoke frobber vm
42  copier_device = '/dev/xenvg/d_wert_hda'
43  check_call(['/usr/sbin/xm', 'create', 'sipb-database',
44              'machine_name='+target,
45              'disks=' + ' '.join(['phy:'+copier_device+',hda,w',
46                                   'phy:'+target_device+',hdc,w',
47                                   'phy:'+args_device+',hdd,w'])])
48
49  # XXX should check_call(['/sbin/lvremove', '-f', 'xenvg/'+args_volume])
50
51def frob_copy(target, hostname, rootpw):
52  """target should be an LV device filename"""
53  # 1: mount filesystem
54  fs = losetup(target, 32256)
55  mntdir = tempfile.mkdtemp('', 'auto-install.frob.', '/tmp')
56  call(['mount', '-t', 'ext3', fs, mntdir])
57  # 2: do frobbing
58  call(['/usr/sbin/chroot', mntdir, '/post-copy', hostname, rootpw])
59  # 3: clean up
60  call(['umount', mntdir])
61  os.rmdir(mntdir)
62  call(['losetup', '-d', fs])
63
64def duplicate_by_vm(source, target, rootpw, nodd=False, nofrob=False):
65  # source, target should be machine names
66  prefix = 'd_'
67  # 1. copy (by dd) source to target
68  source_device = '/dev/xenvg/' + prefix + source + '_hda'
69  target_device = '/dev/xenvg/' + prefix + target + '_hda'
70  if not nodd:
71    check_call(['/bin/dd', 'bs=1M', 'conv=nocreat',
72                'if='+source_device, 'of='+target_device])
73  # 2. frob target
74  if not nofrob:
75    frob_copy(target_device, target, rootpw)
76
77def main(*argv):
78  subcommand = argv[1]
79  args = argv[2:]
80  os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
81  if subcommand == 'lvcopy':
82    kwargs = {}
83    while True:
84      if args[0].startswith('--'):
85        kwargs[args[0][2:]] = True
86        args = args[1:]
87        continue
88      if len(args) != 3:
89        print >>sys.stderr, argv[0]+': bad argument list'
90        return 2
91      break
92    duplicate_by_vm(*args, **kwargs)
93  elif subcommand == 'test':
94    pass
95  else:
96    print >>sys.stderr, argv[0]+": unknown subcommand: "+subcommand
97    return 2
98  return 0
99
100if __name__ == '__main__':
101  sys.exit(main(*sys.argv))
Note: See TracBrowser for help on using the repository browser.