454 "supports_recreate": True, |
454 "supports_recreate": True, |
455 } |
455 } |
456 |
456 |
457 def __init__(self, virtapi): |
457 def __init__(self, virtapi): |
458 self.virtapi = virtapi |
458 self.virtapi = virtapi |
|
459 self._archive_manager = None |
459 self._compute_event_callback = None |
460 self._compute_event_callback = None |
460 self._conductor_api = conductor.API() |
461 self._conductor_api = conductor.API() |
461 self._fc_hbas = None |
462 self._fc_hbas = None |
462 self._fc_wwnns = None |
463 self._fc_wwnns = None |
463 self._fc_wwpns = None |
464 self._fc_wwpns = None |
464 self._host_stats = {} |
465 self._host_stats = {} |
465 self._initiator = None |
466 self._initiator = None |
466 self._install_engine = None |
467 self._install_engine = None |
|
468 self._kstat_control = None |
467 self._pagesize = os.sysconf('SC_PAGESIZE') |
469 self._pagesize = os.sysconf('SC_PAGESIZE') |
468 self._rad_connection = None |
470 self._rad_connection = None |
|
471 self._rootzpool_suffix = ROOTZPOOL_RESOURCE |
469 self._uname = os.uname() |
472 self._uname = os.uname() |
470 self._validated_archives = list() |
473 self._validated_archives = list() |
471 self._volume_api = SolarisVolumeAPI() |
474 self._volume_api = SolarisVolumeAPI() |
472 self._rootzpool_suffix = ROOTZPOOL_RESOURCE |
475 self._zone_manager = None |
473 |
476 |
474 @property |
477 @property |
475 def rad_connection(self): |
478 def rad_connection(self): |
476 if self._rad_connection is None: |
479 if self._rad_connection is None: |
477 self._rad_connection = rad.connect.connect_unix() |
480 self._rad_connection = rad.connect.connect_unix() |
482 # the RAD connection has been lost. Reconnect to RAD |
485 # the RAD connection has been lost. Reconnect to RAD |
483 self._rad_connection = rad.connect.connect_unix() |
486 self._rad_connection = rad.connect.connect_unix() |
484 |
487 |
485 return self._rad_connection |
488 return self._rad_connection |
486 |
489 |
487 def _init_rad(self): |
490 @property |
488 """Obtain required RAD objects for Solaris Zones, kernel statistics, |
491 def zone_manager(self): |
489 and Unified Archive management. |
492 try: |
490 """ |
493 if (self._zone_manager is None or |
491 try: |
494 self._zone_manager._conn._closed is not None): |
492 self._zone_manager = self.rad_connection.get_object( |
495 self._zone_manager = self.rad_connection.get_object( |
493 zonemgr.ZoneManager()) |
496 zonemgr.ZoneManager()) |
494 self._kstat_control = self.rad_connection.get_object( |
|
495 kstat.Control()) |
|
496 self._archive_manager = self.rad_connection.get_object( |
|
497 archivemgr.ArchiveManager()) |
|
498 except Exception as ex: |
497 except Exception as ex: |
499 reason = _("Unable to obtain RAD object: %s") % ex |
498 reason = _("Unable to obtain RAD object: %s") % ex |
500 raise exception.NovaException(reason) |
499 raise exception.NovaException(reason) |
501 |
500 |
|
501 return self._zone_manager |
|
502 |
|
503 @property |
|
504 def kstat_control(self): |
|
505 try: |
|
506 if (self._kstat_control is None or |
|
507 self._kstat_control._conn._closed is not None): |
|
508 self._kstat_control = self.rad_connection.get_object( |
|
509 kstat.Control()) |
|
510 except Exception as ex: |
|
511 reason = _("Unable to obtain RAD object: %s") % ex |
|
512 raise exception.NovaException(reason) |
|
513 |
|
514 return self._kstat_control |
|
515 |
|
516 @property |
|
517 def archive_manager(self): |
|
518 try: |
|
519 if (self._archive_manager is None or |
|
520 self._archive_manager._conn._closed is not None): |
|
521 self._archive_manager = self.rad_connection.get_object( |
|
522 archivemgr.ArchiveManager()) |
|
523 except Exception as ex: |
|
524 reason = _("Unable to obtain RAD object: %s") % ex |
|
525 raise exception.NovaException(reason) |
|
526 |
|
527 return self._archive_manager |
|
528 |
502 def init_host(self, host): |
529 def init_host(self, host): |
503 """Initialize anything that is necessary for the driver to function, |
530 """Initialize anything that is necessary for the driver to function, |
504 including catching up with currently running VM's on the given host. |
531 including catching up with currently running VM's on the given host. |
505 """ |
532 """ |
506 # TODO(Vek): Need to pass context in for access to auth_token |
533 # TODO(Vek): Need to pass context in for access to auth_token |
507 self._init_rad() |
534 pass |
508 |
535 |
509 def cleanup_host(self, host): |
536 def cleanup_host(self, host): |
510 """Clean up anything that is necessary for the driver gracefully stop, |
537 """Clean up anything that is necessary for the driver gracefully stop, |
511 including ending remote sessions. This is optional. |
538 including ending remote sessions. This is optional. |
512 """ |
539 """ |
675 'module': module, |
702 'module': module, |
676 'instance': instance, |
703 'instance': instance, |
677 'name': name |
704 'name': name |
678 } |
705 } |
679 try: |
706 try: |
680 self._kstat_control.update() |
707 self.kstat_control.update() |
681 kstat_object = self.rad_connection.get_object( |
708 kstat_object = self.rad_connection.get_object( |
682 kstat.Kstat(), rad.client.ADRGlobPattern(pattern)) |
709 kstat.Kstat(), rad.client.ADRGlobPattern(pattern)) |
683 except Exception as reason: |
710 except Exception as reason: |
684 LOG.info(_("Unable to retrieve kstat object '%s:%s:%s' of class " |
711 LOG.info(_("Unable to retrieve kstat object '%s:%s:%s' of class " |
685 "'%s' via kstat(3RAD): %s") |
712 "'%s' via kstat(3RAD): %s") |
977 # Skip if the image was already checked and confirmed as valid. |
1004 # Skip if the image was already checked and confirmed as valid. |
978 if instance['image_ref'] in self._validated_archives: |
1005 if instance['image_ref'] in self._validated_archives: |
979 return |
1006 return |
980 |
1007 |
981 try: |
1008 try: |
982 ua = self._archive_manager.getArchive(image) |
1009 ua = self.archive_manager.getArchive(image) |
983 except Exception as ex: |
1010 except Exception as ex: |
984 if isinstance(ex, rad.client.ObjectError): |
1011 if isinstance(ex, rad.client.ObjectError): |
985 reason = ex.get_payload().info |
1012 reason = ex.get_payload().info |
986 else: |
1013 else: |
987 reason = str(ex) |
1014 reason = str(ex) |
1471 self._verify_sysconfig(sc_dir, instance, admin_password) |
1498 self._verify_sysconfig(sc_dir, instance, admin_password) |
1472 |
1499 |
1473 LOG.debug(_("Creating zone configuration for '%s' (%s)") |
1500 LOG.debug(_("Creating zone configuration for '%s' (%s)") |
1474 % (name, instance['display_name'])) |
1501 % (name, instance['display_name'])) |
1475 try: |
1502 try: |
1476 self._zone_manager.create(name, None, template) |
1503 self.zone_manager.create(name, None, template) |
1477 self._set_global_properties(name, extra_specs, brand) |
1504 self._set_global_properties(name, extra_specs, brand) |
1478 if connection_info is not None: |
1505 if connection_info is not None: |
1479 self._set_boot_device(name, connection_info, brand) |
1506 self._set_boot_device(name, connection_info, brand) |
1480 self._set_num_cpu(name, instance['vcpus'], brand) |
1507 self._set_num_cpu(name, instance['vcpus'], brand) |
1481 self._set_memory_cap(name, instance['memory_mb'], brand) |
1508 self._set_memory_cap(name, instance['memory_mb'], brand) |
1733 name = instance['name'] |
1760 name = instance['name'] |
1734 if self._get_zone_by_name(name) is None: |
1761 if self._get_zone_by_name(name) is None: |
1735 raise exception.InstanceNotFound(instance_id=name) |
1762 raise exception.InstanceNotFound(instance_id=name) |
1736 |
1763 |
1737 try: |
1764 try: |
1738 self._zone_manager.delete(name) |
1765 self.zone_manager.delete(name) |
1739 except Exception as ex: |
1766 except Exception as ex: |
1740 reason = zonemgr_strerror(ex) |
1767 reason = zonemgr_strerror(ex) |
1741 LOG.error(_("Unable to delete configuration for instance '%s' via " |
1768 LOG.error(_("Unable to delete configuration for instance '%s' via " |
1742 "zonemgr(3RAD): %s") % (name, reason)) |
1769 "zonemgr(3RAD): %s") % (name, reason)) |
1743 raise |
1770 raise |