summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Meade <alex.meade@rackspace.com>2011-12-19 10:37:43 -0500
committerAlex Meade <alex.meade@rackspace.com>2011-12-20 10:14:27 -0500
commit5c8be0211ca96cd7562fc930f6013c28f1729dd5 (patch)
tree10206afd127c2dbf4604fa7c6ef24ae18ccd1373
parente662da0c634c89ef65150540b9ebbde353d3450e (diff)
Set min_ram and min_disk on snapshot
Fixes bug 884269 Change-Id: Id92727ea09bf73ab8d6201f0aece8018de4b674b
-rw-r--r--nova/compute/api.py30
-rw-r--r--nova/tests/test_compute.py126
2 files changed, 155 insertions, 1 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index bfeb60a7a..2e44c40fa 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -24,6 +24,8 @@ import novaclient
import re
import time
+import webob.exc
+
from nova import block_device
from nova import exception
from nova import flags
@@ -1138,6 +1140,15 @@ class API(base.Base):
properties.update(extra_properties or {})
sent_meta = {'name': name, 'is_public': False,
'status': 'creating', 'properties': properties}
+
+ if image_type == 'snapshot':
+ min_ram, min_disk = self._get_minram_mindisk_params(context,
+ instance)
+ if min_ram is not None:
+ sent_meta['min_ram'] = min_ram
+ if min_disk is not None:
+ sent_meta['min_disk'] = min_disk
+
recv_meta = self.image_service.create(context, sent_meta)
params = {'image_id': recv_meta['id'], 'image_type': image_type,
'backup_type': backup_type, 'rotation': rotation}
@@ -1145,6 +1156,25 @@ class API(base.Base):
params=params)
return recv_meta
+ def _get_minram_mindisk_params(self, context, instance):
+ try:
+ #try to get source image of the instance
+ orig_image = self.image_service.show(context,
+ instance['image_ref'])
+ except webob.exc.HTTPNotFound:
+ return None, None
+
+ #disk format of vhd is non-shrinkable
+ if orig_image.get('disk_format') == 'vhd':
+ min_ram = instance['instance_type']['memory_mb']
+ min_disk = instance['instance_type']['local_gb']
+ else:
+ #set new image values to the original image values
+ min_ram = orig_image.get('min_ram')
+ min_disk = orig_image.get('min_disk')
+
+ return min_ram, min_disk
+
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.RESCUED],
task_state=[None, task_states.RESIZE_VERIFY])
@scheduler_api.reroute_compute("reboot")
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 93eabae3d..8791e009d 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -24,6 +24,7 @@ import datetime
from webob import exc
import mox
+import webob.exc
import nova
from nova import compute
@@ -1693,12 +1694,135 @@ class ComputeAPITestCase(BaseTestCase):
self.compute.terminate_instance(self.context, instance_uuid)
def test_snapshot(self):
- """Can't backup an instance which is already being backed up."""
+ """Ensure a snapshot of an instance can be created"""
+ instance = self._create_fake_instance()
+ image = self.compute_api.snapshot(self.context, instance, 'snap1',
+ {'extra_param': 'value1'})
+
+ self.assertEqual(image['name'], 'snap1')
+ properties = image['properties']
+ self.assertTrue('backup_type' not in properties)
+ self.assertEqual(properties['image_type'], 'snapshot')
+ self.assertEqual(properties['instance_uuid'], instance['uuid'])
+ self.assertEqual(properties['extra_param'], 'value1')
+
+ db.instance_destroy(self.context, instance['id'])
+
+ def test_snapshot_minram_mindisk_VHD(self):
+ """Ensure a snapshots min_ram and min_disk are correct.
+
+ A snapshot of a non-shrinkable VHD should have min_ram
+ and min_disk set to that of the original instances flavor.
+ """
+
+ def fake_show(*args):
+ img = copy(self.fake_image)
+ img['disk_format'] = 'vhd'
+ return img
+ self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
+
+ instance = self._create_fake_instance()
+ inst_params = {'local_gb': 2, 'memory_mb': 256}
+ instance['instance_type'].update(inst_params)
+
+ image = self.compute_api.snapshot(self.context, instance, 'snap1',
+ {'extra_param': 'value1'})
+
+ self.assertEqual(image['name'], 'snap1')
+ self.assertEqual(image['min_ram'], 256)
+ self.assertEqual(image['min_disk'], 2)
+ properties = image['properties']
+ self.assertTrue('backup_type' not in properties)
+ self.assertEqual(properties['image_type'], 'snapshot')
+ self.assertEqual(properties['instance_uuid'], instance['uuid'])
+ self.assertEqual(properties['extra_param'], 'value1')
+
+ db.instance_destroy(self.context, instance['id'])
+
+ def test_snapshot_minram_mindisk(self):
+ """Ensure a snapshots min_ram and min_disk are correct.
+
+ A snapshot of an instance should have min_ram and min_disk
+ set to that of the instances original image unless that
+ image had a disk format of vhd.
+ """
+
+ def fake_show(*args):
+ img = copy(self.fake_image)
+ img['disk_format'] = 'raw'
+ img['min_ram'] = 512
+ img['min_disk'] = 1
+ return img
+ self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
+
+ instance = self._create_fake_instance()
+
+ image = self.compute_api.snapshot(self.context, instance, 'snap1',
+ {'extra_param': 'value1'})
+
+ self.assertEqual(image['name'], 'snap1')
+ self.assertEqual(image['min_ram'], 512)
+ self.assertEqual(image['min_disk'], 1)
+ properties = image['properties']
+ self.assertTrue('backup_type' not in properties)
+ self.assertEqual(properties['image_type'], 'snapshot')
+ self.assertEqual(properties['instance_uuid'], instance['uuid'])
+ self.assertEqual(properties['extra_param'], 'value1')
+
+ db.instance_destroy(self.context, instance['id'])
+
+ def test_snapshot_minram_mindisk_img_missing_minram(self):
+ """Ensure a snapshots min_ram and min_disk are correct.
+
+ Do not show an attribute that the orig img did not have.
+ """
+
+ def fake_show(*args):
+ img = copy(self.fake_image)
+ img['disk_format'] = 'raw'
+ img['min_disk'] = 1
+ return img
+ self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
+
instance = self._create_fake_instance()
+
image = self.compute_api.snapshot(self.context, instance, 'snap1',
{'extra_param': 'value1'})
self.assertEqual(image['name'], 'snap1')
+ self.assertFalse('min_ram' in image)
+ self.assertEqual(image['min_disk'], 1)
+ properties = image['properties']
+ self.assertTrue('backup_type' not in properties)
+ self.assertEqual(properties['image_type'], 'snapshot')
+ self.assertEqual(properties['instance_uuid'], instance['uuid'])
+ self.assertEqual(properties['extra_param'], 'value1')
+
+ db.instance_destroy(self.context, instance['id'])
+
+ def test_snapshot_minram_mindisk_no_image(self):
+ """Ensure a snapshots min_ram and min_disk are correct.
+
+ A snapshots min_ram and min_disk should be set to default if
+ an instances original image cannot be found.
+ """
+
+ def fake_show(*args):
+ raise webob.exc.HTTPNotFound()
+
+ self.stubs.Set(fake_image._FakeImageService, 'show', fake_show)
+
+ instance = self._create_fake_instance()
+
+ image = self.compute_api.snapshot(self.context, instance, 'snap1',
+ {'extra_param': 'value1'})
+
+ self.assertEqual(image['name'], 'snap1')
+
+ # min_ram and min_disk are not returned when set to default
+ self.assertFalse('min_ram' in image)
+ self.assertFalse('min_disk' in image)
+
properties = image['properties']
self.assertTrue('backup_type' not in properties)
self.assertEqual(properties['image_type'], 'snapshot')