iVc@shdZddlZddlZddlZddlZddlZddlZddlmZm Z m Z m Z m Z m Z mZmZmZddlmZmZmZddlmZddlmZmZmZmZmZmZddlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'defd YZ(d e(fd YZ)d e(fd YZ*de*fdYZ+de(fdYZ,defdYZ-de-fdYZ.de-fdYZ/de/fdYZ0de/fdYZ1de/fdYZ2dZ3dej4fd YZ5d!Z6e7d"krdej8ndS(#s6 Abstractions for boot configuration management. A BootConfig object aggregates the boot configuration for a system. Implementations are provided for active systems (systems that boot from disk devices) as well as for installation image creation (i.e. for network-based installation images, optical disc installation images, and USB-based installation images). BootConfig provides access, through abstractions, to the system boot loader, general system boot configuration variables, and the set of bootable instances that the boot loader provides a means to boot. iN( tBootmgmtNotSupportedErrortBootmgmtArgumentErrortBootmgmtMissingInfoErrort BootmgmtErrort!BootmgmtUnsupportedOperationErrort BootmgmtUnsupportedPlatformErrortBootmgmtConfigReadErrortBootmgmtZFSErrortBootmgmtBootPoolFailureError(tbootinfot bootloadertzfs(tCredentialStore(t LoggerMixintget_current_arch_stringt bootfs_splitt parse_booltget_zpool_default_bootfst scrub_kargs( t libzfs_initt libzfs_finit zpool_opent zpool_closetzpool_get_physpathtzpool_set_proptzpool_get_proptZPOOL_PROP_BOOTFStZPOOL_PROP_REALNAMEtlibzfs_error_descriptiont BootConfigcBs|eZdZed\ZZZZZZ dZ dZ dZ dZ dZdZdZd Zd Zd Zd Zed \ZZZZZZZedZejdZdZdZ dZ!dZ"dZ#edZ$edZ%e&dZ'dZ(dZ)dZ*ddZ+ddZ,e-dZ.dZ/d#d#e1d#d#d Z2d!Z3d"Z4RS($s2Abstract base class for boot configuration classesitdisktnettoddt systemroottfilesfile-netconfigszvmm-eltorito-imagesbios-eltorito-imagesuefi-eltorito-imagesnbp-platform-0x0000snbp-platform-0x0007icCs|jS(N(t_dirty(tself((s#../../common/bootmgmt/bootconfig.pytdirty]scCs/|j|kr+|jd|||_ndS(Ns dirty => %s(R#t_debug(R$tval((s#../../common/bootmgmt/bootconfig.pyR%ascKsVt|_g|_|jd|_|jd|_|jd|_|jd k rt|jt t f st |jdkrt dnt |_t ||_|j||_t |_|jdt |_tj|jkrtj|jkrtdntj|jkr4|j|n|jrtjj|jjkr|jdt|jj|j|nky|j|Wn)t k rtj!|jkrqnXtj"|jkr|j#d n t |_$tj%|jkr|j&|nt'|_g|jD]}|j(r!|^q!}|rRt'|d _)nd S( sB Initialize the basic set of attributes for all BootConfig classes ----------------------------------------------------------------- Argument| Valid Value(s) --------+-------------------------------------------------------- flags | [tuple] | | Allowed values in the tuple: | ---------------------------- | BootConfig.BCF_CREATE: Create a new boot | configuration. If one already | exists, it will be discarded. | If this flag is not present and | no boot configuration exists, | an exception | (BootmgmtConfigReadError) | will be raised. | BootConfig.BCF_ONESHOT:If True, only the final boot | configuration files will be | created when the | commit_boot_config() is called. | This is useful for one-shot | creation of boot configurations | for installation media. | BootConfig.BCF_AUTOGEN:The set of boot instances will be | automatically generated by | scanning the system. The list of | boot instances found by the scan | will be available after | the BootConfig object is created. | This set of boot instances can | then be tailored before calling | commit_boot_config(). Note that | the set of BootInstance objects | added to this object's boot_instances | are only guaranteed to include | Solaris boot instances. | BootConfig.BCF_MIGRATE:If supported, the existing boot | configuration will be migrated | from an older form to a newer | form (i.e. conversion from legacy | GRUB's menu.lst to GRUB2's | configuration format). The conversion | is performed at commit_boot_config() | time. Cannot be used with the | BCF_CREATE flag. | BootConfig.BCF_NO_LOAD_BOOT_INSTANCES: Omits boot instances | from the set of configuration data | loaded. | BootConfig.BCF_LOAD_SILENT_FAILURE: Does not raise an | exception when loading configuration | data fails. Using this allows a | partial set of configuration data to | be read. | platform| [optional] The target system architecture / firmware tuple for (keyword| which this boot configuration will be written. Useful arg) | for the creation of boot configuration files for network | boot instances, or when a boot configuration is created | on a system of a different architecture / firmware than | the target. If this is not supplied, the assumption is | that the boot configuration will be for the current | system. Supported tuple values are: | { ('sparc', 'obp'), | ('x86', 'bios'), | ('x86', 'uefi64'), | ('x86', 'zvmm') } | A firmware value of None means that the boot | configuration will be written for all supported | firmware types for the specified architecture. Note | that not all BootConfig subclasses support this | wildcard platform firmware specification. | If a particular BootConfig subclass does not support | manipulation of a different platform's boot | configuration, a BootmgmtNotSupportedError will be | raised. loader\ | class | The class corresponding to the BootLoader that the | BootConfig's creator requests wants to be this | BootConfig's BootLoader. If this BootLoader cannot be | used, a BootmgmtInvalidBootloaderError is raised. | verbose | True if BootConfig (or subordinate) operation should | be verbosely printed to sys.stderr. ----------------------------------------------------------------- t boot_classt boot_fstypetplatformisBInvalid platform value specified. Expected 2-tuple or 2-item listtverboses*Migration cannot be combined with creationsCONFIGFILE artifact not present. Will not attempt to load boot loader configuration. Creating new boot configuration instead. artifacts were %s.cSstS(N(tTrue(tx((s#../../common/bootmgmt/bootconfig.pytsiN(*R t credentialtboot_instancestgetR(R)t _platformtNonet isinstancettupletlisttlenRtFalseR#t_flagst_get_boot_loadert boot_loadert track_changesR+Rt BCF_CREATEt BCF_MIGRATERt_new_boot_configR t BootLoadertARTIFACT_BOOTLOADER_CONFIGFILESt artifactsR&tstrt_load_boot_configRtBCF_LOAD_SILENT_FAILUREtBCF_NO_LOAD_BOOT_INSTANCEStdelete_boot_instanceR%t BCF_AUTOGENt_autogenerate_configR,tdefaultt last_default(R$tflagstkwargsR-tdefaults((s#../../common/bootmgmt/bootconfig.pyt__init__gsPY            %cKsPddlm}|j|}t|dkrL|j|7_t|_ndS(Ni(tBootInstanceAutogenFactoryi(tbootmgmt.backend.autogenRPtautogenR7R0R,R%(R$RMRPt inst_list((s#../../common/bootmgmt/bootconfig.pyRIs cKsdS(s`[Implemented by child classes] Loads the boot configuration (with guidance from kwargs).N((R$RM((s#../../common/bootmgmt/bootconfig.pyRDscKsdS(s{[Implemented by child classes] Initializes this instance with a new boot configuration (with guidance from kwargs).N((R$RM((s#../../common/bootmgmt/bootconfig.pyR?scKs,tjjd||}|jd||S(s'Initializes this instance's boot_loadert bootconfigs loader = %s(R R@R1R&(R$RMtloader((s#../../common/bootmgmt/bootconfig.pyR:scCs|jr|jdSdS(sBReturns the requested platform string for this BootConfig iN(R2(R$((s#../../common/bootmgmt/bootconfig.pytplatform_requested s cCs|jr|jdSdS(sBReturns the requested firmware string for this BootConfig iN(R2(R$((s#../../common/bootmgmt/bootconfig.pytfirmware_requesteds c Cs|s |Sg}x|D]}t|dkrL|ddkrLd|}nW|jddkry|jddd}n*y8tj|}tj|jr|j|wnWn&tk r}t d||nXy|j dd \}}} Wnt k rd }nHXtj j|d || }ytj|Wntk rYd }nX|d krtjd d rtj j|rqntd |n|j|qW|S(sGiven a list of devices, transform them into character-device equivalents, suitable for passing to BootLoader.install() it/s /dev/rdsk/s/dsk/is/rdsk/isProblem accessing %sitrtBOOTMGMT_TESTINGsGUnknown device path scheme -- cannot determine character device for %s.N(R7tfindtreplacetoststattS_ISCHRtst_modetappendtOSErrorRtrsplitt ValueErrorR3tpathtjointgetenvtisfileR( tclstdevlistt newdevlisttdevtrdsktsttosetbasetparenttlast((s#../../common/bootmgmt/bootconfig.pyt_complete_boot_device_lists@ "         cCsgS(s>Abstract method for determining list of boot devices. ((R$((s#../../common/bootmgmt/bootconfig.pyt_get_boot_device_list_implRscCs|j}|j|}|S(sYReturns a list of devices that the boot loader should be installed onto. (RtRs(R$Rjt final_devlist((s#../../common/bootmgmt/bootconfig.pytget_boot_device_listWs cCsdS(s<Return the root directory where this BootConfig is be storedN(R3(R$((s#../../common/bootmgmt/bootconfig.pytget_root_sicCsct|tjrOxJ|D]/}|j|||dkr|d}qqWn|j||dS(sq Adds one or more new boot instances to this boot configuration. boot_instance is a list of BootInstance references or a single BootInstance reference. The where argument determines where in the ordered list of boot instances this boot instance entry will be placed. The default is -1, which means the end of the list of boot instances. If where is a callable object, it will be used to iterate through the boot instances list. If it returns a negative value, the boot_instance will be inserted BEFORE that item; If it returns a positive value, the boot_instance will be inserted AFTER that item; If it returns 0, no insertion will occur at that point in the iteration. The arguments to the function are (, boot_instance). iiN(R4t collectionstIterablet_add_one_boot_instance(R$R0twheretinstance((s#../../common/bootmgmt/bootconfig.pytadd_boot_instancecs   c Csd}|jtkrrg|jD]}|jtkr|^q}t|dkrr|d}|jd|qrnt|tkr|dkr|n t|j}|g|j||+||_t|_ nt |r}xt |jD]\}}|||}|dkr9|g|j||+||_t|_ Pq|dkr|g|j|d|d+||_t|_ PqqWn t d|dk rt |_ndS(NisPrevious default was: %sis The where parameter is malformed(R3RJR,R0R7R&ttypetintt _bootconfigR%tcallablet enumerateRR8( R$t boot_instanceR{t prevDefaultR-RNtindextinsttwhereval((s#../../common/bootmgmt/bootconfig.pyRzs8 !            cs|tkrht|j}tfd|j|_t|j}||kr`t|_n||SxFt|jD]5\}}|tkrx|j|=t|_dSqxWdSdS(s\ Deletes one or more boot instances from the boot configuration. filter_func is a function that takes a single argument (a BootInstance). If it returns True, that BootInstance is removed from the boot configuration. The 'all' parameter is True if all matching boot instances are to be deleted. If False, only the first instance for which filter_func returns True is deleted. For example: delete_boot_instance(lambda x: x.title == 'snv_158') will delete all boot instances whose titles match 'snv_158'. cs | S(N((R-(t filter_func(s#../../common/bootmgmt/bootconfig.pyR.siiN(R,R7R0tfilterR%R(R$RtalltoldlentnewlentidxR((Rs#../../common/bootmgmt/bootconfig.pyRGs     cCs+x$t||jD]}||qWdS(sC Applies mod_func to all boot instances for which filter_func returns True. This is shorthand for: for bi in filter(filter_func, bootconfig_obj.boot_instances): mod_func(bi) (The (single) argument to filter_func and mod_func is a BootInstance ref). N(RR0(R$Rtmod_funcR((s#../../common/bootmgmt/bootconfig.pytmodify_boot_instances c Cs|jd|||f|js1tdn|dkrZ|sR|jtkrxQ|jD]C}|jdk r\|s|jjtkr\|jjd|q\q\Wn|s|jtks|jjtkr|jj ||||n|jd|j r |j nxG|jD]<}t |ddtkr=|` n|jrt|_ qqWdSg}xN|jD]C}|jdk rj|jj||}|r|j|qqjqjW|jdk r|jj |} | r|j| qn|jd||j r|j n|SdS(sWrites the boot configuration (including boot instances and boot loader settings) to stable storage. If this object was created with the BootConfig.BC_ONESHOT flag, then only the final boot configuration file(s) will be created (i.e. the Legacy GRUB menu.lst, GRUB2 configuration file, or SPARC menu.lst)-- any other state files that store boot configuration information will not be written (customizations to this boot configuration may not persist). This may prevent incremental modifications to the boot configuration from being possible (depending on the boot loader in use). BC_ONESHOT should only be used when creating a boot configuration that is not intended to change (i.e. when creating a boot configuration for use with an install image, not a running system). boot_devices is a list of strings, each of which is the path to a character-special device where the boot loader should be installed. This argument should be omitted when the consumer desires to write the boot configuration files to a temporary directory. If temp_dir is not None, then the set of files that constitute the boot configuration is written to a temporary directory (and not to the official location(s)). (temp_dir must exist or an IOError will be raised). When files are written to temp_dir, commit_boot_config() returns a list of 7-tuples of the following form: (, , , , , , ) Each of these tuples describes a boot configuration file that was written, along with the required system-relative path where it must be copied. This enables a consumer to install the file(s) into the correct place(s) on a system or install image without having to hard-code knowledge of the filenames)). For example: [('file', '/tmp/bc.Jzx1cZa/boot/solaris/bootenv.rc', , '%(systemroot)s/boot/solaris/bootenv.rc', 'root', 'sys', 0644)] The value in the tuple identifies the type of file in the tuple. This is useful for conveying platform-specific attributes of a particular file. For example, could be 'eltorito' to identify an eltorito boot image, which a consumer would recognize and then use to supply the argument to `mkisofs -b`. See child class definitions for additional values. Only ='file' is defined at the BootConfig level. The element, if not None, is a reference to a BootInstance object. It provides clarification for tokens that are embedded in the destination path. In the above example, the `systemroot' token refers to the root path of the Solaris BE identified by the SolarisDiskBootInstance object in the tuple. In this example, including the object allows the consumer to resolve the root path location. Note the use of Python string-formatting tokens, for which a consumer must supply definitions. The following list of tokens are defined at the BootConfig level; child classes may define additional tokens: ---------------------------------------------------------------- Token Name | Meaning ------------------+--------------------------------------------- systemroot | The path to a boot instance's mounted root | filesystem. [string] ---------------------------------------------------------------- s:commit_boot_config: temp_dir=%s, boot_devices=%s, force=%ssA boot loader could not be established for this boot configuration (this is usually due to missing boot loader files). The system cannot be guaranteed to be bootable.Rs return NoneRKs return %sN(R&R;RR3R%R,R0t boot_varstwritetinstallR<treset_tracked_changestgetattrRKRJtextend( R$ttemp_dirt boot_devicestforcet verbose_filetplatdictRt tuple_listt bv_tuplest bl_tuples((s#../../common/bootmgmt/bootconfig.pytcommit_boot_configsHC   '        cCs-x&|jD]}|jr d|_q q WdS(sClears retained original values tracked by each boot instance in the boot instance list. Typically useful after changed have been committed to stable storage. N(R0toriginal_valuesR3(R$R((s#../../common/bootmgmt/bootconfig.pyREs cCs9d|jrdndd}|d|jdk r;|jndd7}|d|jdk re|jndd7}|d tt|jd7}xYt|jD]H\}}|d t|d 7}|d t|jdd d7}qW|d7}|j dk r+|d7}|t|j d7}n |d7}|S(NsState: R%tcleans sClass: tnonesFSType: tunknownsBoot instances: s===[ Instance s ]=== s s s===[ End Boot Instances ]=== s Boot loader: sNo boot loader( R%R(R3R)RCR7R0RR\R;(R$tsRR((s#../../common/bootmgmt/bootconfig.pyt__str__Ns ' !(   N(5t__name__t __module__t__doc__trangeR=t BCF_ONESHOTRHR>RFREtBOOT_CLASS_DISKtBOOT_CLASS_NETtBOOT_CLASS_ODDtTOKEN_SYSTEMROOTtOUTPUT_TYPE_FILEtOUTPUT_TYPE_NETCONFIGtOUTPUT_TYPE_ZVMM_ELTORITOtOUTPUT_TYPE_BIOS_ELTORITOtOUTPUT_TYPE_UEFI_ELTORITOtOUTPUT_TYPE_BIOS_NBPtOUTPUT_TYPE_UEFI64_NBPt IDX_FILETYPEt IDX_TEMPNAMEt IDX_INSTANCEt IDX_DESTNAMEtIDX_USERt IDX_GROUPtIDX_MODEtpropertyR%tsetterRORIRDR?R:RVRWt classmethodRsRtRvRwR}RzR,RGRR3R8RRR(((s#../../common/bootmgmt/bootconfig.pyR;sF !    8     %  t tDiskBootConfigcBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZddZdZddedddZdZRS(sA class for managing the boot configuration stored on hard disk-like storage devices. Handles Solaris boot configurations stored in ZFS root pools and on devices with a UFS root filesystemtrpnamettldpathtzfspathtset_bootfs_on_committvalidate_bootfst rpool_onlytufsroott no_create_bptrpool_top_datasetcKs|jdd}|dk rJ|dtkrJt|jjdnd}tj|krtj|krd}|jtj d|_ |tj|_ |tj|_ |jtj t|_n(tj|krd}|tj|_ n|dkr tdntj|kr,|tj|_n t|_tj|krW|tj|_n t|_t|j|j|dtjd ||d dl}yStj|kr|jj|d t|_n|jj||_|jjWn,tk r}d|_|jd |nXdS( NR*is, does not support cross-processor operationsR RXtufssQThe filesystem type supplied to the DiskBootConfig constructor was not recognizedR(R)itautocreate_bootpools"VersaBoot instantiation failed: %s( R1R3RRt __class__RRtARG_ZFS_RPNAMEtARG_ZFS_TLDPATHtARG_ZFS_SYSROOT_PATHtsysroottzfstoptzfsrptARG_ZFS_SET_BOOTFS_ON_COMMITR8t set_bootfst ARG_UFS_ROOTtARG_ZFS_RPOOL_ONLYRtARG_ZFS_VALIDATE_BOOTFSRR,tsuperRORRtbootmgmt.versaboottARG_NO_CREATE_BOOTPOOLt versaboott VersaBoott deferred_initR&(R$RLRMR*tfstypetbootmgmttbmnse((s#../../common/bootmgmt/bootconfig.pyROtsJ       cCs|jS(N(R(R$((s#../../common/bootmgmt/bootconfig.pyRwscKs|jr|jjnt|dd}|dks[|dks[t|dddkrl|jddSg|jD]}|jtkrv|^qv}t|dkr|jddSt }t ||j }t ||dkrdSg|jD]$}t|dd|kr|^q}t|dkrog|jD]'}t|d d|j kr?|^q?}nt|dkrt|d_ndS( sLoads the boot configurationR)R Rs(skipping bootfs check)Nis3This BootConfig already has a default boot instancetbootfstrpool( R;t load_configRR3R&R0RJR,R7RRRR(R$RMRRtdefault_instancestlzfshtpool_default_bootfs((s#../../common/bootmgmt/bootconfig.pyRDs2      *cKs|jr|jjndS(s7Initializes this instance with a new boot configurationN(R;t new_config(R$RM((s#../../common/bootmgmt/bootconfig.pyR?s c Cs:t|jdkr%|dkr%dS|dkrd}x*|jD]}|jtkrA|}PqAqAW|dkr|jd|jd}nt|dd}|dkr|jddSn|}t}t||j }t ||t }t ||j d}|d} || krH|j } | ddj|d}nt|| }t ||t} | dkr~d} n| |krt|d|dkrdn|} | dkr|jd | t| |fqnd} |jd | |ft |t|} t|| dkr6t| n| S( Nis0No default boot instance found-- using first oneRs]Could not find a boot instance with a bootfs attribute; Not setting root pool bootfs propertyRXit-tspool %s bootfs was %s now %ss#pool %s bootfs is already set to %s(R7R0R3RJR,R&RRRRRRRtsplitRfRRRCRRR( R$t newbootfst default_instRtdefault_bootfsRtzpht pool_realnametdefault_bootfs_splittrootpoolRt setprop_rvterror_description((s#../../common/bootmgmt/bootconfig.pyt_set_default_bootfssX!                      cCs|jdkr |jdgS|jrE|jjrE|jjjS|j}y tj|}tj|SWn/t k r}|jd|tj fnXdS(sLooks up the ZFS pool configuration for either the root pool or the boot pool (if versaboot is enabled) and returns the list of devices to be used by the boot loader installation algorithm. R sOnly supported on ZFSs*Couldn't get boot pool (%s) disk list (%s)N( R)R&Rt boot_pooltboot_device_listRR tzpool_get_configtzpool_config_to_partlistRtzfs_error_string(R$Rt confignvltbpzerr((s#../../common/bootmgmt/bootconfig.pyRt#s   c Cs2|dkr*|jtkr*|j}nd}yd}|jry2|jj|||||jjrsg}nWqtk r}|}qXntt |j |||||} |r|n| SWn`t k r-y|r|j|nWn/t k r&} |j d|t | fnXnXdS(Ns.Couldn't revert bootfs to %s after failure: %s(R3RR,RRtcommitRRRRRRR&RC( R$RRRRRt orig_bootfstversaboot_exceptiontbmfailttuplestbme((s#../../common/bootmgmt/bootconfig.pyR9s4       cCs ||_dS(s Enables VersaBoot by initializing the association between this DiskBootConfig and the VersaBoot instance passed in. N(R(R$tvbinst((s#../../common/bootmgmt/bootconfig.pytenable_versabootdsN(RRRRRRRRRRRtTOKEN_ZFS_RPOOL_TOP_DATASETRORwRDR?R3RRtR8RR(((s#../../common/bootmgmt/bootconfig.pyRas& :  +  B *t ODDBootConfigcBs&eZdZdZdZdZRS(sA class for managing the boot configuration stored on optical disk storage devices. Handles Solaris boot configurations stored on DVD mediat oddimage_rootcKstj|kr(t|jjdn|jdd|_|jdkr[tdnt t |j |dtj |dS(RsP: Migration is not supportedRsMissing oddimage_root argumentR(N( RR>RRRR1R3todd_image_rootRRRROR(R$RLRM((s#../../common/bootmgmt/bootconfig.pyROss  cCs|jS(N(R(R$((s#../../common/bootmgmt/bootconfig.pyRws(RRRtTOKEN_ODD_ROOTRORw(((s#../../common/bootmgmt/bootconfig.pyRls tZvmmODDBootConfigcBseZdZdZRS(sA class for managing hybrid optical disk boot environments that contain both a traditional boot loader (grub2) and a zvmm boot loader (zvboot).cKsd|krtdnt|j|jdd|}t|j|jdd|}|jd||jd|tj||}|jd||S(Ntfwtypes3Cannot specify firmware type for ZvmmODDBootConfig.tbiostzvmmsfirst loader = %sssecond loader = %ssdual loader = %s(RRRR:R&R tDualBootLoader(R$RMtfirsttsecondRU((s#../../common/bootmgmt/bootconfig.pyR:s   (RRRR:(((s#../../common/bootmgmt/bootconfig.pyRst NetBootConfigcBsYeZdZeZdZdZdZdZdZ dde dZ dZ RS( sUA class for managing the boot configuration stored on a network boot server. ttftprootcKsNtj|kr(t|jjdn|jdd |_|jd kr[tdn|jdd |_ |j d krtdn|jdd|_ |jdd |_ |j r%t j d |j }|d krtd |j nd |j kr%|j jd d|_ q%nt|j|j|d tj|d S(RsP: Migration is not supportedt osimage_roots!Missing net_osimage_root argumentt data_rootsMissing net_data_root argumentttftproot_subdirRXt client_ids8^(([0-9A-Fa-f]){12}|([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2})$sBad client_id value: %st:R(N(RR>RRRR1R3tnet_osimage_rootRt net_data_roottnet_tftproot_subdirRtretmatchR\RROR(R$RLRMtclient_id_valid((s#../../common/bootmgmt/bootconfig.pyROs.     cKs|jr|jjndS(sLoads the boot configurationN(R;R(R$RM((s#../../common/bootmgmt/bootconfig.pyRDs cKs|jr|jjndS(s7Initializes this instance with a new boot configurationN(R;R(R$RM((s#../../common/bootmgmt/bootconfig.pyR?s cCs|jS(N(R(R$((s#../../common/bootmgmt/bootconfig.pyRwscCstt|j|j||S(s (RRRR(R$RRR((s#../../common/bootmgmt/bootconfig.pyRs cCs"|jrd|jjSdSdS(sReturns a string that should be used as a client-specific suffix for configuration filenames, or the empty string if this configuration is not client-specific.s.01RN(Rtupper(R$((s#../../common/bootmgmt/bootconfig.pyt pxe_suffixs N(RRRR,tEXCLUSIVE_LOADERtTOKEN_TFTP_ROOTRORDR?RwR3R8RR(((s#../../common/bootmgmt/bootconfig.pyRs '    t BootInstancecBseZdZdZidd6ed6dd6dd6ZdZedZ dZ dZ d Z d Z ed Zd Zd ZdZedZdZdZdZdZdZRS(sBootInstance is the core abstraction for a bootable instance of an operating system. BootConfig objects aggregate zero or more BootInstance objects. A BootInstance should always be associated with a BootConfig object (so that if a consumer modifies a BootInstance, the BootConfig is notified that its state has changed so it can write updated configuration information at BootConfig.commit_boot_config()-time). This association is made when a BootInstance is passed to BootConfig.add_boot_instance().ttitlet transientt identfileR*cKs|jd}|rt|j|jd<|j}|j|j|jj||j|_d|_ ||_ d|_ |j |g|_ d|_dS|jjdijtjd|_ t|_d|_d|_ d|_ g|_ d|_xa|jjD]P\}}||kr||jkr|jd||f|j||qqWxv|jD]h\}}|dkrtj||_ n||jkrqsn|jd||f|j||qsW|dk r|j |ndS(Ntcopysrct _attributessDEFAULT: Setting %s="%s"R/sKWARGS: Setting %s="%s"(R1tdictR%t__dict__tdefault_attributestupdatetserialization_dictt_defaultR3Rtrootpathtlinked_boot_instancetinit_from_rootpatht cred_listRt setdefaultR R8RtitemsR&t __setattr__tastt literal_eval(R$R,RMR$t wholedicttkeytvalue((s#../../common/bootmgmt/bootconfig.pyROsH                  cCs|jS(N(R+(R$((s#../../common/bootmgmt/bootconfig.pyRJTscCsttj}t|d<|S(s3Returns a dictionary of default attributes RJ(R&R R%R8(R$tdefattr((s#../../common/bootmgmt/bootconfig.pyR(Xs cCsli}x9|jD]+}t||d}|r|||t cmp_defaultR;R6R@((s#../../common/bootmgmt/bootconfig.pytcompare~s +   cCsR||_y|j||_Wn,tk rM}|jd|d|_nXdS(sInitialize the boot instance with information from the root path given. This can be done after the object has been constructed, so that consumers do not have to complete the cumbersome task of mounting each BootInstance that's created.sError loading bootvars: %sN(R,t_get_boot_varsRRR&R3(R$R,tbmerr((s#../../common/bootmgmt/bootconfig.pyR.s  cCs|tk r'|tk r'tdn|j|kr:dS|tkrRt|_ngt|_|jdk rxL|jjD];}||k rw|jtkrw|jdt|_dSqwWn|jdk rt|j_ ndS(sBy setting this BootInstance to be the default, the previous default must be disabled. This property setter function does just that by using the _bootconfig reference to find the list of boot instances, locating the previous default, and setting it to False. Note that only setting the default to True triggers this search (otherwise, we could end up in an infinite recursive loop).s$default must be either True or FalseNs%Found previous default -- clearing it( R8R,RR+RR3R0RJR&R%(R$R7R((s#../../common/bootmgmt/bootconfig.pyt _set_defaults      cCstjjd|d|jS(s%Initializes this instance's boot_varsRtarch(R t BootVariablesR1RV(R$R,((s#../../common/bootmgmt/bootconfig.pyRDscCs\|j}t|tr|St|trXt|dkrXt|dtrX|dSdS(Nii(R*R4t basestringR5R7R3(R$R*((s#../../common/bootmgmt/bootconfig.pyRVs !cCsd}t|tr"||}nZt|trgt|dkrgt|dtrg|d|}n|r|tdn||jkr|std}qn||jkrd}n|jj|iS(sReturns the platform-specific default-attribute dict (if it exists) otherwise returns the _attributes dict (if it exists), otherwise returns {} R%iisNInvalid platform given: Must be a string or a 2-tuple of (string, string|None)(R4RIR5R7RR'RR1(R$t classnameR*tattrname((s#../../common/bootmgmt/bootconfig.pyt_get_attrdict_by_platforms ! cCs|dkr/|jd||f|j|S||jkr|jdk r|jjr|jdkrti|_n||jkr|jj|d|j|s is===[ %d Boot variables ]=== s ===[ End Boot Variables ]===s===[ No Boot Variables ]===( RJR,R%R;RCRRR7Rftmap(R$Rtitem((s#../../common/bootmgmt/bootconfig.pyRs $  cCsMxF|jD];}||jkr#tSt||t||kr tSq WtS(N(R%R8RR,(R$R>R6((s#../../common/bootmgmt/bootconfig.pyt__eq__"s N(RRRR3tTARGETR8R%RORRJR(R*R:R)R,RCR.RFRDRVRLR2RMRRP(((s#../../common/bootmgmt/bootconfig.pyR s,   A     !     tChainDiskBootInstancecBsfeZdZddgfZid d6dd6dd6ed6Zd d Zd Zd Z d Z RS(s1A boot instance of a chainloaded operating systemtx86R t chaininfot0t chainstartt1t chaincountt forceactivecKs~|jd}|sF|j|}|jjdijtjntt|jd||rzt |j |_ ndS(s2rootpath is not supported, so should remain `None'R$R%N( R1t_sanitize_kwargsR'R0R)RRR%RROR3R5RT(R$R,RMR$((s#../../common/bootmgmt/bootconfig.pyRO6s cCs)tt|j}|jtj|S(s3Returns a dictionary of default attributes (RRRR(R)R%(R$t superdict((s#../../common/bootmgmt/bootconfig.pyR(GscCstt|j}|jrt|jtkrg}x]|jD]R}t|tkrx7|D]}|jt|qbWqC|jt|qCWdj||d"s>      @.F( ]0ZC