659
676
self.cloud.delete_security_group(self.context, 'testgrp')
661
def test_describe_volumes(self):
662
"""Makes sure describe_volumes works and filters results."""
663
vol1 = db.volume_create(self.context, {'project_id': self.project_id})
664
vol2 = db.volume_create(self.context, {'project_id': self.project_id})
665
result = self.cloud.describe_volumes(self.context)
666
self.assertEqual(len(result['volumeSet']), 2)
667
volume_id = ec2utils.id_to_ec2_vol_id(vol2['id'])
668
result = self.cloud.describe_volumes(self.context,
669
volume_id=[volume_id])
670
self.assertEqual(len(result['volumeSet']), 1)
672
ec2utils.ec2_vol_id_to_uuid(
673
result['volumeSet'][0]['volumeId']),
675
db.volume_destroy(self.context, vol1['id'])
676
db.volume_destroy(self.context, vol2['id'])
678
def test_create_volume_in_availability_zone(self):
679
"""Makes sure create_volume works when we specify an availability
682
availability_zone = 'zone1:host1'
684
result = self.cloud.create_volume(self.context,
686
availability_zone=availability_zone)
687
volume_id = result['volumeId']
688
availabilityZone = result['availabilityZone']
689
self.assertEqual(availabilityZone, availability_zone)
690
result = self.cloud.describe_volumes(self.context)
691
self.assertEqual(len(result['volumeSet']), 1)
692
self.assertEqual(result['volumeSet'][0]['volumeId'], volume_id)
693
self.assertEqual(result['volumeSet'][0]['availabilityZone'],
696
db.volume_destroy(self.context, ec2utils.ec2_vol_id_to_uuid(volume_id))
698
def test_create_volume_from_snapshot(self):
699
"""Makes sure create_volume works when we specify a snapshot."""
700
vol = db.volume_create(self.context, {'size': 1,
701
'project_id': self.project_id})
702
snap = db.snapshot_create(self.context, {'volume_id': vol['id'],
703
'volume_size': vol['size'],
704
'status': "available"})
705
snapshot_id = ec2utils.id_to_ec2_snap_id(snap['id'])
707
result = self.cloud.create_volume(self.context,
708
snapshot_id=snapshot_id)
709
volume_id = result['volumeId']
710
result = self.cloud.describe_volumes(self.context)
711
self.assertEqual(len(result['volumeSet']), 2)
712
self.assertEqual(result['volumeSet'][1]['volumeId'], volume_id)
714
db.volume_destroy(self.context, ec2utils.ec2_vol_id_to_uuid(volume_id))
715
db.snapshot_destroy(self.context, snap['id'])
716
db.volume_destroy(self.context, vol['id'])
718
678
def test_describe_availability_zones(self):
719
679
"""Makes sure describe_availability_zones works and filters results."""
720
680
service1 = db.service_create(self.context, {'host': 'host1_zones',
749
709
result = self.cloud.describe_availability_zones(admin_ctxt,
750
710
zone_name='verbose')
752
self.assertEqual(len(result['availabilityZoneInfo']), 15)
712
self.assertEqual(len(result['availabilityZoneInfo']), 13)
753
713
db.service_destroy(self.context, service1['id'])
754
714
db.service_destroy(self.context, service2['id'])
756
def test_describe_snapshots(self):
757
"""Makes sure describe_snapshots works and filters results."""
758
vol = db.volume_create(self.context, {})
759
snap1 = db.snapshot_create(self.context,
760
{'volume_id': vol['id'], 'project_id': self.project_id})
761
snap2 = db.snapshot_create(self.context,
762
{'volume_id': vol['id'], 'project_id': self.project_id})
763
result = self.cloud.describe_snapshots(self.context)
764
self.assertEqual(len(result['snapshotSet']), 2)
765
snapshot_id = ec2utils.id_to_ec2_snap_id(snap2['id'])
766
result = self.cloud.describe_snapshots(self.context,
767
snapshot_id=[snapshot_id])
768
self.assertEqual(len(result['snapshotSet']), 1)
770
ec2utils.ec2_snap_id_to_uuid(
771
result['snapshotSet'][0]['snapshotId']),
773
db.snapshot_destroy(self.context, snap1['id'])
774
db.snapshot_destroy(self.context, snap2['id'])
775
db.volume_destroy(self.context, vol['id'])
777
def test_create_snapshot(self):
778
"""Makes sure create_snapshot works."""
779
vol = db.volume_create(self.context,
780
{'status': "available", 'size': 0})
781
volume_id = ec2utils.id_to_ec2_vol_id(vol['id'])
783
result = self.cloud.create_snapshot(self.context,
785
snapshot_id = result['snapshotId']
786
result = self.cloud.describe_snapshots(self.context)
787
self.assertEqual(len(result['snapshotSet']), 1)
788
self.assertEqual(result['snapshotSet'][0]['snapshotId'], snapshot_id)
790
db.snapshot_destroy(self.context, ec2utils.ec2_id_to_id(snapshot_id))
791
db.volume_destroy(self.context, vol['id'])
793
def test_delete_snapshot(self):
794
"""Makes sure delete_snapshot works."""
795
vol = db.volume_create(self.context,
796
{'status': "available", 'size': 0})
797
snap = db.snapshot_create(self.context,
798
{'volume_id': vol['id'],
799
'status': "available",
801
snapshot_id = ec2utils.id_to_ec2_snap_id(snap['id'])
803
result = self.cloud.delete_snapshot(self.context,
804
snapshot_id=snapshot_id)
805
self.assertTrue(result)
807
db.volume_destroy(self.context, vol['id'])
809
716
def test_describe_instances(self):
810
717
"""Makes sure describe_instances works and filters results."""
811
718
self.flags(use_ipv6=True)
1012
919
result = self.cloud.describe_instances(self.context)
1013
920
self.assertEqual(len(result['reservationSet']), 2)
1015
def _block_device_mapping_create(self, instance_uuid, mappings):
1017
for bdm in mappings:
1018
db.block_device_mapping_create(self.context, bdm)
1019
if 'volume_id' in bdm:
1020
values = {'id': bdm['volume_id']}
1021
for bdm_key, vol_key in [('snapshot_id', 'snapshot_id'),
1022
('snapshot_size', 'volume_size'),
1023
('delete_on_termination',
1024
'delete_on_termination')]:
1026
values[vol_key] = bdm[bdm_key]
1027
vol = db.volume_create(self.context, values)
1028
db.volume_attached(self.context, vol['id'],
1029
instance_uuid, bdm['device_name'])
1033
def _setUpBlockDeviceMapping(self):
1034
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
1035
inst1 = db.instance_create(self.context,
1036
{'image_ref': image_uuid,
1037
'instance_type_id': 1,
1038
'root_device_name': '/dev/sdb1'})
1039
inst2 = db.instance_create(self.context,
1040
{'image_ref': image_uuid,
1041
'instance_type_id': 1,
1042
'root_device_name': '/dev/sdc1'})
1044
instance_id = inst1['id']
1045
instance_uuid = inst1['uuid']
1047
{'instance_uuid': instance_uuid,
1048
'device_name': '/dev/sdb1',
1051
{'instance_uuid': instance_uuid,
1052
'device_name': '/dev/sdb2',
1055
{'instance_uuid': instance_uuid,
1056
'device_name': '/dev/sdb3',
1057
'delete_on_termination': True,
1060
{'instance_uuid': instance_uuid,
1061
'device_name': '/dev/sdb4',
1062
'delete_on_termination': False,
1065
{'instance_uuid': instance_uuid,
1066
'device_name': '/dev/sdb5',
1070
{'instance_uuid': instance_uuid,
1071
'device_name': '/dev/sdb6',
1072
'snapshot_id': '10',
1075
{'instance_uuid': instance_uuid,
1076
'device_name': '/dev/sdb7',
1078
{'instance_uuid': instance_uuid,
1079
'device_name': '/dev/sdb8',
1080
'virtual_name': 'swap'},
1081
{'instance_uuid': instance_uuid,
1082
'device_name': '/dev/sdb9',
1083
'virtual_name': 'ephemeral3'}]
1085
volumes = self._block_device_mapping_create(instance_uuid, mappings0)
1086
return (inst1, inst2, volumes)
1088
def _tearDownBlockDeviceMapping(self, inst1, inst2, volumes):
1090
db.volume_destroy(self.context, vol['id'])
1091
for uuid in (inst1['uuid'], inst2['uuid']):
1092
for bdm in db.block_device_mapping_get_all_by_instance(
1093
self.context, uuid):
1094
db.block_device_mapping_destroy(self.context, bdm['id'])
1095
db.instance_destroy(self.context, inst2['uuid'])
1096
db.instance_destroy(self.context, inst1['uuid'])
1098
_expected_instance_bdm1 = {
1099
'instanceId': 'i-00000001',
1100
'rootDeviceName': '/dev/sdb1',
1101
'rootDeviceType': 'ebs'}
1103
_expected_block_device_mapping0 = [
1104
{'deviceName': '/dev/sdb1',
1105
'ebs': {'status': 'in-use',
1106
'deleteOnTermination': False,
1109
{'deviceName': '/dev/sdb2',
1110
'ebs': {'status': 'in-use',
1111
'deleteOnTermination': False,
1114
{'deviceName': '/dev/sdb3',
1115
'ebs': {'status': 'in-use',
1116
'deleteOnTermination': True,
1119
{'deviceName': '/dev/sdb4',
1120
'ebs': {'status': 'in-use',
1121
'deleteOnTermination': False,
1124
{'deviceName': '/dev/sdb5',
1125
'ebs': {'status': 'in-use',
1126
'deleteOnTermination': False,
1129
{'deviceName': '/dev/sdb6',
1130
'ebs': {'status': 'in-use',
1131
'deleteOnTermination': False,
1132
'volumeId': '11', }}]
1133
# NOTE(yamahata): swap/ephemeral device case isn't supported yet.
1135
_expected_instance_bdm2 = {
1136
'instanceId': 'i-00000002',
1137
'rootDeviceName': '/dev/sdc1',
1138
'rootDeviceType': 'instance-store'}
1140
def test_format_instance_bdm(self):
1141
(inst1, inst2, volumes) = self._setUpBlockDeviceMapping()
1144
self.cloud._format_instance_bdm(self.context, inst1['uuid'],
1145
'/dev/sdb1', result)
1146
self.assertSubDictMatch(
1147
{'rootDeviceType': self._expected_instance_bdm1['rootDeviceType']},
1149
self._assertEqualBlockDeviceMapping(
1150
self._expected_block_device_mapping0, result['blockDeviceMapping'])
1153
self.cloud._format_instance_bdm(self.context, inst2['uuid'],
1154
'/dev/sdc1', result)
1155
self.assertSubDictMatch(
1156
{'rootDeviceType': self._expected_instance_bdm2['rootDeviceType']},
1159
self._tearDownBlockDeviceMapping(inst1, inst2, volumes)
1161
def _assertInstance(self, instance_id):
1162
ec2_instance_id = ec2utils.id_to_ec2_inst_id(instance_id)
1163
result = self.cloud.describe_instances(self.context,
1164
instance_id=[ec2_instance_id])
1165
result = result['reservationSet'][0]
1166
self.assertEqual(len(result['instancesSet']), 1)
1167
result = result['instancesSet'][0]
1168
self.assertEqual(result['instanceId'], ec2_instance_id)
1171
def _assertEqualBlockDeviceMapping(self, expected, result):
1172
self.assertEqual(len(expected), len(result))
1176
if x['deviceName'] == y['deviceName']:
1177
self.assertSubDictMatch(x, y)
1180
self.assertTrue(found)
1182
def test_describe_instances_bdm(self):
1183
"""Make sure describe_instances works with root_device_name and
1184
block device mappings
1186
(inst1, inst2, volumes) = self._setUpBlockDeviceMapping()
1188
result = self._assertInstance(inst1['uuid'])
1189
self.assertSubDictMatch(self._expected_instance_bdm1, result)
1190
self._assertEqualBlockDeviceMapping(
1191
self._expected_block_device_mapping0, result['blockDeviceMapping'])
1193
result = self._assertInstance(inst2['uuid'])
1194
self.assertSubDictMatch(self._expected_instance_bdm2, result)
1196
self._tearDownBlockDeviceMapping(inst1, inst2, volumes)
1198
922
def test_describe_images(self):
1199
923
describe_images = self.cloud.describe_images
2035
1767
self.assertTrue(result)
2037
1769
def _volume_create(self, volume_id=None):
2038
location = '10.0.2.15:3260'
2039
iqn = 'iqn.2010-10.org.openstack:%s' % volume_id
2040
kwargs = {'status': 'available',
2041
'host': self.volume.host,
1770
kwargs = {'name': 'test-volume',
1771
'description': 'test volume description',
1772
'status': 'available',
2043
'provider_location': '1 %s,fake %s' % (location, iqn),
2044
'attach_status': 'detached', }
1775
'attach_status': 'detached'}
2046
kwargs['id'] = volume_id
2047
return db.volume_create(self.context, kwargs)
2049
def _assert_volume_attached(self, vol, instance_uuid, mountpoint):
2050
self.assertEqual(vol['instance_uuid'], instance_uuid)
2051
self.assertEqual(vol['mountpoint'], mountpoint)
2052
self.assertEqual(vol['status'], "in-use")
2053
self.assertEqual(vol['attach_status'], "attached")
2055
def _assert_volume_detached(self, vol):
2056
self.assertEqual(vol['instance_uuid'], None)
2057
self.assertEqual(vol['mountpoint'], None)
2058
self.assertEqual(vol['status'], "available")
2059
self.assertEqual(vol['attach_status'], "detached")
2061
def test_stop_start_with_volume(self):
2062
"""Make sure run instance with block device mapping works"""
2064
# enforce periodic tasks run in short time to avoid wait for 60s.
2065
self._restart_compute_service(periodic_interval=0.3)
2067
vol1 = self._volume_create()
2068
vol2 = self._volume_create()
2069
kwargs = {'image_id': 'ami-1',
2070
'instance_type': FLAGS.default_instance_type,
2072
'block_device_mapping': [{'device_name': '/dev/vdb',
2073
'volume_id': vol1['id'],
2074
'delete_on_termination': False},
2075
{'device_name': '/dev/vdc',
2076
'volume_id': vol2['id'],
2077
'delete_on_termination': True},
2079
ec2_instance_id = self._run_instance(**kwargs)
2080
instance_uuid = ec2utils.ec2_instance_id_to_uuid(self.context,
2082
instance_id = ec2utils.ec2_id_to_id(ec2_instance_id)
2084
vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2085
self.assertEqual(len(vols), 2)
2087
self.assertTrue(vol['id'] == vol1['id'] or vol['id'] == vol2['id'])
2089
vol = db.volume_get(self.context, vol1['id'])
2090
self._assert_volume_attached(vol, instance_uuid, '/dev/vdb')
2092
vol = db.volume_get(self.context, vol2['id'])
2093
self._assert_volume_attached(vol, instance_uuid, '/dev/vdc')
2095
result = self.cloud.stop_instances(self.context, [ec2_instance_id])
2096
self.assertTrue(result)
2098
vol = db.volume_get(self.context, vol1['id'])
2099
self._assert_volume_attached(vol, instance_uuid, '/dev/vdb')
2101
vol = db.volume_get(self.context, vol2['id'])
2102
self._assert_volume_attached(vol, instance_uuid, '/dev/vdc')
2104
self.cloud.start_instances(self.context, [ec2_instance_id])
2105
vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2106
self.assertEqual(len(vols), 2)
2108
self.assertTrue(vol['id'] == vol1['id'] or vol['id'] == vol2['id'])
2109
self.assertTrue(vol['mountpoint'] == '/dev/vdb' or
2110
vol['mountpoint'] == '/dev/vdc')
2111
self.assertEqual(vol['instance_uuid'], instance_uuid)
2112
self.assertEqual(vol['status'], "in-use")
2113
self.assertEqual(vol['attach_status'], "attached")
2115
self.cloud.terminate_instances(self.context, [ec2_instance_id])
2117
admin_ctxt = context.get_admin_context(read_deleted="no")
2118
vol = db.volume_get(admin_ctxt, vol1['id'])
2119
self.assertFalse(vol['deleted'])
2120
db.volume_destroy(self.context, vol1['id'])
2122
admin_ctxt = context.get_admin_context(read_deleted="only")
2123
vol = db.volume_get(admin_ctxt, vol2['id'])
2124
self.assertTrue(vol['deleted'])
2126
self._restart_compute_service()
2128
def test_stop_with_attached_volume(self):
2129
"""Make sure attach info is reflected to block device mapping"""
2130
# enforce periodic tasks run in short time to avoid wait for 60s.
2131
self._restart_compute_service(periodic_interval=0.3)
2133
vol1 = self._volume_create()
2134
vol2 = self._volume_create()
2135
kwargs = {'image_id': 'ami-1',
2136
'instance_type': FLAGS.default_instance_type,
2138
'block_device_mapping': [{'device_name': '/dev/sdb',
2139
'volume_id': vol1['id'],
2140
'delete_on_termination': True}]}
2141
ec2_instance_id = self._run_instance(**kwargs)
2142
instance_id = ec2utils.ec2_id_to_id(ec2_instance_id)
2143
instance_uuid = ec2utils.ec2_instance_id_to_uuid(self.context,
2146
vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2147
self.assertEqual(len(vols), 1)
2149
self.assertEqual(vol['id'], vol1['id'])
2150
self._assert_volume_attached(vol, instance_uuid, '/dev/sdb')
2152
vol = db.volume_get(self.context, vol2['id'])
2153
self._assert_volume_detached(vol)
2155
instance = db.instance_get(self.context, instance_id)
2156
self.cloud.compute_api.attach_volume(self.context,
2158
volume_id=vol2['id'],
2160
vol = db.volume_get(self.context, vol2['id'])
2161
self._assert_volume_attached(vol, instance_uuid, '/dev/sdc')
2163
self.cloud.compute_api.detach_volume(self.context,
2164
volume_id=vol1['id'])
2165
vol = db.volume_get(self.context, vol1['id'])
2166
self._assert_volume_detached(vol)
2168
result = self.cloud.stop_instances(self.context, [ec2_instance_id])
2169
self.assertTrue(result)
2171
vol = db.volume_get(self.context, vol2['id'])
2172
self._assert_volume_attached(vol, instance_uuid, '/dev/sdc')
2174
self.cloud.start_instances(self.context, [ec2_instance_id])
2175
vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2176
self.assertEqual(len(vols), 1)
2178
self.assertEqual(vol['id'], vol2['id'])
2179
self._assert_volume_attached(vol, instance_uuid, '/dev/sdc')
2181
vol = db.volume_get(self.context, vol1['id'])
2182
self._assert_volume_detached(vol)
2184
self.cloud.terminate_instances(self.context, [ec2_instance_id])
2186
for vol_id in (vol1['id'], vol2['id']):
2187
vol = db.volume_get(self.context, vol_id)
2188
self.assertEqual(vol['id'], vol_id)
2189
self._assert_volume_detached(vol)
2190
db.volume_destroy(self.context, vol_id)
2192
self._restart_compute_service()
1777
kwargs['volume_id'] = volume_id
1778
return self.volume_api.create_with_kwargs(self.context, **kwargs)
1780
def _snapshot_create(self, snapshot_id=None):
1781
kwargs = {'volume_id': 'ccec42a2-c220-4806-b762-6b12fbb592e4',
1782
'status': "available",
1785
kwargs['snap_id'] = snapshot_id
1786
return self.volume_api.create_snapshot_with_kwargs(self.context,
2194
1789
def _create_snapshot(self, ec2_volume_id):
2195
1790
result = self.cloud.create_snapshot(self.context,
2196
1791
volume_id=ec2_volume_id)
2197
1792
return result['snapshotId']
2199
def test_run_with_snapshot(self):
2200
"""Makes sure run/stop/start instance with snapshot works."""
2201
vol = self._volume_create()
2202
ec2_volume_id = ec2utils.id_to_ec2_vol_id(vol['id'])
2204
ec2_snapshot1_id = self._create_snapshot(ec2_volume_id)
2205
snapshot1_id = ec2utils.ec2_snap_id_to_uuid(ec2_snapshot1_id)
2206
ec2_snapshot2_id = self._create_snapshot(ec2_volume_id)
2207
snapshot2_id = ec2utils.ec2_snap_id_to_uuid(ec2_snapshot2_id)
2209
kwargs = {'image_id': 'ami-1',
2210
'instance_type': FLAGS.default_instance_type,
2212
'block_device_mapping': [{'device_name': '/dev/vdb',
2213
'snapshot_id': snapshot1_id,
2214
'delete_on_termination': False, },
2215
{'device_name': '/dev/vdc',
2216
'snapshot_id': snapshot2_id,
2217
'delete_on_termination': True}]}
2218
ec2_instance_id = self._run_instance(**kwargs)
2219
instance_id = ec2utils.ec2_vol_id_to_uuid(ec2_instance_id)
2220
instance_uuid = ec2utils.ec2_instance_id_to_uuid(self.context,
2223
vols = db.volume_get_all_by_instance_uuid(self.context, instance_uuid)
2224
self.assertEqual(len(vols), 2)
2228
snapshot_id = vol['snapshot_id']
2229
if snapshot_id == snapshot1_id:
2231
mountpoint = '/dev/vdb'
2232
elif snapshot_id == snapshot2_id:
2234
mountpoint = '/dev/vdc'
2238
self._assert_volume_attached(vol, instance_uuid, mountpoint)
2240
self.assertTrue(vol1_id)
2241
self.assertTrue(vol2_id)
2243
self.cloud.terminate_instances(self.context, [ec2_instance_id])
2245
admin_ctxt = context.get_admin_context(read_deleted="no")
2246
vol = db.volume_get(admin_ctxt, vol1_id)
2247
self._assert_volume_detached(vol)
2248
self.assertFalse(vol['deleted'])
2249
db.volume_destroy(self.context, vol1_id)
2251
admin_ctxt = context.get_admin_context(read_deleted="only")
2252
vol = db.volume_get(admin_ctxt, vol2_id)
2253
self.assertTrue(vol['deleted'])
2255
for snapshot_id in (ec2_snapshot1_id, ec2_snapshot2_id):
2256
self.cloud.delete_snapshot(self.context, snapshot_id)
2258
1794
def _do_test_create_image(self, no_reboot):
2259
1795
"""Make sure that CreateImage works"""
2260
1796
# enforce periodic tasks run in short time to avoid wait for 60s.