summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorNachi Ueno <ueno.nachi@lab.ntt.co.jp>2011-01-14 06:50:44 +0900
committerNachi Ueno <ueno.nachi@lab.ntt.co.jp>2011-01-14 06:50:44 +0900
commitb3778edddb4e58e2518adbdca4621bea8c419c97 (patch)
treeb5fe62d442cf553382bc76818194ed6296272ae3 /nova
parentbc0c5ba5026610013759fa731d21e2287e3d709a (diff)
parent24e6372891be1b6dd81de0af89ece88f256a32e9 (diff)
downloadnova-b3778edddb4e58e2518adbdca4621bea8c419c97.tar.gz
nova-b3778edddb4e58e2518adbdca4621bea8c419c97.tar.xz
nova-b3778edddb4e58e2518adbdca4621bea8c419c97.zip
Merged with r561
Diffstat (limited to 'nova')
-rw-r--r--nova/api/ec2/cloud.py32
-rw-r--r--nova/auth/manager.py2
-rw-r--r--nova/db/api.py4
-rw-r--r--nova/db/sqlalchemy/models.py4
-rw-r--r--nova/tests/test_cloud.py15
-rw-r--r--nova/virt/libvirt_conn.py67
6 files changed, 72 insertions, 52 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py
index c7ee8eae8..630aaeaf2 100644
--- a/nova/api/ec2/cloud.py
+++ b/nova/api/ec2/cloud.py
@@ -75,17 +75,13 @@ def _gen_key(context, user_id, key_name):
def ec2_id_to_id(ec2_id):
- """Convert an ec2 ID (i-[base 36 number]) to an instance id (int)"""
- return int(ec2_id[2:], 36)
+ """Convert an ec2 ID (i-[base 16 number]) to an instance id (int)"""
+ return int(ec2_id.split('-')[-1], 16)
-def id_to_ec2_id(instance_id):
- """Convert an instance ID (int) to an ec2 ID (i-[base 36 number])"""
- digits = []
- while instance_id != 0:
- instance_id, remainder = divmod(instance_id, 36)
- digits.append('0123456789abcdefghijklmnopqrstuvwxyz'[remainder])
- return "i-%s" % ''.join(reversed(digits))
+def id_to_ec2_id(instance_id, template='i-%08x'):
+ """Convert an instance ID (int) to an ec2 ID (i-[base 16 number])"""
+ return template % instance_id
class CloudController(object):
@@ -544,6 +540,8 @@ class CloudController(object):
return self.compute_api.get_ajax_console(context, internal_id)
def describe_volumes(self, context, volume_id=None, **kwargs):
+ if volume_id:
+ volume_id = [ec2_id_to_id(x) for x in volume_id]
volumes = self.volume_api.get_all(context)
# NOTE(vish): volume_id is an optional list of volume ids to filter by.
volumes = [self._format_volume(context, v) for v in volumes
@@ -559,7 +557,7 @@ class CloudController(object):
instance_data = '%s[%s]' % (instance_ec2_id,
volume['instance']['host'])
v = {}
- v['volumeId'] = volume['id']
+ v['volumeId'] = id_to_ec2_id(volume['id'], 'vol-%08x')
v['status'] = volume['status']
v['size'] = volume['size']
v['availabilityZone'] = volume['availability_zone']
@@ -577,7 +575,8 @@ class CloudController(object):
'device': volume['mountpoint'],
'instanceId': instance_ec2_id,
'status': 'attached',
- 'volume_id': volume['ec2_id']}]
+ 'volumeId': id_to_ec2_id(volume['id'],
+ 'vol-%08x')}]
else:
v['attachmentSet'] = [{}]
@@ -596,10 +595,12 @@ class CloudController(object):
return {'volumeSet': [self._format_volume(context, dict(volume))]}
def delete_volume(self, context, volume_id, **kwargs):
+ volume_id = ec2_id_to_id(volume_id)
self.volume_api.delete(context, volume_id)
return True
def update_volume(self, context, volume_id, **kwargs):
+ volume_id = ec2_id_to_id(volume_id)
updatable_fields = ['display_name', 'display_description']
changes = {}
for field in updatable_fields:
@@ -610,18 +611,21 @@ class CloudController(object):
return True
def attach_volume(self, context, volume_id, instance_id, device, **kwargs):
+ volume_id = ec2_id_to_id(volume_id)
+ instance_id = ec2_id_to_id(instance_id)
LOG.audit(_("Attach volume %s to instacne %s at %s"), volume_id,
instance_id, device, context=context)
self.compute_api.attach_volume(context, instance_id, volume_id, device)
volume = self.volume_api.get(context, volume_id)
return {'attachTime': volume['attach_time'],
'device': volume['mountpoint'],
- 'instanceId': instance_id,
+ 'instanceId': id_to_ec2_id(instance_id),
'requestId': context.request_id,
'status': volume['attach_status'],
- 'volumeId': volume_id}
+ 'volumeId': id_to_ec2_id(volume_id, 'vol-%08x')}
def detach_volume(self, context, volume_id, **kwargs):
+ volume_id = ec2_id_to_id(volume_id)
LOG.audit(_("Detach volume %s"), volume_id, context=context)
volume = self.volume_api.get(context, volume_id)
instance = self.compute_api.detach_volume(context, volume_id)
@@ -630,7 +634,7 @@ class CloudController(object):
'instanceId': id_to_ec2_id(instance['id']),
'requestId': context.request_id,
'status': volume['attach_status'],
- 'volumeId': volume_id}
+ 'volumeId': id_to_ec2_id(volume_id, 'vol-%08x')}
def _convert_to_set(self, lst, label):
if lst == None or lst == []:
diff --git a/nova/auth/manager.py b/nova/auth/manager.py
index 6fb9b522f..de18a3838 100644
--- a/nova/auth/manager.py
+++ b/nova/auth/manager.py
@@ -721,7 +721,7 @@ class AuthManager(object):
if project is None:
project = user.id
pid = Project.safe_id(project)
- return self.__generate_rc(user.access, user.secret, pid, use_dmz)
+ return self.__generate_rc(user, pid, use_dmz)
@staticmethod
def __generate_rc(user, pid, use_dmz=True, host=None):
diff --git a/nova/db/api.py b/nova/db/api.py
index ad6bfd12c..f9d561587 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -42,6 +42,10 @@ flags.DEFINE_string('db_backend', 'sqlalchemy',
'The backend to use for db')
flags.DEFINE_boolean('enable_new_services', True,
'Services to be added to the available pool on create')
+flags.DEFINE_string('instance_name_template', 'instance-%08x',
+ 'Template string to be used to generate instance names')
+flags.DEFINE_string('volume_name_template', 'volume-%08x',
+ 'Template string to be used to generate instance names')
IMPL = utils.LazyPluggable(FLAGS['db_backend'],
diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py
index 6bea83709..af9584f81 100644
--- a/nova/db/sqlalchemy/models.py
+++ b/nova/db/sqlalchemy/models.py
@@ -169,7 +169,7 @@ class Instance(BASE, NovaBase):
@property
def name(self):
- return "instance-%08x" % self.id
+ return FLAGS.instance_name_template % self.id
admin_pass = Column(String(255))
user_id = Column(String(255))
@@ -256,7 +256,7 @@ class Volume(BASE, NovaBase):
@property
def name(self):
- return "volume-%08x" % self.id
+ return FLAGS.volume_name_template % self.id
user_id = Column(String(255))
project_id = Column(String(255))
diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py
index fdacb04f6..2e350cd5a 100644
--- a/nova/tests/test_cloud.py
+++ b/nova/tests/test_cloud.py
@@ -126,10 +126,13 @@ class CloudTestCase(test.TestCase):
vol2 = db.volume_create(self.context, {})
result = self.cloud.describe_volumes(self.context)
self.assertEqual(len(result['volumeSet']), 2)
+ volume_id = cloud.id_to_ec2_id(vol2['id'], 'vol-%08x')
result = self.cloud.describe_volumes(self.context,
- volume_id=[vol2['id']])
+ volume_id=[volume_id])
self.assertEqual(len(result['volumeSet']), 1)
- self.assertEqual(result['volumeSet'][0]['volumeId'], vol2['id'])
+ self.assertEqual(
+ cloud.ec2_id_to_id(result['volumeSet'][0]['volumeId']),
+ vol2['id'])
db.volume_destroy(self.context, vol1['id'])
db.volume_destroy(self.context, vol2['id'])
@@ -385,7 +388,8 @@ class CloudTestCase(test.TestCase):
def test_update_of_volume_display_fields(self):
vol = db.volume_create(self.context, {})
- self.cloud.update_volume(self.context, vol['id'],
+ self.cloud.update_volume(self.context,
+ cloud.id_to_ec2_id(vol['id'], 'vol-%08x'),
display_name='c00l v0lum3')
vol = db.volume_get(self.context, vol['id'])
self.assertEqual('c00l v0lum3', vol['display_name'])
@@ -393,8 +397,9 @@ class CloudTestCase(test.TestCase):
def test_update_of_volume_wont_update_private_fields(self):
vol = db.volume_create(self.context, {})
- self.cloud.update_volume(self.context, vol['id'],
- mountpoint='/not/here')
+ self.cloud.update_volume(self.context,
+ cloud.id_to_ec2_id(vol['id'], 'vol-%08x'),
+ mountpoint='/not/here')
vol = db.volume_get(self.context, vol['id'])
self.assertEqual(None, vol['mountpoint'])
db.volume_destroy(self.context, vol['id'])
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index 4ee3d5b22..c2d17c34a 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -207,40 +207,29 @@ class LibvirtConnection(object):
pass
# If the instance is already terminated, we're still happy
- done = event.Event()
-
# We'll save this for when we do shutdown,
# instead of destroy - but destroy returns immediately
timer = utils.LoopingCall(f=None)
- def _wait_for_shutdown():
+ while True:
try:
state = self.get_info(instance['name'])['state']
db.instance_set_state(context.get_admin_context(),
instance['id'], state)
if state == power_state.SHUTDOWN:
- timer.stop()
+ break
except Exception:
db.instance_set_state(context.get_admin_context(),
instance['id'],
power_state.SHUTDOWN)
- timer.stop()
+ break
- timer.f = _wait_for_shutdown
- timer_done = timer.start(interval=0.5, now=True)
+ self.firewall_driver.unfilter_instance(instance)
- # NOTE(termie): this is strictly superfluous (we could put the
- # cleanup code in the timer), but this emulates the
- # previous model so I am keeping it around until
- # everything has been vetted a bit
- def _wait_for_timer():
- timer_done.wait()
- if cleanup:
- self._cleanup(instance)
- done.send()
+ if cleanup:
+ self._cleanup(instance)
- greenthread.spawn(_wait_for_timer)
- return done
+ return True
def _cleanup(self, instance):
target = os.path.join(FLAGS.instances_path, instance['name'])
@@ -818,6 +807,10 @@ class FirewallDriver(object):
At this point, the instance isn't running yet."""
raise NotImplementedError()
+ def unfilter_instance(self, instance):
+ """Stop filtering instance"""
+ raise NotImplementedError()
+
def apply_instance_filter(self, instance):
"""Apply instance filter.
@@ -1031,6 +1024,10 @@ class NWFilterFirewall(FirewallDriver):
# execute in a native thread and block current greenthread until done
tpool.execute(self._conn.nwfilterDefineXML, xml)
+ def unfilter_instance(self, instance):
+ # Nothing to do
+ pass
+
def prepare_instance_filter(self, instance):
"""
Creates an NWFilter for the given instance. In the process,
@@ -1125,17 +1122,25 @@ class NWFilterFirewall(FirewallDriver):
class IptablesFirewallDriver(FirewallDriver):
def __init__(self, execute=None):
self.execute = execute or utils.execute
- self.instances = set()
+ self.instances = {}
def apply_instance_filter(self, instance):
"""No-op. Everything is done in prepare_instance_filter"""
pass
def remove_instance(self, instance):
- self.instances.remove(instance)
+ if instance['id'] in self.instances:
+ del self.instances[instance['id']]
+ else:
+ LOG.info(_('Attempted to unfilter instance %s which is not '
+ 'filtered'), instance['id'])
def add_instance(self, instance):
- self.instances.add(instance)
+ self.instances[instance['id']] = instance
+
+ def unfilter_instance(self, instance):
+ self.remove_instance(instance)
+ self.apply_ruleset()
def prepare_instance_filter(self, instance):
self.add_instance(instance)
@@ -1174,10 +1179,11 @@ class IptablesFirewallDriver(FirewallDriver):
our_chains += [':nova-local - [0:0]']
our_rules += ['-A FORWARD -j nova-local']
- security_groups = set()
+ security_groups = {}
# Add our chains
# First, we add instance chains and rules
- for instance in self.instances:
+ for instance_id in self.instances:
+ instance = self.instances[instance_id]
chain_name = self._instance_chain_name(instance)
if(ip_version == 4):
ip_address = self._ip_for_instance(instance)
@@ -1202,9 +1208,10 @@ class IptablesFirewallDriver(FirewallDriver):
for security_group in \
db.security_group_get_by_instance(ctxt,
instance['id']):
- security_groups.add(security_group)
+ security_groups[security_group['id']] = security_group
- sg_chain_name = self._security_group_chain_name(security_group)
+ sg_chain_name = self._security_group_chain_name(
+ security_group['id'])
our_rules += ['-A %s -j %s' % (chain_name, sg_chain_name)]
@@ -1223,13 +1230,13 @@ class IptablesFirewallDriver(FirewallDriver):
our_rules += ['-A %s -j nova-fallback' % (chain_name,)]
# then, security group chains and rules
- for security_group in security_groups:
- chain_name = self._security_group_chain_name(security_group)
+ for security_group_id in security_groups:
+ chain_name = self._security_group_chain_name(security_group_id)
our_chains += [':%s - [0:0]' % chain_name]
rules = \
db.security_group_rule_get_by_security_group(ctxt,
- security_group['id'])
+ security_group_id)
for rule in rules:
logging.info('%r', rule)
@@ -1289,8 +1296,8 @@ class IptablesFirewallDriver(FirewallDriver):
def refresh_security_group_rules(self, security_group):
self.apply_ruleset()
- def _security_group_chain_name(self, security_group):
- return 'nova-sg-%s' % (security_group['id'],)
+ def _security_group_chain_name(self, security_group_id):
+ return 'nova-sg-%s' % (security_group_id,)
def _instance_chain_name(self, instance):
return 'nova-inst-%s' % (instance['id'],)