#!/usr/bin/env python2.5

import sys
import os
import shutil
import tempfile
import time
from subprocess import call, check_call, Popen, PIPE

def losetup(source, offset=0):
  p = Popen(['sipb-xen-losetup', source, str(offset)], stdout=PIPE)
  return p.communicate()[0].strip()

def frob_copy_in_vm(target, *args):
  '''UNUSED: maybe we'll use this someday; it does isolate the frobber.'''
  # 1. prepare arguments volume
  args_volume = prefix+target+'_args'
  args_device = '/dev/xenvg/' + args_volume
  check_call(['/sbin/lvcreate', 'xenvg', '--name', args_volume, '--size', '4K'])
  file(args_device, 'w').write('\n'.join(args) + '\n')

  # 2. invoke frobber vm
  copier_device = '/dev/xenvg/d_wert_hda'
  check_call(['/usr/sbin/xm', 'create', 'sipb-database',
              'machine_name='+target,
              'disks=' + ' '.join(['phy:'+copier_device+',hda,w',
                                   'phy:'+target_device+',hdc,w',
                                   'phy:'+args_device+',hdd,w'])])

  # XXX should check_call(['/sbin/lvremove', '-f', 'xenvg/'+args_volume])

def frob_copy(target, hostname, rootpw):
  """target should be an LV device filename"""
  # 1: mount filesystem
  fs = losetup(target, 32256)
  mntdir = tempfile.mkdtemp('', 'auto-install.frob.', '/tmp')
  call(['mount', '-t', 'ext3', fs, mntdir])
  # 2: do frobbing
  call(['/usr/sbin/chroot', mntdir, '/post-copy', hostname, rootpw])
  # 3: clean up
  call(['umount', mntdir])
  os.rmdir(mntdir)
  call(['losetup', '-d', fs])

def duplicate_by_vm(source, target, rootpw, nodd=False, nofrob=False):
  # source, target should be machine names
  prefix = 'd_'
  # 1. copy (by dd) source to target
  source_device = '/dev/xenvg/' + prefix + source + '_hda'
  target_device = '/dev/xenvg/' + prefix + target + '_hda'
  if not nodd:
    check_call(['/bin/dd', 'bs=1M', 'conv=nocreat',
                'if='+source_device, 'of='+target_device])
  # 2. frob target
  if not nofrob:
    frob_copy(target_device, target, rootpw)

def main(*argv):
  subcommand = argv[1]
  args = argv[2:]
  os.environ['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
  if subcommand == 'lvcopy':
    kwargs = {}
    while True:
      if args[0].startswith('--'):
        kwargs[args[0][2:]] = True
        args = args[1:]
        continue
      if len(args) != 3:
        print >>sys.stderr, argv[0]+': bad argument list'
        return 2
      break
    duplicate_by_vm(*args, **kwargs)
  elif subcommand == 'test':
    pass
  else:
    print >>sys.stderr, argv[0]+": unknown subcommand: "+subcommand
    return 2
  return 0

if __name__ == '__main__':
  sys.exit(main(*sys.argv))