usr/src/cmd/auto-install/checkpoints/target_selection.py
changeset 1227 4ecf733307ad
parent 1197 41dc6c86a4c3
child 1247 e93173cd968b
equal deleted inserted replaced
1226:93f99ab36b2c 1227:4ecf733307ad
    26 
    26 
    27 ''' target_selection.py - Select Install Target(s)
    27 ''' target_selection.py - Select Install Target(s)
    28 '''
    28 '''
    29 import copy
    29 import copy
    30 import os
    30 import os
    31 import os.path
       
    32 import platform
    31 import platform
    33 import re
    32 import re
    34 import traceback
    33 import traceback
    35 
    34 
    36 from operator import attrgetter
    35 from operator import attrgetter
    41 from solaris_install.target.controller import TargetController, \
    40 from solaris_install.target.controller import TargetController, \
    42     DEFAULT_VDEV_NAME, SwapDumpGeneralError, SwapDumpSpaceError
    41     DEFAULT_VDEV_NAME, SwapDumpGeneralError, SwapDumpSpaceError
    43 from solaris_install.target.logical import Logical, Zpool, Vdev, BE, Zvol, \
    42 from solaris_install.target.logical import Logical, Zpool, Vdev, BE, Zvol, \
    44     Filesystem, DatasetOptions, PoolOptions
    43     Filesystem, DatasetOptions, PoolOptions
    45 from solaris_install.target.physical import Disk, Partition, Slice
    44 from solaris_install.target.physical import Disk, Partition, Slice
    46 from solaris_install.target.shadow.physical import ShadowPhysical
       
    47 from solaris_install.target.size import Size
    45 from solaris_install.target.size import Size
    48 
    46 
    49 DISK_RE = "c\d+(?:t\d+)?d\d+"
    47 DISK_RE = "c\d+(?:t\d+)?d\d+"
    50 
    48 
    51 
    49 
   325                 new_fs = self.__handle_filesystem(child)
   323                 new_fs = self.__handle_filesystem(child)
   326                 if new_fs is not None:
   324                 if new_fs is not None:
   327                     if new_fs.action == "preserve" and \
   325                     if new_fs.action == "preserve" and \
   328                         new_zpool.action not in self.PRESERVED:
   326                         new_zpool.action not in self.PRESERVED:
   329                         raise SelectionError("Filesystem '%s' cannot be "
   327                         raise SelectionError("Filesystem '%s' cannot be "
   330                             "preserved in non-preserved zpool '%s'."
   328                             "preserved in non-preserved zpool '%s'." % \
   331                             (new_fs.name, new_zpool.name))
   329                             (new_fs.name, new_zpool.name))
   332 
   330 
   333                     fs_key = new_zpool.name + ":" + new_fs.name
   331                     fs_key = new_zpool.name + ":" + new_fs.name
   334                     # Filesystem name must be unique within each pool
   332                     # Filesystem name must be unique within each pool
   335                     if fs_key not in self._fs_map and \
   333                     if fs_key not in self._fs_map and \
   349                 new_zvol = self.__handle_zvol(child)
   347                 new_zvol = self.__handle_zvol(child)
   350                 if new_zvol is not None:
   348                 if new_zvol is not None:
   351                     if new_zvol.action in self.PRESERVED and \
   349                     if new_zvol.action in self.PRESERVED and \
   352                         new_zpool.action not in self.PRESERVED:
   350                         new_zpool.action not in self.PRESERVED:
   353                         raise SelectionError("Zvol '%s' cannot be "
   351                         raise SelectionError("Zvol '%s' cannot be "
   354                             "preserved in non-preserved zpool '%s'."
   352                             "preserved in non-preserved zpool '%s'." % \
   355                             (new_zvol.name, zpool.name))
   353                             (new_zvol.name, zpool.name))
   356                     zvol_key = new_zpool.name + ":" + new_zvol.name
   354                     zvol_key = new_zpool.name + ":" + new_zvol.name
   357                     # Zvol name must be unique within each pool
   355                     # Zvol name must be unique within each pool
   358                     if zvol_key not in self._zvol_map and \
   356                     if zvol_key not in self._zvol_map and \
   359                         zvol_key not in self._fs_map:
   357                         zvol_key not in self._fs_map:
   531                 if new_fs is not None:
   529                 if new_fs is not None:
   532                     fs_key = zpool.name + ":" + new_fs.name
   530                     fs_key = zpool.name + ":" + new_fs.name
   533                     # Check if this filesystem already exists as zvol
   531                     # Check if this filesystem already exists as zvol
   534                     if fs_key in self._zvol_map:
   532                     if fs_key in self._zvol_map:
   535                         raise SelectionError("Filesystem '%s' specified on "
   533                         raise SelectionError("Filesystem '%s' specified on "
   536                             "preserved zpool '%s' exists as Zvol."
   534                             "preserved zpool '%s' exists as Zvol." % \
   537                             (new_fs.name, zpool.name))
   535                             (new_fs.name, zpool.name))
   538                     elif fs_key in self._fs_map:
   536                     elif fs_key in self._fs_map:
   539                         # Only preserve and delete are allowed for existing
   537                         # Only preserve and delete are allowed for existing
   540                         if new_fs.action not in ["preserve", "delete"]:
   538                         if new_fs.action not in ["preserve", "delete"]:
   541                             raise SelectionError("Filesystem '%s' specified on"
   539                             raise SelectionError("Filesystem '%s' specified on"
   542                                 " preserved zpool '%s' contains invalid action"
   540                                 " preserved zpool '%s' contains invalid action"
   543                                 " of '%s'."
   541                                 " of '%s'." % \
   544                                 (new_fs.name, zpool.name, new_fs.action))
   542                                 (new_fs.name, zpool.name, new_fs.action))
   545                         # Remove discovered item in order to add user specified
   543                         # Remove discovered item in order to add user specified
   546                         discovered_zpool.delete_children(new_fs)
   544                         discovered_zpool.delete_children(new_fs)
   547                     else:
   545                     else:
   548                         # Only create allowed for new filesystems
   546                         # Only create allowed for new filesystems
   549                         if new_fs.action != "create":
   547                         if new_fs.action != "create":
   550                             raise SelectionError("Filesystem '%s' specified on"
   548                             raise SelectionError("Filesystem '%s' specified on"
   551                                 " preserved zpool '%s' contains invalid action"
   549                                 " preserved zpool '%s' contains invalid action"
   552                                 " of '%s'."
   550                                 " of '%s'." % \
   553                                 (new_fs.name, zpool.name, new_fs.action))
   551                                 (new_fs.name, zpool.name, new_fs.action))
   554                         self._fs_map[fs_key] = new_fs
   552                         self._fs_map[fs_key] = new_fs
   555 
   553 
   556                     self.logger.debug("Adding Filesystem '%s' to zpool" %
   554                     self.logger.debug("Adding Filesystem '%s' to zpool" %
   557                          (new_fs.name))
   555                          (new_fs.name))
   565                     zvol_key = zpool.name + ":" + new_zvol.name
   563                     zvol_key = zpool.name + ":" + new_zvol.name
   566 
   564 
   567                     # Check if This Zvol already exists as filesystem
   565                     # Check if This Zvol already exists as filesystem
   568                     if zvol_key in self._fs_map:
   566                     if zvol_key in self._fs_map:
   569                         raise SelectionError("Zvol '%s' specified on "
   567                         raise SelectionError("Zvol '%s' specified on "
   570                             "preserved zpool '%s' exists as Filesystem."
   568                             "preserved zpool '%s' exists as Filesystem." % \
   571                             (new_zvol.name, zpool.name))
   569                             (new_zvol.name, zpool.name))
   572                     elif zvol_key in self._zvol_map:
   570                     elif zvol_key in self._zvol_map:
   573                         # Only preserve, delete, use_existing are allowed
   571                         # Only preserve, delete, use_existing are allowed
   574                         if new_zvol.action not in \
   572                         if new_zvol.action not in \
   575                             ["preserve", "delete", "use_existing"]:
   573                             ["preserve", "delete", "use_existing"]:
   576                             raise SelectionError("Zvol '%s' specified on "
   574                             raise SelectionError("Zvol '%s' specified on "
   577                                 "preserved zpool '%s' contains invalid action "
   575                                 "preserved zpool '%s' contains invalid action "
   578                                 "of '%s'."
   576                                 "of '%s'." % \
   579                                 (new_zvol.name, zpool.name, new_zvol.action))
   577                                 (new_zvol.name, zpool.name, new_zvol.action))
   580 
   578 
   581                         discovered_zvol = discovered_zpool.get_first_child(
   579                         discovered_zvol = discovered_zpool.get_first_child(
   582                             new_zvol.name, Zvol)
   580                             new_zvol.name, Zvol)
   583 
   581 
   592                                     (new_zvol.name))
   590                                     (new_zvol.name))
   593                             elif discovered_zvol.use == "dump":
   591                             elif discovered_zvol.use == "dump":
   594                                 # Cannot delete a dump zvol
   592                                 # Cannot delete a dump zvol
   595                                 self.__raise_dump_zvol_deletion_exception()
   593                                 self.__raise_dump_zvol_deletion_exception()
   596 
   594 
   597                             elif new_zovl.use == "dump":
   595                             elif new_zvol.use == "dump":
   598                                 # Can only specify one Dump Zvol
   596                                 # Can only specify one Dump Zvol
   599                                 if self._dump_zvol is not None:
   597                                 if self._dump_zvol is not None:
   600                                     raise SelectionError(
   598                                     raise SelectionError(
   601                                         "Dump zvol specified twice.")
   599                                         "Dump zvol specified twice.")
   602 
   600 
   641                     else:
   639                     else:
   642                         # Only create allowed for new zvol
   640                         # Only create allowed for new zvol
   643                         if new_zvol.action != "create":
   641                         if new_zvol.action != "create":
   644                             raise SelectionError("Zvol '%s' specified on "
   642                             raise SelectionError("Zvol '%s' specified on "
   645                                 "preserved zpool '%s' contains invalid action "
   643                                 "preserved zpool '%s' contains invalid action "
   646                                 "of '%s'."
   644                                 "of '%s'." % \
   647                                 (new_zvol.name, zpool.name, new_zvol.action))
   645                                 (new_zvol.name, zpool.name, new_zvol.action))
   648                         self._zvol_map[zvol_key] = new_zvol
   646                         self._zvol_map[zvol_key] = new_zvol
   649 
   647 
   650                     self._zvol_map[zvol_key] = new_zvol
   648                     self._zvol_map[zvol_key] = new_zvol
   651                     self.logger.debug("Adding Zvol '%s' to zpool" %
   649                     self.logger.debug("Adding Zvol '%s' to zpool" %
   926                                     if slc.in_zpool is not None and \
   924                                     if slc.in_zpool is not None and \
   927                                         slc.in_zpool == zpool.name:
   925                                         slc.in_zpool == zpool.name:
   928                                         disk_found = True
   926                                         disk_found = True
   929                                         break
   927                                         break
   930 
   928 
   931                     elif isinstance(disk_kd, Slice):
   929                     elif isinstance(disk_kid, Slice):
   932                         if disk_kid.in_zpool is not None and \
   930                         if disk_kid.in_zpool is not None and \
   933                             disk_kid.in_zpool == zpool.name:
   931                             disk_kid.in_zpool == zpool.name:
   934                             disk_found = True
   932                             disk_found = True
   935                             break
   933                             break
   936 
   934 
  2301                 else:
  2299                 else:
  2302                     if isinstance(parent_object, Disk):
  2300                     if isinstance(parent_object, Disk):
  2303                         raise SelectionError(
  2301                         raise SelectionError(
  2304                             "Cannot %s slice %s that doesn't exist on disk %s"
  2302                             "Cannot %s slice %s that doesn't exist on disk %s"
  2305                             % (orig_slice.action, orig_slice.name,
  2303                             % (orig_slice.action, orig_slice.name,
  2306                             self.__pretty_print_disk(discovered_disk)))
  2304                             self.__pretty_print_disk(parent_object)))
  2307                     else:
  2305                     else:
  2308                         raise SelectionError(
  2306                         raise SelectionError(
  2309                             "Cannot %s slice %s that doesn't exist on "
  2307                             "Cannot %s slice %s that doesn't exist on "
  2310                             "partition %s, disk %s" % (orig_slice.action,
  2308                             "partition %s, disk %s" % (orig_slice.action,
  2311                             orig_slice.name, parent_object.name,
  2309                             orig_slice.name, parent_object.name,
  2753 
  2751 
  2754         # Check error service for errors
  2752         # Check error service for errors
  2755         errors = errsvc.get_all_errors()
  2753         errors = errsvc.get_all_errors()
  2756 
  2754 
  2757         # Found errors and they cannot be ignored
  2755         # Found errors and they cannot be ignored
  2758         if errors and not self.__can_ignore_errors(errors):
  2756         if errors:
  2759             # Print desired contents to log
  2757             # Print desired contents to log
  2760             existing_desired = \
  2758             existing_desired = \
  2761                 self.doc.persistent.get_first_child(Target.DESIRED)
  2759                 self.doc.persistent.get_first_child(Target.DESIRED)
  2762             if existing_desired:
  2760             if existing_desired:
  2763                 self.logger.debug("Desired =\n%s\n" % (str(existing_desired)))
  2761                 self.logger.debug("Desired =\n%s\n" % (str(existing_desired)))
  2765             errstr = "Following errors occurred processing disks :\n%s" % \
  2763             errstr = "Following errors occurred processing disks :\n%s" % \
  2766                 (str(errors[0]))
  2764                 (str(errors[0]))
  2767             raise SelectionError(errstr)
  2765             raise SelectionError(errstr)
  2768 
  2766 
  2769         return ret_disk
  2767         return ret_disk
  2770 
       
  2771     def __can_ignore_errors(self, errors):
       
  2772         '''
       
  2773             Process list of errors found in error service, and make a
       
  2774             judgement call on whether we can ignore them.
       
  2775 
       
  2776             Add errors being ignored and reasoning here.
       
  2777 
       
  2778             Errors to ignore for physical :
       
  2779             - SliceInUseError() we are overriding this existing slice
       
  2780               so we can ignore.
       
  2781         '''
       
  2782         return False
       
  2783         can_ignore = True
       
  2784 
       
  2785         for error in errors:
       
  2786             for key in error.error_data:
       
  2787                 if error.mod_id == "physical validation" and \
       
  2788                     isinstance(error.error_data[key], \
       
  2789                         ShadowPhysical.SliceInUseError):
       
  2790                     # We can ignore, just pass onto next error
       
  2791                     pass
       
  2792                 else:
       
  2793                     # Error does not match one we can ignore, so set return
       
  2794                     # value and break.
       
  2795                     can_ignore = False
       
  2796                     break
       
  2797 
       
  2798         return can_ignore
       
  2799 
  2768 
  2800     def __create_temp_logical_tree(self, existing_logicals):
  2769     def __create_temp_logical_tree(self, existing_logicals):
  2801         '''Create a set of logicals that we will use should there be no other
  2770         '''Create a set of logicals that we will use should there be no other
  2802            logicals defined in the manifest.
  2771            logicals defined in the manifest.
  2803         '''
  2772         '''