def autogenerate_boot_instances(bootconfig): sbia = SolarisBootInstanceAutogenerator() # XXX - Handle bootconfig instances that have boot_class != disk if bootconfig.boot_class != BootConfig.BOOT_CLASS_DISK: raise BootmgmtUnsupportedOperationError('XXX - Fix Me') # Use libbe_py to get the list of boot environments, then iterate # over the list, creating a new SolarisDiskBootInstance for each # Note that the title will just be the last portion of the bootfs # (i.e. <pool>/ROOT/<title>) retcode, belist = libbe_py.beList() if retcode != 0: sbia._debug('libbe_py.beList() failed; return code was ' + str(retcode)) return [] inst_list = [] for bootenv in belist: if bootenv.get('orig_be_name', None) is None: continue # skip over snapshots bootinst = SolarisDiskBootInstance(None, title=bootenv['orig_be_name'], bootfs=bootenv['root_ds']) if bootenv['active'] is True: sbia._debug('default boot instance is:\n' + str(bootinst)) bootinst.default = True inst_list.append(bootinst) return inst_list
def getActiveBEAndActiveOnBootBE(): """Return the 'active on boot' BE, the 'active' BE or None.""" active_be = None active_be_on_boot = None rc, be_list = lb.beList() if rc != 0: if rc == msg.Msgs.BE_ERR_BE_NOENT: string = msg.getMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST) else: string = lb.beGetErrDesc(rc) if string == None: string = msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1) return None for be_vals in be_list: srcBeName = be_vals.get("orig_be_name") if be_vals.get("active"): active_be = srcBeName if be_vals.get("active_boot"): active_be_on_boot = srcBeName if active_be is not None and active_be_on_boot is not None: break return active_be, active_be_on_boot
def getActiveBEAndActiveOnBootBE(): """Return the 'active on boot' BE, the 'active' BE or None.""" active_be = None active_be_on_boot = None rc, be_list = lb.beList() if rc != 0: if rc == msg.Msgs.BE_ERR_BE_NOENT: string = \ msg.getMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST) else: string = lb.beGetErrDesc(rc) if string == None: string = \ msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1) return None for be_vals in be_list: srcBeName = be_vals.get("orig_be_name") if be_vals.get("active"): active_be = srcBeName if be_vals.get("active_boot"): active_be_on_boot = srcBeName if active_be is not None and active_be_on_boot is not None: break return active_be, active_be_on_boot
def get_be_list(): # Check for the old beList() API since pkg(1) can be # back published and live on a system without the # latest libbe. rc = 0 beVals = be.beList() if isinstance(beVals[0], int): rc, beList = beVals else: beList = beVals if not beList or rc != 0: beList = [] return beList
def get_be_list(raise_error=False): # This check enables the test suite to run much more quickly. # It is necessary because pkg5unittest (eventually) imports this # module before the environment is sanitized. if "PKG_NO_LIVE_ROOT" in os.environ: return BootEnvNull.get_be_list() rc, beList = be.beList(nosnaps=True) if not beList or rc != 0: if raise_error: # Happens e.g. in zones (for now) or live CD # environment. raise RuntimeError("nobootenvironments") beList = [] return beList
def list(opts): """ Description: List the attributes of a Boot Environment. The following is the subcommand, options and args that make up the opts object passed in: list [[-a] | [-d] [-s]] [-H] [beName] -a displays all info -d displays BE info plus dataset info -s displays BE info plus snapshot info -H displays info parsable by a computer Parameters: opts - A object containing the list subcommand and all the options and arguments passed in on the command line mentioned above. Returns: 0 - Success 1 - Failure """ be = BootEnvironment() list_all_attrs = "" list_datasets = "" list_snapshots = "" dont_display_headers = False be_name = None be_list = None # Counters for detecting multiple options. # e.g. beadm list -a -a newbe num_a_opts = 0 num_d_opts = 0 num_s_opts = 0 num_h_opts = 0 try: opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, "adHs") except getopt.GetoptError: msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) usage() for opt, arg in opts_args: if opt == "-a": list_all_attrs = opt num_a_opts += 1 elif opt == "-d": list_datasets = opt num_d_opts += 1 elif opt == "-s": list_snapshots = opt num_s_opts += 1 elif opt == "-H": dont_display_headers = True num_h_opts += 1 if num_a_opts > 1 or num_d_opts > 1 or num_s_opts > 1 or num_h_opts > 1: msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) usage() if len(be.trgt_be_name_or_snapshot) > 1: msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) usage() if len(be.trgt_be_name_or_snapshot) == 1: be_name = be.trgt_be_name_or_snapshot[0] if lb.beVerifyBEName(be_name) != 0: msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) return 1 if list_all_attrs == "-a" and (list_datasets == "-d" or list_snapshots == "-s"): msg.printMsg(msg.Msgs.BEADM_ERR_MUTUALLY_EXCL, list_all_attrs + " " + list_datasets + " " + list_snapshots, -1) usage() list_options = "" # When zones are implemented add "listZones == "-z" below # Coelesce options to pass to displayBEs if list_datasets == "-d" and list_snapshots == "-s" or list_all_attrs == "-a": list_options = "-a" elif list_datasets != "" or list_snapshots != "" or list_all_attrs != "": list_options = list_datasets + " " + list_snapshots rc, be_list = lb.beList() if rc != 0: if rc == msg.Msgs.BE_ERR_BE_NOENT: if be_name == None: msg.printMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST, None, -1) return 1 string = msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, be_name) else: string = lb.beGetErrDesc(rc) if string == None: string = msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1) return 1 # classify according to command line options if list_options.find("-a") != -1 or (list_options.find("-d") != -1 and list_options.find("-s") != -1): list_object = CompleteList(dont_display_headers) # all elif list_options.find("-d") != -1: list_object = DatasetList(dont_display_headers) # dataset elif list_options.find("-s") != -1: list_object = SnapshotList(dont_display_headers) # snapshot else: list_object = BEList(dont_display_headers) # only BE # use list method for object if list_object.list(be_list, dont_display_headers, be_name) != 0: msg.printMsg(msg.Msgs.BEADM_ERR_LIST_DATA, None, -1) return 1 return 0
logging.debug("Displaying screen: %s", type(SCREEN)) SCREEN = SCREEN.show(INSTALL_PROFILE) if not OPTIONS.debug and CTRL_C is None: # This prevents the user from accidentally hitting # ctrl-c halfway through the install. Ctrl-C is left # available through the first screen in case terminal # display issues make it impossible for the user to # quit gracefully CTRL_C = signal.signal(signal.SIGINT, signal.SIG_IGN) cleanup_curses() ERRCODE = 0 finally: cleanup_curses() except RebootException: if INSTALL_PROFILE.is_x86: RET_VAL, BE_LIST = libbe_py.beList() if RET_VAL == 0: for be in BE_LIST: if be.get("active_boot", False): root_ds = be['root_ds'] call_cmd = ["/usr/sbin/reboot", "-f", "--", root_ds] try: subprocess.call(call_cmd) except OSError, err: logging.warn("Fast reboot failed:\n\t'%s'\n%s", " ".join(call_cmd), err) else: logging.warn( "Fast reboot failed. Will attempt" " standard reboot\n(Fast reboot " "args:%s)", " ".join(call_cmd))
def __init__(self, root): self.be_name = None self.dataset = None self.be_name_clone = None self.clone_dir = None self.img = None self.is_live_BE = False self.is_valid = False self.snapshot_name = None self.root = root rc = 0 assert root != None # Check for the old beList() API since pkg(1) can be # back published and live on a system without the latest libbe. beVals = be.beList() if isinstance(beVals[0], int): rc, self.beList = beVals else: self.beList = beVals # Happens e.g. in zones (at least, for now) if not self.beList or rc != 0: raise RuntimeError, "nobootenvironments" # Need to find the name of the BE we're operating on in order # to create a snapshot and/or a clone of the BE. for i, beVals in enumerate(self.beList): # pkg(1) expects a directory as the target of an # operation. BootEnv needs to determine if this target # directory maps to a BE. If a bogus directory is # provided to pkg(1) via -R, then pkg(1) just updates # '/' which also causes BootEnv to manage '/' as well. # This should be fixed before this class is ever # instantiated. be_name = beVals.get("orig_be_name") # If we're not looking at a boot env entry or an # entry that is not mounted then continue. if not be_name or not beVals.get("mounted"): continue # Check if we're operating on the live BE. # If so it must also be active. If we are not # operating on the live BE, then verify # that the mountpoint of the BE matches # the -R argument passed in by the user. if root == '/': if not beVals.get("active"): continue else: self.is_live_BE = True else: if beVals.get("mountpoint") != root: continue # Set the needed BE components so snapshots # and clones can be managed. self.be_name = be_name self.dataset = beVals.get("dataset") # Let libbe provide the snapshot name err, snapshot_name = be.beCreateSnapshot(self.be_name) self.clone_dir = tempfile.mkdtemp() # Check first field for failure. # 2nd field is the returned snapshot name if err == 0: self.snapshot_name = snapshot_name else: logger.error( _("pkg: unable to create an auto " "snapshot. pkg recovery is disabled.")) raise RuntimeError, "recoveryDisabled" self.is_valid = True break else: # We will get here if we don't find find any BE's. e.g # if were are on UFS. raise RuntimeError, "recoveryDisabled"
def list(opts): """ Description: List the attributes of a Boot Environment. The following is the subcommand, options and args that make up the opts object passed in: list [[-a] | [-d] [-s]] [-H] [beName] -a displays all info -d displays BE info plus dataset info -s displays BE info plus snapshot info -H displays info parsable by a computer Parameters: opts - A object containing the list subcommand and all the options and arguments passed in on the command line mentioned above. Returns: 0 - Success 1 - Failure """ be = BootEnvironment() list_all_attrs = "" list_datasets = "" list_snapshots = "" dont_display_headers = False be_name = None be_list = None # Counters for detecting multiple options. # e.g. beadm list -a -a newbe num_a_opts = 0 num_d_opts = 0 num_s_opts = 0 num_h_opts = 0 try: opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, "adHs") except getopt.GetoptError: msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) usage() for opt, arg in opts_args: if opt == "-a": list_all_attrs = opt num_a_opts += 1 elif opt == "-d": list_datasets = opt num_d_opts += 1 elif opt == "-s": list_snapshots = opt num_s_opts += 1 elif opt == "-H": dont_display_headers = True num_h_opts += 1 if num_a_opts > 1 or num_d_opts > 1 or num_s_opts > 1 or num_h_opts > 1: msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) usage() if len(be.trgt_be_name_or_snapshot) > 1: msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) usage() if len(be.trgt_be_name_or_snapshot) == 1: be_name = be.trgt_be_name_or_snapshot[0] if lb.beVerifyBEName(be_name) != 0: msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) return 1 if (list_all_attrs == "-a" and (list_datasets == "-d" \ or list_snapshots == "-s")): msg.printMsg(msg.Msgs.BEADM_ERR_MUTUALLY_EXCL, list_all_attrs + " " + list_datasets + " " + list_snapshots, -1) usage() list_options = "" # When zones are implemented add "listZones == "-z" below # Coelesce options to pass to displayBEs if (list_datasets == "-d" and list_snapshots == "-s" or \ list_all_attrs == "-a"): list_options = "-a" elif list_datasets != "" or list_snapshots != "" or list_all_attrs != "": list_options = list_datasets + " " + list_snapshots rc, be_list = lb.beList() if rc != 0: if rc == msg.Msgs.BE_ERR_BE_NOENT: if be_name == None: msg.printMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST, None, -1) return 1 string = \ msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, be_name) else: string = lb.beGetErrDesc(rc) if string == None: string = \ msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1) return 1 # classify according to command line options if list_options.find("-a") != -1 or \ (list_options.find("-d") != -1 and list_options.find("-s") != -1): list_object = CompleteList(dont_display_headers) #all elif list_options.find("-d") != -1: list_object = DatasetList(dont_display_headers) #dataset elif list_options.find("-s") != -1: list_object = SnapshotList(dont_display_headers) #snapshot else: list_object = BEList(dont_display_headers) #only BE # use list method for object if list_object.list(be_list, dont_display_headers, be_name) != 0: msg.printMsg(msg.Msgs.BEADM_ERR_LIST_DATA, None, -1) return 1 return 0
def __init__(self, root): self.be_name = None self.dataset = None self.be_name_clone = None self.clone_dir = None self.img = None self.is_live_BE = False self.is_valid = False self.snapshot_name = None self.root = root rc = 0 assert root != None # Check for the old beList() API since pkg(1) can be # back published and live on a system without the latest libbe. beVals = be.beList() if isinstance(beVals[0], int): rc, self.beList = beVals else: self.beList = beVals # Happens e.g. in zones (at least, for now) if not self.beList or rc != 0: raise RuntimeError, "nobootenvironments" # Need to find the name of the BE we're operating on in order # to create a snapshot and/or a clone of the BE. for i, beVals in enumerate(self.beList): # pkg(1) expects a directory as the target of an # operation. BootEnv needs to determine if this target # directory maps to a BE. If a bogus directory is # provided to pkg(1) via -R, then pkg(1) just updates # '/' which also causes BootEnv to manage '/' as well. # This should be fixed before this class is ever # instantiated. be_name = beVals.get("orig_be_name") # If we're not looking at a boot env entry or an # entry that is not mounted then continue. if not be_name or not beVals.get("mounted"): continue # Check if we're operating on the live BE. # If so it must also be active. If we are not # operating on the live BE, then verify # that the mountpoint of the BE matches # the -R argument passed in by the user. if root == '/': if not beVals.get("active"): continue else: self.is_live_BE = True else: if beVals.get("mountpoint") != root: continue # Set the needed BE components so snapshots # and clones can be managed. self.be_name = be_name self.dataset = beVals.get("dataset") # Let libbe provide the snapshot name err, snapshot_name = be.beCreateSnapshot(self.be_name) self.clone_dir = tempfile.mkdtemp() # Check first field for failure. # 2nd field is the returned snapshot name if err == 0: self.snapshot_name = snapshot_name else: logger.error(_("pkg: unable to create an auto " "snapshot. pkg recovery is disabled.")) raise RuntimeError, "recoveryDisabled" self.is_valid = True break else: # We will get here if we don't find find any BE's. e.g # if were are on UFS. raise RuntimeError, "recoveryDisabled"