#!/bin/python # Migrates the machine passed as arguments from the dev cluster. # To be run on the prod cluster. from invirt import remctl as r from lib import database import subprocess import sys dev_db_uri = 'postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen' database.connect(dev_db_uri) dev_sess = database.session database.connect() prod_sess = database.session ## dump from dev db def take_data(machine_name): dev_sess.begin() machine = dev_sess.query(database.Machine).filter_by(name=machine_name).one() # Clean out the ACL just so we don't have to think about it machine.acl = [] dev_sess.update(machine) print 'VM Info:' print ' name: %s' % machine.name print ' description: %s' % machine.description print ' cpus: %s' % machine.cpus print ' memory: %s' % machine.memory print ' owner: %s' % machine.owner print ' contact: %s' % machine.contact print ' administrator: %s' % machine.administrator print ' uuid: %s' % machine.uuid print ' type: %s' % machine.type.type_id print ' autorestart: %s' % machine.autorestart print ' adminable: %s' % machine.adminable print ' Disks:' for disk in machine.disks: print ' - %s (%s)' % (disk.guest_device_name, disk.size) print ' NICs:' for nic in machine.nics: print ' - %s, %s, %s' % (nic.mac_addr, nic.ip, nic.hostname) print '===============================================' print disks = machine.disks nics = machine.nics for r in disks + nics + [machine]: dev_sess.delete(r) dev_sess.commit() for r in disks + nics + [machine]: dev_sess.expunge(r) del r._instance_key return machine ## add to prod db def restore_data(machine): # The machine's type is still the one attached to the dev database; # get the right one machine.type = prod_sess.query(database.Type).filter_by(type_id=machine.type.type_id).one() prod_sess.begin() prod_sess.save(machine) prod_sess.commit() def migrate_vm(machine_name): # Power off the VM on dev # # This has to be done first, because once the machine is deleted # from the database, we can't remctl for it anymore out, err = r.remctl('xvm-remote.mit.edu', 'control', machine_name, 'destroy', err=True) print out machine = take_data(machine_name) ## copy disk image... copy, copy... for disk in machine.disks: lvname='d_%s_%s' % (machine.name, disk.guest_device_name) subprocess.check_call(['lvcreate', '-L%sM' % str(disk.size), '-n', lvname, 'xenvg']) ssh = subprocess.Popen(['ssh', '-o', 'GSSAPIDelegateCredentials=no', 'torchwood-institute.mit.edu', 'dd', 'if=/dev/xenvg/%s' % lvname, 'bs=1M'], stdout=subprocess.PIPE) dd = subprocess.Popen(['dd', 'of=/dev/xenvg/%s' % lvname, 'bs=1M'], stdin=ssh.stdout) dd.wait() restore_data(machine) if __name__ == '__main__': for vm in sys.argv[1:]: print '===============================================' print 'Migrating %s' % vm print '===============================================' migrate_vm(vm.strip())