232 if payload.stderr is not None and payload.stderr != '': |
232 if payload.stderr is not None and payload.stderr != '': |
233 stderr = payload.stderr.rstrip() |
233 stderr = payload.stderr.rstrip() |
234 error.append(stderr.replace('\n', ': ')) |
234 error.append(stderr.replace('\n', ': ')) |
235 result = ': '.join(error) |
235 result = ': '.join(error) |
236 return result |
236 return result |
|
237 |
|
238 |
|
239 class MemoryAlignmentIncorrect(exception.FlavorMemoryTooSmall): |
|
240 msg_fmt = _("Requested flavor, %(flavor)s, memory size %(memsize)s does " |
|
241 "not align on %(align)s boundary.") |
237 |
242 |
238 |
243 |
239 class SolarisVolumeAPI(API): |
244 class SolarisVolumeAPI(API): |
240 """ Extending the volume api to support additional cinder sub-commands |
245 """ Extending the volume api to support additional cinder sub-commands |
241 """ |
246 """ |
1157 reason = _("Image contains more than one ZFS pool.") |
1162 reason = _("Image contains more than one ZFS pool.") |
1158 raise exception.ImageUnacceptable(image_id=instance['image_ref'], |
1163 raise exception.ImageUnacceptable(image_id=instance['image_ref'], |
1159 reason=reason) |
1164 reason=reason) |
1160 # - looks like it's OK |
1165 # - looks like it's OK |
1161 self._validated_archives.append(instance['image_ref']) |
1166 self._validated_archives.append(instance['image_ref']) |
|
1167 |
|
1168 def _validate_flavor(self, instance): |
|
1169 """Validate the flavor for compatibility with zone brands""" |
|
1170 flavor = self._get_flavor(instance) |
|
1171 extra_specs = flavor['extra_specs'].copy() |
|
1172 brand = extra_specs.get('zonecfg:brand', ZONE_BRAND_SOLARIS) |
|
1173 |
|
1174 if brand == ZONE_BRAND_SOLARIS_KZ: |
|
1175 # verify the memory is 256mb aligned |
|
1176 test_size = Size('256MB') |
|
1177 instance_size = Size('%sMB' % instance['memory_mb']) |
|
1178 |
|
1179 if instance_size.byte_value % test_size.byte_value: |
|
1180 # non-zero result so it doesn't align |
|
1181 raise MemoryAlignmentIncorrect( |
|
1182 flavor=flavor['name'], |
|
1183 memsize=str(instance['memory_mb']), |
|
1184 align='256') |
1162 |
1185 |
1163 def _suri_from_volume_info(self, connection_info): |
1186 def _suri_from_volume_info(self, connection_info): |
1164 """Returns a suri(5) formatted string based on connection_info. |
1187 """Returns a suri(5) formatted string based on connection_info. |
1165 Currently supports local ZFS volume, NFS, Fibre Channel and iSCSI |
1188 Currently supports local ZFS volume, NFS, Fibre Channel and iSCSI |
1166 driver types. |
1189 driver types. |
2144 :param block_device_info: Information about block devices to be |
2167 :param block_device_info: Information about block devices to be |
2145 attached to the instance. |
2168 attached to the instance. |
2146 """ |
2169 """ |
2147 image = self._fetch_image(context, instance) |
2170 image = self._fetch_image(context, instance) |
2148 self._validate_image(context, image, instance) |
2171 self._validate_image(context, image, instance) |
|
2172 self._validate_flavor(instance) |
2149 |
2173 |
2150 # c1d0 is the standard dev for the default boot device. |
2174 # c1d0 is the standard dev for the default boot device. |
2151 # Irrelevant value for ZFS, but Cinder gets stroppy without it. |
2175 # Irrelevant value for ZFS, but Cinder gets stroppy without it. |
2152 mountpoint = "c1d0" |
2176 mountpoint = "c1d0" |
2153 |
2177 |