Commit 4244dfba authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

cyclades: Implement reconciliation for volumes

Extend the 'reconcile-servers' management command, to reconcile the
state of Cyclades Volumes with the corresponding disks of instances in
the Ganeti backends.
parent d9f13745
......@@ -1112,7 +1112,7 @@ def set_firewall_profile(vm, profile, nic):
def attach_volume(vm, volume, depends=[]):
log.debug("Attaching volume %s to vm %s", vm, volume)
log.debug("Attaching volume %s to vm %s", volume, vm)
disk = {"size": int(volume.size) << 10,
"name": volume.backend_volume_uuid,
......
......@@ -69,6 +69,9 @@ class Command(SynnefoCommand):
make_option('--fix-unsynced-nics', action='store_true',
dest='fix_unsynced_nics', default=False,
help='Fix unsynced nics between DB and Ganeti'),
make_option('--fix-unsynced-disks', action='store_true',
dest='fix_unsynced_disks', default=False,
help='Fix unsynced disks between DB and Ganeti'),
make_option('--fix-unsynced-flavors', action='store_true',
dest='fix_unsynced_flavors', default=False,
help='Fix unsynced flavors between DB and Ganeti'),
......
......@@ -326,7 +326,35 @@ class BackendReconciler(object):
nics=gnt_nics)
def reconcile_unsynced_disks(self, server_id, db_server, gnt_server):
pass
building_time = self.event_time - BUILDING_NIC_TIMEOUT
db_disks = db_server.volumes.exclude(status="CREATING",
created__lte=building_time) \
.filter(deleted=False)\
.order_by("id")
gnt_disks = gnt_server["disks"]
gnt_disks_parsed = backend_mod.process_ganeti_disks(gnt_disks)
disks_changed = len(db_disks) != len(gnt_disks)
for db_disk, gnt_disk in zip(db_disks,
sorted(gnt_disks_parsed.items())):
gnt_disk_id, gnt_disk = gnt_disk
if (db_disk.id == gnt_disk_id) and\
backend_mod.disks_are_equal(db_disk, gnt_disk):
continue
else:
disks_changed = True
break
if disks_changed:
msg = "Found unsynced disks for server '%s'.\n"\
"\tDB:\n\t\t%s\n\tGaneti:\n\t\t%s"
db_disks_str = "\n\t\t".join(map(format_db_disk, db_disks))
gnt_disks_str = "\n\t\t".join(map(format_gnt_disk,
sorted(gnt_disks_parsed.items())))
self.log.info(msg, server_id, db_disks_str, gnt_disks_str)
if self.options["fix_unsynced_disks"]:
vm = get_locked_server(server_id)
backend_mod.process_disks_status(vm=vm,
etime=self.event_time,
disks=gnt_disks)
def reconcile_pending_task(self, server_id, db_server):
job_id = db_server.task_job_id
......@@ -367,6 +395,17 @@ def format_gnt_nic(nic):
nic["network"].id, nic["mac"], nic["index"],
nic["firewall_profile"])
DISK_MSG = ": %s\t".join(["ID", "State", "Size", "Index"]) + ": %s"
def format_db_disk(disk):
return DISK_MSG % (disk.id, disk.status, disk.size, disk.index)
def format_gnt_disk(disk):
disk_name, disk = disk
return DISK_MSG % (disk_name, disk["status"], disk["size"], disk["index"])
#
# Networks
......
......@@ -124,6 +124,8 @@ class ServerReconciliationTest(TestCase):
"oper_state": True,
"mtime": time(),
"disk.sizes": [],
"disk.names": [],
"disk.uuids": [],
"nic.ips": [],
"nic.names": [],
"nic.macs": [],
......@@ -145,6 +147,8 @@ class ServerReconciliationTest(TestCase):
"oper_state": True,
"mtime": time(),
"disk.sizes": [],
"disk.names": [],
"disk.uuids": [],
"nic.ips": [],
"nic.names": [],
"nic.macs": [],
......@@ -172,6 +176,8 @@ class ServerReconciliationTest(TestCase):
"oper_state": True,
"mtime": time(),
"disk.sizes": [],
"disk.names": [],
"disk.uuids": [],
"nic.ips": [],
"nic.names": [],
"nic.macs": [],
......@@ -204,6 +210,8 @@ class ServerReconciliationTest(TestCase):
"oper_state": True,
"mtime": time(),
"disk.sizes": [],
"disk.names": [],
"disk.uuids": [],
"nic.names": [nic.backend_uuid],
"nic.ips": ["192.168.2.5"],
"nic.macs": ["aa:00:bb:cc:dd:ee"],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment