32
42
from nova.db.sqlalchemy import models
33
43
from nova.db.sqlalchemy.session import get_session
34
44
from nova import exception
35
from nova import flags
45
from nova.openstack.common import cfg
36
46
from nova.openstack.common import log as logging
37
47
from nova.openstack.common import timeutils
38
from nova import utils
39
from sqlalchemy import and_
40
from sqlalchemy.exc import IntegrityError
41
from sqlalchemy import or_
42
from sqlalchemy.orm import joinedload
43
from sqlalchemy.orm import joinedload_all
44
from sqlalchemy.sql.expression import asc
45
from sqlalchemy.sql.expression import desc
46
from sqlalchemy.sql.expression import literal_column
47
from sqlalchemy.sql import func
48
from nova.openstack.common import uuidutils
52
CONF.import_opt('compute_topic', 'nova.config')
53
CONF.import_opt('sql_connection', 'nova.config')
51
55
LOG = logging.getLogger(__name__)
54
def is_admin_context(context):
55
"""Indicates if the request context is an administrator."""
57
warnings.warn(_('Use of empty request context is deprecated'),
59
raise Exception('die')
60
return context.is_admin
63
58
def is_user_context(context):
64
59
"""Indicates if the request context is a normal user."""
821
772
def floating_ip_deallocate(context, address):
822
session = get_session()
823
with session.begin():
824
floating_ip_ref = floating_ip_get_by_address(context,
827
floating_ip_ref['project_id'] = None
828
floating_ip_ref['host'] = None
829
floating_ip_ref['auto_assigned'] = False
830
floating_ip_ref.save(session=session)
773
model_query(context, models.FloatingIp).\
774
filter_by(address=address).\
775
update({'project_id': None,
777
'auto_assigned': False})
834
781
def floating_ip_destroy(context, address):
835
session = get_session()
836
with session.begin():
837
floating_ip_ref = floating_ip_get_by_address(context,
840
floating_ip_ref.delete(session=session)
782
model_query(context, models.FloatingIp).\
783
filter_by(address=address).\
844
788
def floating_ip_disassociate(context, address):
845
789
session = get_session()
846
790
with session.begin():
847
floating_ip_ref = floating_ip_get_by_address(context,
850
fixed_ip_ref = fixed_ip_get(context,
851
floating_ip_ref['fixed_ip_id'])
791
floating_ip_ref = model_query(context,
794
filter_by(address=address).\
796
if not floating_ip_ref:
797
raise exception.FloatingIpNotFoundForAddress(address=address)
799
fixed_ip_ref = model_query(context, models.FixedIp, session=session).\
800
filter_by(id=floating_ip_ref['fixed_ip_id']).\
853
803
fixed_ip_address = fixed_ip_ref['address']
1155
@require_admin_context
1156
def fixed_ip_get_by_address_detailed(context, address, session=None):
1158
:returns: a tuple of (models.FixedIp, models.Network, models.Instance)
1161
session = get_session()
1163
result = session.query(models.FixedIp, models.Network, models.Instance).\
1164
filter_by(address=address).\
1165
outerjoin((models.Network,
1166
models.Network.id ==
1167
models.FixedIp.network_id)).\
1168
outerjoin((models.Instance,
1169
models.Instance.uuid ==
1170
models.FixedIp.instance_uuid)).\
1174
raise exception.FixedIpNotFoundForAddress(address=address)
1214
1179
@require_context
1215
1180
def fixed_ip_get_by_instance(context, instance_uuid):
1216
if not utils.is_uuid_like(instance_uuid):
1181
if not uuidutils.is_uuid_like(instance_uuid):
1217
1182
raise exception.InvalidUUID(uuid=instance_uuid)
1219
1184
result = model_query(context, models.FixedIp, read_deleted="no").\
1395
1353
return metadata_refs
1356
def _validate_unique_server_name(context, session, name):
1357
if not CONF.osapi_compute_unique_server_name_scope:
1360
search_opts = {'deleted': False}
1361
if CONF.osapi_compute_unique_server_name_scope == 'project':
1362
search_opts['project_id'] = context.project_id
1363
instance_list = instance_get_all_by_filters(context, search_opts,
1364
'created_at', 'desc',
1366
elif CONF.osapi_compute_unique_server_name_scope == 'global':
1367
instance_list = instance_get_all_by_filters(context.elevated(),
1369
'created_at', 'desc',
1372
msg = _('Unknown osapi_compute_unique_server_name_scope value: %s'
1373
' Flag must be empty, "global" or'
1374
' "project"') % CONF.osapi_compute_unique_server_name_scope
1378
lowername = name.lower()
1379
for instance in instance_list:
1380
if instance['hostname'].lower() == lowername:
1381
raise exception.InstanceExists(name=instance['hostname'])
1398
1384
@require_context
1399
1385
def instance_create(context, values):
1400
1386
"""Create a new Instance record in the database.
1533
1522
query = model_query(context, models.Instance)
1534
1523
for column in columns_to_join:
1535
1524
query = query.options(joinedload(column))
1525
if not context.is_admin:
1526
# If we're not admin context, add appropriate filter..
1527
if context.project_id:
1528
query = query.filter_by(project_id=context.project_id)
1530
query = query.filter_by(user_id=context.user_id)
1536
1531
return query.all()
1539
1534
@require_context
1540
1535
def instance_get_all_by_filters(context, filters, sort_key, sort_dir,
1541
limit=None, marker=None):
1536
limit=None, marker=None, session=None):
1542
1537
"""Return instances that match all filters. Deleted instances
1543
1538
will be returned by default, unless there's a filter that says
1546
1541
sort_fn = {'desc': desc, 'asc': asc}
1548
session = get_session()
1544
session = get_session()
1549
1546
query_prefix = session.query(models.Instance).\
1550
1547
options(joinedload('info_cache')).\
1551
1548
options(joinedload('security_groups')).\
1549
options(joinedload('system_metadata')).\
1552
1550
options(joinedload('metadata')).\
1553
1551
options(joinedload('instance_type')).\
1554
1552
order_by(sort_fn[sort_dir](getattr(models.Instance, sort_key)))
1818
1835
def _instance_update(context, instance_uuid, values, copy_old_instance=False):
1819
1836
session = get_session()
1821
if not utils.is_uuid_like(instance_uuid):
1838
if not uuidutils.is_uuid_like(instance_uuid):
1822
1839
raise exception.InvalidUUID(instance_uuid)
1824
1841
with session.begin():
1825
1842
instance_ref = instance_get_by_uuid(context, instance_uuid,
1826
1843
session=session)
1844
# TODO(deva): remove extra_specs from here after it is included
1845
# in system_metadata. Until then, the baremetal driver
1846
# needs extra_specs added to instance[]
1847
inst_type_ref = _instance_type_get_query(context, session=session).\
1848
filter_by(id=instance_ref['instance_type_id']).\
1851
instance_ref['extra_specs'] = \
1852
_dict_with_extra_specs(inst_type_ref).get('extra_specs', {})
1854
instance_ref['extra_specs'] = {}
1827
1856
if "expected_task_state" in values:
1828
1857
# it is not a db column so always pop out
1829
1858
expected = values.pop("expected_task_state")
2417
2441
@require_admin_context
2418
2442
def quota_update(context, project_id, resource, limit):
2419
session = get_session()
2420
with session.begin():
2421
quota_ref = quota_get(context, project_id, resource, session=session)
2422
quota_ref.hard_limit = limit
2423
quota_ref.save(session=session)
2426
@require_admin_context
2427
def quota_destroy(context, project_id, resource):
2428
session = get_session()
2429
with session.begin():
2430
quota_ref = quota_get(context, project_id, resource, session=session)
2431
quota_ref.delete(session=session)
2443
result = model_query(context, models.Quota, read_deleted="no").\
2444
filter_by(project_id=project_id).\
2445
filter_by(resource=resource).\
2446
update({'hard_limit': limit})
2449
raise exception.ProjectQuotaNotFound(project_id=project_id)
2434
2452
###################
2437
2455
@require_context
2438
def quota_class_get(context, class_name, resource, session=None):
2439
result = model_query(context, models.QuotaClass, session=session,
2440
read_deleted="no").\
2456
def quota_class_get(context, class_name, resource):
2457
result = model_query(context, models.QuotaClass, read_deleted="no").\
2441
2458
filter_by(class_name=class_name).\
2442
2459
filter_by(resource=resource).\
2476
2493
@require_admin_context
2477
2494
def quota_class_update(context, class_name, resource, limit):
2478
session = get_session()
2479
with session.begin():
2480
quota_class_ref = quota_class_get(context, class_name, resource,
2482
quota_class_ref.hard_limit = limit
2483
quota_class_ref.save(session=session)
2486
@require_admin_context
2487
def quota_class_destroy(context, class_name, resource):
2488
session = get_session()
2489
with session.begin():
2490
quota_class_ref = quota_class_get(context, class_name, resource,
2492
quota_class_ref.delete(session=session)
2495
@require_admin_context
2496
def quota_class_destroy_all_by_name(context, class_name):
2497
session = get_session()
2498
with session.begin():
2499
quota_classes = model_query(context, models.QuotaClass,
2500
session=session, read_deleted="no").\
2501
filter_by(class_name=class_name).\
2504
for quota_class_ref in quota_classes:
2505
quota_class_ref.delete(session=session)
2495
result = model_query(context, models.QuotaClass, read_deleted="no").\
2496
filter_by(class_name=class_name).\
2497
filter_by(resource=resource).\
2498
update({'hard_limit': limit})
2501
raise exception.QuotaClassNotFound(class_name=class_name)
2508
2504
###################
2511
2507
@require_context
2512
def quota_usage_get(context, project_id, resource, session=None):
2513
result = model_query(context, models.QuotaUsage, session=session,
2514
read_deleted="no").\
2508
def quota_usage_get(context, project_id, resource):
2509
result = model_query(context, models.QuotaUsage, read_deleted="no").\
2515
2510
filter_by(project_id=project_id).\
2516
2511
filter_by(resource=resource).\
2546
2541
quota_usage_ref.in_use = in_use
2547
2542
quota_usage_ref.reserved = reserved
2548
2543
quota_usage_ref.until_refresh = until_refresh
2549
2545
quota_usage_ref.save(session=session)
2551
2547
return quota_usage_ref
2554
2550
@require_admin_context
2555
def quota_usage_update(context, project_id, resource, in_use, reserved,
2556
until_refresh, session=None):
2557
def do_update(session):
2558
quota_usage_ref = quota_usage_get(context, project_id, resource,
2560
quota_usage_ref.in_use = in_use
2561
quota_usage_ref.reserved = reserved
2562
quota_usage_ref.until_refresh = until_refresh
2563
quota_usage_ref.save(session=session)
2566
# Assume caller started a transaction
2569
session = get_session()
2570
with session.begin():
2574
@require_admin_context
2575
def quota_usage_destroy(context, project_id, resource):
2576
session = get_session()
2577
with session.begin():
2578
quota_usage_ref = quota_usage_get(context, project_id, resource,
2580
quota_usage_ref.delete(session=session)
2551
def quota_usage_update(context, project_id, resource, **kwargs):
2553
if 'in_use' in kwargs:
2554
updates['in_use'] = kwargs['in_use']
2555
if 'reserved' in kwargs:
2556
updates['reserved'] = kwargs['reserved']
2557
if 'until_refresh' in kwargs:
2558
updates['until_refresh'] = kwargs['until_refresh']
2560
result = model_query(context, models.QuotaUsage, read_deleted="no").\
2561
filter_by(project_id=project_id).\
2562
filter_by(resource=resource).\
2566
raise exception.QuotaUsageNotFound(project_id=project_id)
2583
2569
###################
2586
2572
@require_context
2587
def reservation_get(context, uuid, session=None):
2588
result = model_query(context, models.Reservation, session=session,
2589
read_deleted="no").\
2573
def reservation_get(context, uuid):
2574
result = model_query(context, models.Reservation, read_deleted="no").\
2590
2575
filter_by(uuid=uuid).\
2883
2854
###################
2886
@require_admin_context
2887
def volume_allocate_iscsi_target(context, volume_id, host):
2888
session = get_session()
2889
with session.begin():
2890
iscsi_target_ref = model_query(context, models.IscsiTarget,
2891
session=session, read_deleted="no").\
2892
filter_by(volume=None).\
2893
filter_by(host=host).\
2894
with_lockmode('update').\
2897
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
2898
# then this has concurrency issues
2899
if not iscsi_target_ref:
2900
raise db.NoMoreTargets()
2902
iscsi_target_ref.volume_id = volume_id
2903
session.add(iscsi_target_ref)
2905
return iscsi_target_ref.target_num
2908
@require_admin_context
2909
def volume_attached(context, volume_id, instance_uuid, mountpoint):
2910
if not utils.is_uuid_like(instance_uuid):
2911
raise exception.InvalidUUID(instance_uuid)
2913
session = get_session()
2914
with session.begin():
2915
volume_ref = volume_get(context, volume_id, session=session)
2916
volume_ref['status'] = 'in-use'
2917
volume_ref['mountpoint'] = mountpoint
2918
volume_ref['attach_status'] = 'attached'
2919
volume_ref['instance_uuid'] = instance_uuid
2920
volume_ref['attach_time'] = timeutils.utcnow()
2921
volume_ref.save(session=session)
2925
def volume_create(context, values):
2926
values['volume_metadata'] = _metadata_refs(values.get('metadata'),
2927
models.VolumeMetadata)
2928
volume_ref = models.Volume()
2929
if not values.get('id'):
2930
values['id'] = str(utils.gen_uuid())
2931
volume_ref.update(values)
2933
session = get_session()
2934
with session.begin():
2935
volume_ref.save(session=session)
2937
return volume_get(context, values['id'], session=session)
2940
@require_admin_context
2941
def volume_data_get_for_project(context, project_id, session=None):
2942
result = model_query(context,
2943
func.count(models.Volume.id),
2944
func.sum(models.Volume.size),
2947
filter_by(project_id=project_id).\
2950
# NOTE(vish): convert None to 0
2951
return (result[0] or 0, result[1] or 0)
2954
@require_admin_context
2955
def volume_destroy(context, volume_id):
2956
session = get_session()
2957
with session.begin():
2958
volume_ref = volume_get(context, volume_id, session=session)
2959
session.query(models.Volume).\
2960
filter_by(id=volume_id).\
2961
update({'deleted': True,
2962
'deleted_at': timeutils.utcnow(),
2963
'updated_at': literal_column('updated_at')})
2964
session.query(models.IscsiTarget).\
2965
filter_by(volume_id=volume_id).\
2966
update({'volume_id': None})
2967
session.query(models.VolumeMetadata).\
2968
filter_by(volume_id=volume_id).\
2969
update({'deleted': True,
2970
'deleted_at': timeutils.utcnow(),
2971
'updated_at': literal_column('updated_at')})
2975
@require_admin_context
2976
def volume_detached(context, volume_id):
2977
session = get_session()
2978
with session.begin():
2979
volume_ref = volume_get(context, volume_id, session=session)
2980
volume_ref['status'] = 'available'
2981
volume_ref['mountpoint'] = None
2982
volume_ref['attach_status'] = 'detached'
2983
volume_ref['instance_uuid'] = None
2984
volume_ref.save(session=session)
2988
def _volume_get_query(context, session=None, project_only=False):
2989
return model_query(context, models.Volume, session=session,
2990
project_only=project_only).\
2991
options(joinedload('volume_metadata')).\
2992
options(joinedload('volume_type'))
2995
2857
@require_context
2996
2858
def _ec2_volume_get_query(context, session=None):
2997
2859
return model_query(context, models.VolumeIdMapping,
3004
2866
session=session, read_deleted='yes')
3008
def volume_get(context, volume_id, session=None):
3009
result = _volume_get_query(context, session=session, project_only=True).\
3010
filter_by(id=volume_id).\
3014
raise exception.VolumeNotFound(volume_id=volume_id)
3019
@require_admin_context
3020
def volume_get_all(context):
3021
return _volume_get_query(context).all()
3024
@require_admin_context
3025
def volume_get_all_by_host(context, host):
3026
return _volume_get_query(context).filter_by(host=host).all()
3029
@require_admin_context
3030
def volume_get_all_by_instance_uuid(context, instance_uuid):
3031
result = model_query(context, models.Volume, read_deleted="no").\
3032
options(joinedload('volume_metadata')).\
3033
options(joinedload('volume_type')).\
3034
filter_by(instance_uuid=instance_uuid).\
3044
def volume_get_all_by_project(context, project_id):
3045
authorize_project_context(context, project_id)
3046
return _volume_get_query(context).filter_by(project_id=project_id).all()
3049
2869
@require_admin_context
3050
2870
def volume_get_iscsi_target_num(context, volume_id):
3051
2871
result = model_query(context, models.IscsiTarget, read_deleted="yes").\
3149
2952
return result['uuid']
3152
####################
3154
def _volume_metadata_get_query(context, volume_id, session=None):
3155
return model_query(context, models.VolumeMetadata,
3156
session=session, read_deleted="no").\
3157
filter_by(volume_id=volume_id)
3161
@require_volume_exists
3162
def volume_metadata_get(context, volume_id):
3163
rows = _volume_metadata_get_query(context, volume_id).all()
3166
result[row['key']] = row['value']
3172
@require_volume_exists
3173
def volume_metadata_delete(context, volume_id, key):
3174
_volume_metadata_get_query(context, volume_id).\
3175
filter_by(key=key).\
3176
update({'deleted': True,
3177
'deleted_at': timeutils.utcnow(),
3178
'updated_at': literal_column('updated_at')})
3182
@require_volume_exists
3183
def volume_metadata_get_item(context, volume_id, key, session=None):
3184
result = _volume_metadata_get_query(context, volume_id, session=session).\
3185
filter_by(key=key).\
3189
raise exception.VolumeMetadataNotFound(metadata_key=key,
3190
volume_id=volume_id)
3195
@require_volume_exists
3196
def volume_metadata_update(context, volume_id, metadata, delete):
3197
session = get_session()
3199
# Set existing metadata to deleted if delete argument is True
3201
original_metadata = volume_metadata_get(context, volume_id)
3202
for meta_key, meta_value in original_metadata.iteritems():
3203
if meta_key not in metadata:
3204
meta_ref = volume_metadata_get_item(context, volume_id,
3206
meta_ref.update({'deleted': True})
3207
meta_ref.save(session=session)
3211
# Now update all existing items with new values, or create new meta objects
3212
for meta_key, meta_value in metadata.iteritems():
3214
# update the value whether it exists or not
3215
item = {"value": meta_value}
3218
meta_ref = volume_metadata_get_item(context, volume_id,
3220
except exception.VolumeMetadataNotFound, e:
3221
meta_ref = models.VolumeMetadata()
3222
item.update({"key": meta_key, "volume_id": volume_id})
3224
meta_ref.update(item)
3225
meta_ref.save(session=session)
3234
def snapshot_create(context, values):
3235
snapshot_ref = models.Snapshot()
3236
if not values.get('id'):
3237
values['id'] = str(utils.gen_uuid())
3238
snapshot_ref.update(values)
3240
session = get_session()
3241
with session.begin():
3242
snapshot_ref.save(session=session)
3246
@require_admin_context
3247
def snapshot_destroy(context, snapshot_id):
3248
session = get_session()
3249
with session.begin():
3250
session.query(models.Snapshot).\
3251
filter_by(id=snapshot_id).\
3252
update({'deleted': True,
3253
'deleted_at': timeutils.utcnow(),
3254
'updated_at': literal_column('updated_at')})
3258
def snapshot_get(context, snapshot_id, session=None):
3259
result = model_query(context, models.Snapshot, session=session,
3260
project_only=True).\
3261
filter_by(id=snapshot_id).\
3265
raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
3270
@require_admin_context
3271
def snapshot_get_all(context):
3272
return model_query(context, models.Snapshot).all()
3276
def snapshot_get_all_for_volume(context, volume_id):
3277
return model_query(context, models.Snapshot, read_deleted='no',
3278
project_only=True).\
3279
filter_by(volume_id=volume_id).all()
3283
def snapshot_get_all_by_project(context, project_id):
3284
authorize_project_context(context, project_id)
3285
return model_query(context, models.Snapshot).\
3286
filter_by(project_id=project_id).\
3291
def snapshot_update(context, snapshot_id, values):
3292
session = get_session()
3293
with session.begin():
3294
snapshot_ref = snapshot_get(context, snapshot_id, session=session)
3295
snapshot_ref.update(values)
3296
snapshot_ref.save(session=session)
3299
2955
###################
4427
@require_admin_context
4428
def volume_type_create(context, values):
4429
"""Create a new instance type. In order to pass in extra specs,
4430
the values dict should contain a 'extra_specs' key/value pair:
4432
{'extra_specs' : {'k1': 'v1', 'k2': 'v2', ...}}
4435
session = get_session()
4436
with session.begin():
4438
volume_type_get_by_name(context, values['name'], session)
4439
raise exception.VolumeTypeExists(name=values['name'])
4440
except exception.VolumeTypeNotFoundByName:
4443
values['extra_specs'] = _metadata_refs(values.get('extra_specs'),
4444
models.VolumeTypeExtraSpecs)
4445
volume_type_ref = models.VolumeTypes()
4446
volume_type_ref.update(values)
4447
volume_type_ref.save()
4448
except Exception, e:
4449
raise exception.DBError(e)
4450
return volume_type_ref
4454
def volume_type_get_all(context, inactive=False, filters=None):
4456
Returns a dict describing all volume_types with name as key.
4458
filters = filters or {}
4460
read_deleted = "yes" if inactive else "no"
4461
rows = model_query(context, models.VolumeTypes,
4462
read_deleted=read_deleted).\
4463
options(joinedload('extra_specs')).\
4467
# TODO(sirp): this patern of converting rows to a result with extra_specs
4468
# is repeated quite a bit, might be worth creating a method for it
4471
result[row['name']] = _dict_with_extra_specs(row)
4477
def volume_type_get(context, id, session=None):
4478
"""Returns a dict describing specific volume_type"""
4479
result = model_query(context, models.VolumeTypes, session=session).\
4480
options(joinedload('extra_specs')).\
4485
raise exception.VolumeTypeNotFound(volume_type_id=id)
4487
return _dict_with_extra_specs(result)
4491
def volume_type_get_by_name(context, name, session=None):
4492
"""Returns a dict describing specific volume_type"""
4493
result = model_query(context, models.VolumeTypes, session=session).\
4494
options(joinedload('extra_specs')).\
4495
filter_by(name=name).\
4499
raise exception.VolumeTypeNotFoundByName(volume_type_name=name)
4501
return _dict_with_extra_specs(result)
4504
@require_admin_context
4505
def volume_type_destroy(context, name):
4506
session = get_session()
4507
with session.begin():
4508
volume_type_ref = volume_type_get_by_name(context, name,
4510
volume_type_id = volume_type_ref['id']
4511
session.query(models.VolumeTypes).\
4512
filter_by(id=volume_type_id).\
4513
update({'deleted': True,
4514
'deleted_at': timeutils.utcnow(),
4515
'updated_at': literal_column('updated_at')})
4516
session.query(models.VolumeTypeExtraSpecs).\
4517
filter_by(volume_type_id=volume_type_id).\
4518
update({'deleted': True,
4519
'deleted_at': timeutils.utcnow(),
4520
'updated_at': literal_column('updated_at')})
4524
def volume_get_active_by_window(context, begin, end=None,
4526
"""Return volumes that were active during window."""
4527
session = get_session()
4528
query = session.query(models.Volume)
4530
query = query.filter(or_(models.Volume.deleted_at == None,
4531
models.Volume.deleted_at > begin))
4533
query = query.filter(models.Volume.created_at < end)
4535
query = query.filter_by(project_id=project_id)
4540
####################
4543
def _volume_type_extra_specs_query(context, volume_type_id, session=None):
4544
return model_query(context, models.VolumeTypeExtraSpecs, session=session,
4545
read_deleted="no").\
4546
filter_by(volume_type_id=volume_type_id)
4550
def volume_type_extra_specs_get(context, volume_type_id):
4551
rows = _volume_type_extra_specs_query(context, volume_type_id).\
4556
result[row['key']] = row['value']
4562
def volume_type_extra_specs_delete(context, volume_type_id, key):
4563
_volume_type_extra_specs_query(context, volume_type_id).\
4564
filter_by(key=key).\
4565
update({'deleted': True,
4566
'deleted_at': timeutils.utcnow(),
4567
'updated_at': literal_column('updated_at')})
4571
def volume_type_extra_specs_get_item(context, volume_type_id, key,
4573
result = _volume_type_extra_specs_query(
4574
context, volume_type_id, session=session).\
4575
filter_by(key=key).\
4579
raise exception.VolumeTypeExtraSpecsNotFound(
4580
extra_specs_key=key, volume_type_id=volume_type_id)
4586
def volume_type_extra_specs_update_or_create(context, volume_type_id,
4588
session = get_session()
4590
for key, value in specs.iteritems():
4592
spec_ref = volume_type_extra_specs_get_item(
4593
context, volume_type_id, key, session)
4594
except exception.VolumeTypeExtraSpecsNotFound, e:
4595
spec_ref = models.VolumeTypeExtraSpecs()
4596
spec_ref.update({"key": key, "value": value,
4597
"volume_type_id": volume_type_id,
4599
spec_ref.save(session=session)
4603
4102
####################
4642
4141
####################
4645
@require_admin_context
4646
def sm_backend_conf_create(context, values):
4647
session = get_session()
4648
with session.begin():
4649
config_params = values['config_params']
4650
backend_conf = model_query(context, models.SMBackendConf,
4652
read_deleted="yes").\
4653
filter_by(config_params=config_params).\
4657
raise exception.Duplicate(_('Backend exists'))
4659
backend_conf = models.SMBackendConf()
4660
backend_conf.update(values)
4661
backend_conf.save(session=session)
4665
@require_admin_context
4666
def sm_backend_conf_update(context, sm_backend_id, values):
4667
session = get_session()
4668
with session.begin():
4669
backend_conf = model_query(context, models.SMBackendConf,
4671
read_deleted="yes").\
4672
filter_by(id=sm_backend_id).\
4675
if not backend_conf:
4676
raise exception.NotFound(
4677
_("No backend config with id %(sm_backend_id)s") % locals())
4679
backend_conf.update(values)
4680
backend_conf.save(session=session)
4684
@require_admin_context
4685
def sm_backend_conf_delete(context, sm_backend_id):
4686
# FIXME(sirp): for consistency, shouldn't this just mark as deleted with
4687
# `purge` actually deleting the record?
4688
session = get_session()
4689
with session.begin():
4690
model_query(context, models.SMBackendConf, session=session,
4691
read_deleted="yes").\
4692
filter_by(id=sm_backend_id).\
4696
@require_admin_context
4697
def sm_backend_conf_get(context, sm_backend_id):
4698
result = model_query(context, models.SMBackendConf, read_deleted="yes").\
4699
filter_by(id=sm_backend_id).\
4703
raise exception.NotFound(_("No backend config with id "
4704
"%(sm_backend_id)s") % locals())
4709
@require_admin_context
4710
def sm_backend_conf_get_by_sr(context, sr_uuid):
4711
result = model_query(context, models.SMBackendConf, read_deleted="yes").\
4712
filter_by(sr_uuid=sr_uuid).\
4715
raise exception.NotFound(_("No backend config with sr uuid "
4716
"%(sr_uuid)s") % locals())
4720
@require_admin_context
4721
def sm_backend_conf_get_all(context):
4722
return model_query(context, models.SMBackendConf, read_deleted="yes").\
4726
####################
4729
def _sm_flavor_get_query(context, sm_flavor_id, session=None):
4730
return model_query(context, models.SMFlavors, session=session,
4731
read_deleted="yes").\
4732
filter_by(id=sm_flavor_id)
4735
@require_admin_context
4736
def sm_flavor_create(context, values):
4737
session = get_session()
4738
with session.begin():
4739
sm_flavor = model_query(context, models.SMFlavors,
4741
read_deleted="yes").\
4742
filter_by(label=values['label']).\
4745
sm_flavor = models.SMFlavors()
4746
sm_flavor.update(values)
4747
sm_flavor.save(session=session)
4749
raise exception.Duplicate(_('Flavor exists'))
4753
@require_admin_context
4754
def sm_flavor_update(context, sm_flavor_id, values):
4755
session = get_session()
4756
with session.begin():
4757
sm_flavor = model_query(context, models.SMFlavors,
4759
read_deleted="yes").\
4760
filter_by(id=sm_flavor_id).\
4763
raise exception.NotFound(
4764
_('%(sm_flavor_id) flavor not found') % locals())
4765
sm_flavor.update(values)
4766
sm_flavor.save(session=session)
4770
@require_admin_context
4771
def sm_flavor_delete(context, sm_flavor_id):
4772
session = get_session()
4773
with session.begin():
4774
_sm_flavor_get_query(context, sm_flavor_id).delete()
4777
@require_admin_context
4778
def sm_flavor_get(context, sm_flavor_id):
4779
result = _sm_flavor_get_query(context, sm_flavor_id).first()
4782
raise exception.NotFound(
4783
_("No sm_flavor called %(sm_flavor_id)s") % locals())
4788
@require_admin_context
4789
def sm_flavor_get_all(context):
4790
return model_query(context, models.SMFlavors, read_deleted="yes").all()
4793
@require_admin_context
4794
def sm_flavor_get_by_label(context, sm_flavor_label):
4795
result = model_query(context, models.SMFlavors,
4796
read_deleted="yes").\
4797
filter_by(label=sm_flavor_label).first()
4799
raise exception.NotFound(
4800
_("No sm_flavor called %(sm_flavor_label)s") % locals())
4804
###############################
4807
def _sm_volume_get_query(context, volume_id, session=None):
4808
return model_query(context, models.SMVolume, session=session,
4809
read_deleted="yes").\
4810
filter_by(id=volume_id)
4813
def sm_volume_create(context, values):
4814
sm_volume = models.SMVolume()
4815
sm_volume.update(values)
4820
def sm_volume_update(context, volume_id, values):
4821
sm_volume = sm_volume_get(context, volume_id)
4822
sm_volume.update(values)
4827
def sm_volume_delete(context, volume_id):
4828
session = get_session()
4829
with session.begin():
4830
_sm_volume_get_query(context, volume_id, session=session).delete()
4833
def sm_volume_get(context, volume_id):
4834
result = _sm_volume_get_query(context, volume_id).first()
4837
raise exception.NotFound(
4838
_("No sm_volume with id %(volume_id)s") % locals())
4843
def sm_volume_get_all(context):
4844
return model_query(context, models.SMVolume, read_deleted="yes").all()
4850
4144
def _aggregate_get_query(context, model_class, id_field, id,
4851
4145
session=None, read_deleted=None):
4852
4146
return model_query(context, model_class, session=session,