Files
placement/nova/db/sqlalchemy/api.py
2010-08-31 16:48:41 -07:00

570 lines
18 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from nova import db
from nova import exception
from nova import flags
from nova.db.sqlalchemy import models
from nova.db.sqlalchemy.session import managed_session
from sqlalchemy import or_
FLAGS = flags.FLAGS
###################
def daemon_get(context, daemon_id):
return models.Daemon.find(daemon_id)
def daemon_get_by_args(context, host, binary):
return models.Daemon.find_by_args(host, binary)
def daemon_create(context, values):
daemon_ref = models.Daemon()
for (key, value) in values.iteritems():
daemon_ref[key] = value
daemon_ref.save()
return daemon_ref.id
def daemon_update(context, daemon_id, values):
daemon_ref = daemon_get(context, daemon_id)
for (key, value) in values.iteritems():
daemon_ref[key] = value
daemon_ref.save()
###################
def floating_ip_allocate_address(context, host, project_id):
with managed_session(autocommit=False) as session:
floating_ip_ref = session.query(models.FloatingIp) \
.filter_by(host=host) \
.filter_by(fixed_ip_id=None) \
.filter_by(deleted=False) \
.with_lockmode('update') \
.first()
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
# then this has concurrency issues
if not floating_ip_ref:
raise db.NoMoreAddresses()
floating_ip_ref['project_id'] = project_id
session.add(floating_ip_ref)
session.commit()
return floating_ip_ref['address']
def floating_ip_create(context, address, host):
floating_ip_ref = models.FloatingIp()
floating_ip_ref['address'] = address
floating_ip_ref['host'] = host
floating_ip_ref.save()
return floating_ip_ref
def floating_ip_fixed_ip_associate(context, floating_address, fixed_address):
with managed_session(autocommit=False) as session:
floating_ip_ref = models.FloatingIp.find_by_str(floating_address,
session=session)
fixed_ip_ref = models.FixedIp.find_by_str(fixed_address,
session=session)
floating_ip_ref.fixed_ip = fixed_ip_ref
floating_ip_ref.save(session=session)
session.commit()
def floating_ip_disassociate(context, address):
with managed_session(autocommit=False) as session:
floating_ip_ref = models.FloatingIp.find_by_str(address,
session=session)
fixed_ip_ref = floating_ip_ref.fixed_ip
if fixed_ip_ref:
fixed_ip_address = fixed_ip_ref['address']
else:
fixed_ip_address = None
floating_ip_ref.fixed_ip = None
floating_ip_ref.save(session=session)
session.commit()
return fixed_ip_address
def floating_ip_deallocate(context, address):
with managed_session(autocommit=False) as session:
floating_ip_ref = models.FloatingIp.find_by_str(address,
session=session)
floating_ip_ref['project_id'] = None
floating_ip_ref.save(session=session)
def floating_ip_get_by_address(context, address):
return models.FloatingIp.find_by_str(address)
def floating_ip_get_instance(context, address):
with managed_session() as session:
floating_ip_ref = models.FloatingIp.find_by_str(address,
session=session)
return floating_ip_ref.fixed_ip.instance
###################
def fixed_ip_allocate(context, network_id):
with managed_session(autocommit=False) as session:
network_or_none = or_(models.FixedIp.network_id == network_id,
models.FixedIp.network_id == None)
fixed_ip_ref = session.query(models.FixedIp) \
.filter(network_or_none) \
.filter_by(reserved=False) \
.filter_by(allocated=False) \
.filter_by(leased=False) \
.filter_by(deleted=False) \
.with_lockmode('update') \
.first()
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
# then this has concurrency issues
if not fixed_ip_ref:
raise db.NoMoreAddresses()
if not fixed_ip_ref.network:
fixed_ip_ref.network = models.Network.find(network_id)
fixed_ip_ref['allocated'] = True
session.add(fixed_ip_ref)
session.commit()
return fixed_ip_ref['address']
def fixed_ip_create(context, values):
fixed_ip_ref = models.FixedIp()
for (key, value) in values.iteritems():
fixed_ip_ref[key] = value
fixed_ip_ref.save()
return fixed_ip_ref['address']
def fixed_ip_get_by_address(context, address):
return models.FixedIp.find_by_str(address)
def fixed_ip_get_instance(context, address):
with managed_session() as session:
return models.FixedIp.find_by_str(address, session=session).instance
def fixed_ip_get_network(context, address):
with managed_session() as session:
return models.FixedIp.find_by_str(address, session=session).network
def fixed_ip_deallocate(context, address):
fixed_ip_ref = fixed_ip_get_by_address(context, address)
fixed_ip_ref['allocated'] = False
fixed_ip_ref.save()
def fixed_ip_instance_associate(context, address, instance_id):
with managed_session(autocommit=False) as session:
fixed_ip_ref = models.FixedIp.find_by_str(address, session=session)
instance_ref = models.Instance.find(instance_id, session=session)
fixed_ip_ref.instance = instance_ref
fixed_ip_ref.save(session=session)
session.commit()
def fixed_ip_instance_disassociate(context, address):
with managed_session(autocommit=False) as session:
fixed_ip_ref = models.FixedIp.find_by_str(address, session=session)
fixed_ip_ref.instance = None
fixed_ip_ref.save(session=session)
session.commit()
def fixed_ip_update(context, address, values):
fixed_ip_ref = fixed_ip_get_by_address(context, address)
for (key, value) in values.iteritems():
fixed_ip_ref[key] = value
fixed_ip_ref.save()
###################
def instance_create(context, values):
instance_ref = models.Instance()
for (key, value) in values.iteritems():
instance_ref[key] = value
instance_ref.save()
return instance_ref.id
def instance_destroy(context, instance_id):
instance_ref = instance_get(context, instance_id)
instance_ref.delete()
def instance_get(context, instance_id):
return models.Instance.find(instance_id)
def instance_get_all(context):
return models.Instance.all()
def instance_get_by_project(context, project_id):
with managed_session() as session:
return session.query(models.Instance) \
.filter_by(project_id=project_id) \
.filter_by(deleted=False) \
.all()
def instance_get_by_reservation(context, reservation_id):
with managed_session() as session:
return session.query(models.Instance) \
.filter_by(reservation_id=reservation_id) \
.filter_by(deleted=False) \
.all()
def instance_get_by_str(context, str_id):
return models.Instance.find_by_str(str_id)
def instance_get_fixed_address(context, instance_id):
with managed_session() as session:
instance_ref = models.Instance.find(instance_id, session=session)
if not instance_ref.fixed_ip:
return None
return instance_ref.fixed_ip['address']
def instance_get_floating_address(context, instance_id):
with managed_session() as session:
instance_ref = models.Instance.find(instance_id, session=session)
if not instance_ref.fixed_ip:
return None
if not instance_ref.fixed_ip.floating_ips:
return None
# NOTE(vish): this just returns the first floating ip
return instance_ref.fixed_ip.floating_ips[0]['address']
def instance_get_host(context, instance_id):
instance_ref = instance_get(context, instance_id)
return instance_ref['host']
def instance_is_vpn(context, instance_id):
instance_ref = instance_get(context, instance_id)
return instance_ref['image_id'] == FLAGS.vpn_image_id
def instance_state(context, instance_id, state, description=None):
instance_ref = instance_get(context, instance_id)
instance_ref.set_state(state, description)
def instance_update(context, instance_id, values):
instance_ref = instance_get(context, instance_id)
for (key, value) in values.iteritems():
instance_ref[key] = value
instance_ref.save()
###################
def network_count(context):
return models.Network.count()
def network_count_allocated_ips(context, network_id):
with managed_session() as session:
return session.query(models.FixedIp) \
.filter_by(network_id=network_id) \
.filter_by(allocated=True) \
.filter_by(deleted=False) \
.count()
def network_count_available_ips(context, network_id):
with managed_session() as session:
return session.query(models.FixedIp) \
.filter_by(network_id=network_id) \
.filter_by(allocated=False) \
.filter_by(reserved=False) \
.filter_by(deleted=False) \
.count()
def network_count_reserved_ips(context, network_id):
with managed_session() as session:
return session.query(models.FixedIp) \
.filter_by(network_id=network_id) \
.filter_by(reserved=True) \
.filter_by(deleted=False) \
.count()
def network_create(context, values):
network_ref = models.Network()
for (key, value) in values.iteritems():
network_ref[key] = value
network_ref.save()
return network_ref
def network_destroy(context, network_id):
with managed_session(autocommit=False) as session:
# TODO(vish): do we have to use sql here?
session.execute('update networks set deleted=1 where id=:id',
{'id': network_id})
session.execute('update fixed_ips set deleted=1 where network_id=:id',
{'id': network_id})
session.execute('update floating_ips set deleted=1 '
'where fixed_ip_id in '
'(select id from fixed_ips '
'where network_id=:id)',
{'id': network_id})
session.execute('update network_indexes set network_id=NULL '
'where network_id=:id',
{'id': network_id})
session.commit()
def network_get(context, network_id):
return models.Network.find(network_id)
def network_get_associated_fixed_ips(context, network_id):
with managed_session() as session:
return session.query(models.FixedIp) \
.filter(models.FixedIp.instance_id != None) \
.filter_by(deleted=False) \
.all()
def network_get_by_bridge(context, bridge):
with managed_session() as session:
rv = session.query(models.Network) \
.filter_by(bridge=bridge) \
.filter_by(deleted=False) \
.first()
if not rv:
raise exception.NotFound('No network for bridge %s' % bridge)
return rv
def network_get_host(context, network_id):
network_ref = network_get(context, network_id)
return network_ref['host']
def network_get_index(context, network_id):
with managed_session(autocommit=False) as session:
network_index = session.query(models.NetworkIndex) \
.filter_by(network_id=None) \
.filter_by(deleted=False) \
.with_lockmode('update') \
.first()
if not network_index:
raise db.NoMoreNetworks()
network_index['network'] = models.Network.find(network_id,
session=session)
session.add(network_index)
session.commit()
return network_index['index']
def network_index_count(context):
return models.NetworkIndex.count()
def network_index_create(context, values):
network_index_ref = models.NetworkIndex()
for (key, value) in values.iteritems():
network_index_ref[key] = value
network_index_ref.save()
def network_set_host(context, network_id, host_id):
with managed_session(autocommit=False) as session:
network = session.query(models.Network) \
.filter_by(id=network_id) \
.filter_by(deleted=False) \
.with_lockmode('update') \
.first()
if not network:
raise exception.NotFound("Couldn't find network with %s" %
network_id)
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
# then this has concurrency issues
if network.host:
session.commit()
return network['host']
network['host'] = host_id
session.add(network)
session.commit()
return network['host']
def network_update(context, network_id, values):
network_ref = network_get(context, network_id)
for (key, value) in values.iteritems():
network_ref[key] = value
network_ref.save()
###################
def project_get_network(context, project_id):
with managed_session() as session:
rv = session.query(models.Network) \
.filter_by(project_id=project_id) \
.filter_by(deleted=False) \
.first()
if not rv:
raise exception.NotFound('No network for project: %s' % project_id)
return rv
###################
def queue_get_for(context, topic, physical_node_id):
# FIXME(ja): this should be servername?
return "%s.%s" % (topic, physical_node_id)
###################
def export_device_count(context):
return models.ExportDevice.count()
def export_device_create(context, values):
export_device_ref = models.ExportDevice()
for (key, value) in values.iteritems():
export_device_ref[key] = value
export_device_ref.save()
return export_device_ref
###################
def volume_allocate_shelf_and_blade(context, volume_id):
with managed_session(autocommit=False) as session:
export_device = session.query(models.ExportDevice) \
.filter_by(volume=None) \
.filter_by(deleted=False) \
.with_lockmode('update') \
.first()
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
# then this has concurrency issues
if not export_device:
raise db.NoMoreBlades()
export_device.volume_id = volume_id
session.add(export_device)
session.commit()
return (export_device.shelf_id, export_device.blade_id)
def volume_attached(context, volume_id, instance_id, mountpoint):
volume_ref = volume_get(context, volume_id)
volume_ref.instance_id = instance_id
volume_ref['status'] = 'in-use'
volume_ref['mountpoint'] = mountpoint
volume_ref['attach_status'] = 'attached'
volume_ref.save()
def volume_create(context, values):
volume_ref = models.Volume()
for (key, value) in values.iteritems():
volume_ref[key] = value
volume_ref.save()
return volume_ref
def volume_destroy(context, volume_id):
with managed_session(autocommit=False) as session:
# TODO(vish): do we have to use sql here?
session.execute('update volumes set deleted=1 where id=:id',
{'id': volume_id})
session.execute('update export_devices set volume_id=NULL '
'where volume_id=:id',
{'id': volume_id})
session.commit()
def volume_detached(context, volume_id):
volume_ref = volume_get(context, volume_id)
volume_ref['instance_id'] = None
volume_ref['mountpoint'] = None
volume_ref['status'] = 'available'
volume_ref['attach_status'] = 'detached'
volume_ref.save()
def volume_get(context, volume_id):
return models.Volume.find(volume_id)
def volume_get_all(context):
return models.Volume.all()
def volume_get_by_project(context, project_id):
with managed_session() as session:
return session.query(models.Volume) \
.filter_by(project_id=project_id) \
.filter_by(deleted=False) \
.all()
def volume_get_by_str(context, str_id):
return models.Volume.find_by_str(str_id)
def volume_get_host(context, volume_id):
volume_ref = volume_get(context, volume_id)
return volume_ref['host']
def volume_get_shelf_and_blade(context, volume_id):
with managed_session() as session:
export_device = session.query(models.ExportDevice) \
.filter_by(volume_id=volume_id) \
.first()
if not export_device:
raise exception.NotFound()
return (export_device.shelf_id, export_device.blade_id)
def volume_update(context, volume_id, values):
volume_ref = volume_get(context, volume_id)
for (key, value) in values.iteritems():
volume_ref[key] = value
volume_ref.save()