Refactor how migrations work to allow unmigrate and avoid code duplication

This commit is contained in:
Joshua Boniface 2018-06-04 12:15:37 -04:00
parent 4c7f7180b6
commit 533a70972f
1 changed files with 49 additions and 26 deletions

View File

@ -112,52 +112,75 @@ class VMInstance:
self.dom = None self.dom = None
self.inshutdown = False self.inshutdown = False
# Migrate the VM to a target host def live_migrate_vm(self, dest_hypervisor):
def migrate_vm(self):
print('>>> %s - Migrating VM to %s' % (self.domuuid, self.hypervisor))
self.inmigrate = True
former_hypervisor = self.thishypervisor.name
try: try:
dest_conn = libvirt.open('qemu+tcp://%s/system' % self.hypervisor) dest_conn = libvirt.open('qemu+tcp://%s/system' % self.hypervisor)
if dest_conn == None: if dest_conn == None:
raise raise
except: except:
print('>>> %s - Failed to open connection to qemu+tcp://%s/system; aborting migration' % self.hypervisor) print('>>> %s - Failed to open connection to qemu+tcp://%s/system; aborting migration' % self.hypervisor)
self.zk.set(self.zkey + '/hypervisor', former_hypervisor.encode('ascii')) return 1
self.zk.set(self.zkey + '/state', 'start'.encode('ascii'))
return
try: try:
target_dom = self.dom.migrate(dest_conn, libvirt.VIR_MIGRATE_LIVE, None, None, 0) target_dom = self.dom.migrate(dest_conn, libvirt.VIR_MIGRATE_LIVE, None, None, 0)
if target_dom == None: if target_dom == None:
raise raise
# Set the former hypervisor to us
self.zk.set(self.zkey + '/formerhypervisor', former_hypervisor.encode('ascii'))
print('>>> %s - Migrated successfully' % self.domuuid) print('>>> %s - Migrated successfully' % self.domuuid)
except: except:
dest_conn.close()
print('>>> %s - Could not live migrate VM' % self.domuuid)
return 1
dest_conn.close()
return 0
# Migrate the VM to a target host
def migrate_vm(self):
self.inmigrate = True
this_hypervisor = self.thishypervisor.name
new_hypervisor = self.hypervisor
previous_hypervisor = self.zk.get(self.zkey + '/formerhypervisor')[0].decode('ascii')
print('>>> %s - Migrating VM to %s' % (self.domuuid, new_hypervisor))
migrate_ret = live_migrate_vm(new_hypervisor)
if migrate_ret != 0:
print('>>> %s - Could not live migrate VM; forcing away uncleanly' % self.domuuid) print('>>> %s - Could not live migrate VM; forcing away uncleanly' % self.domuuid)
self.stop_vm() self.stop_vm()
time.sleep(0.5) time.sleep(0.5)
self.zk.set(self.zkey + '/state', 'start'.encode('ascii')) return
else:
try: try:
self.thishypervisor.domain_list.remove(self.domuuid) self.thishypervisor.domain_list.remove(self.domuuid)
except ValueError: except ValueError:
pass pass
dest_conn.close()
self.inmigrate = False self.inmigrate = False
def unmigrate_vm(self): def unmigrate_vm(self):
self.inmigrate = True
this_hypervisor = self.thishypervisor.name
new_hypervisor = self.zk.get(self.zkey + '/formerhypervisor')[0].decode('ascii')
if new_hypervisor != '':
print('>>> %s - Unmigrating VM' % self.domuuid) print('>>> %s - Unmigrating VM' % self.domuuid)
former_hypervisor = self.zk.get(self.zkey + '/formerhypervisor')[0] # I don't decode this
transaction = self.zk.transaction() transaction = self.zk.transaction()
transaction.set_data('/domains/' + self.domuuid + '/state', 'migrate'.encode('ascii')) transaction.set_data('/domains/' + self.domuuid + '/hypervisor', new_hypervisor.encode('ascii'))
transaction.set_data('/domains/' + self.domuuid + '/hypervisor', former_hypervisor)
transaction.set_data('/domains/' + self.domuuid + '/formerhypervisor', ''.encode('ascii')) transaction.set_data('/domains/' + self.domuuid + '/formerhypervisor', ''.encode('ascii'))
result = transaction.commit() result = transaction.commit()
migrate_ret = live_migrate_vm(new_hypervisor)
if migrate_ret != 0:
print('>>> %s - Could not live migrate VM; forcing away uncleanly' % self.domuuid)
self.stop_vm()
time.sleep(0.5)
return
else:
try:
self.thishypervisor.domain_list.remove(self.domuuid)
except ValueError:
pass
else:
transaction.set_data('/domains/' + self.domuuid + '/state', 'start'.encode('ascii'))
self.inmigrate = False
# Receive the migration from another host (wait until VM is running) # Receive the migration from another host (wait until VM is running)
def receive_migrate(self): def receive_migrate(self):