~ubuntu-branches/ubuntu/raring/nova/raring-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-11-23 09:04:58 UTC
  • mfrom: (1.1.66)
  • Revision ID: package-import@ubuntu.com-20121123090458-91565o7aev1i1h71
Tags: 2013.1~g1-0ubuntu1
[ Adam Gandelman ]
* debian/control: Ensure novaclient is upgraded with nova,
  require python-keystoneclient >= 1:2.9.0. (LP: #1073289)
* debian/patches/{ubuntu/*, rbd-security.patch}: Dropped, applied
  upstream.
* debian/control: Add python-testtools to Build-Depends.

[ Chuck Short ]
* New upstream version.
* Refreshed debian/patches/avoid_setuptools_git_dependency.patch.
* debian/rules: FTBFS if missing binaries.
* debian/nova-scheudler.install: Add missing rabbit-queues and
  nova-rpc-zmq-receiver.
* Remove nova-volume since it doesnt exist anymore, transition to cinder-*.
* debian/rules: install apport hook in the right place.
* debian/patches/ubuntu-show-tests.patch: Display test failures.
* debian/control: Add depends on genisoimage
* debian/control: Suggest guestmount.
* debian/control: Suggest websockify. (LP: #1076442)
* debian/nova.conf: Disable nova-volume service.
* debian/control: Depend on xen-system-* rather than the hypervisor.
* debian/control, debian/mans/nova-conductor.8, debian/nova-conductor.init,
  debian/nova-conductor.install, debian/nova-conductor.logrotate
  debian/nova-conductor.manpages, debian/nova-conductor.postrm
  debian/nova-conductor.upstart.in: Add nova-conductor service.
* debian/control: Add python-fixtures as a build deps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
import copy
24
24
import datetime
25
25
import functools
26
 
import warnings
 
26
import uuid
 
27
 
 
28
from sqlalchemy import and_
 
29
from sqlalchemy.exc import IntegrityError
 
30
from sqlalchemy import or_
 
31
from sqlalchemy.orm import joinedload
 
32
from sqlalchemy.orm import joinedload_all
 
33
from sqlalchemy.sql.expression import asc
 
34
from sqlalchemy.sql.expression import desc
 
35
from sqlalchemy.sql.expression import literal_column
 
36
from sqlalchemy.sql import func
27
37
 
28
38
from nova import block_device
29
39
from nova.common.sqlalchemyutils import paginate_query
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
 
 
49
 
FLAGS = flags.FLAGS
 
48
from nova.openstack.common import uuidutils
 
49
 
 
50
 
 
51
CONF = cfg.CONF
 
52
CONF.import_opt('compute_topic', 'nova.config')
 
53
CONF.import_opt('sql_connection', 'nova.config')
50
54
 
51
55
LOG = logging.getLogger(__name__)
52
56
 
53
57
 
54
 
def is_admin_context(context):
55
 
    """Indicates if the request context is an administrator."""
56
 
    if not context:
57
 
        warnings.warn(_('Use of empty request context is deprecated'),
58
 
                      DeprecationWarning)
59
 
        raise Exception('die')
60
 
    return context.is_admin
61
 
 
62
 
 
63
58
def is_user_context(context):
64
59
    """Indicates if the request context is a normal user."""
65
60
    if not context:
106
101
    """
107
102
 
108
103
    def wrapper(*args, **kwargs):
109
 
        if not is_admin_context(args[0]):
 
104
        context = args[0]
 
105
        if not context.is_admin:
110
106
            raise exception.AdminRequired()
111
107
        return f(*args, **kwargs)
112
108
    return wrapper
124
120
    """
125
121
 
126
122
    def wrapper(*args, **kwargs):
127
 
        if not is_admin_context(args[0]) and not is_user_context(args[0]):
 
123
        context = args[0]
 
124
        if not context.is_admin and not is_user_context(context):
128
125
            raise exception.NotAuthorized()
129
126
        return f(*args, **kwargs)
130
127
    return wrapper
131
128
 
132
129
 
133
 
def require_instance_exists(f):
134
 
    """Decorator to require the specified instance to exist.
135
 
 
136
 
    Requires the wrapped function to use context and instance_id as
137
 
    their first two arguments.
138
 
    """
139
 
    @functools.wraps(f)
140
 
    def wrapper(context, instance_id, *args, **kwargs):
141
 
        db.instance_get(context, instance_id)
142
 
        return f(context, instance_id, *args, **kwargs)
143
 
 
144
 
    return wrapper
145
 
 
146
 
 
147
130
def require_instance_exists_using_uuid(f):
148
131
    """Decorator to require the specified instance to exist.
149
132
 
158
141
    return wrapper
159
142
 
160
143
 
161
 
def require_volume_exists(f):
162
 
    """Decorator to require the specified volume to exist.
163
 
 
164
 
    Requires the wrapped function to use context and volume_id as
165
 
    their first two arguments.
166
 
    """
167
 
 
168
 
    def wrapper(context, volume_id, *args, **kwargs):
169
 
        db.volume_get(context, volume_id)
170
 
        return f(context, volume_id, *args, **kwargs)
171
 
    wrapper.__name__ = f.__name__
172
 
    return wrapper
173
 
 
174
 
 
175
144
def require_aggregate_exists(f):
176
145
    """Decorator to require the specified aggregate to exist.
177
146
 
331
300
        service_ref = service_get(context, service_id, session=session)
332
301
        service_ref.delete(session=session)
333
302
 
334
 
        if service_ref.topic == 'compute' and service_ref.compute_node:
 
303
        if (service_ref.topic == CONF.compute_topic and
 
304
            service_ref.compute_node):
335
305
            for c in service_ref.compute_node:
336
306
                c.delete(session=session)
337
307
 
387
357
    result = model_query(context, models.Service, read_deleted="no").\
388
358
                options(joinedload('compute_node')).\
389
359
                filter_by(host=host).\
390
 
                filter_by(topic="compute").\
 
360
                filter_by(topic=CONF.compute_topic).\
391
361
                all()
392
362
 
393
363
    if not result:
420
390
        #             (SELECT host, SUM(instances.vcpus) AS instance_cores
421
391
        #              FROM instances GROUP BY host) AS inst_cores
422
392
        #             ON services.host = inst_cores.host
423
 
        topic = 'compute'
 
393
        topic = CONF.compute_topic
424
394
        label = 'instance_cores'
425
395
        subq = model_query(context, models.Instance.host,
426
396
                           func.sum(models.Instance.vcpus).label(label),
435
405
 
436
406
 
437
407
@require_admin_context
438
 
def service_get_all_volume_sorted(context):
439
 
    session = get_session()
440
 
    with session.begin():
441
 
        topic = 'volume'
442
 
        label = 'volume_gigabytes'
443
 
        subq = model_query(context, models.Volume.host,
444
 
                           func.sum(models.Volume.size).label(label),
445
 
                           session=session, read_deleted="no").\
446
 
                       group_by(models.Volume.host).\
447
 
                       subquery()
448
 
        return _service_get_all_topic_subquery(context,
449
 
                                               session,
450
 
                                               topic,
451
 
                                               subq,
452
 
                                               label)
453
 
 
454
 
 
455
 
@require_admin_context
456
408
def service_get_by_args(context, host, binary):
457
409
    result = model_query(context, models.Service).\
458
410
                     filter_by(host=host).\
469
421
def service_create(context, values):
470
422
    service_ref = models.Service()
471
423
    service_ref.update(values)
472
 
    if not FLAGS.enable_new_services:
 
424
    if not CONF.enable_new_services:
473
425
        service_ref.disabled = True
474
426
    service_ref.save()
475
427
    return service_ref
486
438
 
487
439
###################
488
440
 
489
 
def compute_node_get(context, compute_id, session=None):
 
441
def compute_node_get(context, compute_id):
 
442
    return _compute_node_get(context, compute_id)
 
443
 
 
444
 
 
445
def _compute_node_get(context, compute_id, session=None):
490
446
    result = model_query(context, models.ComputeNode, session=session).\
491
447
            filter_by(id=compute_id).\
492
448
            options(joinedload('service')).\
500
456
 
501
457
 
502
458
@require_admin_context
503
 
def compute_node_get_all(context, session=None):
504
 
    return model_query(context, models.ComputeNode, session=session).\
 
459
def compute_node_get_all(context):
 
460
    return model_query(context, models.ComputeNode).\
505
461
            options(joinedload('service')).\
506
462
            options(joinedload('stats')).\
507
463
            all()
529
485
 
530
486
 
531
487
@require_admin_context
532
 
def compute_node_create(context, values, session=None):
 
488
def compute_node_create(context, values):
533
489
    """Creates a new ComputeNode and populates the capacity fields
534
490
    with the most recent data."""
535
491
    _prep_stats_dict(values)
536
492
 
537
 
    if not session:
538
 
        session = get_session()
539
 
 
540
 
    with session.begin(subtransactions=True):
541
 
        compute_node_ref = models.ComputeNode()
542
 
        session.add(compute_node_ref)
543
 
        compute_node_ref.update(values)
 
493
    compute_node_ref = models.ComputeNode()
 
494
    compute_node_ref.update(values)
 
495
    compute_node_ref.save()
544
496
    return compute_node_ref
545
497
 
546
498
 
587
539
    session = get_session()
588
540
    with session.begin(subtransactions=True):
589
541
        _update_stats(context, stats, compute_id, session, prune_stats)
590
 
        compute_ref = compute_node_get(context, compute_id, session=session)
 
542
        compute_ref = _compute_node_get(context, compute_id, session=session)
591
543
        compute_ref.update(values)
592
544
    return compute_ref
593
545
 
594
546
 
595
547
def compute_node_get_by_host(context, host):
596
548
    """Get all capacity entries for the given host."""
597
 
    session = get_session()
598
 
    with session.begin():
599
 
        node = session.query(models.ComputeNode).\
600
 
                             join('service').\
601
 
                             filter(models.Service.host == host).\
602
 
                             filter_by(deleted=False)
603
 
        return node.first()
 
549
    result = model_query(context, models.ComputeNode).\
 
550
            join('service').\
 
551
            filter(models.Service.host == host).\
 
552
            filter_by(deleted=False).\
 
553
            first()
 
554
    return result
604
555
 
605
556
 
606
557
def compute_node_statistics(context):
777
728
    # check uniqueness for not deleted addresses
778
729
    if not floating_ip_ref.deleted:
779
730
        try:
780
 
            floating_ip = floating_ip_get_by_address(context,
781
 
                                                     floating_ip_ref.address,
782
 
                                                     session)
 
731
            floating_ip = _floating_ip_get_by_address(context,
 
732
                                                      floating_ip_ref.address,
 
733
                                                      session)
783
734
        except exception.FloatingIpNotFoundForAddress:
784
735
            pass
785
736
        else:
806
757
                                   fixed_address, host):
807
758
    session = get_session()
808
759
    with session.begin():
809
 
        floating_ip_ref = floating_ip_get_by_address(context,
810
 
                                                     floating_address,
811
 
                                                     session=session)
 
760
        floating_ip_ref = _floating_ip_get_by_address(context,
 
761
                                                      floating_address,
 
762
                                                      session=session)
812
763
        fixed_ip_ref = fixed_ip_get_by_address(context,
813
764
                                               fixed_address,
814
765
                                               session=session)
819
770
 
820
771
@require_context
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,
825
 
                                                     address,
826
 
                                                     session=session)
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,
 
776
                    'host': None,
 
777
                    'auto_assigned': False})
831
778
 
832
779
 
833
780
@require_context
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,
838
 
                                                     address,
839
 
                                                     session=session)
840
 
        floating_ip_ref.delete(session=session)
 
782
    model_query(context, models.FloatingIp).\
 
783
            filter_by(address=address).\
 
784
            delete()
841
785
 
842
786
 
843
787
@require_context
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,
848
 
                                                     address,
849
 
                                                     session=session)
850
 
        fixed_ip_ref = fixed_ip_get(context,
851
 
                                    floating_ip_ref['fixed_ip_id'])
 
791
        floating_ip_ref = model_query(context,
 
792
                                      models.FloatingIp,
 
793
                                      session=session).\
 
794
                            filter_by(address=address).\
 
795
                            first()
 
796
        if not floating_ip_ref:
 
797
            raise exception.FloatingIpNotFoundForAddress(address=address)
 
798
 
 
799
        fixed_ip_ref = model_query(context, models.FixedIp, session=session).\
 
800
                            filter_by(id=floating_ip_ref['fixed_ip_id']).\
 
801
                            first()
852
802
        if fixed_ip_ref:
853
803
            fixed_ip_address = fixed_ip_ref['address']
854
804
        else:
861
811
 
862
812
@require_context
863
813
def floating_ip_set_auto_assigned(context, address):
864
 
    session = get_session()
865
 
    with session.begin():
866
 
        floating_ip_ref = floating_ip_get_by_address(context,
867
 
                                                     address,
868
 
                                                     session=session)
869
 
        floating_ip_ref.auto_assigned = True
870
 
        floating_ip_ref.save(session=session)
 
814
    model_query(context, models.FloatingIp).\
 
815
            filter_by(address=address).\
 
816
            update({'auto_assigned': True})
871
817
 
872
818
 
873
819
def _floating_ip_get_all(context, session=None):
904
850
 
905
851
 
906
852
@require_context
907
 
def floating_ip_get_by_address(context, address, session=None):
 
853
def floating_ip_get_by_address(context, address):
 
854
    return _floating_ip_get_by_address(context, address)
 
855
 
 
856
 
 
857
@require_context
 
858
def _floating_ip_get_by_address(context, address, session=None):
908
859
    result = model_query(context, models.FloatingIp, session=session).\
909
860
                filter_by(address=address).\
910
861
                first()
921
872
 
922
873
 
923
874
@require_context
924
 
def floating_ip_get_by_fixed_address(context, fixed_address, session=None):
925
 
    if not session:
926
 
        session = get_session()
927
 
 
928
 
    fixed_ip = fixed_ip_get_by_address(context, fixed_address, session)
929
 
    fixed_ip_id = fixed_ip['id']
930
 
 
931
 
    return model_query(context, models.FloatingIp, session=session).\
932
 
                   filter_by(fixed_ip_id=fixed_ip_id).\
933
 
                   all()
 
875
def floating_ip_get_by_fixed_address(context, fixed_address):
 
876
    subq = model_query(context, models.FixedIp.id).\
 
877
            filter_by(address=fixed_address).\
 
878
            limit(1).\
 
879
            subquery()
 
880
    return model_query(context, models.FloatingIp).\
 
881
            filter_by(fixed_ip_id=subq.as_scalar()).\
 
882
            all()
934
883
 
935
884
    # NOTE(tr3buchet) please don't invent an exception here, empty list is fine
936
885
 
949
898
def floating_ip_update(context, address, values):
950
899
    session = get_session()
951
900
    with session.begin():
952
 
        floating_ip_ref = floating_ip_get_by_address(context, address, session)
 
901
        floating_ip_ref = _floating_ip_get_by_address(context,
 
902
                                                      address,
 
903
                                                      session)
953
904
        for (key, value) in values.iteritems():
954
905
            floating_ip_ref[key] = value
955
906
        floating_ip_ref.save(session=session)
1006
957
 
1007
958
@require_admin_context
1008
959
def dnsdomain_unregister(context, fqdomain):
1009
 
    session = get_session()
1010
 
    with session.begin():
1011
 
        session.query(models.DNSDomain).\
1012
 
                     filter_by(domain=fqdomain).\
1013
 
                     delete()
 
960
    model_query(context, models.DNSDomain).\
 
961
                 filter_by(domain=fqdomain).\
 
962
                 delete()
1014
963
 
1015
964
 
1016
965
@require_context
1017
966
def dnsdomain_list(context):
1018
 
    session = get_session()
1019
 
    records = model_query(context, models.DNSDomain,
1020
 
                  session=session, read_deleted="no").\
1021
 
                  all()
1022
 
    domains = []
1023
 
    for record in records:
1024
 
        domains.append(record.domain)
1025
 
 
1026
 
    return domains
 
967
    query = model_query(context, models.DNSDomain, read_deleted="no")
 
968
    return [row.domain for row in query.all()]
1027
969
 
1028
970
 
1029
971
###################
1036
978
    reserved -- should be a boolean value(True or False), exact value will be
1037
979
    used to filter on the fixed ip address
1038
980
    """
1039
 
    if not utils.is_uuid_like(instance_uuid):
 
981
    if not uuidutils.is_uuid_like(instance_uuid):
1040
982
        raise exception.InvalidUUID(uuid=instance_uuid)
1041
983
 
1042
984
    session = get_session()
1068
1010
@require_admin_context
1069
1011
def fixed_ip_associate_pool(context, network_id, instance_uuid=None,
1070
1012
                            host=None):
1071
 
    if instance_uuid and not utils.is_uuid_like(instance_uuid):
 
1013
    if instance_uuid and not uuidutils.is_uuid_like(instance_uuid):
1072
1014
        raise exception.InvalidUUID(uuid=instance_uuid)
1073
1015
 
1074
1016
    session = get_session()
1146
1088
                     join((models.Network,
1147
1089
                           models.Network.id == models.FixedIp.network_id)).\
1148
1090
                     join((models.Instance,
1149
 
                           models.Instance.uuid == \
 
1091
                           models.Instance.uuid ==
1150
1092
                               models.FixedIp.instance_uuid)).\
1151
1093
                     filter(host_filter).\
1152
1094
                     all()
1163
1105
 
1164
1106
 
1165
1107
@require_context
1166
 
def fixed_ip_get(context, id, session=None):
1167
 
    result = model_query(context, models.FixedIp, session=session).\
 
1108
def fixed_ip_get(context, id):
 
1109
    result = model_query(context, models.FixedIp).\
1168
1110
                     filter_by(id=id).\
1169
1111
                     first()
1170
1112
    if not result:
1174
1116
    # results?
1175
1117
    if is_user_context(context) and result['instance_uuid'] is not None:
1176
1118
        instance = instance_get_by_uuid(context.elevated(read_deleted='yes'),
1177
 
                                        result['instance_uuid'],
1178
 
                                        session)
 
1119
                                        result['instance_uuid'])
1179
1120
        authorize_project_context(context, instance.project_id)
1180
1121
 
1181
1122
    return result
1211
1152
    return result
1212
1153
 
1213
1154
 
 
1155
@require_admin_context
 
1156
def fixed_ip_get_by_address_detailed(context, address, session=None):
 
1157
    """
 
1158
    :returns: a tuple of (models.FixedIp, models.Network, models.Instance)
 
1159
    """
 
1160
    if not session:
 
1161
        session = get_session()
 
1162
 
 
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)).\
 
1171
        first()
 
1172
 
 
1173
    if not result:
 
1174
        raise exception.FixedIpNotFoundForAddress(address=address)
 
1175
 
 
1176
    return result
 
1177
 
 
1178
 
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)
1218
1183
 
1219
1184
    result = model_query(context, models.FixedIp, read_deleted="no").\
1248
1213
    return result
1249
1214
 
1250
1215
 
1251
 
@require_admin_context
1252
 
def fixed_ip_get_network(context, address):
1253
 
    fixed_ip_ref = fixed_ip_get_by_address(context, address)
1254
 
    return fixed_ip_ref.network
1255
 
 
1256
 
 
1257
1216
@require_context
1258
1217
def fixed_ip_update(context, address, values):
1259
1218
    session = get_session()
1278
1237
        vif_ref = models.VirtualInterface()
1279
1238
        vif_ref.update(values)
1280
1239
        vif_ref.save()
1281
 
    except IntegrityError:
 
1240
    except exception.DBError:
1282
1241
        raise exception.VirtualInterfaceCreateException()
1283
1242
 
1284
1243
    return vif_ref
1291
1250
 
1292
1251
 
1293
1252
@require_context
1294
 
def virtual_interface_get(context, vif_id, session=None):
 
1253
def virtual_interface_get(context, vif_id):
1295
1254
    """Gets a virtual interface from the table.
1296
1255
 
1297
1256
    :param vif_id: = id of the virtual interface
1298
1257
    """
1299
 
    vif_ref = _virtual_interface_query(context, session=session).\
 
1258
    vif_ref = _virtual_interface_query(context).\
1300
1259
                      filter_by(id=vif_id).\
1301
1260
                      first()
1302
1261
    return vif_ref
1356
1315
 
1357
1316
    :param vif_id: = id of vif to delete
1358
1317
    """
1359
 
    session = get_session()
1360
 
    vif_ref = virtual_interface_get(context, vif_id, session)
1361
 
    with session.begin():
1362
 
        session.delete(vif_ref)
 
1318
    _virtual_interface_query(context).\
 
1319
                      filter_by(id=vif_id).\
 
1320
                      delete()
1363
1321
 
1364
1322
 
1365
1323
@require_context
1369
1327
 
1370
1328
    :param instance_uuid: = uuid of instance
1371
1329
    """
1372
 
    vif_refs = virtual_interface_get_by_instance(context, instance_uuid)
1373
 
    for vif_ref in vif_refs:
1374
 
        virtual_interface_delete(context, vif_ref['id'])
 
1330
    _virtual_interface_query(context).\
 
1331
           filter_by(instance_uuid=instance_uuid).\
 
1332
           delete()
1375
1333
 
1376
1334
 
1377
1335
@require_context
1395
1353
    return metadata_refs
1396
1354
 
1397
1355
 
 
1356
def _validate_unique_server_name(context, session, name):
 
1357
    if not CONF.osapi_compute_unique_server_name_scope:
 
1358
        return
 
1359
 
 
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',
 
1365
                                                    session=session)
 
1366
    elif CONF.osapi_compute_unique_server_name_scope == 'global':
 
1367
        instance_list = instance_get_all_by_filters(context.elevated(),
 
1368
                                                    search_opts,
 
1369
                                                    'created_at', 'desc',
 
1370
                                                    session=session)
 
1371
    else:
 
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
 
1375
        LOG.warn(msg)
 
1376
        return
 
1377
 
 
1378
    lowername = name.lower()
 
1379
    for instance in instance_list:
 
1380
        if instance['hostname'].lower() == lowername:
 
1381
            raise exception.InstanceExists(name=instance['hostname'])
 
1382
 
 
1383
 
1398
1384
@require_context
1399
1385
def instance_create(context, values):
1400
1386
    """Create a new Instance record in the database.
1411
1397
 
1412
1398
    instance_ref = models.Instance()
1413
1399
    if not values.get('uuid'):
1414
 
        values['uuid'] = str(utils.gen_uuid())
 
1400
        values['uuid'] = str(uuid.uuid4())
1415
1401
    instance_ref['info_cache'] = models.InstanceInfoCache()
1416
1402
    info_cache = values.pop('info_cache', None)
1417
1403
    if info_cache is not None:
1434
1420
 
1435
1421
    session = get_session()
1436
1422
    with session.begin():
 
1423
        if 'hostname' in values:
 
1424
            _validate_unique_server_name(context, session, values['hostname'])
1437
1425
        instance_ref.security_groups = _get_sec_group_models(session,
1438
1426
                security_groups)
1439
1427
        instance_ref.save(session=session)
1442
1430
        instance_ref.instance_type
1443
1431
 
1444
1432
    # create the instance uuid to ec2_id mapping entry for instance
1445
 
    ec2_instance_create(context, instance_ref['uuid'])
 
1433
    db.ec2_instance_create(context, instance_ref['uuid'])
1446
1434
 
1447
1435
    return instance_ref
1448
1436
 
1465
1453
def instance_destroy(context, instance_uuid, constraint=None):
1466
1454
    session = get_session()
1467
1455
    with session.begin():
1468
 
        if utils.is_uuid_like(instance_uuid):
 
1456
        if uuidutils.is_uuid_like(instance_uuid):
1469
1457
            instance_ref = instance_get_by_uuid(context, instance_uuid,
1470
1458
                    session=session)
1471
1459
        else:
1522
1510
            options(joinedload_all('security_groups.rules')).\
1523
1511
            options(joinedload('info_cache')).\
1524
1512
            options(joinedload('metadata')).\
1525
 
            options(joinedload('instance_type'))
1526
 
 
1527
 
 
1528
 
@require_admin_context
 
1513
            options(joinedload('instance_type')).\
 
1514
            options(joinedload('system_metadata'))
 
1515
 
 
1516
 
 
1517
@require_context
1529
1518
def instance_get_all(context, columns_to_join=None):
1530
1519
    if columns_to_join is None:
1531
1520
        columns_to_join = ['info_cache', 'security_groups',
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)
 
1529
        else:
 
1530
            query = query.filter_by(user_id=context.user_id)
1536
1531
    return query.all()
1537
1532
 
1538
1533
 
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
1544
1539
    otherwise"""
1545
1540
 
1546
1541
    sort_fn = {'desc': desc, 'asc': asc}
1547
1542
 
1548
 
    session = get_session()
 
1543
    if not session:
 
1544
        session = get_session()
 
1545
 
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)))
1597
1595
    if marker is not None:
1598
1596
        try:
1599
1597
            marker = instance_get_by_uuid(context, marker, session=session)
1600
 
        except exception.InstanceNotFound as e:
 
1598
        except exception.InstanceNotFound:
1601
1599
            raise exception.MarkerNotFound(marker)
1602
1600
    query_prefix = paginate_query(query_prefix, models.Instance, limit,
1603
1601
                           [sort_key, 'created_at', 'id'],
1624
1622
        'oracle': 'REGEXP_LIKE',
1625
1623
        'sqlite': 'REGEXP'
1626
1624
    }
1627
 
    db_string = FLAGS.sql_connection.split(':')[0].split('+')[0]
 
1625
    db_string = CONF.sql_connection.split(':')[0].split('+')[0]
1628
1626
    db_regexp_op = regexp_op_map.get(db_string, 'LIKE')
1629
1627
    for filter_name in filters.iterkeys():
1630
1628
        try:
1695
1693
 
1696
1694
 
1697
1695
@require_admin_context
 
1696
def instance_get_all_by_host_and_node(context, host, node):
 
1697
    return _instance_get_all_query(context).filter_by(host=host).\
 
1698
                                            filter_by(node=node).all()
 
1699
 
 
1700
 
 
1701
@require_admin_context
1698
1702
def instance_get_all_by_host_and_not_type(context, host, type_id=None):
1699
1703
    return _instance_get_all_query(context).filter_by(host=host).\
1700
1704
                   filter(models.Instance.instance_type_id != type_id).all()
1738
1742
    return floating_ips[0]['address']
1739
1743
 
1740
1744
 
 
1745
@require_context
 
1746
def instance_floating_address_get_all(context, instance_uuid):
 
1747
    fixed_ips = fixed_ip_get_by_instance(context, instance_uuid)
 
1748
 
 
1749
    floating_ips = []
 
1750
    for fixed_ip in fixed_ips:
 
1751
        _floating_ips = floating_ip_get_by_fixed_ip_id(context,
 
1752
                                                    fixed_ip['id'])
 
1753
        floating_ips += _floating_ips
 
1754
 
 
1755
    return floating_ips
 
1756
 
 
1757
 
1741
1758
@require_admin_context
1742
1759
def instance_get_all_hung_in_rebooting(context, reboot_window, session=None):
1743
1760
    reboot_window = (timeutils.utcnow() -
1766
1783
        query = model_query(context, models.Instance, session=session,
1767
1784
                            project_only=True)
1768
1785
 
1769
 
        if utils.is_uuid_like(instance_uuid):
 
1786
        if uuidutils.is_uuid_like(instance_uuid):
1770
1787
            query = query.filter_by(uuid=instance_uuid)
1771
1788
        else:
1772
1789
            raise exception.InvalidUUID(instance_uuid)
1818
1835
def _instance_update(context, instance_uuid, values, copy_old_instance=False):
1819
1836
    session = get_session()
1820
1837
 
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)
1823
1840
 
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']).\
 
1849
                            first()
 
1850
        if inst_type_ref:
 
1851
            instance_ref['extra_specs'] = \
 
1852
                _dict_with_extra_specs(inst_type_ref).get('extra_specs', {})
 
1853
        else:
 
1854
            instance_ref['extra_specs'] = {}
 
1855
 
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")
1834
1863
                raise exception.UnexpectedTaskStateError(actual=actual_state,
1835
1864
                                                         expected=expected)
1836
1865
 
 
1866
        if ("hostname" in values and
 
1867
            values["hostname"].lower() != instance_ref["hostname"].lower()):
 
1868
                _validate_unique_server_name(context,
 
1869
                                             session,
 
1870
                                             values['hostname'])
 
1871
 
1837
1872
        if copy_old_instance:
1838
1873
            old_instance_ref = copy.copy(instance_ref)
1839
1874
        else:
1853
1888
 
1854
1889
        instance_ref.update(values)
1855
1890
        instance_ref.save(session=session)
 
1891
        if 'instance_type_id' in values:
 
1892
            # NOTE(comstud): It appears that sqlalchemy doesn't refresh
 
1893
            # the instance_type model after you update the ID.  You end
 
1894
            # up with an instance_type model that only has 'id' updated,
 
1895
            # but the rest of the model has the data from the old
 
1896
            # instance_type.
 
1897
            session.refresh(instance_ref['instance_type'])
1856
1898
 
1857
1899
    return (old_instance_ref, instance_ref)
1858
1900
 
1979
2021
 
1980
2022
 
1981
2023
@require_context
1982
 
def key_pair_destroy_all_by_user(context, user_id):
1983
 
    authorize_user_context(context, user_id)
1984
 
    session = get_session()
1985
 
    with session.begin():
1986
 
        session.query(models.KeyPair).\
1987
 
                filter_by(user_id=user_id).\
1988
 
                update({'deleted': True,
1989
 
                        'deleted_at': timeutils.utcnow(),
1990
 
                        'updated_at': literal_column('updated_at')})
1991
 
 
1992
 
 
1993
 
@require_context
1994
2024
def key_pair_get(context, user_id, name, session=None):
1995
2025
    authorize_user_context(context, user_id)
1996
2026
    result = model_query(context, models.KeyPair, session=session).\
2073
2103
 
2074
2104
 
2075
2105
@require_admin_context
2076
 
def network_count(context):
2077
 
    return model_query(context, models.Network).count()
2078
 
 
2079
 
 
2080
 
@require_admin_context
2081
2106
def _network_ips_query(context, network_id):
2082
2107
    return model_query(context, models.FixedIp, read_deleted="no").\
2083
2108
                   filter_by(network_id=network_id)
2099
2124
            raise exception.DuplicateVlan(vlan=values['vlan'])
2100
2125
 
2101
2126
    network_ref = models.Network()
2102
 
    network_ref['uuid'] = str(utils.gen_uuid())
 
2127
    network_ref['uuid'] = str(uuid.uuid4())
2103
2128
    network_ref.update(values)
2104
2129
 
2105
2130
    try:
2376
2401
 
2377
2402
 
2378
2403
@require_context
2379
 
def quota_get(context, project_id, resource, session=None):
2380
 
    result = model_query(context, models.Quota, session=session,
2381
 
                         read_deleted="no").\
 
2404
def quota_get(context, project_id, resource):
 
2405
    result = model_query(context, models.Quota, read_deleted="no").\
2382
2406
                     filter_by(project_id=project_id).\
2383
2407
                     filter_by(resource=resource).\
2384
2408
                     first()
2416
2440
 
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)
2424
 
 
2425
 
 
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})
 
2447
 
 
2448
    if not result:
 
2449
        raise exception.ProjectQuotaNotFound(project_id=project_id)
2432
2450
 
2433
2451
 
2434
2452
###################
2435
2453
 
2436
2454
 
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).\
2443
2460
                     first()
2475
2492
 
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,
2481
 
                                          session=session)
2482
 
        quota_class_ref.hard_limit = limit
2483
 
        quota_class_ref.save(session=session)
2484
 
 
2485
 
 
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,
2491
 
                                          session=session)
2492
 
        quota_class_ref.delete(session=session)
2493
 
 
2494
 
 
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).\
2502
 
                                all()
2503
 
 
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})
 
2499
 
 
2500
    if not result:
 
2501
        raise exception.QuotaClassNotFound(class_name=class_name)
2506
2502
 
2507
2503
 
2508
2504
###################
2509
2505
 
2510
2506
 
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).\
2517
2512
                     first()
2538
2533
 
2539
2534
 
2540
2535
@require_admin_context
2541
 
def quota_usage_create(context, project_id, resource, in_use, reserved,
 
2536
def _quota_usage_create(context, project_id, resource, in_use, reserved,
2542
2537
                       until_refresh, session=None):
2543
2538
    quota_usage_ref = models.QuotaUsage()
2544
2539
    quota_usage_ref.project_id = project_id
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
 
2544
 
2549
2545
    quota_usage_ref.save(session=session)
2550
2546
 
2551
2547
    return quota_usage_ref
2552
2548
 
2553
2549
 
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,
2559
 
                                          session=session)
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)
2564
 
 
2565
 
    if session:
2566
 
        # Assume caller started a transaction
2567
 
        do_update(session)
2568
 
    else:
2569
 
        session = get_session()
2570
 
        with session.begin():
2571
 
            do_update(session)
2572
 
 
2573
 
 
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,
2579
 
                                          session=session)
2580
 
        quota_usage_ref.delete(session=session)
 
2551
def quota_usage_update(context, project_id, resource, **kwargs):
 
2552
    updates = {}
 
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']
 
2559
 
 
2560
    result = model_query(context, models.QuotaUsage, read_deleted="no").\
 
2561
                     filter_by(project_id=project_id).\
 
2562
                     filter_by(resource=resource).\
 
2563
                     update(updates)
 
2564
 
 
2565
    if not result:
 
2566
        raise exception.QuotaUsageNotFound(project_id=project_id)
2581
2567
 
2582
2568
 
2583
2569
###################
2584
2570
 
2585
2571
 
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).\
2591
2576
                     first()
2592
2577
 
2596
2581
    return result
2597
2582
 
2598
2583
 
2599
 
@require_context
2600
 
def reservation_get_all_by_project(context, project_id):
2601
 
    authorize_project_context(context, project_id)
2602
 
 
2603
 
    rows = model_query(context, models.QuotaUsage, read_deleted="no").\
2604
 
                   filter_by(project_id=project_id).\
2605
 
                   all()
2606
 
 
2607
 
    result = {'project_id': project_id}
2608
 
    for row in rows:
2609
 
        result.setdefault(row.resource, {})
2610
 
        result[row.resource][row.uuid] = row.delta
2611
 
 
2612
 
    return result
2613
 
 
2614
 
 
2615
2584
@require_admin_context
2616
2585
def reservation_create(context, uuid, usage, project_id, resource, delta,
2617
2586
                       expire, session=None):
2628
2597
 
2629
2598
@require_admin_context
2630
2599
def reservation_destroy(context, uuid):
2631
 
    session = get_session()
2632
 
    with session.begin():
2633
 
        reservation_ref = reservation_get(context, uuid, session=session)
2634
 
        reservation_ref.delete(session=session)
 
2600
    result = model_query(context, models.Reservation, read_deleted="no").\
 
2601
                     filter_by(uuid=uuid).\
 
2602
                     delete()
 
2603
 
 
2604
    if not result:
 
2605
        raise exception.ReservationNotFound(uuid=uuid)
2635
2606
 
2636
2607
 
2637
2608
###################
2670
2641
            # Do we need to refresh the usage?
2671
2642
            refresh = False
2672
2643
            if resource not in usages:
2673
 
                usages[resource] = quota_usage_create(elevated,
 
2644
                usages[resource] = _quota_usage_create(elevated,
2674
2645
                                                      context.project_id,
2675
2646
                                                      resource,
2676
2647
                                                      0, 0,
2698
2669
                for res, in_use in updates.items():
2699
2670
                    # Make sure we have a destination for the usage!
2700
2671
                    if res not in usages:
2701
 
                        usages[res] = quota_usage_create(elevated,
 
2672
                        usages[res] = _quota_usage_create(elevated,
2702
2673
                                                         context.project_id,
2703
2674
                                                         res,
2704
2675
                                                         0, 0,
2747
2718
            reservations = []
2748
2719
            for resource, delta in deltas.items():
2749
2720
                reservation = reservation_create(elevated,
2750
 
                                                 str(utils.gen_uuid()),
 
2721
                                                 str(uuid.uuid4()),
2751
2722
                                                 usages[resource],
2752
2723
                                                 context.project_id,
2753
2724
                                                 resource, delta, expire,
2883
2854
###################
2884
2855
 
2885
2856
 
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').\
2895
 
                                first()
2896
 
 
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()
2901
 
 
2902
 
        iscsi_target_ref.volume_id = volume_id
2903
 
        session.add(iscsi_target_ref)
2904
 
 
2905
 
    return iscsi_target_ref.target_num
2906
 
 
2907
 
 
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)
2912
 
 
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)
2922
 
 
2923
 
 
2924
 
@require_context
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)
2932
 
 
2933
 
    session = get_session()
2934
 
    with session.begin():
2935
 
        volume_ref.save(session=session)
2936
 
 
2937
 
    return volume_get(context, values['id'], session=session)
2938
 
 
2939
 
 
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),
2945
 
                         read_deleted="no",
2946
 
                         session=session).\
2947
 
                     filter_by(project_id=project_id).\
2948
 
                     first()
2949
 
 
2950
 
    # NOTE(vish): convert None to 0
2951
 
    return (result[0] or 0, result[1] or 0)
2952
 
 
2953
 
 
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')})
2972
 
    return volume_ref
2973
 
 
2974
 
 
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)
2985
 
 
2986
 
 
2987
 
@require_context
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'))
2993
 
 
2994
 
 
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')
3005
2867
 
3006
2868
 
3007
 
@require_context
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).\
3011
 
                    first()
3012
 
 
3013
 
    if not result:
3014
 
        raise exception.VolumeNotFound(volume_id=volume_id)
3015
 
 
3016
 
    return result
3017
 
 
3018
 
 
3019
 
@require_admin_context
3020
 
def volume_get_all(context):
3021
 
    return _volume_get_query(context).all()
3022
 
 
3023
 
 
3024
 
@require_admin_context
3025
 
def volume_get_all_by_host(context, host):
3026
 
    return _volume_get_query(context).filter_by(host=host).all()
3027
 
 
3028
 
 
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).\
3035
 
                     all()
3036
 
 
3037
 
    if not result:
3038
 
        return []
3039
 
 
3040
 
    return result
3041
 
 
3042
 
 
3043
 
@require_context
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()
3047
 
 
3048
 
 
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").\
3059
2879
 
3060
2880
 
3061
2881
@require_context
3062
 
def volume_update(context, volume_id, values):
3063
 
    session = get_session()
3064
 
    volume_ref = volume_get(context, volume_id, session=session)
3065
 
    metadata = values.get('metadata')
3066
 
    if metadata is not None:
3067
 
        volume_metadata_update(context,
3068
 
                                volume_id,
3069
 
                                values.pop('metadata'),
3070
 
                                delete=True)
3071
 
    with session.begin():
3072
 
        volume_ref.update(values)
3073
 
        volume_ref.save(session=session)
3074
 
 
3075
 
    return volume_ref
3076
 
 
3077
 
 
3078
 
@require_context
3079
2882
def ec2_volume_create(context, volume_uuid, id=None):
3080
2883
    """Create ec2 compatable volume by provided uuid"""
3081
2884
    ec2_volume_ref = models.VolumeIdMapping()
3149
2952
    return result['uuid']
3150
2953
 
3151
2954
 
3152
 
####################
3153
 
 
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)
3158
 
 
3159
 
 
3160
 
@require_context
3161
 
@require_volume_exists
3162
 
def volume_metadata_get(context, volume_id):
3163
 
    rows = _volume_metadata_get_query(context, volume_id).all()
3164
 
    result = {}
3165
 
    for row in rows:
3166
 
        result[row['key']] = row['value']
3167
 
 
3168
 
    return result
3169
 
 
3170
 
 
3171
 
@require_context
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')})
3179
 
 
3180
 
 
3181
 
@require_context
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).\
3186
 
                    first()
3187
 
 
3188
 
    if not result:
3189
 
        raise exception.VolumeMetadataNotFound(metadata_key=key,
3190
 
                                               volume_id=volume_id)
3191
 
    return result
3192
 
 
3193
 
 
3194
 
@require_context
3195
 
@require_volume_exists
3196
 
def volume_metadata_update(context, volume_id, metadata, delete):
3197
 
    session = get_session()
3198
 
 
3199
 
    # Set existing metadata to deleted if delete argument is True
3200
 
    if delete:
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,
3205
 
                                                    meta_key, session)
3206
 
                meta_ref.update({'deleted': True})
3207
 
                meta_ref.save(session=session)
3208
 
 
3209
 
    meta_ref = None
3210
 
 
3211
 
    # Now update all existing items with new values, or create new meta objects
3212
 
    for meta_key, meta_value in metadata.iteritems():
3213
 
 
3214
 
        # update the value whether it exists or not
3215
 
        item = {"value": meta_value}
3216
 
 
3217
 
        try:
3218
 
            meta_ref = volume_metadata_get_item(context, volume_id,
3219
 
                                                  meta_key, session)
3220
 
        except exception.VolumeMetadataNotFound, e:
3221
 
            meta_ref = models.VolumeMetadata()
3222
 
            item.update({"key": meta_key, "volume_id": volume_id})
3223
 
 
3224
 
        meta_ref.update(item)
3225
 
        meta_ref.save(session=session)
3226
 
 
3227
 
    return metadata
3228
 
 
3229
 
 
3230
 
###################
3231
 
 
3232
 
 
3233
 
@require_context
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)
3239
 
 
3240
 
    session = get_session()
3241
 
    with session.begin():
3242
 
        snapshot_ref.save(session=session)
3243
 
    return snapshot_ref
3244
 
 
3245
 
 
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')})
3255
 
 
3256
 
 
3257
 
@require_context
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).\
3262
 
                first()
3263
 
 
3264
 
    if not result:
3265
 
        raise exception.SnapshotNotFound(snapshot_id=snapshot_id)
3266
 
 
3267
 
    return result
3268
 
 
3269
 
 
3270
 
@require_admin_context
3271
 
def snapshot_get_all(context):
3272
 
    return model_query(context, models.Snapshot).all()
3273
 
 
3274
 
 
3275
 
@require_context
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()
3280
 
 
3281
 
 
3282
 
@require_context
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).\
3287
 
                   all()
3288
 
 
3289
 
 
3290
 
@require_context
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)
3297
 
 
3298
 
 
3299
2955
###################
3300
2956
 
3301
2957
 
3403
3059
    query = model_query(context, models.SecurityGroup, session=session,
3404
3060
            read_deleted=read_deleted, project_only=project_only)
3405
3061
    if join_rules:
3406
 
        query = query.options(joinedload_all('rules'))
 
3062
        query = query.options(joinedload_all('rules.grantee_group'))
3407
3063
    return query
3408
3064
 
3409
3065
 
3460
3116
            filter_by(name=group_name)
3461
3117
 
3462
3118
    if columns_to_join is None:
3463
 
        columns_to_join = ['instances', 'rules']
 
3119
        columns_to_join = ['instances', 'rules.grantee_group']
3464
3120
 
3465
3121
    for column in columns_to_join:
3466
3122
        query = query.options(joinedload_all(column))
3573
3229
                        'deleted_at': timeutils.utcnow(),
3574
3230
                        'updated_at': literal_column('updated_at')})
3575
3231
 
 
3232
        session.query(models.SecurityGroupIngressRule).\
 
3233
                filter_by(parent_group_id=security_group_id).\
 
3234
                update({'deleted': True,
 
3235
                        'deleted_at': timeutils.utcnow(),
 
3236
                        'updated_at': literal_column('updated_at')})
 
3237
 
3576
3238
 
3577
3239
@require_context
3578
3240
def security_group_count_by_project(context, project_id, session=None):
3758
3420
            all()
3759
3421
 
3760
3422
 
 
3423
@require_admin_context
 
3424
def migration_get_in_progress_by_host(context, host, session=None):
 
3425
 
 
3426
    return model_query(context, models.Migration, session=session).\
 
3427
            filter(or_(models.Migration.source_compute == host,
 
3428
                       models.Migration.dest_compute == host)).\
 
3429
            filter(~models.Migration.status.in_(['confirmed', 'reverted'])).\
 
3430
            options(joinedload('instance')).\
 
3431
            all()
 
3432
 
 
3433
 
3761
3434
##################
3762
3435
 
3763
3436
 
3871
3544
        try:
3872
3545
            instance_type_get_by_flavor_id(context, values['flavorid'],
3873
3546
                                           session)
3874
 
            raise exception.InstanceTypeExists(name=values['name'])
 
3547
            raise exception.InstanceTypeIdExists(flavor_id=values['flavorid'])
3875
3548
        except exception.FlavorNotFound:
3876
3549
            pass
3877
3550
        try:
3893
3566
 
3894
3567
 
3895
3568
def _dict_with_extra_specs(inst_type_query):
3896
 
    """Takes an instance, volume, or instance type query returned
 
3569
    """Takes an instance or instance type query returned
3897
3570
    by sqlalchemy and returns it as a dictionary, converting the
3898
3571
    extra_specs entry from a list of dicts:
3899
3572
 
4157
3830
        try:
4158
3831
            meta_ref = instance_metadata_get_item(context, instance_uuid,
4159
3832
                                                  meta_key, session)
4160
 
        except exception.InstanceMetadataNotFound, e:
 
3833
        except exception.InstanceMetadataNotFound:
4161
3834
            meta_ref = models.InstanceMetadata()
4162
3835
            item.update({"key": meta_key, "instance_uuid": instance_uuid})
4163
3836
 
4188
3861
    return result
4189
3862
 
4190
3863
 
4191
 
@require_context
4192
 
def instance_system_metadata_delete(context, instance_uuid, key):
4193
 
    _instance_system_metadata_get_query(context, instance_uuid).\
4194
 
        filter_by(key=key).\
4195
 
        update({'deleted': True,
4196
 
                'deleted_at': timeutils.utcnow(),
4197
 
                'updated_at': literal_column('updated_at')})
4198
 
 
4199
 
 
4200
3864
def _instance_system_metadata_get_item(context, instance_uuid, key,
4201
3865
                                       session=None):
4202
3866
    result = _instance_system_metadata_get_query(
4239
3903
        try:
4240
3904
            meta_ref = _instance_system_metadata_get_item(
4241
3905
                    context, instance_uuid, meta_key, session)
4242
 
        except exception.InstanceSystemMetadataNotFound, e:
 
3906
        except exception.InstanceSystemMetadataNotFound:
4243
3907
            meta_ref = models.InstanceSystemMetadata()
4244
3908
            item.update({"key": meta_key, "instance_uuid": instance_uuid})
4245
3909
 
4305
3969
####################
4306
3970
 
4307
3971
@require_context
 
3972
def bw_usage_get(context, uuid, start_period, mac):
 
3973
    return model_query(context, models.BandwidthUsage, read_deleted="yes").\
 
3974
                      filter_by(start_period=start_period).\
 
3975
                      filter_by(uuid=uuid).\
 
3976
                      filter_by(mac=mac).\
 
3977
                      first()
 
3978
 
 
3979
 
 
3980
@require_context
4308
3981
def bw_usage_get_by_uuids(context, uuids, start_period):
4309
3982
    return model_query(context, models.BandwidthUsage, read_deleted="yes").\
4310
3983
                   filter(models.BandwidthUsage.uuid.in_(uuids)).\
4314
3987
 
4315
3988
@require_context
4316
3989
def bw_usage_update(context, uuid, mac, start_period, bw_in, bw_out,
4317
 
                    last_refreshed=None, session=None):
 
3990
                    last_ctr_in, last_ctr_out, last_refreshed=None,
 
3991
                    session=None):
4318
3992
    if not session:
4319
3993
        session = get_session()
4320
3994
 
4326
4000
    # records.  Fall back to creation when no rows are updated.
4327
4001
    with session.begin():
4328
4002
        values = {'last_refreshed': last_refreshed,
 
4003
                  'last_ctr_in': last_ctr_in,
 
4004
                  'last_ctr_out': last_ctr_out,
4329
4005
                  'bw_in': bw_in,
4330
4006
                  'bw_out': bw_out}
4331
4007
        rows = model_query(context, models.BandwidthUsage,
4344
4020
        bwusage.last_refreshed = last_refreshed
4345
4021
        bwusage.bw_in = bw_in
4346
4022
        bwusage.bw_out = bw_out
 
4023
        bwusage.last_ctr_in = last_ctr_in
 
4024
        bwusage.last_ctr_out = last_ctr_out
4347
4025
        bwusage.save(session=session)
4348
4026
 
4349
4027
 
4359
4037
              subquery()
4360
4038
    return model_query(context, models.InstanceTypeExtraSpecs,
4361
4039
                       session=session, read_deleted="no").\
4362
 
                       filter(models.InstanceTypeExtraSpecs.\
 
4040
                       filter(models.InstanceTypeExtraSpecs.
4363
4041
                              instance_type_id.in_(t))
4364
4042
 
4365
4043
 
4412
4090
        try:
4413
4091
            spec_ref = instance_type_extra_specs_get_item(
4414
4092
                context, flavor_id, key, session)
4415
 
        except exception.InstanceTypeExtraSpecsNotFound, e:
 
4093
        except exception.InstanceTypeExtraSpecsNotFound:
4416
4094
            spec_ref = models.InstanceTypeExtraSpecs()
4417
4095
        spec_ref.update({"key": key, "value": value,
4418
4096
                         "instance_type_id": instance_type["id"],
4421
4099
    return specs
4422
4100
 
4423
4101
 
4424
 
##################
4425
 
 
4426
 
 
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:
4431
 
 
4432
 
    {'extra_specs' : {'k1': 'v1', 'k2': 'v2', ...}}
4433
 
 
4434
 
    """
4435
 
    session = get_session()
4436
 
    with session.begin():
4437
 
        try:
4438
 
            volume_type_get_by_name(context, values['name'], session)
4439
 
            raise exception.VolumeTypeExists(name=values['name'])
4440
 
        except exception.VolumeTypeNotFoundByName:
4441
 
            pass
4442
 
        try:
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
4451
 
 
4452
 
 
4453
 
@require_context
4454
 
def volume_type_get_all(context, inactive=False, filters=None):
4455
 
    """
4456
 
    Returns a dict describing all volume_types with name as key.
4457
 
    """
4458
 
    filters = filters or {}
4459
 
 
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')).\
4464
 
                        order_by("name").\
4465
 
                        all()
4466
 
 
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
4469
 
    result = {}
4470
 
    for row in rows:
4471
 
        result[row['name']] = _dict_with_extra_specs(row)
4472
 
 
4473
 
    return result
4474
 
 
4475
 
 
4476
 
@require_context
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')).\
4481
 
                    filter_by(id=id).\
4482
 
                    first()
4483
 
 
4484
 
    if not result:
4485
 
        raise exception.VolumeTypeNotFound(volume_type_id=id)
4486
 
 
4487
 
    return _dict_with_extra_specs(result)
4488
 
 
4489
 
 
4490
 
@require_context
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).\
4496
 
                    first()
4497
 
 
4498
 
    if not result:
4499
 
        raise exception.VolumeTypeNotFoundByName(volume_type_name=name)
4500
 
    else:
4501
 
        return _dict_with_extra_specs(result)
4502
 
 
4503
 
 
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,
4509
 
                                                  session=session)
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')})
4521
 
 
4522
 
 
4523
 
@require_context
4524
 
def volume_get_active_by_window(context, begin, end=None,
4525
 
                                         project_id=None):
4526
 
    """Return volumes that were active during window."""
4527
 
    session = get_session()
4528
 
    query = session.query(models.Volume)
4529
 
 
4530
 
    query = query.filter(or_(models.Volume.deleted_at == None,
4531
 
                             models.Volume.deleted_at > begin))
4532
 
    if end:
4533
 
        query = query.filter(models.Volume.created_at < end)
4534
 
    if project_id:
4535
 
        query = query.filter_by(project_id=project_id)
4536
 
 
4537
 
    return query.all()
4538
 
 
4539
 
 
4540
 
####################
4541
 
 
4542
 
 
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)
4547
 
 
4548
 
 
4549
 
@require_context
4550
 
def volume_type_extra_specs_get(context, volume_type_id):
4551
 
    rows = _volume_type_extra_specs_query(context, volume_type_id).\
4552
 
                    all()
4553
 
 
4554
 
    result = {}
4555
 
    for row in rows:
4556
 
        result[row['key']] = row['value']
4557
 
 
4558
 
    return result
4559
 
 
4560
 
 
4561
 
@require_context
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')})
4568
 
 
4569
 
 
4570
 
@require_context
4571
 
def volume_type_extra_specs_get_item(context, volume_type_id, key,
4572
 
                                     session=None):
4573
 
    result = _volume_type_extra_specs_query(
4574
 
                                    context, volume_type_id, session=session).\
4575
 
                    filter_by(key=key).\
4576
 
                    first()
4577
 
 
4578
 
    if not result:
4579
 
        raise exception.VolumeTypeExtraSpecsNotFound(
4580
 
                   extra_specs_key=key, volume_type_id=volume_type_id)
4581
 
 
4582
 
    return result
4583
 
 
4584
 
 
4585
 
@require_context
4586
 
def volume_type_extra_specs_update_or_create(context, volume_type_id,
4587
 
                                             specs):
4588
 
    session = get_session()
4589
 
    spec_ref = None
4590
 
    for key, value in specs.iteritems():
4591
 
        try:
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,
4598
 
                         "deleted": False})
4599
 
        spec_ref.save(session=session)
4600
 
    return specs
4601
 
 
4602
 
 
4603
4102
####################
4604
4103
 
4605
4104
 
4642
4141
####################
4643
4142
 
4644
4143
 
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,
4651
 
                                   session=session,
4652
 
                                   read_deleted="yes").\
4653
 
                                   filter_by(config_params=config_params).\
4654
 
                                   first()
4655
 
 
4656
 
        if backend_conf:
4657
 
            raise exception.Duplicate(_('Backend exists'))
4658
 
        else:
4659
 
            backend_conf = models.SMBackendConf()
4660
 
            backend_conf.update(values)
4661
 
            backend_conf.save(session=session)
4662
 
    return backend_conf
4663
 
 
4664
 
 
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,
4670
 
                                   session=session,
4671
 
                                   read_deleted="yes").\
4672
 
                           filter_by(id=sm_backend_id).\
4673
 
                           first()
4674
 
 
4675
 
        if not backend_conf:
4676
 
            raise exception.NotFound(
4677
 
                _("No backend config with id %(sm_backend_id)s") % locals())
4678
 
 
4679
 
        backend_conf.update(values)
4680
 
        backend_conf.save(session=session)
4681
 
    return backend_conf
4682
 
 
4683
 
 
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).\
4693
 
                delete()
4694
 
 
4695
 
 
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).\
4700
 
                     first()
4701
 
 
4702
 
    if not result:
4703
 
        raise exception.NotFound(_("No backend config with id "
4704
 
                                   "%(sm_backend_id)s") % locals())
4705
 
 
4706
 
    return result
4707
 
 
4708
 
 
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).\
4713
 
                         first()
4714
 
    if not result:
4715
 
        raise exception.NotFound(_("No backend config with sr uuid "
4716
 
                                   "%(sr_uuid)s") % locals())
4717
 
    return result
4718
 
 
4719
 
 
4720
 
@require_admin_context
4721
 
def sm_backend_conf_get_all(context):
4722
 
    return model_query(context, models.SMBackendConf, read_deleted="yes").\
4723
 
                    all()
4724
 
 
4725
 
 
4726
 
####################
4727
 
 
4728
 
 
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)
4733
 
 
4734
 
 
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,
4740
 
                                   session=session,
4741
 
                                   read_deleted="yes").\
4742
 
                           filter_by(label=values['label']).\
4743
 
                           first()
4744
 
        if not sm_flavor:
4745
 
            sm_flavor = models.SMFlavors()
4746
 
            sm_flavor.update(values)
4747
 
            sm_flavor.save(session=session)
4748
 
        else:
4749
 
            raise exception.Duplicate(_('Flavor exists'))
4750
 
    return sm_flavor
4751
 
 
4752
 
 
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,
4758
 
                                   session=session,
4759
 
                                   read_deleted="yes").\
4760
 
                           filter_by(id=sm_flavor_id).\
4761
 
                           first()
4762
 
        if not sm_flavor:
4763
 
            raise exception.NotFound(
4764
 
                    _('%(sm_flavor_id) flavor not found') % locals())
4765
 
        sm_flavor.update(values)
4766
 
        sm_flavor.save(session=session)
4767
 
    return sm_flavor
4768
 
 
4769
 
 
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()
4775
 
 
4776
 
 
4777
 
@require_admin_context
4778
 
def sm_flavor_get(context, sm_flavor_id):
4779
 
    result = _sm_flavor_get_query(context, sm_flavor_id).first()
4780
 
 
4781
 
    if not result:
4782
 
        raise exception.NotFound(
4783
 
                _("No sm_flavor called %(sm_flavor_id)s") % locals())
4784
 
 
4785
 
    return result
4786
 
 
4787
 
 
4788
 
@require_admin_context
4789
 
def sm_flavor_get_all(context):
4790
 
    return model_query(context, models.SMFlavors, read_deleted="yes").all()
4791
 
 
4792
 
 
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()
4798
 
    if not result:
4799
 
        raise exception.NotFound(
4800
 
                _("No sm_flavor called %(sm_flavor_label)s") % locals())
4801
 
    return result
4802
 
 
4803
 
 
4804
 
###############################
4805
 
 
4806
 
 
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)
4811
 
 
4812
 
 
4813
 
def sm_volume_create(context, values):
4814
 
    sm_volume = models.SMVolume()
4815
 
    sm_volume.update(values)
4816
 
    sm_volume.save()
4817
 
    return sm_volume
4818
 
 
4819
 
 
4820
 
def sm_volume_update(context, volume_id, values):
4821
 
    sm_volume = sm_volume_get(context, volume_id)
4822
 
    sm_volume.update(values)
4823
 
    sm_volume.save()
4824
 
    return sm_volume
4825
 
 
4826
 
 
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()
4831
 
 
4832
 
 
4833
 
def sm_volume_get(context, volume_id):
4834
 
    result = _sm_volume_get_query(context, volume_id).first()
4835
 
 
4836
 
    if not result:
4837
 
        raise exception.NotFound(
4838
 
                _("No sm_volume with id %(volume_id)s") % locals())
4839
 
 
4840
 
    return result
4841
 
 
4842
 
 
4843
 
def sm_volume_get_all(context):
4844
 
    return model_query(context, models.SMVolume, read_deleted="yes").all()
4845
 
 
4846
 
 
4847
 
################
4848
 
 
4849
 
 
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,
4951
4245
        raise exception.AggregateNotFound(aggregate_id=aggregate_id)
4952
4246
 
4953
4247
    #Delete Metadata
4954
 
    rows = model_query(context,
4955
 
                       models.AggregateMetadata).\
4956
 
                       filter_by(aggregate_id=aggregate_id).\
4957
 
                       update({'deleted': True,
4958
 
                      'deleted_at': timeutils.utcnow(),
4959
 
                      'updated_at': literal_column('updated_at')})
 
4248
    model_query(context,
 
4249
                models.AggregateMetadata).\
 
4250
                filter_by(aggregate_id=aggregate_id).\
 
4251
                update({'deleted': True,
 
4252
                'deleted_at': timeutils.utcnow(),
 
4253
                'updated_at': literal_column('updated_at')})
4960
4254
 
4961
4255
 
4962
4256
@require_admin_context
5167
4461
@require_context
5168
4462
def _ec2_instance_get_query(context, session=None):
5169
4463
    return model_query(context,
5170
 
                       models.InstanceIdMapping, 
 
4464
                       models.InstanceIdMapping,
5171
4465
                       session=session,
5172
4466
                       read_deleted='yes')
5173
4467