~ubuntu-branches/ubuntu/saucy/nova/saucy-proposed

« back to all changes in this revision

Viewing changes to nova/db/sqlalchemy/api.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-05-24 13:12:53 UTC
  • mfrom: (1.1.55)
  • Revision ID: package-import@ubuntu.com-20120524131253-ommql08fg1en06ut
Tags: 2012.2~f1-0ubuntu1
* New upstream release.
* Prepare for quantal:
  - Dropped debian/patches/upstream/0006-Use-project_id-in-ec2.cloud._format_image.patch
  - Dropped debian/patches/upstream/0005-Populate-image-properties-with-project_id-again.patch
  - Dropped debian/patches/upstream/0004-Fixed-bug-962840-added-a-test-case.patch
  - Dropped debian/patches/upstream/0003-Allow-unprivileged-RADOS-users-to-access-rbd-volumes.patch
  - Dropped debian/patches/upstream/0002-Stop-libvirt-test-from-deleting-instances-dir.patch
  - Dropped debian/patches/upstream/0001-fix-bug-where-nova-ignores-glance-host-in-imageref.patch 
  - Dropped debian/patches/0001-fix-useexisting-deprecation-warnings.patch
* debian/control: Add python-keystone as a dependency. (LP: #907197)
* debian/patches/kombu_tests_timeout.patch: Refreshed.
* debian/nova.conf, debian/nova-common.postinst: Convert to new ini
  file configuration
* debian/patches/nova-manage_flagfile_location.patch: Refreshed

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
import warnings
26
26
 
27
27
from nova import block_device
 
28
from nova.compute import aggregate_states
 
29
from nova.compute import vm_states
28
30
from nova import db
 
31
from nova.db.sqlalchemy import models
 
32
from nova.db.sqlalchemy.session import get_session
29
33
from nova import exception
30
34
from nova import flags
 
35
from nova import log as logging
31
36
from nova import utils
32
 
from nova import log as logging
33
 
from nova.compute import aggregate_states
34
 
from nova.compute import vm_states
35
 
from nova.db.sqlalchemy import models
36
 
from nova.db.sqlalchemy.session import get_session
37
37
from sqlalchemy import and_
 
38
from sqlalchemy.exc import IntegrityError
38
39
from sqlalchemy import or_
39
 
from sqlalchemy.exc import IntegrityError
40
40
from sqlalchemy.orm import joinedload
41
41
from sqlalchemy.orm import joinedload_all
42
 
from sqlalchemy.sql import func
43
42
from sqlalchemy.sql.expression import asc
44
43
from sqlalchemy.sql.expression import desc
45
44
from sqlalchemy.sql.expression import literal_column
 
45
from sqlalchemy.sql import func
46
46
 
47
47
FLAGS = flags.FLAGS
48
48
flags.DECLARE('reserved_host_disk_mb', 'nova.scheduler.host_manager')
89
89
            raise exception.NotAuthorized()
90
90
 
91
91
 
 
92
def authorize_quota_class_context(context, class_name):
 
93
    """Ensures a request has permission to access the given quota class."""
 
94
    if is_user_context(context):
 
95
        if not context.quota_class:
 
96
            raise exception.NotAuthorized()
 
97
        elif context.quota_class != class_name:
 
98
            raise exception.NotAuthorized()
 
99
 
 
100
 
92
101
def require_admin_context(f):
93
102
    """Decorator to require admin request context.
94
103
 
127
136
    Requires the wrapped function to use context and instance_id as
128
137
    their first two arguments.
129
138
    """
130
 
 
 
139
    @functools.wraps(f)
131
140
    def wrapper(context, instance_id, *args, **kwargs):
132
141
        db.instance_get(context, instance_id)
133
142
        return f(context, instance_id, *args, **kwargs)
134
 
    wrapper.__name__ = f.__name__
 
143
 
 
144
    return wrapper
 
145
 
 
146
 
 
147
def require_instance_exists_using_uuid(f):
 
148
    """Decorator to require the specified instance to exist.
 
149
 
 
150
    Requires the wrapped function to use context and instance_uuid as
 
151
    their first two arguments.
 
152
    """
 
153
    @functools.wraps(f)
 
154
    def wrapper(context, instance_uuid, *args, **kwargs):
 
155
        db.instance_get_by_uuid(context, instance_uuid)
 
156
        return f(context, instance_uuid, *args, **kwargs)
 
157
 
135
158
    return wrapper
136
159
 
137
160
 
654
677
 
655
678
 
656
679
@require_context
657
 
def floating_ip_count_by_project(context, project_id):
 
680
def floating_ip_count_by_project(context, project_id, session=None):
658
681
    authorize_project_context(context, project_id)
659
682
    # TODO(tr3buchet): why leave auto_assigned floating IPs out?
660
 
    return model_query(context, models.FloatingIp, read_deleted="no").\
 
683
    return model_query(context, models.FloatingIp, read_deleted="no",
 
684
                       session=session).\
661
685
                   filter_by(project_id=project_id).\
662
686
                   filter_by(auto_assigned=False).\
663
687
                   count()
1046
1070
@require_context
1047
1071
def fixed_ip_get_by_address(context, address, session=None):
1048
1072
    result = model_query(context, models.FixedIp, session=session,
1049
 
                         read_deleted="yes").\
 
1073
                         read_deleted=context.read_deleted).\
1050
1074
                     filter_by(address=address).\
1051
1075
                     first()
1052
1076
    if not result:
1250
1274
    values - dict containing column values.
1251
1275
    """
1252
1276
    values = values.copy()
1253
 
    values['metadata'] = _metadata_refs(values.get('metadata'),
1254
 
                                        models.InstanceMetadata)
 
1277
    values['metadata'] = _metadata_refs(
 
1278
            values.get('metadata'), models.InstanceMetadata)
 
1279
 
 
1280
    values['system_metadata'] = _metadata_refs(
 
1281
            values.get('system_metadata'), models.InstanceSystemMetadata)
 
1282
 
1255
1283
    instance_ref = models.Instance()
1256
1284
    if not values.get('uuid'):
1257
1285
        values['uuid'] = str(utils.gen_uuid())
1268
1296
 
1269
1297
 
1270
1298
@require_admin_context
1271
 
def instance_data_get_for_project(context, project_id):
 
1299
def instance_data_get_for_project(context, project_id, session=None):
1272
1300
    result = model_query(context,
1273
1301
                         func.count(models.Instance.id),
1274
1302
                         func.sum(models.Instance.vcpus),
1275
1303
                         func.sum(models.Instance.memory_mb),
1276
 
                         read_deleted="no").\
 
1304
                         read_deleted="no",
 
1305
                         session=session).\
1277
1306
                     filter_by(project_id=project_id).\
1278
1307
                     first()
1279
1308
    # NOTE(vish): convert None to 0
1306
1335
                update({'deleted': True,
1307
1336
                        'deleted_at': utils.utcnow(),
1308
1337
                        'updated_at': literal_column('updated_at')})
 
1338
        session.query(models.InstanceSystemMetadata).\
 
1339
                filter_by(instance_uuid=instance_ref['uuid']).\
 
1340
                update({'deleted': True,
 
1341
                        'deleted_at': utils.utcnow(),
 
1342
                        'updated_at': literal_column('updated_at')})
1309
1343
        session.query(models.BlockDeviceMapping).\
1310
 
                filter_by(instance_id=instance_id).\
 
1344
                filter_by(instance_uuid=instance_ref['uuid']).\
1311
1345
                update({'deleted': True,
1312
1346
                        'deleted_at': utils.utcnow(),
1313
1347
                        'updated_at': literal_column('updated_at')})
1347
1381
                        project_only=True).\
1348
1382
            options(joinedload_all('security_groups.rules')).\
1349
1383
            options(joinedload('info_cache')).\
1350
 
            options(joinedload('volumes')).\
1351
1384
            options(joinedload('metadata')).\
1352
1385
            options(joinedload('instance_type'))
1353
1386
 
1533
1566
# NOTE(jkoelker) This is only being left here for compat with floating
1534
1567
#                ips. Currently the network_api doesn't return floaters
1535
1568
#                in network_info. Once it starts return the model. This
1536
 
#                function and it's call in compute/manager.py on 1829 can
 
1569
#                function and its call in compute/manager.py on 1829 can
1537
1570
#                go away
1538
1571
@require_context
1539
1572
def instance_get_floating_address(context, instance_id):
1611
1644
 
1612
1645
    metadata = values.get('metadata')
1613
1646
    if metadata is not None:
1614
 
        instance_metadata_update(context,
1615
 
                                 instance_ref['id'],
1616
 
                                 values.pop('metadata'),
1617
 
                                 delete=True)
 
1647
        instance_metadata_update(
 
1648
            context, instance_ref['id'], values.pop('metadata'), delete=True)
 
1649
 
 
1650
    system_metadata = values.get('system_metadata')
 
1651
    if system_metadata is not None:
 
1652
        instance_system_metadata_update(
 
1653
             context, instance_ref['uuid'], values.pop('system_metadata'),
 
1654
             delete=True)
 
1655
 
1618
1656
    with session.begin():
1619
1657
        instance_ref.update(values)
1620
1658
        instance_ref.save(session=session)
1650
1688
 
1651
1689
 
1652
1690
@require_context
1653
 
def instance_action_create(context, values):
1654
 
    """Create an instance action from the values dictionary."""
1655
 
    action_ref = models.InstanceActions()
1656
 
    action_ref.update(values)
1657
 
 
1658
 
    session = get_session()
1659
 
    with session.begin():
1660
 
        action_ref.save(session=session)
1661
 
    return action_ref
1662
 
 
1663
 
 
1664
 
@require_admin_context
1665
 
def instance_get_actions(context, instance_uuid):
1666
 
    """Return the actions associated to the given instance id"""
1667
 
    session = get_session()
1668
 
    return session.query(models.InstanceActions).\
1669
 
                   filter_by(instance_uuid=instance_uuid).\
1670
 
                   all()
1671
 
 
1672
 
 
1673
 
@require_context
1674
1691
def instance_get_id_to_uuid_mapping(context, ids):
1675
1692
    session = get_session()
1676
1693
    instances = session.query(models.Instance).\
1807
1824
                   all()
1808
1825
 
1809
1826
 
 
1827
def key_pair_count_by_user(context, user_id):
 
1828
    authorize_user_context(context, user_id)
 
1829
    return model_query(context, models.KeyPair, read_deleted="no").\
 
1830
                   filter_by(user_id=user_id).\
 
1831
                   count()
 
1832
 
 
1833
 
1810
1834
###################
1811
1835
 
1812
1836
 
1898
1922
def network_delete_safe(context, network_id):
1899
1923
    session = get_session()
1900
1924
    with session.begin():
 
1925
        result = session.query(models.FixedIp).\
 
1926
                         filter_by(network_id=network_id).\
 
1927
                         filter_by(deleted=False).\
 
1928
                         filter_by(allocated=True).\
 
1929
                         all()
 
1930
        if result:
 
1931
            raise exception.NetworkInUse(network_id=network_id)
1901
1932
        network_ref = network_get(context, network_id=network_id,
1902
1933
                                  session=session)
 
1934
        session.query(models.FixedIp).\
 
1935
                filter_by(network_id=network_id).\
 
1936
                filter_by(deleted=False).\
 
1937
                update({'deleted': True,
 
1938
                        'updated_at': literal_column('updated_at'),
 
1939
                        'deleted_at': utils.utcnow()})
1903
1940
        session.delete(network_ref)
1904
1941
 
1905
1942
 
2149
2186
@require_admin_context
2150
2187
def iscsi_target_create_safe(context, values):
2151
2188
    iscsi_target_ref = models.IscsiTarget()
 
2189
 
2152
2190
    for (key, value) in values.iteritems():
2153
2191
        iscsi_target_ref[key] = value
2154
2192
    try:
2232
2270
 
2233
2271
@require_admin_context
2234
2272
def quota_create(context, project_id, resource, limit):
2235
 
    # NOTE: Treat -1 as unlimited for consistency w/ flags
2236
 
    if limit == -1:
2237
 
        limit = None
2238
2273
    quota_ref = models.Quota()
2239
2274
    quota_ref.project_id = project_id
2240
2275
    quota_ref.resource = resource
2245
2280
 
2246
2281
@require_admin_context
2247
2282
def quota_update(context, project_id, resource, limit):
2248
 
    # NOTE: Treat -1 as unlimited for consistency w/ flags
2249
 
    if limit == -1:
2250
 
        limit = None
2251
2283
    session = get_session()
2252
2284
    with session.begin():
2253
2285
        quota_ref = quota_get(context, project_id, resource, session=session)
2263
2295
        quota_ref.delete(session=session)
2264
2296
 
2265
2297
 
 
2298
###################
 
2299
 
 
2300
 
 
2301
@require_context
 
2302
def quota_class_get(context, class_name, resource, session=None):
 
2303
    result = model_query(context, models.QuotaClass, session=session,
 
2304
                         read_deleted="no").\
 
2305
                     filter_by(class_name=class_name).\
 
2306
                     filter_by(resource=resource).\
 
2307
                     first()
 
2308
 
 
2309
    if not result:
 
2310
        raise exception.QuotaClassNotFound(class_name=class_name)
 
2311
 
 
2312
    return result
 
2313
 
 
2314
 
 
2315
@require_context
 
2316
def quota_class_get_all_by_name(context, class_name):
 
2317
    authorize_quota_class_context(context, class_name)
 
2318
 
 
2319
    rows = model_query(context, models.QuotaClass, read_deleted="no").\
 
2320
                   filter_by(class_name=class_name).\
 
2321
                   all()
 
2322
 
 
2323
    result = {'class_name': class_name}
 
2324
    for row in rows:
 
2325
        result[row.resource] = row.hard_limit
 
2326
 
 
2327
    return result
 
2328
 
 
2329
 
 
2330
@require_admin_context
 
2331
def quota_class_create(context, class_name, resource, limit):
 
2332
    quota_class_ref = models.QuotaClass()
 
2333
    quota_class_ref.class_name = class_name
 
2334
    quota_class_ref.resource = resource
 
2335
    quota_class_ref.hard_limit = limit
 
2336
    quota_class_ref.save()
 
2337
    return quota_class_ref
 
2338
 
 
2339
 
 
2340
@require_admin_context
 
2341
def quota_class_update(context, class_name, resource, limit):
 
2342
    session = get_session()
 
2343
    with session.begin():
 
2344
        quota_class_ref = quota_class_get(context, class_name, resource,
 
2345
                                          session=session)
 
2346
        quota_class_ref.hard_limit = limit
 
2347
        quota_class_ref.save(session=session)
 
2348
 
 
2349
 
 
2350
@require_admin_context
 
2351
def quota_class_destroy(context, class_name, resource):
 
2352
    session = get_session()
 
2353
    with session.begin():
 
2354
        quota_class_ref = quota_class_get(context, class_name, resource,
 
2355
                                          session=session)
 
2356
        quota_class_ref.delete(session=session)
 
2357
 
 
2358
 
 
2359
@require_admin_context
 
2360
def quota_class_destroy_all_by_name(context, class_name):
 
2361
    session = get_session()
 
2362
    with session.begin():
 
2363
        quota_classes = model_query(context, models.QuotaClass,
 
2364
                                    session=session, read_deleted="no").\
 
2365
                                filter_by(class_name=class_name).\
 
2366
                                all()
 
2367
 
 
2368
        for quota_class_ref in quota_classes:
 
2369
            quota_class_ref.delete(session=session)
 
2370
 
 
2371
 
 
2372
###################
 
2373
 
 
2374
 
 
2375
@require_context
 
2376
def quota_usage_get(context, project_id, resource, session=None):
 
2377
    result = model_query(context, models.QuotaUsage, session=session,
 
2378
                         read_deleted="no").\
 
2379
                     filter_by(project_id=project_id).\
 
2380
                     filter_by(resource=resource).\
 
2381
                     first()
 
2382
 
 
2383
    if not result:
 
2384
        raise exception.QuotaUsageNotFound(project_id=project_id)
 
2385
 
 
2386
    return result
 
2387
 
 
2388
 
 
2389
@require_context
 
2390
def quota_usage_get_all_by_project(context, project_id):
 
2391
    authorize_project_context(context, project_id)
 
2392
 
 
2393
    rows = model_query(context, models.QuotaUsage, read_deleted="no").\
 
2394
                   filter_by(project_id=project_id).\
 
2395
                   all()
 
2396
 
 
2397
    result = {'project_id': project_id}
 
2398
    for row in rows:
 
2399
        result[row.resource] = dict(in_use=row.in_use, reserved=row.reserved)
 
2400
 
 
2401
    return result
 
2402
 
 
2403
 
 
2404
@require_admin_context
 
2405
def quota_usage_create(context, project_id, resource, in_use, reserved,
 
2406
                       until_refresh, session=None, save=True):
 
2407
    quota_usage_ref = models.QuotaUsage()
 
2408
    quota_usage_ref.project_id = project_id
 
2409
    quota_usage_ref.resource = resource
 
2410
    quota_usage_ref.in_use = in_use
 
2411
    quota_usage_ref.reserved = reserved
 
2412
    quota_usage_ref.until_refresh = until_refresh
 
2413
 
 
2414
    # Allow us to hold the save operation until later; keeps the
 
2415
    # transaction in quota_reserve() from breaking too early
 
2416
    if save:
 
2417
        quota_usage_ref.save(session=session)
 
2418
 
 
2419
    return quota_usage_ref
 
2420
 
 
2421
 
 
2422
@require_admin_context
 
2423
def quota_usage_update(context, project_id, resource, in_use, reserved,
 
2424
                       until_refresh, session=None):
 
2425
    def do_update(session):
 
2426
        quota_usage_ref = quota_usage_get(context, project_id, resource,
 
2427
                                          session=session)
 
2428
        quota_usage_ref.in_use = in_use
 
2429
        quota_usage_ref.reserved = reserved
 
2430
        quota_usage_ref.until_refresh = until_refresh
 
2431
        quota_usage_ref.save(session=session)
 
2432
 
 
2433
    if session:
 
2434
        # Assume caller started a transaction
 
2435
        do_update(session)
 
2436
    else:
 
2437
        session = get_session()
 
2438
        with session.begin():
 
2439
            do_update(session)
 
2440
 
 
2441
 
 
2442
@require_admin_context
 
2443
def quota_usage_destroy(context, project_id, resource):
 
2444
    session = get_session()
 
2445
    with session.begin():
 
2446
        quota_usage_ref = quota_usage_get(context, project_id, resource,
 
2447
                                          session=session)
 
2448
        quota_usage_ref.delete(session=session)
 
2449
 
 
2450
 
 
2451
###################
 
2452
 
 
2453
 
 
2454
@require_context
 
2455
def reservation_get(context, uuid, session=None):
 
2456
    result = model_query(context, models.Reservation, session=session,
 
2457
                         read_deleted="no").\
 
2458
                     filter_by(uuid=uuid).\
 
2459
                     first()
 
2460
 
 
2461
    if not result:
 
2462
        raise exception.ReservationNotFound(uuid=uuid)
 
2463
 
 
2464
    return result
 
2465
 
 
2466
 
 
2467
@require_context
 
2468
def reservation_get_all_by_project(context, project_id):
 
2469
    authorize_project_context(context, project_id)
 
2470
 
 
2471
    rows = model_query(context, models.QuotaUsage, read_deleted="no").\
 
2472
                   filter_by(project_id=project_id).\
 
2473
                   all()
 
2474
 
 
2475
    result = {'project_id': project_id}
 
2476
    for row in rows:
 
2477
        result.setdefault(row.resource, {})
 
2478
        result[row.resource][row.uuid] = row.delta
 
2479
 
 
2480
    return result
 
2481
 
 
2482
 
 
2483
@require_admin_context
 
2484
def reservation_create(context, uuid, usage, project_id, resource, delta,
 
2485
                       expire, session=None):
 
2486
    reservation_ref = models.Reservation()
 
2487
    reservation_ref.uuid = uuid
 
2488
    reservation_ref.usage = usage
 
2489
    reservation_ref.project_id = project_id
 
2490
    reservation_ref.resource = resource
 
2491
    reservation_ref.delta = delta
 
2492
    reservation_ref.expire = expire
 
2493
    reservation_ref.save(session=session)
 
2494
    return reservation_ref
 
2495
 
 
2496
 
 
2497
@require_admin_context
 
2498
def reservation_destroy(context, uuid):
 
2499
    session = get_session()
 
2500
    with session.begin():
 
2501
        reservation_ref = reservation_get(context, uuid, session=session)
 
2502
        reservation_ref.delete(session=session)
 
2503
 
 
2504
 
 
2505
###################
 
2506
 
 
2507
 
 
2508
def _get_quota_usages(context, session, keys):
 
2509
    # Broken out for testability
 
2510
    rows = model_query(context, models.QuotaUsage,
 
2511
                       read_deleted="no",
 
2512
                       session=session).\
 
2513
                   filter_by(project_id=context.project_id).\
 
2514
                   filter(models.QuotaUsage.resource.in_(keys)).\
 
2515
                   with_lockmode('update').\
 
2516
                   all()
 
2517
    return dict((row.resource, row) for row in rows)
 
2518
 
 
2519
 
 
2520
@require_context
 
2521
def quota_reserve(context, resources, quotas, deltas, expire,
 
2522
                  until_refresh, max_age):
 
2523
    elevated = context.elevated()
 
2524
    session = get_session()
 
2525
    with session.begin():
 
2526
        # Get the current usages
 
2527
        usages = _get_quota_usages(context, session, deltas.keys())
 
2528
 
 
2529
        # Handle usage refresh
 
2530
        work = set(deltas.keys())
 
2531
        while work:
 
2532
            resource = work.pop()
 
2533
 
 
2534
            # Do we need to refresh the usage?
 
2535
            refresh = False
 
2536
            if resource not in usages:
 
2537
                # Note we're inhibiting save...
 
2538
                usages[resource] = quota_usage_create(elevated,
 
2539
                                                      context.project_id,
 
2540
                                                      resource,
 
2541
                                                      0, 0,
 
2542
                                                      until_refresh or None,
 
2543
                                                      session=session,
 
2544
                                                      save=False)
 
2545
                refresh = True
 
2546
            elif usages[resource].until_refresh is not None:
 
2547
                usages[resource].until_refresh -= 1
 
2548
                if usages[resource].until_refresh <= 0:
 
2549
                    refresh = True
 
2550
            elif max_age and (usages[resource].updated_at -
 
2551
                              utils.utcnow()).seconds >= max_age:
 
2552
                refresh = True
 
2553
 
 
2554
            # OK, refresh the usage
 
2555
            if refresh:
 
2556
                # Grab the sync routine
 
2557
                sync = resources[resource].sync
 
2558
 
 
2559
                updates = sync(elevated, context.project_id, session)
 
2560
                for res, in_use in updates.items():
 
2561
                    # Make sure we have a destination for the usage!
 
2562
                    if res not in usages:
 
2563
                        # Note we're inhibiting save...
 
2564
                        usages[res] = quota_usage_create(elevated,
 
2565
                                                         context.project_id,
 
2566
                                                         res,
 
2567
                                                         0, 0,
 
2568
                                                         until_refresh or None,
 
2569
                                                         session=session,
 
2570
                                                         save=False)
 
2571
 
 
2572
                    # Update the usage
 
2573
                    usages[res].in_use = in_use
 
2574
                    usages[res].until_refresh = until_refresh or None
 
2575
 
 
2576
                    # Because more than one resource may be refreshed
 
2577
                    # by the call to the sync routine, and we don't
 
2578
                    # want to double-sync, we make sure all refreshed
 
2579
                    # resources are dropped from the work set.
 
2580
                    work.discard(res)
 
2581
 
 
2582
                    # NOTE(Vek): We make the assumption that the sync
 
2583
                    #            routine actually refreshes the
 
2584
                    #            resources that it is the sync routine
 
2585
                    #            for.  We don't check, because this is
 
2586
                    #            a best-effort mechanism.
 
2587
 
 
2588
        # Check for deltas that would go negative
 
2589
        unders = [resource for resource, delta in deltas.items()
 
2590
                  if delta < 0 and
 
2591
                  delta + usages[resource].in_use < 0]
 
2592
 
 
2593
        # Now, let's check the quotas
 
2594
        # NOTE(Vek): We're only concerned about positive increments.
 
2595
        #            If a project has gone over quota, we want them to
 
2596
        #            be able to reduce their usage without any
 
2597
        #            problems.
 
2598
        overs = [resource for resource, delta in deltas.items()
 
2599
                 if quotas[resource] >= 0 and delta >= 0 and
 
2600
                 quotas[resource] < delta + usages[resource].total]
 
2601
 
 
2602
        # NOTE(Vek): The quota check needs to be in the transaction,
 
2603
        #            but the transaction doesn't fail just because
 
2604
        #            we're over quota, so the OverQuota raise is
 
2605
        #            outside the transaction.  If we did the raise
 
2606
        #            here, our usage updates would be discarded, but
 
2607
        #            they're not invalidated by being over-quota.
 
2608
 
 
2609
        # Create the reservations
 
2610
        if not unders and not overs:
 
2611
            reservations = []
 
2612
            for resource, delta in deltas.items():
 
2613
                reservation = reservation_create(elevated,
 
2614
                                                 str(utils.gen_uuid()),
 
2615
                                                 usages[resource],
 
2616
                                                 context.project_id,
 
2617
                                                 resource, delta, expire,
 
2618
                                                 session=session)
 
2619
                reservations.append(reservation.uuid)
 
2620
 
 
2621
                # Also update the reserved quantity
 
2622
                # NOTE(Vek): Again, we are only concerned here about
 
2623
                #            positive increments.  Here, though, we're
 
2624
                #            worried about the following scenario:
 
2625
                #
 
2626
                #            1) User initiates resize down.
 
2627
                #            2) User allocates a new instance.
 
2628
                #            3) Resize down fails or is reverted.
 
2629
                #            4) User is now over quota.
 
2630
                #
 
2631
                #            To prevent this, we only update the
 
2632
                #            reserved value if the delta is positive.
 
2633
                if delta > 0:
 
2634
                    usages[resource].reserved += delta
 
2635
 
 
2636
        # Apply updates to the usages table
 
2637
        for usage_ref in usages.values():
 
2638
            usage_ref.save(session=session)
 
2639
 
 
2640
    if unders:
 
2641
        raise exception.InvalidQuotaValue(unders=sorted(unders))
 
2642
    if overs:
 
2643
        usages = dict((k, dict(in_use=v['in_use'], reserved=v['reserved']))
 
2644
                      for k, v in usages.items())
 
2645
        raise exception.OverQuota(overs=sorted(overs), quotas=quotas,
 
2646
                                  usages=usages)
 
2647
 
 
2648
    return reservations
 
2649
 
 
2650
 
 
2651
def _quota_reservations(session, context, reservations):
 
2652
    """Return the relevant reservations."""
 
2653
 
 
2654
    # Get the listed reservations
 
2655
    return model_query(context, models.Reservation,
 
2656
                       read_deleted="no",
 
2657
                       session=session).\
 
2658
                   options(joinedload('usage')).\
 
2659
                   filter(models.Reservation.uuid.in_(reservations)).\
 
2660
                   with_lockmode('update').\
 
2661
                   all()
 
2662
 
 
2663
 
 
2664
@require_context
 
2665
def reservation_commit(context, reservations):
 
2666
    session = get_session()
 
2667
    with session.begin():
 
2668
        for reservation in _quota_reservations(session, context, reservations):
 
2669
            if reservation.delta >= 0:
 
2670
                reservation.usage.reserved -= reservation.delta
 
2671
            reservation.usage.in_use += reservation.delta
 
2672
 
 
2673
            reservation.usage.save(session=session)
 
2674
            reservation.delete(session=session)
 
2675
 
 
2676
 
 
2677
@require_context
 
2678
def reservation_rollback(context, reservations):
 
2679
    session = get_session()
 
2680
    with session.begin():
 
2681
        for reservation in _quota_reservations(session, context, reservations):
 
2682
            if reservation.delta >= 0:
 
2683
                reservation.usage.reserved -= reservation.delta
 
2684
                reservation.usage.save(session=session)
 
2685
 
 
2686
            reservation.delete(session=session)
 
2687
 
 
2688
 
2266
2689
@require_admin_context
2267
2690
def quota_destroy_all_by_project(context, project_id):
2268
2691
    session = get_session()
2275
2698
        for quota_ref in quotas:
2276
2699
            quota_ref.delete(session=session)
2277
2700
 
 
2701
        quota_usages = model_query(context, models.QuotaUsage,
 
2702
                                   session=session, read_deleted="no").\
 
2703
                               filter_by(project_id=project_id).\
 
2704
                               all()
 
2705
 
 
2706
        for quota_usage_ref in quota_usages:
 
2707
            quota_usage_ref.delete(session=session)
 
2708
 
 
2709
        reservations = model_query(context, models.Reservation,
 
2710
                                   session=session, read_deleted="no").\
 
2711
                               filter_by(project_id=project_id).\
 
2712
                               all()
 
2713
 
 
2714
        for reservation_ref in reservations:
 
2715
            reservation_ref.delete(session=session)
 
2716
 
 
2717
 
 
2718
@require_admin_context
 
2719
def reservation_expire(context):
 
2720
    session = get_session()
 
2721
    with session.begin():
 
2722
        results = model_query(context, models.Reservation, session=session,
 
2723
                              read_deleted="no").\
 
2724
                          filter(models.Reservation.expire < utils.utcnow()).\
 
2725
                          all()
 
2726
 
 
2727
        if results:
 
2728
            for reservation in results:
 
2729
                if reservation.delta >= 0:
 
2730
                    reservation.usage.reserved -= reservation.delta
 
2731
                    reservation.usage.save(session=session)
 
2732
 
 
2733
                reservation.delete(session=session)
 
2734
 
2278
2735
 
2279
2736
###################
2280
2737
 
2302
2759
 
2303
2760
 
2304
2761
@require_admin_context
2305
 
def volume_attached(context, volume_id, instance_id, mountpoint):
 
2762
def volume_attached(context, volume_id, instance_uuid, mountpoint):
 
2763
    if not utils.is_uuid_like(instance_uuid):
 
2764
        raise exception.InvalidUUID(instance_uuid)
 
2765
 
2306
2766
    session = get_session()
2307
2767
    with session.begin():
2308
2768
        volume_ref = volume_get(context, volume_id, session=session)
2309
2769
        volume_ref['status'] = 'in-use'
2310
2770
        volume_ref['mountpoint'] = mountpoint
2311
2771
        volume_ref['attach_status'] = 'attached'
2312
 
        volume_ref.instance = instance_get(context, instance_id,
2313
 
                                           session=session)
 
2772
        volume_ref['instance_uuid'] = instance_uuid
2314
2773
        volume_ref.save(session=session)
2315
2774
 
2316
2775
 
2319
2778
    values['volume_metadata'] = _metadata_refs(values.get('metadata'),
2320
2779
                                               models.VolumeMetadata)
2321
2780
    volume_ref = models.Volume()
 
2781
    if not values.get('id'):
 
2782
        values['id'] = str(utils.gen_uuid())
2322
2783
    volume_ref.update(values)
2323
2784
 
2324
2785
    session = get_session()
2325
2786
    with session.begin():
2326
2787
        volume_ref.save(session=session)
 
2788
 
 
2789
    ec2_volume_create(context, volume_ref['id'])
2327
2790
    return volume_ref
2328
2791
 
2329
2792
 
2330
2793
@require_admin_context
2331
 
def volume_data_get_for_project(context, project_id):
 
2794
def volume_data_get_for_project(context, project_id, session=None):
2332
2795
    result = model_query(context,
2333
2796
                         func.count(models.Volume.id),
2334
2797
                         func.sum(models.Volume.size),
2335
 
                         read_deleted="no").\
 
2798
                         read_deleted="no",
 
2799
                         session=session).\
2336
2800
                     filter_by(project_id=project_id).\
2337
2801
                     first()
2338
2802
 
2367
2831
        volume_ref['status'] = 'available'
2368
2832
        volume_ref['mountpoint'] = None
2369
2833
        volume_ref['attach_status'] = 'detached'
2370
 
        volume_ref.instance = None
 
2834
        volume_ref['instance_uuid'] = None
2371
2835
        volume_ref.save(session=session)
2372
2836
 
2373
2837
 
2375
2839
def _volume_get_query(context, session=None, project_only=False):
2376
2840
    return model_query(context, models.Volume, session=session,
2377
2841
                       project_only=project_only).\
2378
 
                     options(joinedload('instance')).\
2379
 
                     options(joinedload('volume_metadata')).\
2380
 
                     options(joinedload('volume_type'))
 
2842
                       options(joinedload('volume_metadata')).\
 
2843
                       options(joinedload('volume_type'))
 
2844
 
 
2845
 
 
2846
@require_context
 
2847
def _ec2_volume_get_query(context, session=None, project_only=False):
 
2848
    return model_query(context, models.VolumeIdMapping, session=session,
 
2849
                       project_only=project_only)
 
2850
 
 
2851
 
 
2852
@require_context
 
2853
def _ec2_snapshot_get_query(context, session=None, project_only=False):
 
2854
    return model_query(context, models.SnapshotIdMapping, session=session,
 
2855
                       project_only=project_only)
2381
2856
 
2382
2857
 
2383
2858
@require_context
2403
2878
 
2404
2879
 
2405
2880
@require_admin_context
2406
 
def volume_get_all_by_instance(context, instance_id):
 
2881
def volume_get_all_by_instance_uuid(context, instance_uuid):
2407
2882
    result = model_query(context, models.Volume, read_deleted="no").\
2408
2883
                     options(joinedload('volume_metadata')).\
2409
2884
                     options(joinedload('volume_type')).\
2410
 
                     filter_by(instance_id=instance_id).\
 
2885
                     filter_by(instance_uuid=instance_uuid).\
2411
2886
                     all()
2412
2887
 
2413
2888
    if not result:
2414
 
        raise exception.VolumeNotFoundForInstance(instance_id=instance_id)
 
2889
        return []
2415
2890
 
2416
2891
    return result
2417
2892
 
2423
2898
 
2424
2899
 
2425
2900
@require_admin_context
2426
 
def volume_get_instance(context, volume_id):
2427
 
    result = _volume_get_query(context).filter_by(id=volume_id).first()
2428
 
 
2429
 
    if not result:
2430
 
        raise exception.VolumeNotFound(volume_id=volume_id)
2431
 
 
2432
 
    return result.instance
2433
 
 
2434
 
 
2435
 
@require_admin_context
2436
2901
def volume_get_iscsi_target_num(context, volume_id):
2437
2902
    result = model_query(context, models.IscsiTarget, read_deleted="yes").\
2438
2903
                     filter_by(volume_id=volume_id).\
2459
2924
        volume_ref.save(session=session)
2460
2925
 
2461
2926
 
 
2927
@require_context
 
2928
def ec2_volume_create(context, volume_uuid, id=None):
 
2929
    """Create ec2 compatable volume by provided uuid"""
 
2930
    ec2_volume_ref = models.VolumeIdMapping()
 
2931
    ec2_volume_ref.update({'uuid': volume_uuid})
 
2932
    if id is not None:
 
2933
        ec2_volume_ref.update({'id': id})
 
2934
 
 
2935
    ec2_volume_ref.save()
 
2936
 
 
2937
    return ec2_volume_ref
 
2938
 
 
2939
 
 
2940
@require_context
 
2941
def get_ec2_volume_id_by_uuid(context, volume_id, session=None):
 
2942
    result = _ec2_volume_get_query(context,
 
2943
                                   session=session,
 
2944
                                   project_only=True).\
 
2945
                    filter_by(uuid=volume_id).\
 
2946
                    first()
 
2947
 
 
2948
    if not result:
 
2949
        raise exception.VolumeNotFound(uuid=volume_id)
 
2950
 
 
2951
    return result['id']
 
2952
 
 
2953
 
 
2954
@require_context
 
2955
def get_volume_uuid_by_ec2_id(context, ec2_id, session=None):
 
2956
    result = _ec2_volume_get_query(context,
 
2957
                                   session=session,
 
2958
                                   project_only=True).\
 
2959
                    filter_by(id=ec2_id).\
 
2960
                    first()
 
2961
 
 
2962
    if not result:
 
2963
        raise exception.VolumeNotFound(ec2_id=ec2_id)
 
2964
 
 
2965
    return result['uuid']
 
2966
 
 
2967
 
 
2968
@require_context
 
2969
def ec2_snapshot_create(context, snapshot_uuid, id=None):
 
2970
    """Create ec2 compatable snapshot by provided uuid"""
 
2971
    ec2_snapshot_ref = models.SnapshotIdMapping()
 
2972
    ec2_snapshot_ref.update({'uuid': snapshot_uuid})
 
2973
    if id is not None:
 
2974
        ec2_snapshot_ref.update({'id': id})
 
2975
 
 
2976
    ec2_snapshot_ref.save()
 
2977
 
 
2978
    return ec2_snapshot_ref
 
2979
 
 
2980
 
 
2981
@require_context
 
2982
def get_ec2_snapshot_id_by_uuid(context, snapshot_id, session=None):
 
2983
    result = _ec2_snapshot_get_query(context,
 
2984
                                   session=session,
 
2985
                                   project_only=True).\
 
2986
                    filter_by(uuid=snapshot_id).\
 
2987
                    first()
 
2988
 
 
2989
    if not result:
 
2990
        raise exception.SnapshotNotFound(uuid=snapshot_id)
 
2991
 
 
2992
    return result['id']
 
2993
 
 
2994
 
 
2995
@require_context
 
2996
def get_snapshot_uuid_by_ec2_id(context, ec2_id, session=None):
 
2997
    result = _ec2_snapshot_get_query(context,
 
2998
                                   session=session,
 
2999
                                   project_only=True).\
 
3000
                    filter_by(id=ec2_id).\
 
3001
                    first()
 
3002
 
 
3003
    if not result:
 
3004
        raise exception.SnapshotNotFound(ec2_id=ec2_id)
 
3005
 
 
3006
    return result['uuid']
 
3007
 
 
3008
 
2462
3009
####################
2463
3010
 
2464
3011
def _volume_metadata_get_query(context, volume_id, session=None):
2543
3090
@require_context
2544
3091
def snapshot_create(context, values):
2545
3092
    snapshot_ref = models.Snapshot()
 
3093
    if not values.get('id'):
 
3094
        values['id'] = str(utils.gen_uuid())
2546
3095
    snapshot_ref.update(values)
2547
3096
 
2548
3097
    session = get_session()
2549
3098
    with session.begin():
2550
3099
        snapshot_ref.save(session=session)
 
3100
    ec2_snapshot_create(context, snapshot_ref['id'])
2551
3101
    return snapshot_ref
2552
3102
 
2553
3103
 
2636
3186
    session = get_session()
2637
3187
    with session.begin():
2638
3188
        result = _block_device_mapping_get_query(context, session=session).\
2639
 
                 filter_by(instance_id=values['instance_id']).\
 
3189
                 filter_by(instance_uuid=values['instance_uuid']).\
2640
3190
                 filter_by(device_name=values['device_name']).\
2641
3191
                 first()
2642
3192
        if not result:
2652
3202
        if (virtual_name is not None and
2653
3203
            block_device.is_swap_or_ephemeral(virtual_name)):
2654
3204
            session.query(models.BlockDeviceMapping).\
2655
 
                filter_by(instance_id=values['instance_id']).\
 
3205
                filter_by(instance_uuid=values['instance_uuid']).\
2656
3206
                filter_by(virtual_name=virtual_name).\
2657
3207
                filter(models.BlockDeviceMapping.device_name !=
2658
3208
                       values['device_name']).\
2662
3212
 
2663
3213
 
2664
3214
@require_context
2665
 
def block_device_mapping_get_all_by_instance(context, instance_id):
 
3215
def block_device_mapping_get_all_by_instance(context, instance_uuid):
2666
3216
    return _block_device_mapping_get_query(context).\
2667
 
                 filter_by(instance_id=instance_id).\
 
3217
                 filter_by(instance_uuid=instance_uuid).\
2668
3218
                 all()
2669
3219
 
2670
3220
 
2680
3230
 
2681
3231
 
2682
3232
@require_context
2683
 
def block_device_mapping_destroy_by_instance_and_volume(context, instance_id,
 
3233
def block_device_mapping_destroy_by_instance_and_volume(context, instance_uuid,
2684
3234
                                                        volume_id):
2685
3235
    session = get_session()
2686
3236
    with session.begin():
2687
3237
        _block_device_mapping_get_query(context, session=session).\
2688
 
            filter_by(instance_id=instance_id).\
 
3238
            filter_by(instance_uuid=instance_uuid).\
2689
3239
            filter_by(volume_id=volume_id).\
2690
3240
            update({'deleted': True,
2691
3241
                    'deleted_at': utils.utcnow(),
2814
3364
 
2815
3365
 
2816
3366
@require_context
2817
 
def security_group_count_by_project(context, project_id):
 
3367
def security_group_count_by_project(context, project_id, session=None):
2818
3368
    authorize_project_context(context, project_id)
2819
 
    return model_query(context, models.SecurityGroup, read_deleted="no").\
 
3369
    return model_query(context, models.SecurityGroup, read_deleted="no",
 
3370
                       session=session).\
2820
3371
                   filter_by(project_id=project_id).\
2821
3372
                   count()
2822
3373
 
3033
3584
        user_ref.save(session=session)
3034
3585
 
3035
3586
 
3036
 
#
3037
3587
###################
3038
3588
 
3039
3589
 
3190
3740
    return model_query(context, models.Migration, session=session,
3191
3741
                       read_deleted="yes").\
3192
3742
            filter(models.Migration.updated_at <= confirm_window).\
3193
 
            filter_by(status="FINISHED").\
 
3743
            filter_by(status="finished").\
3194
3744
            all()
3195
3745
 
3196
3746
 
3491
4041
    return model_query(context, models.Cell, read_deleted="no").all()
3492
4042
 
3493
4043
 
3494
 
####################
3495
 
 
 
4044
########################
 
4045
# User-provided metadata
3496
4046
 
3497
4047
def _instance_metadata_get_query(context, instance_id, session=None):
3498
4048
    return model_query(context, models.InstanceMetadata, session=session,
3573
4123
    return metadata
3574
4124
 
3575
4125
 
 
4126
#######################
 
4127
# System-owned metadata
 
4128
 
 
4129
def _instance_system_metadata_get_query(context, instance_uuid, session=None):
 
4130
    return model_query(context, models.InstanceSystemMetadata, session=session,
 
4131
                       read_deleted="no").\
 
4132
                    filter_by(instance_uuid=instance_uuid)
 
4133
 
 
4134
 
 
4135
@require_context
 
4136
@require_instance_exists_using_uuid
 
4137
def instance_system_metadata_get(context, instance_uuid):
 
4138
    rows = _instance_system_metadata_get_query(context, instance_uuid).all()
 
4139
 
 
4140
    result = {}
 
4141
    for row in rows:
 
4142
        result[row['key']] = row['value']
 
4143
 
 
4144
    return result
 
4145
 
 
4146
 
 
4147
@require_context
 
4148
@require_instance_exists_using_uuid
 
4149
def instance_system_metadata_delete(context, instance_uuid, key):
 
4150
    _instance_system_metadata_get_query(context, instance_uuid).\
 
4151
        filter_by(key=key).\
 
4152
        update({'deleted': True,
 
4153
                'deleted_at': utils.utcnow(),
 
4154
                'updated_at': literal_column('updated_at')})
 
4155
 
 
4156
 
 
4157
def _instance_system_metadata_get_item(context, instance_uuid, key,
 
4158
                                       session=None):
 
4159
    result = _instance_system_metadata_get_query(
 
4160
                            context, instance_uuid, session=session).\
 
4161
                    filter_by(key=key).\
 
4162
                    first()
 
4163
 
 
4164
    if not result:
 
4165
        raise exception.InstanceSystemMetadataNotFound(
 
4166
                metadata_key=key, instance_uuid=instance_uuid)
 
4167
 
 
4168
    return result
 
4169
 
 
4170
 
 
4171
@require_context
 
4172
@require_instance_exists_using_uuid
 
4173
def instance_system_metadata_update(context, instance_uuid, metadata, delete):
 
4174
    session = get_session()
 
4175
 
 
4176
    # Set existing metadata to deleted if delete argument is True
 
4177
    if delete:
 
4178
        original_metadata = instance_system_metadata_get(
 
4179
                context, instance_uuid)
 
4180
        for meta_key, meta_value in original_metadata.iteritems():
 
4181
            if meta_key not in metadata:
 
4182
                meta_ref = _instance_system_metadata_get_item(
 
4183
                        context, instance_uuid, meta_key, session)
 
4184
                meta_ref.update({'deleted': True})
 
4185
                meta_ref.save(session=session)
 
4186
 
 
4187
    meta_ref = None
 
4188
 
 
4189
    # Now update all existing items with new values, or create new meta objects
 
4190
    for meta_key, meta_value in metadata.iteritems():
 
4191
 
 
4192
        # update the value whether it exists or not
 
4193
        item = {"value": meta_value}
 
4194
 
 
4195
        try:
 
4196
            meta_ref = _instance_system_metadata_get_item(
 
4197
                    context, instance_uuid, meta_key, session)
 
4198
        except exception.InstanceSystemMetadataNotFound, e:
 
4199
            meta_ref = models.InstanceSystemMetadata()
 
4200
            item.update({"key": meta_key, "instance_uuid": instance_uuid})
 
4201
 
 
4202
        meta_ref.update(item)
 
4203
        meta_ref.save(session=session)
 
4204
 
 
4205
    return metadata
 
4206
 
 
4207
 
3576
4208
####################
3577
4209
 
3578
4210
 
3629
4261
####################
3630
4262
 
3631
4263
@require_context
3632
 
def bw_usage_get_by_macs(context, macs, start_period):
 
4264
def bw_usage_get_by_uuids(context, uuids, start_period):
3633
4265
    return model_query(context, models.BandwidthUsage, read_deleted="yes").\
3634
 
                   filter(models.BandwidthUsage.mac.in_(macs)).\
 
4266
                   filter(models.BandwidthUsage.uuid.in_(uuids)).\
3635
4267
                   filter_by(start_period=start_period).\
3636
4268
                   all()
3637
4269
 
3638
4270
 
3639
4271
@require_context
3640
4272
def bw_usage_update(context,
 
4273
                    uuid,
3641
4274
                    mac,
3642
4275
                    start_period,
3643
4276
                    bw_in, bw_out,
3649
4282
        bwusage = model_query(context, models.BandwidthUsage,
3650
4283
                              session=session, read_deleted="yes").\
3651
4284
                      filter_by(start_period=start_period).\
3652
 
                      filter_by(mac=mac).\
 
4285
                      filter_by(uuid=uuid).\
3653
4286
                      first()
3654
4287
 
3655
4288
        if not bwusage:
3656
4289
            bwusage = models.BandwidthUsage()
3657
4290
            bwusage.start_period = start_period
 
4291
            bwusage.uuid = uuid
3658
4292
            bwusage.mac = mac
3659
4293
 
3660
4294
        bwusage.last_refreshed = utils.utcnow()
3792
4426
                    first()
3793
4427
 
3794
4428
    if not result:
3795
 
        raise exception.VolumeTypeNotFound(volume_type=id)
 
4429
        raise exception.VolumeTypeNotFound(volume_type_id=id)
3796
4430
 
3797
4431
    return _dict_with_extra_specs(result)
3798
4432
 
3830
4464
                        'updated_at': literal_column('updated_at')})
3831
4465
 
3832
4466
 
 
4467
@require_context
 
4468
def volume_get_active_by_window(context, begin, end=None,
 
4469
                                         project_id=None):
 
4470
    """Return volumes that were active during window."""
 
4471
    session = get_session()
 
4472
    query = session.query(models.Volume)
 
4473
 
 
4474
    query = query.filter(or_(models.Volume.deleted_at == None,
 
4475
                             models.Volume.deleted_at > begin))
 
4476
    if end:
 
4477
        query = query.filter(models.Volume.created_at < end)
 
4478
    if project_id:
 
4479
        query = query.filter_by(project_id=project_id)
 
4480
 
 
4481
    return query.all()
 
4482
 
 
4483
 
3833
4484
####################
3834
4485
 
3835
4486
 
4096
4747
 
4097
4748
 
4098
4749
def _aggregate_get_query(context, model_class, id_field, id,
4099
 
                         session=None, read_deleted='yes'):
 
4750
                         session=None, read_deleted=None):
4100
4751
    return model_query(context, model_class, session=session,
4101
4752
                       read_deleted=read_deleted).filter(id_field == id)
4102
4753
 
4128
4779
 
4129
4780
 
4130
4781
@require_admin_context
4131
 
def aggregate_get(context, aggregate_id, read_deleted='no'):
 
4782
def aggregate_get(context, aggregate_id):
4132
4783
    aggregate = _aggregate_get_query(context,
4133
4784
                                     models.Aggregate,
4134
 
                                     models.Aggregate.id, aggregate_id,
4135
 
                                     read_deleted=read_deleted).first()
 
4785
                                     models.Aggregate.id,
 
4786
                                     aggregate_id).first()
4136
4787
 
4137
4788
    if not aggregate:
4138
4789
        raise exception.AggregateNotFound(aggregate_id=aggregate_id)
4141
4792
 
4142
4793
 
4143
4794
@require_admin_context
4144
 
def aggregate_get_by_host(context, host, read_deleted='no'):
 
4795
def aggregate_get_by_host(context, host):
4145
4796
    aggregate_host = _aggregate_get_query(context,
4146
4797
                                          models.AggregateHost,
4147
4798
                                          models.AggregateHost.host,
4148
 
                                          host,
4149
 
                                          read_deleted='no').first()
 
4799
                                          host).first()
4150
4800
 
4151
4801
    if not aggregate_host:
4152
4802
        raise exception.AggregateHostNotFound(host=host)
4153
4803
 
4154
 
    return aggregate_get(context, aggregate_host.aggregate_id, read_deleted)
 
4804
    return aggregate_get(context, aggregate_host.aggregate_id)
4155
4805
 
4156
4806
 
4157
4807
@require_admin_context
4159
4809
    session = get_session()
4160
4810
    aggregate = _aggregate_get_query(context,
4161
4811
                                     models.Aggregate,
4162
 
                                     models.Aggregate.id, aggregate_id,
4163
 
                                     session=session,
4164
 
                                     read_deleted='no').first()
 
4812
                                     models.Aggregate.id,
 
4813
                                     aggregate_id,
 
4814
                                     session=session).first()
4165
4815
    if aggregate:
4166
4816
        metadata = values.get('metadata')
4167
4817
        if metadata is not None:
4182
4832
def aggregate_delete(context, aggregate_id):
4183
4833
    query = _aggregate_get_query(context,
4184
4834
                                 models.Aggregate,
4185
 
                                 models.Aggregate.id, aggregate_id,
4186
 
                                 read_deleted='no')
 
4835
                                 models.Aggregate.id,
 
4836
                                 aggregate_id)
4187
4837
    if query.first():
4188
4838
        query.update({'deleted': True,
4189
4839
                      'deleted_at': utils.utcnow(),
4194
4844
 
4195
4845
 
4196
4846
@require_admin_context
4197
 
def aggregate_get_all(context, read_deleted='yes'):
4198
 
    return model_query(context,
4199
 
                       models.Aggregate,
4200
 
                       read_deleted=read_deleted).all()
 
4847
def aggregate_get_all(context):
 
4848
    return model_query(context, models.Aggregate).all()
4201
4849
 
4202
4850
 
4203
4851
@require_admin_context
4204
4852
@require_aggregate_exists
4205
 
def aggregate_metadata_get(context, aggregate_id, read_deleted='no'):
 
4853
def aggregate_metadata_get(context, aggregate_id):
4206
4854
    rows = model_query(context,
4207
 
                       models.AggregateMetadata,
4208
 
                       read_deleted=read_deleted).\
 
4855
                       models.AggregateMetadata).\
4209
4856
                       filter_by(aggregate_id=aggregate_id).all()
4210
4857
 
4211
4858
    return dict([(r['key'], r['value']) for r in rows])
4217
4864
    query = _aggregate_get_query(context,
4218
4865
                                 models.AggregateMetadata,
4219
4866
                                 models.AggregateMetadata.aggregate_id,
4220
 
                                 aggregate_id, read_deleted='no').\
 
4867
                                 aggregate_id).\
4221
4868
                                 filter_by(key=key)
4222
4869
    if query.first():
4223
4870
        query.update({'deleted': True,
4230
4877
 
4231
4878
@require_admin_context
4232
4879
@require_aggregate_exists
4233
 
def aggregate_metadata_get_item(context, aggregate_id, key,
4234
 
                                session=None, read_deleted='yes'):
 
4880
def aggregate_metadata_get_item(context, aggregate_id, key, session=None):
4235
4881
    result = _aggregate_get_query(context,
4236
4882
                                  models.AggregateMetadata,
4237
4883
                                  models.AggregateMetadata.aggregate_id,
4238
4884
                                  aggregate_id, session=session,
4239
 
                                  read_deleted=read_deleted).\
 
4885
                                  read_deleted='yes').\
4240
4886
                                  filter_by(key=key).first()
4241
4887
 
4242
4888
    if not result:
4281
4927
 
4282
4928
@require_admin_context
4283
4929
@require_aggregate_exists
4284
 
def aggregate_host_get_all(context, aggregate_id, read_deleted='yes'):
 
4930
def aggregate_host_get_all(context, aggregate_id):
4285
4931
    rows = model_query(context,
4286
 
                       models.AggregateHost,
4287
 
                       read_deleted=read_deleted).\
 
4932
                       models.AggregateHost).\
4288
4933
                       filter_by(aggregate_id=aggregate_id).all()
4289
4934
 
4290
4935
    return [r.host for r in rows]
4296
4941
    query = _aggregate_get_query(context,
4297
4942
                                 models.AggregateHost,
4298
4943
                                 models.AggregateHost.aggregate_id,
4299
 
                                 aggregate_id,
4300
 
                                 read_deleted='no').filter_by(host=host)
 
4944
                                 aggregate_id).filter_by(host=host)
4301
4945
    if query.first():
4302
4946
        query.update({'deleted': True,
4303
4947
                      'deleted_at': utils.utcnow(),