Index: unk/packages/sipb-xen-guest-installer/files/usr/sbin/sipb-xen-duplicate
===================================================================
--- /trunk/packages/sipb-xen-guest-installer/files/usr/sbin/sipb-xen-duplicate	(revision 337)
+++ 	(revision )
@@ -1,144 +1,0 @@
-#!/usr/bin/env python2.5
-
-import sys
-import os
-import shutil
-import tempfile
-import time
-from subprocess import call, check_call, Popen, PIPE
-
-# TODO:
-# . pick a loop device sanely
-# x adapt size of partition to fit volume
-# . fix hostname, root password
-# - (once debugging diminishes) umount, losetup -d, maybe rm -r
-# - avoid race conditions with other loop-device users, too (somehow)
-# - get numbers from actual source partition table rather than
-#   as magic numbers based on what sipb-xen-make-iso does with etch.
-
-def losetup(source, offset=0):
-  # XXX we avoid colliding with other instances of ourself,
-  #     but when it comes to other loop-device users we just
-  #     pick a range things don't seem to use and hope...
-  lockfilename = '/tmp/losetup.lock'
-  os.close(os.open(lockfilename, os.O_CREAT+os.O_EXCL)) #lock
-  try:
-    loopdevice = None
-    for i in xrange(32,60): # totally arbitrary, just looks to be unused on black-mesa
-      filename = '/dev/loop%d'%i
-      if 0 == len(file(filename).read(1)):
-        loopdevice = filename # it's empty
-        break
-    if loopdevice is not None:
-      call(['losetup', '-o', str(offset), loopdevice, source])
-    else:
-      raise RuntimeError('out of loop devices for copying VM image: too many at once?')
-  finally:
-    os.unlink(lockfilename) #unlock
-  return loopdevice
-  # XX this means we can duplicate 9 at once.  since it takes around 30 seconds,
-  # this seems like an adequate capacity.
-
-def duplicate_lv(source, dest):
-  '''OBSOLETE: duplicate boot record, filesystem from LV source to LV dest
-  
-  source, dest should be device filenames.
-
-  Now we just dd.  Doesn't support resizing, but it's easier,
-  especially if we allow the partition table to vary between images.
-  '''
-  # XXX this is very specific to what the etch sipb-xen-make-iso installer does.
-  # XXXX also, it's specific to four gigs.
-  # step 1: copy the MBR
-  call(['dd', 'if='+source, 'bs=512', 'count=63', 'of='+dest])
-  # step 2: fix up partition table
-  # XX actually do this; this is our opportunity to resize the filesystem
-  # step 3: make the filesystem, and copy its contents in
-  sourcefs = losetup(source, 32256)
-  destfs = losetup(dest, 32256)
-  call(['mkfs.ext3', '-b', '4096', destfs, '987989'])
-  tmptree = tempfile.mkdtemp('', 'auto-install.dup.', '/tmp')#yes, args backward
-  os.mkdir(tmptree+"/source")
-  call(['mount', '-t', 'ext3', '-o', 'ro', sourcefs, tmptree+"/source"])
-  os.mkdir(tmptree+"/dest")
-  call(['mount', '-t', 'ext3', destfs, tmptree+"/dest"])
-  call(['cp', '-aT', tmptree+"/source", tmptree+"/dest"])
-  # step 4: twiddle what we want to twiddle
-  # XX do this
-  # step 5: make the swap area
-  swapfs = losetup(dest, 4046870016)
-  call(['mkswap', swapfs, str(240943)])
-  # call(['losetup', '-d', swapfs])
-  print 'losetup -d '+swapfs
-  # step 6: clean up.
-  # XX actually unmount etc (leaving it is for debugging)
-  print 'umount '+tmptree+'/source'
-  call(['umount', tmptree+"/dest"]) # needed to flush writes
-  print 'losetup -d '+sourcefs
-  print 'losetup -d '+destfs
-
-def frob_copy(target, *args):
-  # 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_simple(target, hostname, rootpw, *args):
-  """target should be an LV device filename
-
-  This is highly specific to the etch install produced by sipb-xen-make-iso.
-  Generalizing and customizing to other distros is left to the future...
-  """
-  # 1: mount filesystem
-  fs = losetup(target, 32256)
-  mntdir = tempfile.mkdtemp('', 'auto-install.frob.', '/tmp')
-  call(['mount', '-t', 'ext3', fs, mntdir])
-  # 2: do frobbing
-  # 2a:  (printf "%s\n" "$ROOTPW"; sleep .3; printf "%s\n" "$ROOTPW") 
-  #      | /usr/sbin/chroot "$TARGET" /usr/bin/passwd root
-  p = Popen(['/usr/sbin/chroot', mntdir, '/usr/bin/passwd', 'root'], stdin=PIPE)
-  p.stdin.write(rootpw+'\n')
-  time.sleep(1)
-  p.stdin.write(rootpw+'\n')
-  p.stdin.close()
-  p.wait()
-  os.chdir(mntdir)
-  # 2b: clear generated file that has eth0's old MAC address
-  #      rm $TARGET/etc/udev/rules.d/z25_persistent-net.rules
-  os.unlink('etc/udev/rules.d/z25_persistent-net.rules')
-  # 2c: hostname.
-  # XX Use nullmailer in image, not exim4.  (Fewer copies of hostname.)
-  # 2c1: rm /var/lib/dhcp3/dhclient.eth0.leases
-  os.unlink('var/lib/dhcp3/dhclient.eth0.leases')
-  # 2c2: /etc/hosts, /etc/hostname; /etc/motd? /etc/mailname?
-  call(['perl', '-i', '-pe', 's/ice3.servers.csail.mit.edu/'+hostname+'/g',
-        'etc/hosts', 'etc/hostname', 'etc/motd', 'etc/mailname'])
-  # 3: clean up
-  os.chdir('/')
-  call(['umount', mntdir])
-  call(['losetup', '-d', fs])
-
-def duplicate_by_vm(source, target, *args):
-  # 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'
-  check_call(['/bin/dd', 'bs=1M', 'conv=nocreat',
-              'if='+source_device, 'of='+target_device])
-  # 2. frob target
-  frob_copy_simple(target_device, *args)
-
-if __name__ == '__main__':
-  duplicate_by_vm(*sys.argv[1:])
Index: /trunk/packages/sipb-xen-guest-installer/files/usr/sbin/sipb-xen-lvcopy
===================================================================
--- /trunk/packages/sipb-xen-guest-installer/files/usr/sbin/sipb-xen-lvcopy	(revision 338)
+++ /trunk/packages/sipb-xen-guest-installer/files/usr/sbin/sipb-xen-lvcopy	(revision 338)
@@ -0,0 +1,162 @@
+#!/usr/bin/env python2.5
+
+import sys
+import os
+import shutil
+import tempfile
+import time
+from subprocess import call, check_call, Popen, PIPE
+
+# TODO:
+# . pick a loop device sanely
+# x adapt size of partition to fit volume
+# . fix hostname, root password
+# - (once debugging diminishes) umount, losetup -d, maybe rm -r
+# - avoid race conditions with other loop-device users, too (somehow)
+# - get numbers from actual source partition table rather than
+#   as magic numbers based on what sipb-xen-make-iso does with etch.
+
+def losetup(source, offset=0):
+  # XXX we avoid colliding with other instances of ourself,
+  #     but when it comes to other loop-device users we just
+  #     pick a range things don't seem to use and hope...
+  lockfilename = '/tmp/losetup.lock'
+  os.close(os.open(lockfilename, os.O_CREAT+os.O_EXCL)) #lock
+  try:
+    loopdevice = None
+    for i in xrange(32,60): # totally arbitrary, just looks to be unused on black-mesa
+      filename = '/dev/loop%d'%i
+      if 0 == len(file(filename).read(1)):
+        loopdevice = filename # it's empty
+        break
+    if loopdevice is not None:
+      call(['losetup', '-o', str(offset), loopdevice, source])
+    else:
+      raise RuntimeError('out of loop devices for copying VM image: too many at once?')
+  finally:
+    os.unlink(lockfilename) #unlock
+  return loopdevice
+  # XX this means we can duplicate 9 at once.  since it takes around 30 seconds,
+  # this seems like an adequate capacity.
+
+def duplicate_lv(source, dest):
+  '''OBSOLETE: duplicate boot record, filesystem from LV source to LV dest
+  
+  source, dest should be device filenames.
+
+  Now we just dd.  Doesn't support resizing, but it's easier,
+  especially if we allow the partition table to vary between images.
+  '''
+  # XXX this is very specific to what the etch sipb-xen-make-iso installer does.
+  # XXXX also, it's specific to four gigs.
+  # step 1: copy the MBR
+  call(['dd', 'if='+source, 'bs=512', 'count=63', 'of='+dest])
+  # step 2: fix up partition table
+  # XX actually do this; this is our opportunity to resize the filesystem
+  # step 3: make the filesystem, and copy its contents in
+  sourcefs = losetup(source, 32256)
+  destfs = losetup(dest, 32256)
+  call(['mkfs.ext3', '-b', '4096', destfs, '987989'])
+  tmptree = tempfile.mkdtemp('', 'auto-install.dup.', '/tmp')#yes, args backward
+  os.mkdir(tmptree+"/source")
+  call(['mount', '-t', 'ext3', '-o', 'ro', sourcefs, tmptree+"/source"])
+  os.mkdir(tmptree+"/dest")
+  call(['mount', '-t', 'ext3', destfs, tmptree+"/dest"])
+  call(['cp', '-aT', tmptree+"/source", tmptree+"/dest"])
+  # step 4: twiddle what we want to twiddle
+  # XX do this
+  # step 5: make the swap area
+  swapfs = losetup(dest, 4046870016)
+  call(['mkswap', swapfs, str(240943)])
+  # call(['losetup', '-d', swapfs])
+  print 'losetup -d '+swapfs
+  # step 6: clean up.
+  # XX actually unmount etc (leaving it is for debugging)
+  print 'umount '+tmptree+'/source'
+  call(['umount', tmptree+"/dest"]) # needed to flush writes
+  print 'losetup -d '+sourcefs
+  print 'losetup -d '+destfs
+
+def frob_copy(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_simple(target, hostname, rootpw):
+  """target should be an LV device filename
+
+  This is highly specific to the etch install produced by sipb-xen-make-iso.
+  Generalizing and customizing to other distros is left to the future...
+  """
+  # 1: mount filesystem
+  fs = losetup(target, 32256)
+  mntdir = tempfile.mkdtemp('', 'auto-install.frob.', '/tmp')
+  call(['mount', '-t', 'ext3', fs, mntdir])
+  # 2: do frobbing
+  # 2a:  (printf "%s\n" "$ROOTPW"; sleep .3; printf "%s\n" "$ROOTPW") 
+  #      | /usr/sbin/chroot "$TARGET" /usr/bin/passwd root
+  p = Popen(['/usr/sbin/chroot', mntdir, '/usr/bin/passwd', 'root'], stdin=PIPE)
+  p.stdin.write(rootpw+'\n')
+  time.sleep(1)
+  p.stdin.write(rootpw+'\n')
+  p.stdin.close()
+  p.wait()
+  os.chdir(mntdir)
+  # 2b: clear generated file that has eth0's old MAC address
+  #      rm $TARGET/etc/udev/rules.d/z25_persistent-net.rules
+  os.unlink('etc/udev/rules.d/z25_persistent-net.rules')
+  # 2c: hostname.
+  # XX Use nullmailer in image, not exim4.  (Fewer copies of hostname.)
+  # 2c1: rm /var/lib/dhcp3/dhclient.eth0.leases
+  os.unlink('var/lib/dhcp3/dhclient.eth0.leases')
+  # 2c2: /etc/hosts, /etc/hostname; /etc/motd? /etc/mailname?
+  call(['perl', '-i', '-pe', 's/ice3.servers.csail.mit.edu/'+hostname+'/g',
+        'etc/hosts', 'etc/hostname', 'etc/motd', 'etc/mailname'])
+  # 3: clean up
+  os.chdir('/')
+  call(['umount', mntdir])
+  os.rmdir(mntdir)
+  call(['losetup', '-d', fs])
+
+def duplicate_by_vm(source, target, rootpw, nodd=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
+  frob_copy_simple(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 = {}
+    if args[0] == '--nodd':
+      args = args[1:]
+      kwargs['nodd'] = True
+    duplicate_by_vm(*args, **kwargs)
+  else:
+    print >>sys.stderr, argv[0]+": unknown subcommand: "+subcommand
+    return 2
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main(*sys.argv))
