Commit 7838604e authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

cyclades: reconciliation for resizing VMs

parent 05e0992f
......@@ -71,6 +71,9 @@ class Command(BaseCommand):
make_option('--detect-unsynced-nics', action='store_true',
dest='detect_unsynced_nics', default=False,
help='Detect unsynced nics between DB and Ganeti'),
make_option('--detect-unsynced-flavors', action='store_true',
dest='detect_unsynced_flavors', default=False,
help='Detect unsynced flavors between DB and Ganeti'),
make_option('--detect-all', action='store_true',
dest='detect_all',
default=False, help='Enable all --detect-* arguments'),
......@@ -87,6 +90,9 @@ class Command(BaseCommand):
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-flavors', action='store_true',
dest='fix_unsynced_flavors', default=False,
help='Fix unsynced flavors between DB and Ganeti'),
make_option('--fix-all', action='store_true', dest='fix_all',
default=False, help='Enable all --fix-* arguments'),
make_option('--backend-id', default=None, dest='backend-id',
......@@ -197,6 +203,19 @@ class Command(BaseCommand):
elif verbosity == 2:
print >> sys.stderr, "All instance nics are synced."
if options["detect_unsynced_flavors"]:
unsynced_flavors = reconciliation.unsynced_flavors(DBVMs,
GanetiVMs)
if len(unsynced_flavors) > 0:
print >> sys.stderr, "The flavor of the following server" \
" IDs is out-of-sync:"
print " " + "\n ".join(
["%d is %s in DB, %s in Ganeti" %
(x[0], x[1], x[2])
for x in unsynced_flavors])
elif verbosity == 2:
print >> sys.stderr, "All instance flavors are synced."
#
# Then fix them
#
......@@ -284,3 +303,25 @@ class Command(BaseCommand):
backend_mod.process_net_status(vm=vm, etime=event_time,
nics=final_nics)
print >> sys.stderr, " ...done"
if options["fix_unsynced_flavors"] and len(unsynced_flavors) > 0:
print >> sys.stderr, "Setting the flavor of %d unsynced VMs:" % \
len(unsynced_flavors)
for id, db_flavor, gnt_flavor in unsynced_flavors:
vm = VirtualMachine.objects.get(pk=id)
old_state = vm.operstate
opcode = "OP_INSTANCE_SET_PARAMS"
beparams = {"vcpus": gnt_flavor.cpu,
"minmem": gnt_flavor.ram,
"maxmem": gnt_flavor.ram}
event_time = datetime.datetime.now()
backend_mod.process_op_status(
vm=vm, etime=event_time, jobid=-0,
opcode=opcode, status='success',
beparams=beparams,
logmsg='Reconciliation: simulated Ganeti event')
# process_op_status with beparams will set the vmstate to
# shutdown. Fix this be returning it to old state
vm = VirtualMachine.objects.get(pk=id)
vm.operstate = old_state
vm.save()
print >> sys.stderr, " ...done"
......@@ -72,7 +72,7 @@ setup_environ(settings)
from datetime import datetime, timedelta
from collections import namedtuple
from synnefo.db.models import (VirtualMachine, NetworkInterface,
from synnefo.db.models import (VirtualMachine, NetworkInterface, Flavor,
pooled_rapi_client)
from synnefo.logic.rapi import GanetiApiError
from synnefo.logic.backend import get_instances
......@@ -92,7 +92,7 @@ def needs_reconciliation(vm):
return (now > vm.updated + timedelta(seconds=CHECK_INTERVAL)) or\
(now > vm.backendtime + timedelta(seconds=2*CHECK_INTERVAL))
VMState = namedtuple("VMState", ["state", "nics"])
VMState = namedtuple("VMState", ["state", "cpu", "ram", "nics"])
def stale_servers_in_db(D, G):
......@@ -155,6 +155,25 @@ def unsynced_operstate(D, G):
return unsynced
def unsynced_flavors(D, G):
unsynced = set()
idD = set(D.keys())
idG = set(G.keys())
for i in idD & idG:
if D[i].ram != G[i].ram or D[i].cpu != G[i].cpu:
db_flavor = VirtualMachine.objects.get(id=i).flavor
try:
gnt_flavor = Flavor.objects.get(
ram=G[i].ram, cpu=G[i].cpu,
disk=db_flavor.disk,
disk_template=db_flavor.disk_template)
except Flavor.DoesNotExist:
gnt_flavor = None
unsynced.add((i, db_flavor, gnt_flavor))
return unsynced
def instances_with_build_errors(D, G):
failed = set()
idD = set(D.keys())
......@@ -183,7 +202,7 @@ def instances_with_build_errors(D, G):
def get_servers_from_db(backends, with_nics=True):
vms = VirtualMachine.objects.filter(deleted=False, backend__in=backends)
vm_info = vms.values_list("id", "operstate")
vm_info = vms.values_list("id", "operstate", "flavor__cpu", "flavor__ram")
if with_nics:
nics = NetworkInterface.objects.filter(machine__in=vms)\
.order_by("machine")\
......@@ -199,8 +218,11 @@ def get_servers_from_db(backends, with_nics=True):
'ipv4': ipv4 if ipv4 != '' else None
}
vm_nics[machine][index] = nic
servers = dict([(vm_id, VMState(state=state, nics=vm_nics.get(vm_id, [])))
for vm_id, state in vm_info])
servers = dict([(vm_id, VMState(state=state,
cpu=cpu,
ram=ram,
nics=vm_nics.get(vm_id, [])))
for vm_id, state, cpu, ram in vm_info])
return servers
......@@ -227,7 +249,12 @@ def get_instances_from_ganeti(backends):
continue
nics = get_nics_from_instance(i)
beparams = i["beparams"]
vcpus = beparams["vcpus"]
ram = beparams["maxmem"]
snf_instances[id] = VMState(state=i["oper_state"],
cpu=vcpus,
ram=ram,
nics=nics)
return snf_instances
......
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