components/openstack/nova/files/solariszones/driver.py
changeset 5949 eefd43fe9fc4
parent 5948 bfd525bc0bf2
child 6014 83c60536394d
equal deleted inserted replaced
5948:bfd525bc0bf2 5949:eefd43fe9fc4
   183     return val[0].value if val else None
   183     return val[0].value if val else None
   184 
   184 
   185 
   185 
   186 def lookup_resource_property_value(zone, resource, prop, value):
   186 def lookup_resource_property_value(zone, resource, prop, value):
   187     """Lookup specified property with value from specified Solaris Zone
   187     """Lookup specified property with value from specified Solaris Zone
   188     resource. Returns property if matching value is found, else None
   188     resource. Returns resource object if matching value is found, else None
   189     """
   189     """
   190     try:
   190     try:
   191         resources = zone.getResources(zonemgr.Resource(resource))
   191         resources = zone.getResources(zonemgr.Resource(resource))
   192         for resource in resources:
   192         for resource in resources:
   193             for propertee in resource.properties:
   193             for propertee in resource.properties:
   194                 if propertee.name == prop and propertee.value == value:
   194                 if propertee.name == prop and propertee.value == value:
   195                     return propertee
   195                     return resource
   196         else:
   196         else:
   197             return None
   197             return None
   198     except rad.client.ObjectError:
   198     except rad.client.ObjectError:
   199         return None
   199         return None
   200     except Exception:
   200     except Exception:
  2396                       % brand)
  2396                       % brand)
  2397             raise NotImplementedError(reason)
  2397             raise NotImplementedError(reason)
  2398 
  2398 
  2399         suri = self._suri_from_volume_info(connection_info)
  2399         suri = self._suri_from_volume_info(connection_info)
  2400 
  2400 
       
  2401         resource_scope = [zonemgr.Property("storage", suri)]
       
  2402         if connection_info.get('serial') is not None:
       
  2403             volume = self._volume_api.get(context, connection_info['serial'])
       
  2404             if volume['bootable']:
       
  2405                 resource_scope.append(zonemgr.Property("bootpri", "1"))
       
  2406 
  2401         with ZoneConfig(zone) as zc:
  2407         with ZoneConfig(zone) as zc:
  2402             zc.addresource("device", [zonemgr.Property("storage", suri)])
  2408             zc.addresource("device", resource_scope)
  2403 
  2409 
  2404         # apply the configuration to the running zone
  2410         # apply the configuration to the running zone
  2405         if zone.state == ZONE_STATE_RUNNING:
  2411         if zone.state == ZONE_STATE_RUNNING:
  2406             try:
  2412             try:
  2407                 zone.apply()
  2413                 zone.apply()
  2408             except Exception as ex:
  2414             except Exception as ex:
  2409                 reason = zonemgr_strerror(ex)
  2415                 reason = zonemgr_strerror(ex)
  2410                 LOG.error(_("Unable to attach '%s' to instance '%s' via "
  2416                 LOG.error(_("Unable to attach '%s' to instance '%s' via "
  2411                             "zonemgr(3RAD): %s") % (suri, name, reason))
  2417                             "zonemgr(3RAD): %s") % (suri, name, reason))
  2412                 with ZoneConfig(zone) as zc:
  2418                 with ZoneConfig(zone) as zc:
  2413                     zc.removeresources("device", [zonemgr.Property("storage",
  2419                     zc.removeresources("device", resource_scope)
  2414                                                   suri)])
       
  2415                 raise
  2420                 raise
  2416 
  2421 
  2417     def detach_volume(self, connection_info, instance, mountpoint,
  2422     def detach_volume(self, connection_info, instance, mountpoint,
  2418                       encryption=None):
  2423                       encryption=None):
  2419         """Detach the disk attached to the instance."""
  2424         """Detach the disk attached to the instance."""
  2431             raise NotImplementedError(reason)
  2436             raise NotImplementedError(reason)
  2432 
  2437 
  2433         suri = self._suri_from_volume_info(connection_info)
  2438         suri = self._suri_from_volume_info(connection_info)
  2434 
  2439 
  2435         # Check if the specific property value exists before attempting removal
  2440         # Check if the specific property value exists before attempting removal
  2436         prop = lookup_resource_property_value(zone, "device", "storage", suri)
  2441         resource = lookup_resource_property_value(zone, "device", "storage",
  2437         if not prop:
  2442                                                   suri)
       
  2443         if not resource:
  2438             LOG.warning(_("Storage resource '%s' is not attached to instance "
  2444             LOG.warning(_("Storage resource '%s' is not attached to instance "
  2439                         "'%s'") % (suri, name))
  2445                         "'%s'") % (suri, name))
  2440             return
  2446             return
  2441 
  2447 
  2442         with ZoneConfig(zone) as zc:
  2448         with ZoneConfig(zone) as zc:
  2443             zc.removeresources("device", [zonemgr.Property("storage", suri)])
  2449             zc.removeresources("device", [zonemgr.Property("storage", suri)])
  2444 
  2450 
  2445         # apply the configuration to the running zone
  2451         # apply the configuration to the running zone
  2446         if zone.state == ZONE_STATE_RUNNING:
  2452         if zone.state == ZONE_STATE_RUNNING:
  2447             zone.apply()
  2453             try:
       
  2454                 zone.apply()
       
  2455             except:
       
  2456                 LOG.error(_("Unable to apply the detach of resource '%s' to "
       
  2457                             "running instance '%s' because the resource is "
       
  2458                             "most likely in use.") % (suri, name))
       
  2459 
       
  2460                 # re-add the entry to the zone configuration so that the
       
  2461                 # configuration will reflect what is in cinder before we raise
       
  2462                 # the exception, therefor failing the detach and leaving the
       
  2463                 # volume in-use.
       
  2464                 needed_props = ["storage", "bootpri"]
       
  2465                 props = filter(lambda prop: prop.name in needed_props,
       
  2466                                resource.properties)
       
  2467                 with ZoneConfig(zone) as zc:
       
  2468                     zc.addresource("device", props)
       
  2469 
       
  2470                 raise
  2448 
  2471 
  2449     def swap_volume(self, old_connection_info, new_connection_info,
  2472     def swap_volume(self, old_connection_info, new_connection_info,
  2450                     instance, mountpoint, resize_to):
  2473                     instance, mountpoint, resize_to):
  2451         """Replace the disk attached to the instance.
  2474         """Replace the disk attached to the instance.
  2452 
  2475