Revision 41a7fae7 snf-cyclades-app/synnefo/quotas/__init__.py

b/snf-cyclades-app/synnefo/quotas/__init__.py
46 46
RESOURCES = [
47 47
    "cyclades.vm",
48 48
    "cyclades.cpu",
49
    "cyclades.active_cpu",
49 50
    "cyclades.disk",
50 51
    "cyclades.ram",
52
    "cyclades.active_ram",
51 53
    "cyclades.network.private"
52 54
]
53 55

  
......
107 109
        raise Exception("No serial")
108 110

  
109 111

  
112
def accept_serial(serial, strict=True):
113
    response = resolve_commissions(accept=[serial.serial], strict=strict)
114
    serial.accept = True
115
    serial.resolved = True
116
    serial.save()
117
    return response
118

  
119

  
120
def reject_serial(serial, strict=True):
121
    response = resolve_commissions(reject=[serial.serial], strict=strict)
122
    serial.reject = True
123
    serial.resolved = True
124
    serial.save()
125
    return response
126

  
127

  
110 128
def accept_commissions(accepted, strict=True):
111 129
    return resolve_commissions(accept=accepted, strict=strict)
112 130

  
......
222 240
                  " '%s' is still pending." % (resource, previous_serial)
223 241
            raise Exception(msg)
224 242
        elif previous_serial.accept:
225
            accept_commissions(accepted=[previous_serial.serial], strict=False)
243
            accept_serial(previous_serial, strict=False)
226 244
        else:
227
            reject_commissions(rejected=[previous_serial.serial], strict=False)
228
        previous_serial.resolved = True
245
            reject_serial(previous_serial, strict=False)
229 246

  
230 247
    try:
231 248
        # Convert resources in the format expected by Quotaholder
......
241 258
        raise
242 259

  
243 260
    try:
244
        # Mark the serial as one to accept. This step is necessary for
245
        # reconciliation
261
        # Mark the serial as one to accept and associate it with the resource
246 262
        serial.pending = False
247 263
        serial.accept = True
248 264
        serial.save()
249

  
250
        # Associate serial with the resource
251 265
        resource.serial = serial
252 266
        resource.save()
253

  
254
        # Commit transaction in the DB! If this commit succeeds, then the
255
        # serial is created in the DB with all the necessary information to
256
        # reconcile commission
257 267
        transaction.commit()
268
        # Accept the commission to quotaholder
269
        accept_serial(serial)
270
        transaction.commit()
271
        return serial
258 272
    except:
273
        log.exception("Unexpected ERROR")
259 274
        transaction.rollback()
260
        serial.pending = False
261
        serial.accept = False
262
        serial.save()
275
        reject_serial(serial)
263 276
        transaction.commit()
264 277
        raise
265 278

  
266
    if serial.accept:
267
        # Accept commission to Quotaholder
268
        accept_commissions(accepted=[serial.serial])
269
    else:
270
        reject_commissions(rejected=[serial.serial])
271

  
272
    # Mark the serial as resolved, indicating that no further actions are
273
    # needed for this serial
274
    serial.resolved = True
275
    serial.save()
276
    transaction.commit()
277

  
278
    return serial
279

  
280 279

  
281 280
def prepare_qh_resources(resource):
282 281
    if isinstance(resource, VirtualMachine):
283 282
        flavor = resource.flavor
284 283
        return {'cyclades.vm': 1,
285 284
                'cyclades.cpu': flavor.cpu,
285
                'cyclades.active_cpu': flavor.cpu,
286 286
                'cyclades.disk': 1073741824 * flavor.disk,  # flavor.disk in GB
287 287
                # 'public_ip': 1,
288 288
                #'disk_template': flavor.disk_template,
289
                'cyclades.ram': 1048576 * flavor.ram}  # flavor.ram is in MB
289
                # flavor.ram is in MB
290
                'cyclades.ram': 1048576 * flavor.ram,
291
                'cyclades.active_ram': 1048576 * flavor.ram}
290 292
    elif isinstance(resource, Network):
291 293
        return {"cyclades.network.private": 1}
292 294
    else:
293 295
        raise ValueError("Unknown Resource '%s'" % resource)
294 296

  
295 297

  
298
def get_commission_info(resource, action, action_fields=None):
299
    if isinstance(resource, VirtualMachine):
300
        flavor = resource.flavor
301
        resources = {"cyclades.vm": 1,
302
                     "cyclades.cpu": flavor.cpu,
303
                     "cyclades.disk": 1073741824 * flavor.disk,
304
                     "cyclades.ram": 1048576 * flavor.ram}
305
        online_resources = {"cyclades.active_cpu": flavor.cpu,
306
                            "cyclades.active_ram": 1048576 * flavor.ram}
307
        # No commission for build! Commission has already been issued and
308
        # accepted, since the VM has been created in DB.
309
        #if action == "BUILD":
310
        #    resources.update(online_resources)
311
        #    return resources
312
        if action == "START":
313
            if resource.operstate == "STOPPED":
314
                return online_resources
315
            else:
316
                return None
317
        elif action == "STOP":
318
            if resource.operstate in ["STARTED", "BUILD", "ERROR"]:
319
                return reverse_quantities(online_resources)
320
            else:
321
                return None
322
        elif action == "REBOOT":
323
            if resource.operstate == "STOPPED":
324
                return online_resources
325
            else:
326
                return None
327
        elif action == "DESTROY":
328
            if resource.operstate in ["STARTED", "BUILD", "ERROR"]:
329
                resources.update(online_resources)
330
            return reverse_quantities(resources)
331
        elif action == "RESIZE" and action_fields:
332
            beparams = action_fields.get("beparams")
333
            cpu = beparams.get("vcpus", flavor.cpu)
334
            ram = beparams.get("maxmem", flavor.ram)
335
            return {"cyclades.cpu": cpu - flavor.cpu,
336
                    "cyclades.ram": 1048576 * (ram - flavor.ram)}
337
        else:
338
            #["CONNECT", "DISCONNECT", "SET_FIREWALL_PROFILE"]:
339
            return None
340

  
341

  
296 342
def reverse_quantities(resources):
297 343
    return dict((r, -s) for r, s in resources.items())
344

  
345

  
346
def resolve_vm_commission(serial):
347
    log.warning("Resolving pending commission: %s", serial)
348
    if not serial.pending and serial.accept:
349
        accept_serial(serial)
350
    else:
351
        reject_serial(serial)

Also available in: Unified diff