Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / logic / management / commands / reconcile-servers.py @ 9766a80e

History | View | Annotate | Download (15.5 kB)

1 7e136fd8 Giorgos Verigakis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 8007ba7b Georgios Gousios
#
3 cb409cfd Georgios Gousios
# Redistribution and use in source and binary forms, with or without
4 cb409cfd Georgios Gousios
# modification, are permitted provided that the following conditions
5 cb409cfd Georgios Gousios
# are met:
6 8007ba7b Georgios Gousios
#
7 cb409cfd Georgios Gousios
#   1. Redistributions of source code must retain the above copyright
8 cb409cfd Georgios Gousios
#      notice, this list of conditions and the following disclaimer.
9 8007ba7b Georgios Gousios
#
10 cb409cfd Georgios Gousios
#  2. Redistributions in binary form must reproduce the above copyright
11 cb409cfd Georgios Gousios
#     notice, this list of conditions and the following disclaimer in the
12 cb409cfd Georgios Gousios
#     documentation and/or other materials provided with the distribution.
13 cb409cfd Georgios Gousios
#
14 cb409cfd Georgios Gousios
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
15 cb409cfd Georgios Gousios
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 cb409cfd Georgios Gousios
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 cb409cfd Georgios Gousios
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
18 cb409cfd Georgios Gousios
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 cb409cfd Georgios Gousios
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 cb409cfd Georgios Gousios
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 cb409cfd Georgios Gousios
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 cb409cfd Georgios Gousios
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 cb409cfd Georgios Gousios
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 cb409cfd Georgios Gousios
# SUCH DAMAGE.
25 cb409cfd Georgios Gousios
#
26 cb409cfd Georgios Gousios
# The views and conclusions contained in the software and documentation are
27 cb409cfd Georgios Gousios
# those of the authors and should not be interpreted as representing official
28 cb409cfd Georgios Gousios
# policies, either expressed or implied, of GRNET S.A.
29 cb409cfd Georgios Gousios
#
30 9fea53cc Vangelis Koukis
"""Reconciliation management command
31 9fea53cc Vangelis Koukis

32 9fea53cc Vangelis Koukis
Management command to reconcile the contents of the Synnefo DB with
33 3b40590c Vangelis Koukis
the state of the Ganeti backend. See docstring on top of
34 3b40590c Vangelis Koukis
logic/reconciliation.py for a description of reconciliation rules.
35 9fea53cc Vangelis Koukis

36 9fea53cc Vangelis Koukis
"""
37 9fea53cc Vangelis Koukis
import sys
38 c4e55622 Christos Stavrakakis
import datetime
39 9fea53cc Vangelis Koukis
40 76a429fb Georgios Gousios
from optparse import make_option
41 9fea53cc Vangelis Koukis
42 7e136fd8 Giorgos Verigakis
from django.core.management.base import BaseCommand, CommandError
43 8007ba7b Georgios Gousios
44 e77a29ab Christos Stavrakakis
from synnefo.db.models import (Backend, VirtualMachine, Network,
45 e77a29ab Christos Stavrakakis
                               pooled_rapi_client)
46 c414bc87 Christos Stavrakakis
from synnefo.logic import reconciliation, utils
47 c414bc87 Christos Stavrakakis
from synnefo.logic import backend as backend_mod
48 9e20fcee Christos Stavrakakis
from synnefo.util.mac2eui64 import mac2eui64
49 c414bc87 Christos Stavrakakis
from synnefo.management.common import get_backend
50 8007ba7b Georgios Gousios
51 8007ba7b Georgios Gousios
52 76a429fb Georgios Gousios
class Command(BaseCommand):
53 9fea53cc Vangelis Koukis
    can_import_settings = True
54 9fea53cc Vangelis Koukis
55 9fea53cc Vangelis Koukis
    help = 'Reconcile contents of Synnefo DB with state of Ganeti backend'
56 9fea53cc Vangelis Koukis
    output_transaction = True  # The management command runs inside
57 9fea53cc Vangelis Koukis
                               # an SQL transaction
58 9fea53cc Vangelis Koukis
    option_list = BaseCommand.option_list + (
59 9fea53cc Vangelis Koukis
        make_option('--detect-stale', action='store_true', dest='detect_stale',
60 9fea53cc Vangelis Koukis
                    default=False, help='Detect stale VM entries in DB'),
61 9fea53cc Vangelis Koukis
        make_option('--detect-orphans', action='store_true',
62 9fea53cc Vangelis Koukis
                    dest='detect_orphans',
63 9fea53cc Vangelis Koukis
                    default=False, help='Detect orphan instances in Ganeti'),
64 9fea53cc Vangelis Koukis
        make_option('--detect-unsynced', action='store_true',
65 9fea53cc Vangelis Koukis
                    dest='detect_unsynced',
66 9fea53cc Vangelis Koukis
                    default=False, help='Detect unsynced operstate between ' +
67 9fea53cc Vangelis Koukis
                                        'DB and Ganeti'),
68 4161cb41 Christos Stavrakakis
        make_option('--detect-build-errors', action='store_true',
69 4161cb41 Christos Stavrakakis
                    dest='detect_build_errors', default=False,
70 4161cb41 Christos Stavrakakis
                    help='Detect instances with build error'),
71 0e9a423f Christos Stavrakakis
        make_option('--detect-unsynced-nics', action='store_true',
72 0e9a423f Christos Stavrakakis
                    dest='detect_unsynced_nics', default=False,
73 0e9a423f Christos Stavrakakis
                    help='Detect unsynced nics between DB and Ganeti'),
74 a67419d8 Christos Stavrakakis
        make_option('--detect-unsynced-flavors', action='store_true',
75 a67419d8 Christos Stavrakakis
                    dest='detect_unsynced_flavors', default=False,
76 a67419d8 Christos Stavrakakis
                    help='Detect unsynced flavors between DB and Ganeti'),
77 9fea53cc Vangelis Koukis
        make_option('--detect-all', action='store_true',
78 9fea53cc Vangelis Koukis
                    dest='detect_all',
79 9fea53cc Vangelis Koukis
                    default=False, help='Enable all --detect-* arguments'),
80 9fea53cc Vangelis Koukis
        make_option('--fix-stale', action='store_true', dest='fix_stale',
81 9fea53cc Vangelis Koukis
                    default=False, help='Fix (remove) stale DB entries in DB'),
82 9fea53cc Vangelis Koukis
        make_option('--fix-orphans', action='store_true', dest='fix_orphans',
83 9fea53cc Vangelis Koukis
                    default=False, help='Fix (remove) orphan Ganeti VMs'),
84 9fea53cc Vangelis Koukis
        make_option('--fix-unsynced', action='store_true', dest='fix_unsynced',
85 9fea53cc Vangelis Koukis
                    default=False, help='Fix server operstate in DB, set ' +
86 9fea53cc Vangelis Koukis
                                        'from Ganeti'),
87 4161cb41 Christos Stavrakakis
        make_option('--fix-build-errors', action='store_true',
88 4161cb41 Christos Stavrakakis
                    dest='fix_build_errors', default=False,
89 4161cb41 Christos Stavrakakis
                    help='Fix (remove) instances with build errors'),
90 cc92b70f Christos Stavrakakis
        make_option('--fix-unsynced-nics', action='store_true',
91 c59f7e0f Christos Stavrakakis
                    dest='fix_unsynced_nics', default=False,
92 c59f7e0f Christos Stavrakakis
                    help='Fix unsynced nics between DB and Ganeti'),
93 a67419d8 Christos Stavrakakis
        make_option('--fix-unsynced-flavors', action='store_true',
94 a67419d8 Christos Stavrakakis
                    dest='fix_unsynced_flavors', default=False,
95 a67419d8 Christos Stavrakakis
                    help='Fix unsynced flavors between DB and Ganeti'),
96 9fea53cc Vangelis Koukis
        make_option('--fix-all', action='store_true', dest='fix_all',
97 c414bc87 Christos Stavrakakis
                    default=False, help='Enable all --fix-* arguments'),
98 c414bc87 Christos Stavrakakis
        make_option('--backend-id', default=None, dest='backend-id',
99 c414bc87 Christos Stavrakakis
                    help='Reconcilie VMs only for this backend'),
100 cc92b70f Christos Stavrakakis
    )
101 9fea53cc Vangelis Koukis
102 9fea53cc Vangelis Koukis
    def _process_args(self, options):
103 9fea53cc Vangelis Koukis
        keys_detect = [k for k in options.keys() if k.startswith('detect_')]
104 9fea53cc Vangelis Koukis
        keys_fix = [k for k in options.keys() if k.startswith('fix_')]
105 9fea53cc Vangelis Koukis
106 cc3c59b3 Christos Stavrakakis
        if not reduce(lambda x, y: x or y,
107 cc3c59b3 Christos Stavrakakis
                      map(lambda x: options[x], keys_detect)):
108 cc3c59b3 Christos Stavrakakis
            options['detect_all'] = True
109 cc3c59b3 Christos Stavrakakis
110 9fea53cc Vangelis Koukis
        if options['detect_all']:
111 9fea53cc Vangelis Koukis
            for kd in keys_detect:
112 9fea53cc Vangelis Koukis
                options[kd] = True
113 9fea53cc Vangelis Koukis
        if options['fix_all']:
114 9fea53cc Vangelis Koukis
            for kf in keys_fix:
115 9fea53cc Vangelis Koukis
                options[kf] = True
116 9fea53cc Vangelis Koukis
117 9fea53cc Vangelis Koukis
        for kf in keys_fix:
118 9fea53cc Vangelis Koukis
            kd = kf.replace('fix_', 'detect_', 1)
119 9fea53cc Vangelis Koukis
            if (options[kf] and not options[kd]):
120 7e136fd8 Giorgos Verigakis
                raise CommandError("Cannot use --%s without corresponding "
121 7e136fd8 Giorgos Verigakis
                                   "--%s argument" % (kf, kd))
122 9fea53cc Vangelis Koukis
123 9fea53cc Vangelis Koukis
    def handle(self, **options):
124 9fea53cc Vangelis Koukis
        verbosity = int(options['verbosity'])
125 9fea53cc Vangelis Koukis
        self._process_args(options)
126 c414bc87 Christos Stavrakakis
        backend_id = options['backend-id']
127 e77a29ab Christos Stavrakakis
        if backend_id:
128 e77a29ab Christos Stavrakakis
            backends = [get_backend(backend_id)]
129 e77a29ab Christos Stavrakakis
        else:
130 e77a29ab Christos Stavrakakis
            backends = Backend.objects.filter(offline=False)
131 9fea53cc Vangelis Koukis
132 7ab30015 Christos Stavrakakis
        with_nics = options["detect_unsynced_nics"]
133 9fea53cc Vangelis Koukis
134 7ab30015 Christos Stavrakakis
        DBVMs = reconciliation.get_servers_from_db(backend, with_nics)
135 7ab30015 Christos Stavrakakis
        GanetiVMs = reconciliation.get_instances_from_ganeti(backend)
136 c6ad2f2d Christos Stavrakakis
137 9fea53cc Vangelis Koukis
        #
138 9fea53cc Vangelis Koukis
        # Detect problems
139 9fea53cc Vangelis Koukis
        #
140 9fea53cc Vangelis Koukis
        if options['detect_stale']:
141 7ab30015 Christos Stavrakakis
            stale = reconciliation.stale_servers_in_db(DBVMs, GanetiVMs)
142 9fea53cc Vangelis Koukis
            if len(stale) > 0:
143 9fea53cc Vangelis Koukis
                print >> sys.stderr, "Found the following stale server IDs: "
144 9fea53cc Vangelis Koukis
                print "    " + "\n    ".join(
145 9fea53cc Vangelis Koukis
                    [str(x) for x in stale])
146 9fea53cc Vangelis Koukis
            elif verbosity == 2:
147 9fea53cc Vangelis Koukis
                print >> sys.stderr, "Found no stale server IDs in DB."
148 9fea53cc Vangelis Koukis
149 9fea53cc Vangelis Koukis
        if options['detect_orphans']:
150 7ab30015 Christos Stavrakakis
            orphans = reconciliation.orphan_instances_in_ganeti(DBVMs,
151 7ab30015 Christos Stavrakakis
                                                                GanetiVMs)
152 9fea53cc Vangelis Koukis
            if len(orphans) > 0:
153 9fea53cc Vangelis Koukis
                print >> sys.stderr, "Found orphan Ganeti instances with IDs: "
154 9fea53cc Vangelis Koukis
                print "    " + "\n    ".join(
155 9fea53cc Vangelis Koukis
                    [str(x) for x in orphans])
156 9fea53cc Vangelis Koukis
            elif verbosity == 2:
157 9fea53cc Vangelis Koukis
                print >> sys.stderr, "Found no orphan Ganeti instances."
158 9fea53cc Vangelis Koukis
159 9fea53cc Vangelis Koukis
        if options['detect_unsynced']:
160 7ab30015 Christos Stavrakakis
            unsynced = reconciliation.unsynced_operstate(DBVMs, GanetiVMs)
161 9fea53cc Vangelis Koukis
            if len(unsynced) > 0:
162 9fea53cc Vangelis Koukis
                print >> sys.stderr, "The operstate of the following server" \
163 9fea53cc Vangelis Koukis
                                     " IDs is out-of-sync:"
164 9fea53cc Vangelis Koukis
                print "    " + "\n    ".join(
165 9fea53cc Vangelis Koukis
                    ["%d is %s in DB, %s in Ganeti" %
166 9fea53cc Vangelis Koukis
                     (x[0], x[1], ('UP' if x[2] else 'DOWN'))
167 9fea53cc Vangelis Koukis
                     for x in unsynced])
168 9fea53cc Vangelis Koukis
            elif verbosity == 2:
169 9fea53cc Vangelis Koukis
                print >> sys.stderr, "The operstate of all servers is in sync."
170 9fea53cc Vangelis Koukis
171 4161cb41 Christos Stavrakakis
        if options['detect_build_errors']:
172 7ab30015 Christos Stavrakakis
            build_errors = reconciliation.\
173 7ab30015 Christos Stavrakakis
                instances_with_build_errors(DBVMs, GanetiVMs)
174 4161cb41 Christos Stavrakakis
            if len(build_errors) > 0:
175 c59f7e0f Christos Stavrakakis
                msg = "The os for the following server IDs was not build"\
176 c59f7e0f Christos Stavrakakis
                      " successfully:"
177 c59f7e0f Christos Stavrakakis
                print >> sys.stderr, msg
178 4161cb41 Christos Stavrakakis
                print "    " + "\n    ".join(
179 4161cb41 Christos Stavrakakis
                    ["%d" % x for x in build_errors])
180 4161cb41 Christos Stavrakakis
            elif verbosity == 2:
181 4161cb41 Christos Stavrakakis
                print >> sys.stderr, "Found no instances with build errors."
182 4161cb41 Christos Stavrakakis
183 0e9a423f Christos Stavrakakis
        if options['detect_unsynced_nics']:
184 0e9a423f Christos Stavrakakis
            def pretty_print_nics(nics):
185 0e9a423f Christos Stavrakakis
                if not nics:
186 0e9a423f Christos Stavrakakis
                    print ''.ljust(18) + 'None'
187 0e9a423f Christos Stavrakakis
                for index, info in nics.items():
188 c59f7e0f Christos Stavrakakis
                    print ''.ljust(18) + 'nic/' + str(index) +\
189 c59f7e0f Christos Stavrakakis
                          ': MAC: %s, IP: %s, Network: %s' % \
190 c59f7e0f Christos Stavrakakis
                          (info['mac'], info['ipv4'], info['network'])
191 0e9a423f Christos Stavrakakis
192 7ab30015 Christos Stavrakakis
            unsynced_nics = reconciliation.unsynced_nics(DBVMs, GanetiVMs)
193 0e9a423f Christos Stavrakakis
            if len(unsynced_nics) > 0:
194 c59f7e0f Christos Stavrakakis
                msg = "The NICs of the servers with the following IDs are"\
195 c59f7e0f Christos Stavrakakis
                      " unsynced:"
196 c59f7e0f Christos Stavrakakis
                print >> sys.stderr, msg
197 0e9a423f Christos Stavrakakis
                for id, nics in unsynced_nics.items():
198 0e9a423f Christos Stavrakakis
                    print ''.ljust(2) + '%6d:' % id
199 0e9a423f Christos Stavrakakis
                    print ''.ljust(8) + '%8s:' % 'DB'
200 0e9a423f Christos Stavrakakis
                    pretty_print_nics(nics[0])
201 0e9a423f Christos Stavrakakis
                    print ''.ljust(8) + '%8s:' % 'Ganeti'
202 0e9a423f Christos Stavrakakis
                    pretty_print_nics(nics[1])
203 0e9a423f Christos Stavrakakis
            elif verbosity == 2:
204 0e9a423f Christos Stavrakakis
                print >> sys.stderr, "All instance nics are synced."
205 0e9a423f Christos Stavrakakis
206 a67419d8 Christos Stavrakakis
        if options["detect_unsynced_flavors"]:
207 a67419d8 Christos Stavrakakis
            unsynced_flavors = reconciliation.unsynced_flavors(DBVMs,
208 a67419d8 Christos Stavrakakis
                                                               GanetiVMs)
209 a67419d8 Christos Stavrakakis
            if len(unsynced_flavors) > 0:
210 a67419d8 Christos Stavrakakis
                print >> sys.stderr, "The flavor of the following server" \
211 a67419d8 Christos Stavrakakis
                                     " IDs is out-of-sync:"
212 a67419d8 Christos Stavrakakis
                print "    " + "\n    ".join(
213 a67419d8 Christos Stavrakakis
                    ["%d is %s in DB, %s in Ganeti" %
214 a67419d8 Christos Stavrakakis
                     (x[0], x[1], x[2])
215 a67419d8 Christos Stavrakakis
                     for x in unsynced_flavors])
216 a67419d8 Christos Stavrakakis
            elif verbosity == 2:
217 a67419d8 Christos Stavrakakis
                print >> sys.stderr, "All instance flavors are synced."
218 a67419d8 Christos Stavrakakis
219 9fea53cc Vangelis Koukis
        #
220 9fea53cc Vangelis Koukis
        # Then fix them
221 9fea53cc Vangelis Koukis
        #
222 9fea53cc Vangelis Koukis
        if options['fix_stale'] and len(stale) > 0:
223 9fea53cc Vangelis Koukis
            print >> sys.stderr, \
224 9fea53cc Vangelis Koukis
                "Simulating successful Ganeti removal for %d " \
225 9fea53cc Vangelis Koukis
                "servers in the DB:" % len(stale)
226 9fea53cc Vangelis Koukis
            for vm in VirtualMachine.objects.filter(pk__in=stale):
227 c4e55622 Christos Stavrakakis
                event_time = datetime.datetime.now()
228 cc92b70f Christos Stavrakakis
                backend_mod.process_op_status(
229 cc92b70f Christos Stavrakakis
                    vm=vm,
230 cc92b70f Christos Stavrakakis
                    etime=event_time,
231 cc92b70f Christos Stavrakakis
                    jobid=-0,
232 9fea53cc Vangelis Koukis
                    opcode='OP_INSTANCE_REMOVE', status='success',
233 9fea53cc Vangelis Koukis
                    logmsg='Reconciliation: simulated Ganeti event')
234 9fea53cc Vangelis Koukis
            print >> sys.stderr, "    ...done"
235 9fea53cc Vangelis Koukis
236 9fea53cc Vangelis Koukis
        if options['fix_orphans'] and len(orphans) > 0:
237 9fea53cc Vangelis Koukis
            print >> sys.stderr, \
238 9fea53cc Vangelis Koukis
                "Issuing OP_INSTANCE_REMOVE for %d Ganeti instances:" % \
239 9fea53cc Vangelis Koukis
                len(orphans)
240 9fea53cc Vangelis Koukis
            for id in orphans:
241 e64e7ade Christos Stavrakakis
                try:
242 e64e7ade Christos Stavrakakis
                    vm = VirtualMachine.objects.get(pk=id)
243 3524241a Christos Stavrakakis
                    with pooled_rapi_client(vm) as client:
244 3524241a Christos Stavrakakis
                        client.DeleteInstance(utils.id_to_instance_name(id))
245 e64e7ade Christos Stavrakakis
                except VirtualMachine.DoesNotExist:
246 5706f527 Christos Stavrakakis
                    print >> sys.stderr, "No entry for VM %d in DB !!" % id
247 9fea53cc Vangelis Koukis
            print >> sys.stderr, "    ...done"
248 9fea53cc Vangelis Koukis
249 9fea53cc Vangelis Koukis
        if options['fix_unsynced'] and len(unsynced) > 0:
250 9fea53cc Vangelis Koukis
            print >> sys.stderr, "Setting the state of %d out-of-sync VMs:" % \
251 9fea53cc Vangelis Koukis
                len(unsynced)
252 9fea53cc Vangelis Koukis
            for id, db_state, ganeti_up in unsynced:
253 9fea53cc Vangelis Koukis
                vm = VirtualMachine.objects.get(pk=id)
254 9fea53cc Vangelis Koukis
                opcode = "OP_INSTANCE_REBOOT" if ganeti_up \
255 9fea53cc Vangelis Koukis
                         else "OP_INSTANCE_SHUTDOWN"
256 c4e55622 Christos Stavrakakis
                event_time = datetime.datetime.now()
257 cc92b70f Christos Stavrakakis
                backend_mod.process_op_status(
258 cc92b70f Christos Stavrakakis
                    vm=vm, etime=event_time, jobid=-0,
259 9fea53cc Vangelis Koukis
                    opcode=opcode, status='success',
260 9fea53cc Vangelis Koukis
                    logmsg='Reconciliation: simulated Ganeti event')
261 9fea53cc Vangelis Koukis
            print >> sys.stderr, "    ...done"
262 4161cb41 Christos Stavrakakis
263 4161cb41 Christos Stavrakakis
        if options['fix_build_errors'] and len(build_errors) > 0:
264 c59f7e0f Christos Stavrakakis
            print >> sys.stderr, "Setting the state of %d build-errors VMs:" %\
265 c59f7e0f Christos Stavrakakis
                                 len(build_errors)
266 4161cb41 Christos Stavrakakis
            for id in build_errors:
267 4161cb41 Christos Stavrakakis
                vm = VirtualMachine.objects.get(pk=id)
268 4161cb41 Christos Stavrakakis
                event_time = datetime.datetime.now()
269 c59f7e0f Christos Stavrakakis
                backend_mod.process_op_status(
270 c59f7e0f Christos Stavrakakis
                    vm=vm, etime=event_time, jobid=-0,
271 4161cb41 Christos Stavrakakis
                    opcode="OP_INSTANCE_CREATE", status='error',
272 4161cb41 Christos Stavrakakis
                    logmsg='Reconciliation: simulated Ganeti event')
273 4161cb41 Christos Stavrakakis
            print >> sys.stderr, "    ...done"
274 4161cb41 Christos Stavrakakis
275 0e9a423f Christos Stavrakakis
        if options['fix_unsynced_nics'] and len(unsynced_nics) > 0:
276 0e9a423f Christos Stavrakakis
            print >> sys.stderr, "Setting the nics of %d out-of-sync VMs:" % \
277 c59f7e0f Christos Stavrakakis
                                 len(unsynced_nics)
278 0e9a423f Christos Stavrakakis
            for id, nics in unsynced_nics.items():
279 0e9a423f Christos Stavrakakis
                vm = VirtualMachine.objects.get(pk=id)
280 0e9a423f Christos Stavrakakis
                nics = nics[1]  # Ganeti nics
281 0e9a423f Christos Stavrakakis
                if nics == {}:  # No nics
282 0e9a423f Christos Stavrakakis
                    vm.nics.all.delete()
283 0e9a423f Christos Stavrakakis
                    continue
284 0e9a423f Christos Stavrakakis
                for index, nic in nics.items():
285 cc3f266e Christos Stavrakakis
                    net_id = utils.id_from_network_name(nic['network'])
286 cc3f266e Christos Stavrakakis
                    subnet6 = Network.objects.get(id=net_id).subnet6
287 0e9a423f Christos Stavrakakis
                    # Produce ipv6
288 cc3f266e Christos Stavrakakis
                    ipv6 = subnet6 and mac2eui64(nic['mac'], subnet6) or None
289 0e9a423f Christos Stavrakakis
                    nic['ipv6'] = ipv6
290 0e9a423f Christos Stavrakakis
                    # Rename ipv4 to ip
291 0e9a423f Christos Stavrakakis
                    nic['ip'] = nic['ipv4']
292 0e9a423f Christos Stavrakakis
                # Dict to sorted list
293 0e9a423f Christos Stavrakakis
                final_nics = []
294 0e9a423f Christos Stavrakakis
                nics_keys = nics.keys()
295 0e9a423f Christos Stavrakakis
                nics_keys.sort()
296 0e9a423f Christos Stavrakakis
                for i in nics_keys:
297 0e9a423f Christos Stavrakakis
                    if nics[i]['network']:
298 0e9a423f Christos Stavrakakis
                        final_nics.append(nics[i])
299 0e9a423f Christos Stavrakakis
                    else:
300 0e9a423f Christos Stavrakakis
                        print 'Network of nic %d of vm %s is None. ' \
301 0e9a423f Christos Stavrakakis
                              'Can not reconcile' % (i, vm.backend_vm_id)
302 0e9a423f Christos Stavrakakis
                event_time = datetime.datetime.now()
303 cc92b70f Christos Stavrakakis
                backend_mod.process_net_status(vm=vm, etime=event_time,
304 cc92b70f Christos Stavrakakis
                                               nics=final_nics)
305 0e9a423f Christos Stavrakakis
            print >> sys.stderr, "    ...done"
306 a67419d8 Christos Stavrakakis
        if options["fix_unsynced_flavors"] and len(unsynced_flavors) > 0:
307 a67419d8 Christos Stavrakakis
            print >> sys.stderr, "Setting the flavor of %d unsynced VMs:" % \
308 a67419d8 Christos Stavrakakis
                len(unsynced_flavors)
309 a67419d8 Christos Stavrakakis
            for id, db_flavor, gnt_flavor in unsynced_flavors:
310 a67419d8 Christos Stavrakakis
                vm = VirtualMachine.objects.get(pk=id)
311 a67419d8 Christos Stavrakakis
                old_state = vm.operstate
312 a67419d8 Christos Stavrakakis
                opcode = "OP_INSTANCE_SET_PARAMS"
313 a67419d8 Christos Stavrakakis
                beparams = {"vcpus": gnt_flavor.cpu,
314 a67419d8 Christos Stavrakakis
                            "minmem": gnt_flavor.ram,
315 a67419d8 Christos Stavrakakis
                            "maxmem": gnt_flavor.ram}
316 a67419d8 Christos Stavrakakis
                event_time = datetime.datetime.now()
317 a67419d8 Christos Stavrakakis
                backend_mod.process_op_status(
318 a67419d8 Christos Stavrakakis
                    vm=vm, etime=event_time, jobid=-0,
319 a67419d8 Christos Stavrakakis
                    opcode=opcode, status='success',
320 a67419d8 Christos Stavrakakis
                    beparams=beparams,
321 a67419d8 Christos Stavrakakis
                    logmsg='Reconciliation: simulated Ganeti event')
322 a67419d8 Christos Stavrakakis
                # process_op_status with beparams will set the vmstate to
323 a67419d8 Christos Stavrakakis
                # shutdown. Fix this be returning it to old state
324 a67419d8 Christos Stavrakakis
                vm = VirtualMachine.objects.get(pk=id)
325 a67419d8 Christos Stavrakakis
                vm.operstate = old_state
326 a67419d8 Christos Stavrakakis
                vm.save()
327 a67419d8 Christos Stavrakakis
            print >> sys.stderr, "    ...done"