rename node_name to host

This commit is contained in:
Vishvananda Ishaya 2010-08-31 16:48:41 -07:00
parent ea958aa57f
commit 2c16344cfe
14 changed files with 163 additions and 89 deletions

View File

@ -74,7 +74,7 @@ class ComputeManager(manager.Manager):
self.network_manager.setup_compute_network(context, project_id)
db.instance_update(context,
instance_id,
{'node_name': FLAGS.node_name})
{'host': FLAGS.host})
# TODO(vish) check to make sure the availability zone matches
db.instance_state(context,

View File

@ -1,3 +1,23 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# 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.
"""
DB abstraction for Nova
"""
from nova.db.api import *

View File

@ -15,11 +15,13 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Defines interface for DB access
"""
from nova import exception
from nova import flags
from nova import utils
from nova import validate
FLAGS = flags.FLAGS
@ -33,14 +35,17 @@ _impl = utils.LazyPluggable(FLAGS['db_backend'],
# TODO(vish): where should these exceptions go?
class NoMoreAddresses(exception.Error):
"""No more available addresses"""
pass
class NoMoreBlades(exception.Error):
"""No more available blades"""
pass
class NoMoreNetworks(exception.Error):
"""No more available networks"""
pass
@ -52,9 +57,9 @@ def daemon_get(context, daemon_id):
return _impl.daemon_get(context, daemon_id)
def daemon_get_by_args(context, node_name, binary):
def daemon_get_by_args(context, host, binary):
"""Get the state of an daemon by node name and binary."""
return _impl.daemon_get_by_args(context, node_name, binary)
return _impl.daemon_get_by_args(context, host, binary)
def daemon_create(context, values):
@ -74,12 +79,12 @@ def daemon_update(context, daemon_id, values):
###################
def floating_ip_allocate_address(context, node_name, project_id):
def floating_ip_allocate_address(context, host, project_id):
"""Allocate free floating ip and return the address.
Raises if one is not available.
"""
return _impl.floating_ip_allocate_address(context, node_name, project_id)
return _impl.floating_ip_allocate_address(context, host, project_id)
def floating_ip_create(context, address, host):

View File

@ -1,3 +1,24 @@
from models import register_models
# vim: tabstop=4 shiftwidth=4 softtabstop=4
register_models()
# 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.
"""
SQLAlchemy database backend
"""
from nova.db.sqlalchemy import models
models.register_models()

View File

@ -33,8 +33,8 @@ def daemon_get(context, daemon_id):
return models.Daemon.find(daemon_id)
def daemon_get_by_args(context, node_name, binary):
return models.Daemon.find_by_args(node_name, binary)
def daemon_get_by_args(context, host, binary):
return models.Daemon.find_by_args(host, binary)
def daemon_create(context, values):
@ -55,10 +55,10 @@ def daemon_update(context, daemon_id, values):
###################
def floating_ip_allocate_address(context, node_name, project_id):
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(node_name=node_name) \
.filter_by(host=host) \
.filter_by(fixed_ip_id=None) \
.filter_by(deleted=False) \
.with_lockmode('update') \
@ -76,7 +76,7 @@ def floating_ip_allocate_address(context, node_name, project_id):
def floating_ip_create(context, address, host):
floating_ip_ref = models.FloatingIp()
floating_ip_ref['address'] = address
floating_ip_ref['node_name'] = host
floating_ip_ref['host'] = host
floating_ip_ref.save()
return floating_ip_ref
@ -131,8 +131,8 @@ def floating_ip_get_instance(context, address):
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)
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) \
@ -270,7 +270,7 @@ def instance_get_floating_address(context, instance_id):
def instance_get_host(context, instance_id):
instance_ref = instance_get(context, instance_id)
return instance_ref['node_name']
return instance_ref['host']
def instance_is_vpn(context, instance_id):
@ -376,7 +376,7 @@ def network_get_by_bridge(context, bridge):
def network_get_host(context, network_id):
network_ref = network_get(context, network_id)
return network_ref['node_name']
return network_ref['host']
def network_get_index(context, network_id):
@ -418,13 +418,13 @@ def network_set_host(context, network_id, host_id):
network_id)
# NOTE(vish): if with_lockmode isn't supported, as in sqlite,
# then this has concurrency issues
if network.node_name:
if network.host:
session.commit()
return network['node_name']
network['node_name'] = host_id
return network['host']
network['host'] = host_id
session.add(network)
session.commit()
return network['node_name']
return network['host']
def network_update(context, network_id, values):
@ -549,7 +549,7 @@ def volume_get_by_str(context, str_id):
def volume_get_host(context, volume_id):
volume_ref = volume_get(context, volume_id)
return volume_ref['node_name']
return volume_ref['host']
def volume_get_shelf_and_blade(context, volume_id):

View File

@ -20,23 +20,25 @@
SQLAlchemy models for nova data
"""
# TODO(vish): clean up these imports
from sqlalchemy.orm import relationship, backref, validates, exc
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy import MetaData, ForeignKey, DateTime, Boolean, Text
from sqlalchemy import Column, Integer, String
from sqlalchemy import ForeignKey, DateTime, Boolean, Text
from sqlalchemy.ext.declarative import declarative_base
from nova.db.sqlalchemy.session import managed_session
from nova import auth
from nova import exception
from nova import flags
FLAGS = flags.FLAGS
Base = declarative_base()
BASE = declarative_base()
class NovaBase(object):
"""Base class for Nova Models"""
__table_args__ = {'mysql_engine': 'InnoDB'}
__table_initialized__ = False
__prefix__ = 'none'
@ -46,6 +48,7 @@ class NovaBase(object):
@classmethod
def all(cls, session=None):
"""Get all objects of this type"""
if session:
return session.query(cls) \
.filter_by(deleted=False) \
@ -56,6 +59,7 @@ class NovaBase(object):
@classmethod
def count(cls, session=None):
"""Count objects of this type"""
if session:
return session.query(cls) \
.filter_by(deleted=False) \
@ -66,6 +70,7 @@ class NovaBase(object):
@classmethod
def find(cls, obj_id, session=None):
"""Find object by id"""
if session:
try:
return session.query(cls) \
@ -80,14 +85,17 @@ class NovaBase(object):
@classmethod
def find_by_str(cls, str_id, session=None):
id = int(str_id.rpartition('-')[2])
return cls.find(id, session=session)
"""Find object by str_id"""
int_id = int(str_id.rpartition('-')[2])
return cls.find(int_id, session=session)
@property
def str_id(self):
"""Get string id of object (generally prefix + '-' + id)"""
return "%s-%s" % (self.__prefix__, self.id)
def save(self, session=None):
"""Save this object"""
if session:
session.add(self)
session.flush()
@ -96,6 +104,7 @@ class NovaBase(object):
self.save(session=sess)
def delete(self, session=None):
"""Delete this object"""
self.deleted = True
self.save(session=session)
@ -106,7 +115,8 @@ class NovaBase(object):
return getattr(self, key)
class Image(Base, NovaBase):
class Image(BASE, NovaBase):
"""Represents an image in the datastore"""
__tablename__ = 'images'
__prefix__ = 'ami'
id = Column(Integer, primary_key=True)
@ -139,36 +149,39 @@ class Image(Base, NovaBase):
assert(val is None)
class PhysicalNode(Base, NovaBase):
__tablename__ = 'physical_nodes'
class Host(BASE, NovaBase):
"""Represents a host where services are running"""
__tablename__ = 'hosts'
id = Column(String(255), primary_key=True)
class Daemon(Base, NovaBase):
class Daemon(BASE, NovaBase):
"""Represents a running service on a host"""
__tablename__ = 'daemons'
id = Column(Integer, primary_key=True)
node_name = Column(String(255)) # , ForeignKey('physical_node.id'))
host = Column(String(255), ForeignKey('hosts.id'))
binary = Column(String(255))
report_count = Column(Integer, nullable=False, default=0)
@classmethod
def find_by_args(cls, node_name, binary, session=None):
def find_by_args(cls, host, binary, session=None):
if session:
try:
return session.query(cls) \
.filter_by(node_name=node_name) \
.filter_by(host=host) \
.filter_by(binary=binary) \
.filter_by(deleted=False) \
.one()
except exc.NoResultFound:
raise exception.NotFound("No model for %s, %s" % (node_name,
raise exception.NotFound("No model for %s, %s" % (host,
binary))
else:
with managed_session() as sess:
return cls.find_by_args(node_name, binary, session=sess)
return cls.find_by_args(host, binary, session=sess)
class Instance(Base, NovaBase):
class Instance(BASE, NovaBase):
"""Represents a guest vm"""
__tablename__ = 'instances'
__prefix__ = 'i'
id = Column(Integer, primary_key=True)
@ -191,6 +204,9 @@ class Instance(Base, NovaBase):
image_id = Column(Integer, ForeignKey('images.id'), nullable=True)
kernel_id = Column(Integer, ForeignKey('images.id'), nullable=True)
ramdisk_id = Column(Integer, ForeignKey('images.id'), nullable=True)
# ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id))
# kernel = relationship(Kernel, backref=backref('instances', order_by=id))
# project = relationship(Project, backref=backref('instances', order_by=id))
launch_index = Column(Integer)
key_name = Column(String(255))
@ -201,7 +217,7 @@ class Instance(Base, NovaBase):
state_description = Column(String(255))
hostname = Column(String(255))
node_name = Column(String(255)) # , ForeignKey('physical_node.id'))
host = Column(String(255), ForeignKey('hosts.id'))
instance_type = Column(Integer)
@ -211,17 +227,17 @@ class Instance(Base, NovaBase):
mac_address = Column(String(255))
def set_state(self, state_code, state_description=None):
# TODO(devcamcar): Move this out of models and into api
"""Set the code and description of an instance"""
# TODO(devcamcar): Move this out of models and into driver
from nova.compute import power_state
self.state = state_code
if not state_description:
state_description = power_state.name(state_code)
self.state_description = state_description
self.save()
# ramdisk = relationship(Ramdisk, backref=backref('instances', order_by=id))
# kernel = relationship(Kernel, backref=backref('instances', order_by=id))
# project = relationship(Project, backref=backref('instances', order_by=id))
#TODO - see Ewan's email about state improvements
# TODO(vish): see Ewan's email about state improvements, probably
# should be in a driver base class or some such
# vmstate_state = running, halted, suspended, paused
# power_state = what we have
# task_state = transitory and may trigger power state transition
@ -232,7 +248,8 @@ class Instance(Base, NovaBase):
# 'shutdown', 'shutoff', 'crashed'])
class Volume(Base, NovaBase):
class Volume(BASE, NovaBase):
"""Represents a block storage device that can be attached to a vm"""
__tablename__ = 'volumes'
__prefix__ = 'vol'
id = Column(Integer, primary_key=True)
@ -240,7 +257,7 @@ class Volume(Base, NovaBase):
user_id = Column(String(255))
project_id = Column(String(255))
node_name = Column(String(255)) # , ForeignKey('physical_node.id'))
host = Column(String(255), ForeignKey('hosts.id'))
size = Column(Integer)
availability_zone = Column(String(255)) # TODO(vish): foreign key?
instance_id = Column(Integer, ForeignKey('instances.id'), nullable=True)
@ -250,7 +267,8 @@ class Volume(Base, NovaBase):
attach_status = Column(String(255)) # TODO(vish): enum
class ExportDevice(Base, NovaBase):
class ExportDevice(BASE, NovaBase):
"""Represates a shelf and blade that a volume can be exported on"""
__tablename__ = 'export_devices'
id = Column(Integer, primary_key=True)
shelf_id = Column(Integer)
@ -260,7 +278,8 @@ class ExportDevice(Base, NovaBase):
uselist=False))
class Network(Base, NovaBase):
class Network(BASE, NovaBase):
"""Represents a network"""
__tablename__ = 'networks'
id = Column(Integer, primary_key=True)
@ -279,10 +298,16 @@ class Network(Base, NovaBase):
dhcp_start = Column(String(255))
project_id = Column(String(255))
node_name = Column(String(255)) # , ForeignKey('physical_node.id'))
host = Column(String(255), ForeignKey('hosts.id'))
class NetworkIndex(Base, NovaBase):
class NetworkIndex(BASE, NovaBase):
"""Represents a unique offset for a network
Currently vlan number, vpn port, and fixed ip ranges are keyed off of
this index. These may ultimately need to be converted to separate
pools.
"""
__tablename__ = 'network_indexes'
id = Column(Integer, primary_key=True)
index = Column(Integer)
@ -292,7 +317,8 @@ class NetworkIndex(Base, NovaBase):
# TODO(vish): can these both come from the same baseclass?
class FixedIp(Base, NovaBase):
class FixedIp(BASE, NovaBase):
"""Represents a fixed ip for an instance"""
__tablename__ = 'fixed_ips'
id = Column(Integer, primary_key=True)
address = Column(String(255))
@ -324,7 +350,8 @@ class FixedIp(Base, NovaBase):
return cls.find_by_str(str_id, session=sess)
class FloatingIp(Base, NovaBase):
class FloatingIp(BASE, NovaBase):
"""Represents a floating ip that dynamically forwards to a fixed ip"""
__tablename__ = 'floating_ips'
id = Column(Integer, primary_key=True)
address = Column(String(255))
@ -332,7 +359,7 @@ class FloatingIp(Base, NovaBase):
fixed_ip = relationship(FixedIp, backref=backref('floating_ips'))
project_id = Column(String(255))
node_name = Column(String(255)) # , ForeignKey('physical_node.id'))
host = Column(String(255), ForeignKey('hosts.id'))
@property
def str_id(self):
@ -354,8 +381,9 @@ class FloatingIp(Base, NovaBase):
def register_models():
"""Register Models and create metadata"""
from sqlalchemy import create_engine
models = (Image, PhysicalNode, Daemon, Instance, Volume, ExportDevice,
models = (Image, Host, Daemon, Instance, Volume, ExportDevice,
FixedIp, FloatingIp, Network, NetworkIndex)
engine = create_engine(FLAGS.sql_connection, echo=False)
for model in models:

View File

@ -230,7 +230,7 @@ class CloudController(object):
# instance_id is passed in as a list of instances
instance_ref = db.instance_get_by_str(context, instance_id[0])
return rpc.call('%s.%s' % (FLAGS.compute_topic,
instance_ref['node_name']),
instance_ref['host']),
{"method": "get_console_output",
"args": {"context": None,
"instance_id": instance_ref['id']}})
@ -257,7 +257,7 @@ class CloudController(object):
v['status'] = '%s (%s, %s, %s, %s)' % (
volume['status'],
volume['user_id'],
'node_name',
'host',
volume['instance_id'],
volume['mountpoint'])
if volume['attach_status'] == 'attached':
@ -391,7 +391,7 @@ class CloudController(object):
if context.user.is_admin():
i['key_name'] = '%s (%s, %s)' % (i['key_name'],
instance.project_id,
'node_name') # FIXME
'host') # FIXME
i['product_codes_set'] = self._convert_to_set([], 'product_codes')
i['instance_type'] = instance.instance_type
i['launch_time'] = instance.created_at

View File

@ -206,7 +206,7 @@ DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger')
# UNUSED
DEFINE_string('node_availability_zone', 'nova',
'availability zone of this node')
DEFINE_string('node_name', socket.gethostname(),
DEFINE_string('host', socket.gethostname(),
'name of this node')
DEFINE_string('sql_connection',

View File

@ -93,7 +93,7 @@ class NetworkManager(manager.Manager):
network_id = network_ref['id']
host = self.db.network_set_host(context,
network_id,
FLAGS.node_name)
FLAGS.host)
self._on_set_network_host(context, network_id)
return host
@ -117,7 +117,7 @@ class NetworkManager(manager.Manager):
"""Gets an floating ip from the pool"""
# TODO(vish): add floating ips through manage command
return self.db.floating_ip_allocate_address(context,
FLAGS.node_name,
FLAGS.host,
project_id)
def associate_floating_ip(self, context, floating_address, fixed_address):

View File

@ -89,11 +89,11 @@ class Service(object, service.Service):
proxy=service_ref)
consumer_node = rpc.AdapterConsumer(
connection=conn,
topic='%s.%s' % (topic, FLAGS.node_name),
topic='%s.%s' % (topic, FLAGS.host),
proxy=service_ref)
pulse = task.LoopingCall(service_ref.report_state,
FLAGS.node_name,
FLAGS.host,
bin_name)
pulse.start(interval=report_interval, now=False)
@ -107,14 +107,14 @@ class Service(object, service.Service):
return application
@defer.inlineCallbacks
def report_state(self, node_name, binary, context=None):
def report_state(self, host, binary, context=None):
"""Update the state of this daemon in the datastore."""
try:
try:
daemon_ref = db.daemon_get_by_args(context, node_name, binary)
daemon_ref = db.daemon_get_by_args(context, host, binary)
daemon_id = daemon_ref['id']
except exception.NotFound:
daemon_id = db.daemon_create(context, {'node_name': node_name,
daemon_id = db.daemon_create(context, {'host': host,
'binary': binary,
'report_count': 0})
daemon_ref = db.daemon_get(context, daemon_id)

View File

@ -108,14 +108,14 @@ class ModelTestCase(test.TrialTestCase):
self.assertEqual(x.identifier, 'i-test')
def test_instance_associates_node(self):
"""create, then check that it is listed for the node_name"""
"""create, then check that it is listed for the host"""
instance = self.create_instance()
found = False
for x in model.InstanceDirectory().by_node(FLAGS.node_name):
for x in model.InstanceDirectory().by_node(FLAGS.host):
if x.identifier == 'i-test':
found = True
self.assertFalse(found)
instance['node_name'] = 'test_node'
instance['host'] = 'test_node'
instance.save()
for x in model.InstanceDirectory().by_node('test_node'):
if x.identifier == 'i-test':

View File

@ -91,7 +91,7 @@ class NetworkTestCase(test.TrialTestCase):
try:
db.floating_ip_get_by_address(None, ip_str)
except exception.NotFound:
db.floating_ip_create(None, ip_str, FLAGS.node_name)
db.floating_ip_create(None, ip_str, FLAGS.host)
float_addr = self.network.allocate_floating_ip(self.context,
self.projects[0].id)
fix_addr = self._create_address(0)

View File

@ -58,7 +58,7 @@ class ServiceTestCase(test.BaseTestCase):
rpc.AdapterConsumer)
rpc.AdapterConsumer(connection=mox.IgnoreArg(),
topic='fake.%s' % FLAGS.node_name,
topic='fake.%s' % FLAGS.host,
proxy=mox.IsA(service.Service)).AndReturn(
rpc.AdapterConsumer)
@ -82,37 +82,37 @@ class ServiceTestCase(test.BaseTestCase):
# 'model_disconnected' and report_state doesn't really do much so this
# these are mostly just for coverage
def test_report_state(self):
node_name = 'foo'
host = 'foo'
binary = 'bar'
daemon_ref = {'node_name': node_name,
daemon_ref = {'host': host,
'binary': binary,
'report_count': 0,
'id': 1}
service.db.__getattr__('report_state')
service.db.daemon_get_by_args(None,
node_name,
host,
binary).AndReturn(daemon_ref)
service.db.daemon_update(None, daemon_ref['id'],
mox.ContainsKeyValue('report_count', 1))
self.mox.ReplayAll()
s = service.Service()
rv = yield s.report_state(node_name, binary)
rv = yield s.report_state(host, binary)
def test_report_state_no_daemon(self):
node_name = 'foo'
host = 'foo'
binary = 'bar'
daemon_create = {'node_name': node_name,
daemon_create = {'host': host,
'binary': binary,
'report_count': 0}
daemon_ref = {'node_name': node_name,
daemon_ref = {'host': host,
'binary': binary,
'report_count': 0,
'id': 1}
service.db.__getattr__('report_state')
service.db.daemon_get_by_args(None,
node_name,
host,
binary).AndRaise(exception.NotFound())
service.db.daemon_create(None,
daemon_create).AndReturn(daemon_ref['id'])
@ -122,38 +122,38 @@ class ServiceTestCase(test.BaseTestCase):
self.mox.ReplayAll()
s = service.Service()
rv = yield s.report_state(node_name, binary)
rv = yield s.report_state(host, binary)
def test_report_state_newly_disconnected(self):
node_name = 'foo'
host = 'foo'
binary = 'bar'
daemon_ref = {'node_name': node_name,
daemon_ref = {'host': host,
'binary': binary,
'report_count': 0,
'id': 1}
service.db.__getattr__('report_state')
service.db.daemon_get_by_args(None,
node_name,
host,
binary).AndRaise(Exception())
self.mox.ReplayAll()
s = service.Service()
rv = yield s.report_state(node_name, binary)
rv = yield s.report_state(host, binary)
self.assert_(s.model_disconnected)
def test_report_state_newly_connected(self):
node_name = 'foo'
host = 'foo'
binary = 'bar'
daemon_ref = {'node_name': node_name,
daemon_ref = {'host': host,
'binary': binary,
'report_count': 0,
'id': 1}
service.db.__getattr__('report_state')
service.db.daemon_get_by_args(None,
node_name,
host,
binary).AndReturn(daemon_ref)
service.db.daemon_update(None, daemon_ref['id'],
mox.ContainsKeyValue('report_count', 1))
@ -161,6 +161,6 @@ class ServiceTestCase(test.BaseTestCase):
self.mox.ReplayAll()
s = service.Service()
s.model_disconnected = True
rv = yield s.report_state(node_name, binary)
rv = yield s.report_state(host, binary)
self.assert_(not s.model_disconnected)

View File

@ -78,7 +78,7 @@ class AOEManager(manager.Manager):
self.db.volume_update(context,
volume_id,
{'node_name': FLAGS.node_name})
{'host': FLAGS.host})
size = volume_ref['size']
logging.debug("volume %s: creating lv of size %sG", volume_id, size)
@ -111,7 +111,7 @@ class AOEManager(manager.Manager):
volume_ref = self.db.volume_get(context, volume_id)
if volume_ref['attach_status'] == "attached":
raise exception.Error("Volume is still attached")
if volume_ref['node_name'] != FLAGS.node_name:
if volume_ref['host'] != FLAGS.host:
raise exception.Error("Volume is not local to this node")
shelf_id, blade_id = self.db.volume_get_shelf_and_blade(context,
volume_id)