uUc@sgdZddlZddlZddlZddlZddlZddljjZddl jj Z ddl jj Z ddlmZddlmZddlmZddlmZddlmZmZddlmZmZdd lmZmZdd lmZdd lmZdd lmZdd lmZddl m!Z!ej"dZ#ej"dZ$ej"dZ%ej"dZ&ej"dZ'ej"dZ(ej"dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3d Z4d!Z5d"Z6d#Z7d$Z8d%Z9d&Z:d'Z;d(Z<d)Z=d*Z>d+Z?d,e@fd-YZAd.e@fd/YZBdS(0sxConversion routines used to Solaris 10 convert rules and profile files to the xml format used by the Solaris installer iN(tcommon(t_(tfetch_xpath_node(tgenerate_error(t LOG_KEY_FILEtLOG_KEY_LINE_NUM(tLVL_CONVERSIONt LVL_PROCESS(tLVL_UNSUPPORTEDt LVL_WARNING(tRULES_FILENAME(tDEFAULT_XML_EMPTY(tetree(tStringIO(tPKG5_API_VERSIONs'c[0-9][0-9]*t[0-9][0-9]*.*d[0-9][0-9]*$sc[0-9][0-9]*.*d[0-9][0-9]*$s/(c[0-9][0-9]*t[0-9][0-9]*.*d[0-9][0-9]*)s[0-7]$s#(c[0-9][0-9]*.*d[0-9][0-9]*)s[0-7]$s [0-9][0-9]*$s([0-9][0-9]*)([g|m]?)$s..*:/..*trpoolt rpool_vdevt_vdevt swap_poolsfacet.locale.%stinstallt uninstalltnonetmirrortanytalltautotdeletetexistingtfreetmaxfreetdefaulttexplicittrootdisks rootdisk.tunnamedtdt XMLRuleDatacBseZdZdZdZedZedZdZdZ dZ dZ d Z d Z d Zd Zied 6e d6ed6ed6e d6ed6ed6e d6e d6e d6ed6ed6ed6ed6Zidd6dd6dd6dd6ZRS(sThis object holds all the data read in from the rules file. This data is converted into an xml document which then can be manipluated as needed. cCs@d|_||_||_itt6dt6|_|jdS(sInitialize the object Arguments: rule_dict - a dictionary containing the key values pairs read in from the rule file report - the error report iN( tNonet_roott_reportt rule_dictR RRt_extra_log_paramst_XMLRuleData__process_rule(tselfR'treport((sconv.pyt__init__s     cCst||j||jdS(sLog the specified error message at the specified level and increment the error count associated with that log level in the conversion report by 1 N(RR&R((R*tlvltmessage((sconv.pyt __gen_errscCs|jS(s,Conversion report associated with the object(R&(R*((sconv.pyR+scCs|jS(sThe xml root element(R%(R*((sconv.pytrootscCs%|jttdi|d6dS(s-Generate an unsupported keyword error messagesunsupported keyword: %(key)stkeyN(t_XMLRuleData__gen_errRR(R*tkeywordtvalues((sconv.pyt__unsupported_keywords cCs|jttddS(s.Generate an unsupported negation error messages'negation '!' not supported in manifestsN(R2RR(R*((sconv.pyt__unsupported_negations cCs%|jttdi|d6dS(s(Generate an invalid syntax error messages.invalid syntax for keyword '%(key)s' specifiedR1N(R2RR(R*R3((sconv.pyt__invalid_syntaxs  cCst|dkr#|j|dS|dd kr\|jttdi|dd6dS|dd kr|jttd n|j||dS( sConverts arch keyword and value from a line in the rules file into the xml format for outputting into the criteria file. iNitsun4ctsun4dtsun4ms9Solaris 11 does not support the specified arch '%(arch)s'tarchtsun4usonly a limited set of sun4u hardware is supported by Solaris 11. Consult the Solaris 11 documentation to ensure that the hardware you wish to install on is supported(R8R9R:(tlent_XMLRuleData__invalid_syntaxR2RRR t_XMLRuleData__convert_common(R*R3R4((sconv.pyt__convert_archs    cCst|dkr#|j|dStj|jtj}y|jtj|j |Wn2t k r|j |||jj |dSXtj|tj }|d|_dS(sConverts the specified keyword and value from a line in the rules file into the xml format for outputting into the criteria file. iNi(R=R>R t SubElementR%RtELEMENT_AI_CRITERIAtsettATTRIBUTE_NAMEtrule_keywd_conv_dicttKeyErrort!_XMLRuleData__unsupported_keywordtremovet ELEMENT_VALUEttext(R*R3R4t criteria_namet crit_value((sconv.pyt__convert_commons     cCst|dkr#|j|dStj|jtj}|jtjdd|dkrtj|tj }|dj dd|_ n"tj|tj }|d|_ dS(sConverts memsize value from the form 'value1-value2' to 'value1 value2' and outputs the range node to the criteria file iNtmemt-it ( R=R>R RAR%RRBRCRDt ELEMENT_RANGEtreplaceRJRI(R*R3R4RKt crit_rangeRL((sconv.pyt__convert_memsizes   c Cst|dkr#|j|dStj|jtj}|jtjdy&|dj dd\}}}}Wn/t k r|j||jj |dSXtj|tj }d|d|||f} | |_ dS(sConverts the network keyword and value from a line in the rules file into the xml format for outputting into the criteria file. iNtipv4it.is%s %s.%s.%s.255(R=R>R RAR%RRBRCRDtsplitt ValueErrorRHRQRJ( R*R3R4RKtaddr_ataddr_btaddr_ct _remainderRSt net_range((sconv.pyt__convert_networks   &  cCsr|jdkr4d|j_d|j_d|_dS|jdk rGdStjtj |_|jj }x|j D]}||j }||j }||j}|dks|dks|dkrtn||jtProcess the rules dictionary entries and convert to an xml dociNt!(R'R$R&tconversion_errorstunsupported_itemsR%R tElementRtELEMENT_AI_CRITERIA_MANIFESTtkey_values_dicttiterkeysR1R4tline_numRXR(Rt"_XMLRuleData__unsupported_negationtrule_conversion_dictRFRGtlistR=(R*tkey_dictt key_valuesR3R4Rftfunction_to_calltchildren((sconv.pyt__process_rules6       $     RR;tdisksizet domainnamet hostaddressthostnamet installedtkarchtmemsizetmodeltnetworktosnametprobet totaldisktcpuRUtplatform(t__name__t __module__t__doc__R,R2tpropertyR+R0RGRgR>t_XMLRuleData__convert_archR?t_XMLRuleData__convert_memsizet_XMLRuleData__convert_networkR)RhRE(((sconv.pyR#sB          $ tXMLProfileDatacBs,eZdZdZdZdZdZdZdZdZ dZ e d Z e d Z d Zd Zd ZdZdZdZdZedddZdedZdZdZdZd[eed[dZdZdZd[d[d[d[dZ ddd d!Z!d"Z"d#Z#d$Z$d%Z%d&Z&d'Z'd(Z(d)Z)d*Z*d+Z+d,Z,d-Z-d.Z.d/Z/d0Z0d1Z1d2Z2d3Z3d4Z4d5Z5d6Z6d7Z7d8Z8d9Z9d:Z:d;Z;d[d<Z<d[d=Z=d>Z>d?Z?d@Z@dAZAdBZBe dCZCdDZDdEZEdFZFdGZGid[dH6edI6edJ6edK6edL6edM6e'dN6e-dO6edP6e0dQ6e1dR6edS6e2dT6e@dU6e3dV6d[dW6e4dX6d[dY6ZHdZZIRS(\sEThis object takes the profile data and converts it to an xml documentc Cs||_||_|dkr6tjtt}ntj|j }||_ |j j |_ d}t |j ||_|jdkrtjtt}tjjtj|j dttj|dt} ttdi|jd6| d6ni|jt6dt6|_d|_d|_||_d|_||_d|_t |_!d|_"d|_#d|_$d|_%t&|_'d|_(d|_)t*|_+tj,|_-|jj.tj/|j|j0dS( sInitialize the object Arguments: name - the name of the profile prof_dict - a dictionary containing the key values pairs read in from the profile report - the error report default_xml - the XMLDefaultData object containing the xml tree hierachy that the prof_dict data will be merged into local - boolean flag for where package name looks is local only s/auto_install/ai_instancet pretty_printsb node not found. %(filename)s does not conform to the expected layout of: %(layout)stfilenametlayoutitipsN(1t profile_nameR&R$R tparseR R Rt tree_copyttreet_treetgetrootR%Rt _ai_instancetsyststderrtwritettostringtTrueRXRtnameRRR(t_targett _image_nodet_localt inst_typet prof_dictt _partitioningRit_usediskt _boot_devicet _root_devicet _rootdiskt_rootdisk_set_by_keywordtSIZE_ALLt_rootdisk_sizet _root_poolt_root_pool_create_via_keywordtDEFAULT_POOL_NAMEt_root_pool_namet ARCH_GENERICt_archRCRDt _XMLProfileData__process_profile( R*RRR+t default_xmltlocalt default_treetxpathRtexpected_layout((sconv.pyR,SsH    "                    cCst||j||jdS(sLog the specified error message at the specified level and increment the error count associated with that log level in the conversion report by 1 N(RR&R((R*R-R.((sconv.pyR/scCsRtj|}|r'|jd}n'tj|}|rN|jd}n|S(sTakes a device and if that device is a slice specified device removes the slice portion of the device and returns the new device name. If the device passed in is not a slice device it returns the original device passed in i(tSLICE1_PATTERNtmatchtgrouptSLICE2_PATTERN(R*tdevicet match_pattern((sconv.pyt__device_name_conversionscCs%|jttdi|d6dS(s?Log a duplicate keyword error and add a process error to reports5invalid entry, duplicate keyword encountered: %(key)sR1N(t_XMLProfileData__gen_errRR(R*R3((sconv.pyt__duplicate_keywords  cCs5tj|}|s1tj|}|s1tSntS(sz Validate the disk name based on the regexp used by the check script The disk name is either cXtXdX or cXdX For world wide name(MPXIO), disk is of the form cXtX[combination of alpha numeric characters]dX c[0-9][0-9]*t[0-9][0-9]*.*d[0-9][0-9]*$ c[0-9][0-9]*.*d[0-9][0-9]*$ Returns: True if valid, False otherwise (t DISK1_PATTERNRt DISK2_PATTERNtFalseR(R*RR((sconv.pyt__is_valid_device_names cCs1|jdr$tjj|}n|j|S(s% Validate the disk name based on the regexp used by the check script A valid device is a string that is either a) a string that starts with /dev/dsk/ and ends with a valid slice name, or b) a valid slice name. Returns: True if valid, False otherwise s/dev/dsk(t startswithtostpathtbasenamet_XMLProfileData__is_valid_slice(R*R((sconv.pyt__is_valid_devices cCs)tj|s%tj|s%tSntS(s&Validate the slice name based on the regexp used by the check script The slice name is either cXtXdXsX or cXdXsX For world wide name(MPXIO), disk is of the form cXtX[combination of alpha numeric characters]dXsX Returns: True if valid, False otherwise (RRRRR(R*t slice_name((sconv.pyt__is_valid_slices c Cst|kr1|jttdi|d6dSt|}t|t|kro|jttdtS|tkrg}xd|D]Y}|j d\}}||kr|jttdi|d6tS|j |qWn|rx'|D]} |j || rPqqWnt S(sCheck the devices that will make up the mirror to ensure there are no conflicts Arguments: line_num - the line being processed keyword - the keyword being processed devices - list of devices size - the size to assign to the mirror root_conflict_check - perform check to see if devices conflict with root_disk setting. This should only be done if creating a root pool mirror sWuse of the device entry 'any' is not supported when a mirrored %(keyword)s is specifiedR3Ns-invalid syntax: mirror devices are not uniquetss~invalid syntax: duplicate device %(disk)s found, underlying devices for mirror be different when a size of 'all' is specified.tdisk( t DEVICE_ANYRRRRCR=RRRRWtappendt._XMLProfileData__rootdisk_slice_conflict_checkR( R*R3tdevicestsizetroot_conflict_checktuniquet disk_sliceRt _slice_numR((sconv.pyt__is_valid_mirrors2             cCs|jS(s9Return the converstion report associated with this object(R&(R*((sconv.pytconversion_reportscCs|jS(sReturn the architecture for this profile. A value of NONE indicates the architecture is unknown. If known a value of common.ARCH_X86 or common.ARCH_SPARC will be returned(R(R*((sconv.pyt architecturescCs]|jtjkr||_n;||jkr1tS|jttdi|jd6tStS(s Change the architecture setting that this profile is being generated for. Check for the one possible conflict condition and update error report appropriately. Returns True if change represents no conflict, False otherwise sarchitecuture conflict detected. fdisk is an x86 only keyword operation. This conflicts with 'boot_device %(dev)s' which was specified using the SPARC device syntax instead of the x86 device syntax of cwtxdy or cxdytdev( RRRRRRRRR(R*R;((sconv.pyt __change_arch&s   cCs%|jttdi|d6dS(sGenerate invalid keyword errors.invalid syntax for keyword '%(key)s' specifiedR1N(RRR(R*R3((sconv.pyR7?s  cCs%|jttdi|d6dS(s"Generate unsupported keyword errorsunsupported keyword: %(key)sR1N(RRR(R*R3R4((sconv.pyR5Es cCs,|jttdi|d6|d6dS(s Generate unsupported value errors3unsupported value for '%(key)s' specified: %(val)s tvalR1N(RRR(R*R3tvalue((sconv.pyt__unsupported_valueJs  cCs,|jttdi|d6|d6dS(s!Generate unsupported syntax errors3unsupported syntax for '%(key)s' specified: %(msg)sR1tmsgN(RRR(R*R3R((sconv.pyt__unsupported_syntaxPs  cCsB|jdk r>|jttdi|d6|jd6tStS(sCheck whether root pool has been created and generate error if the root pool already exists. If exists adds a conversion error to report. Return True if exists, False otherwise skthe ZFS root pool was already created using the '%(created_by)s' keyword, ignoring '%(keyword)s' definitionR3t created_byN(RR$RRRRRR(R*R3((sconv.pyt__root_pool_existsVs   cCsBtj|jtj}|jtj||jtj||S(s7Create the node(R RARRtELEMENT_LOGICALRCtATTRIBUTE_NOSWAPtATTRIBUTE_NODUMP(R*tnoswaptnodumptlogical((sconv.pyt__create_logicalhs   tfalsettruecCs|jdk r|jS|jdkrStjtj|_|jjd|jn|jj tj }|dkr|j ||}n|j ||_|jj tjdtj|jtjdd}|j tjdtj|jtjdd||_|jS(sTests to see if a root pool currently exists. If it exists a the existing root pool is returned. If no root pool exists the pool will be created with the specified pool name. Arguments: created_by_keyword - the keyword to associate with the creation of the root pool. This will be used in the error generation for root pool already exists messages pool_name - the name to assign to the root pool noswap - noswap for logical component zpool resides in. Expected value is "true"/"false" nodump - nodump for logical component zpool resides in. Expected value is "true"/"false" iRRtexports/exports export/homeN(RR$RR RbRtELEMENT_TARGETRtinserttfindRt_XMLProfileData__create_logicalt _XMLProfileData__create_zfs_poolRCtATTRIBUTE_IS_ROOTRAtELEMENT_FILESYSTEMtATTRIBUTE_MOUNTPOINTR(R*tcreated_by_keywordt pool_nameRRRtfs((sconv.pyt__create_root_poolps"   RcCstd|}t||}|dkrptjtj}|jd||jtj||jtj |ndS(sqTests to see if a vdev with the specified name currently exists. If it exists the existing vdev is returned. If no vdev exists the vdev will be created with the specified name and redundancy. Arguments: parent - the parent node of the vdev to create name - the name of the vdev redundancy - the vdev redundancy s./vdev[@name='%s']iN( RR$R RbRt ELEMENT_VDEVRRCRDtATTRIBUTE_REDUNDANCY(R*tparentt redundancyRRtvdev((sconv.pyt __create_vdevs  cCstj|tj}|jtj||jtj|tj|tj}|jtj||j }|dk r|dkr|jtj dq|dkr|jtj dqndS(sXCreates a zvol with the specifed name, size, and use. Arguments: parent - the parent node to create the vzol under name - the name of the vpool to create use - the use to specify for the zvol vpool_size - the size for the zvol. Size should include measurement like mb, gb, etc tswapRtdumpN( R RARt ELEMENT_ZVOLRCRDt ATTRIBUTE_USEt ELEMENT_SIZEt ATTRIBUTE_VALt getparentR$RR(R*RRtuset zvol_sizetvpoolRR((sconv.pyt __create_zvols     cCsh|jjtj}|dkr<|jdddd}ntj|tj}|j tj ||S(s Create the xml structureRRRRN( RRRRR$RR RAt ELEMENT_ZPOOLRCRD(R*RRtzpool((sconv.pyt__create_zfs_pools  cCstjtj}|jjd|tj|tj}|jtj ||jtj d|r||jtj dn|S(sCreate the structure used to represent a disk in the system itctdR( R RbRt ELEMENT_DISKRRRAtELEMENT_DISK_NAMERCRDtATTRIBUTE_NAME_TYPEtATTRIBUTE_WHOLE_DISK(R*t disk_namet whole_diskRt diskname_node((sconv.pyt__create_disk_nodes c Cs|tkrdS|tkr%t}nt}y|jd\}}Wn#tk ri|}d}t}nX|jj|r|jj||j t krt}qn|j |} | dkr)|j tjkr|jdsdSn|j||} |j tjkr| } qu|j| } nL|j dtjgkrYd} t| | } n| } |j||sudS|j| |d||||dS(sAdded device to the target xml hierachy Arguments: device - the device/slice to add. "any" may be specified size = #size or all or none in_pool - the root pool to associate the device with if any. in_vdev - the vdev the the device is placed in is_swap - Indicates the device is a non ZFS swap device May not be mixed with in_pool or in_vdev NRt0s/./partition[@action='create'][@part_type='191']tcreate(RRRRRWRXRtcountRHRtPARTITIONING_DEFAULTt _XMLProfileData__fetch_disk_nodeR$RRRt_XMLProfileData__change_archt!_XMLProfileData__create_disk_nodet ARCH_SPARCt_XMLProfileData__add_partitiontARCH_X86Rt&_XMLProfileData__is_valid_to_add_slicet_XMLProfileData__add_slice( R*RRtin_pooltin_vdevtis_swaptdelete_existingR t slice_numt disk_nodeRtslice_parent_nodeR((sconv.pyt __add_devices@         cCsUd|}t||}|dk rQ|jttdi|d6|d6tStS(sChecks whether the specified slice can be added to structure If the slice already exists and error will be outputed s%./slice[@name='%s'][@action='create']s#%(device)ss%(slice)s already existsRtsliceN(RR$RRRRR(R*tslice_node_parentRRRt slice_node((sconv.pyt__slice_exists(s    c Csd|krtS|jd\}}|j|}|d krDtS|jd kse|jtjkr|jj tj }|d krtSn|}|j |||rtSd}t ||}|d k r|j tj } | d krO|ttd gkr|jttdi|d6|d6|jtjd6|jd6tSq|ttd gkr|jttdi|d6|d6|jtjd6|d 6|jd6| jtjd 6tSntS( s`Perform some basic checks to prevent an invalid manifest from being generated. Rs./slice[@action='create']scan not create %(device)ss%(slice1)s. Conflicts with %(device)ss%(slice2)s that was created earlier via keyword '%(rp_kw)s' without a specified numeric size.Rtslice1tslice2trp_kwscan not create %(device)ss%(slice1)s with a size of '%(size)s'. Conflicts with %(device)ss%(slice2)s that was created earlier via keyword '%(rp_kw)s' with a size of %(rp_size)s.Rtrp_sizeN(RRWt$_XMLProfileData__fetch_diskname_nodeR$RRRRRRtELEMENT_PARTITIONt_XMLProfileData__slice_existsRRt SIZE_AUTORRRRtgetRDRR( R*RRR RR R#RR$t size_node((sconv.pyt__is_valid_to_add_slice8sL  !            c Cs|s |r'|r'ttdntj|tj}|jtj||jtj||jtj d|dk r|jtj |n|dk r|jtj |n|dk r|jtj |n|dttgkrtj|tj} | jtj|ndS(sYAdd the node with the specified attributes as a child of parent s0is_swap can not be mixed with in_vdev or in_poolRN(RXRR RARt ELEMENT_SLICERCRDtATTRIBUTE_ACTIONtATTRIBUTE_FORCER$tATTRIBUTE_IN_ZPOOLtATTRIBUTE_IN_VDEVtATTRIBUTE_IS_SWAPR-RRR( R*RRtactionRRRRR$R/((sconv.pyt __add_slices      t1t191RcCss|jtj}|dkrotj|tj}|jtj||jtj||jtj |n|S(s+Add node as a child of parentN( RRR+R$R RARCR2RDtATTRIBUTE_PART_TYPE(R*RRt part_typeR7tpartition_node((sconv.pyt__add_partitions cCsd}t|j|}|dk r4|jjSx3|jjtjD]}|jtjsJ|SqJWt j |jtj}|j tj d|S(s:Fetch the software publisher node instance in the xml trees9./software[@type='IPS']/source/publisher[@name='solaris']tIPSN( RRR$RtfindallRtELEMENT_SOFTWARERtELEMENT_SOURCER RARCtATTRIBUTE_TYPE(R*Rt publishertsoftware((sconv.pyt__fetch_solaris_software_nodes   cCstj}tjddtj}tjdt|t d}d|}tj |t t g}|j |dddt }|j|} d} |jsy|j|} Wn tk rt |_d} nX| dk r| }qn|jre| rey|j| } Wn;tk rL} |jttdi|d 6| d 6nX| dk re| }qentj||j} | dkrd |}nd} t| | t}t| | t}|tkr|}n|}|dk r9d}x'|D]}|j|kr|}PqqW|dk r9|j|q9n|tkrN|}n|}|dkr~tj| tjd|}ntj|tj }||_dS(sCreate a $package node and add it to the existing node for the specified action. If the node does not exist, create it and add it as a child of the specified parent node. Arguments: package - the name of the package element to add as a $package child node of action - install or uninstall the package tpkgs/usr/share/localet/tjs2ais:legacy:legacy_pkg:tserverstprune_versionss>package name translation failed for '%(package)s': %(message)stpackageR.tSUNWcstSUNWcsdspkg:/s./software_data[@action='%s']R7N(RMRN(!RtgetcwdtgettextRtprogresstCommandLineProgressTrackertapitImageInterfaceRRtQueryRt remote_searchR$t local_searchRt_XMLProfileData__do_pkg_searcht ExceptionRRRtchdirt,_XMLProfileData__fetch_solaris_software_nodeRtSOFTWARE_UNINSTALLtSOFTWARE_INSTALLRJRHR RARtELEMENT_SOFTWARE_DATAt ELEMENT_NAME(R*RLR7torig_pwdt prog_trackertapi_instt pkg_querytqueryt search_remotet search_localtpkg_nameRRERtsoftware_uninstalltsoftware_installtsearcht match_nodetchildt software_dataR((sconv.pyt__add_software_datast                                 c Csd}tj|}|dk rynxg|D]_}|\}}\}}} | d} | j}|dkrqq+n|dk r+d|_|Sq+WWqtjk r} |jtt di| d6qXn|S( s7Grab the new package name returned from the ipkg searchiRMRNRs/package name lookup returned error: %(message)sR.N(sSUNWcssSUNWcsd( R$t itertoolstchaintget_nameRtapxtSlowSearchUsedRR R( R*RjRgt search_valuest raw_valuet _query_numt_pubt_valuet _return_typetpkg_infotpfmriR((sconv.pyt__do_pkg_searchs$          cCs|jdkrtS|jdk r+|}n"|jdkr>dS|j|}||jkr|jttdi|d6|jd6t |jd6t StS(sChecks the specified slice to see if it conflicts with the root_device or boot_device settings that may have been specified by the profile. Returns True if conflict found, false otherwise tfdiskNsmconflicting ZFS root pool definition: %(keyword)s definition will be used instead of '%(rd_kw)s %(rootdisk)s'R3trd_kwR ( RR$RRRt'_XMLProfileData__device_name_conversionRRRtstrR(R*R3Rt cmp_device((sconv.pyt__rootdisk_slice_conflict_check/s     cCs|dk r|j|r|jdkrV|jttdi|d6|d6dS|j|j}|j||d}n|S(sChecks the 'device' for the presence of 'prefix' if found and the root disk has been determined the 'prefix' will be replaced with the name of the root disk sLunable to convert '%(device)s'. Replace'%(prefix)s' with actual device nameRtprefixiN(R$RRRRRRRR(R*RRR((sconv.pyt__rootdisk_conversionPs    c Cst|dkr#|j|dS|dj}|tkrY|jtd|dS|j|t}|dkr{dS|j |s|j t tdi|dd6dS|d}|dkr|jtd |dS|d j}|t t d gkr"|jtd |dS|tkrS|j||}|dkrSdSn|jdkr|jtkr|jdkr||_|tkr||_nd |_n|j|}|dkr|j||tk}n"|tkr|jtjdn|j|}|jtj}|tkr|dkrvtjtj}|jd||jtj |q|j!tj } || kr|j t tdi| d6qndS(s=Processes the fdisk keyword/values from the profile iNis s$invalid device specified: %(device)sRitsolarissiRsR}Rs[conflicting fdisk specified: size was previously defined as %(size)s. Ignoring entryR("R=t_XMLProfileData__invalid_syntaxtlowerRt"_XMLProfileData__unsupported_valueRt$_XMLProfileData__rootdisk_conversiontPREFIX_ROOTDISKR$t%_XMLProfileData__is_valid_device_nameRRt SIZE_MAXFREEt SIZE_DELETEt _XMLProfileData__size_conversionRRRRRRRRRCRR RRRR RbRRR.( R*R3R4R t fdisk_typeRRt part_nodeR/t spec_size((sconv.pyt__convert_fdisk_entryssh                       cCs5|dkr1|jttdi|d6tStS(s{Check whether this is a valid supported mount point. Return True if supported. Otherwise return False RHRsjunsupported mount point of '%(mount)s' specified, mount points other than '/' and 'swap' are not supportedtmount(RHsswap(RRRRR(R*R((sconv.pyt__is_valid_filesys_mounts    cCs|jdkr|jdkr8|jttdtS|jtkr\|jt|_n|j |j }|j ||j |j|j |jtSdS(sForce the creation of root pool since it doesn't exist. Return True if pool can be created. False otherwise. sswap mount is only supported when preceded by a entry that causes the root pool to be created. For example root_device, boot_device, pool, or filesys with a mount point of '/'N(RR$RRRRRRt"_XMLProfileData__pop_usedisk_entryt!_XMLProfileData__create_root_poolRt_XMLProfileData__create_vdevt_XMLProfileData__add_deviceRRR(R*R((sconv.pyt__swap_force_root_pool_creations    cCs|tkr{|r6|j}|dkrEt}qEn|jt}|tkr|r[|S|jttddSqn"|j|t}|dkrdS|j |s|jttdi|d6dS|S(sPerform conversion on the device specified if necessary. Return None if an error condition occurs (device invalid, device could not be converted) Arguments: device - the device being converted allow_any_value - boolean to indicate whether to allow of "any" to be returned use_rootdisk - indicates whether to translate "any" using rootdisk if rootdisk is set sXunable to convert 'any' device to physical device. Replace 'any' with actual device names$invalid slice specified: %(device)s RN( Rt%_XMLProfileData__fetch_rootdisk_sliceR$t)_XMLProfileData__pop_usedisk__slice_entryRRRRtPREFIX_ROOTDISK_DOTR(R*Rtallow_any_valuet use_rootdisk((sconv.pyt__device_conversions,             cCsvtj|}|rD|jddkr7|d7}qr|d7}n.|jttdi|d6|d6d}|S( sPerform the necessary conversion for fileys size. Returns None and generates error if not a valid numeric size. ittmbtbs-invalid size '%(size)s' specified for %(key)sR1RN(t SIZE_PATTERNRRRRRR$(R*R3RR((sconv.pyt__size_conversion,s    c Cst|}|dkr)|j|dS|d}|dkrR|dj}nt}t}|dkrw|d7}n|dkry|djd\}}Wqtk r|j|dSXn|d}|d } |d j} |d kr|jtt d i|d d6n|j |s0dS|j d|dt dt }|dkr^dS|j d| dt dt } | dkrdS| ttttgkr|j|t ddS|j|| } | dkrdS|dkr|j|rdS|j||| g| |dks'dS|dkrM|j||| | dS|jdk rzd|_d|_d|_n|t} |jd|d| d|d| dd|jd| d| d|d| dd|j||} |j| t| dS(s*Perform conversion of filesys mirror entryiNiRt_swapRt:iiiis0ignoring optional filesys parameters: %(params)sitparamsRRRsCsizes other than a number are not supported for filesys mirror swapRHRRRR(R=RRtFILESYS_DEFAULT_MOUNT_POINTRRWRXRRRt'_XMLProfileData__is_valid_filesys_mountt"_XMLProfileData__device_conversionRR$t SIZE_FREEt SIZE_EXISTINGRR-t#_XMLProfileData__unsupported_syntaxRt!_XMLProfileData__root_pool_existst _XMLProfileData__is_valid_mirrort-_XMLProfileData__create_filesys_mirrored_swapRRt VDEV_SUFFIXRRRtREDUNDANCY_MIRROR( R*R3R4tlengtht mirror_nameRRt_mirrortdevice1tdevice2Rt vdev_nameR((sconv.pyt__convert_filesys_mirror_entry@s                                cCs|jdkr)|j|tddStj|drV|j|tddSt|}|dkr|j|dS|djdr|j||dS|d}|dj }|d kr|dj }nt }|d kr|j t td i|d d 6n|j |s,dS|jd |d|tkd|dk}|dkrfdS|tttgkr|j|tddS|tkr|j||}|dkrdSn|dkr|j||dS|j|rdS|jdk r)|j||s)d|_q)n|jdkrY||_|j|_||_n|j|t}|j||j|||jdS(s^Converts the filesys keyword/values from the profile into the new xml format RsFfilesys keyword not supported when partition_type is set to 'existing'Nis%remote file systems are not supportediRiiis0ignoring optional filesys parameters: %(params)sRRRRRHs2sizes other than a number or all are not supportedR( RRRtFILESYS_ARG_PATTERNRR=RRt-_XMLProfileData__convert_filesys_mirror_entryRRRRRRRR$RRR-Rt$_XMLProfileData__create_filesys_swapRRRRRRRRRR(R*R3R4RRRRR((sconv.pyt__convert_filesys_entrysl                        c Csc|jtkr7|jttdi|jd6d S|jd|d|dd dd ddd S( sCreate a non ZFS SWAP devicesunable to to use specified swap for device since the device 'any' was used to create the root pool via keyword %(rd_kw)s. Replace 'any' with actual device nameR~RRRRRRN(RRRRRRR$R(R*RR((sconv.pyt__create_filesys_swap s  c Cs|j||sdS|tkr<|jttddS|t}|jd|d|d|d|dd|jd|d|d|d|dd|j|}|j |t ||tt gkr|j d|d d d d d |ndS( s2Create a mirror swap for devices specified by userNsefilesys mirror with a mount of swap and all is not supported. Change size to actual swap size desiredRRRRRRRRRR( RRRRRRRR$RRRR-t_XMLProfileData__create_zvol(R*RRRRRR((sconv.pyt__create_filesys_mirrored_swaps$      cCsdS(scConverts the install_type keyword/values from the profile into the new xml format N((R*R3R4((sconv.pyt__convert_install_type_entry;scCsBt|dkr#|j|dS|jdkr|j}|jtj}|dkrtj tj}|j d|n.|jtj }|dk r|j |ntj |tj |_tj |jtj}|jtjdtd|_ntj |jtj}|jtjdt|d|_dS(scConverts the install_type keyword/values from the profile into the new xml format iNiRt*R(R=RRR$R[RRtELEMENT_DESTINATIONR RbRt ELEMENT_IMAGERHRAt ELEMENT_FACETRCt ATTRIBUTE_SETtFACET_LOCALE_FORMRJ(R*R3R4REtdesttimagetfacet((sconv.pyt__convert_locale_entryCs&    cCs|d}t|dkr/|dj}n5t|dkrJd}n|j|tddS|dkr|dkr|j|dS|dkr|j|tn|dkr|j|tndS(s^Converts the package keyword/values from the profile into the new xml format iiitaddsKpackage install from specified locations is not supported for SVR4 packagesNR(R=RRRRt"_XMLProfileData__add_software_dataR]R\(R*R3R4RLR7((sconv.pyt__convert_package_entryys"          c Cst|}|dkr)|j|dS|d}t|}|dksW|dkr||jttdi|d6dS||_|dj}|tkr|j|tddS|t kr|j d |}|dkrdSn|d j}d }|d krd}d }n1|t krN|j d|}|dkrNdSn|dj} d } | d krd} d } n1| t kr|j d| } | dkrdSn|ddkrt } |dkr|j|dSd} |d} n3t } |dkr|j|dSd} |d} t}xg| D]_}| t koT|t k}|jd|d|d| t k}|dkrdS|j|q9W|} | r|j|| |t sdSn|j|| d|j||j|| }|j|| x$| D]}|j|||jq W|dk rj|t krj|jd|ddddd|n| dk r| t kr|jd|ddddd| n| r|jdkr| d|_|j|_||_ndS(s[Converts the pool keyword/values from the profile into the new xml format iNiisfinvalid pool name of '%(pool)s': must be at least 1 character and no more than 30 characters in lengthtpoolis8pool sizes other than a number or auto are not supporteds iRRRs is iRiRRRRRRRRRR(R=RRRRRRRRR$R-RRRRiRRRRRRRRRRR(R*R3R4RRt name_lengtht pool_sizet swap_sizeRt dump_sizeRRRRt updated_listRt allow_anyt update_deviceR((sconv.pyt__convert_pool_entrys                                     cCs`t|}|dks$|dkr5|j|dS|ddkr\|j||dndS(s{Processes the system_type entry in profile and flags any value other than standalone as unsupported value iiNt standalone(R=RR(R*R3R4R((sconv.pyt__convert_system_type_entrys   cCs)|j|}|dkrdS|jS(s0Returns the node for the disk 'disk_name'N(R*R$R(R*R R ((sconv.pyt__fetch_disk_node*s cCsd}t|j||S(s;Returns the diskname node with the disk_name of 'disk_name's./disk/disk_name[@name='%s'](RR(R*R R((sconv.pyt__fetch_diskname_node1scCsd|}t|j|S(s7Fetch the ZFS pool with the specified name if it existss./logical/zpool[@name='%s'](RR(R*RR((sconv.pyt __fetch_pool6s cCsd}t|j|S(sFetch the ZFS root pools ./logical/zpool[@is_root='true'](RR(R*R((sconv.pyt__fetch_root_pool;scCs=|jdk r6|jtkr6|jt|_q6n|jS(sFetch the rootdisk device valueN(RR$RR(R*((sconv.pyt__fetch_rootdisk@scCs<|j}|dtgkr8|j|s8|dSn|S(ssFetch the rootdisk device value. Convert it to slice form if not currently in the slice form. ts0N(t_XMLProfileData__fetch_rootdiskR$RR(R*R((sconv.pyt__fetch_rootdisk_sliceGs   cCsN|j|}|dkrdS|jdtjgkrJd}t||S|S(sReturn the insertion point for adding slices to the specified disk. On sparc this is on x86 this is Returns None is disk doesn't exist. s*./partition[@action='create'][@type='191']N(RR$RRRR(R*R RR((sconv.pyt__fetch_slice_insertion_pointSs  cCs#t|jr|jjdS|S(snReturn the 1st device off the usedisk stack if one exists. Otherwise return default_value i(R=Rtpop(R*t default_value((sconv.pyt__pop_usedisk_entrybscCs't|jr#|jjddS|S(s|Return the 1st device off the usedisk stack in slice form if one exists. Otherwise return default_value iR(R=RR(R*R((sconv.pyt__pop_usedisk__slice_entrykscCs|jdk r |j|dSt|}|dksD|dkrU|j|dS|dj}|dkr|jtd|dS|tkr|j | r|j | r|j t tdi|d6dS|j |r|j tjsdSq|j tjsdSn|dkr|dj}|d krHq|d krm|j ttd q|j|dSn|jdk r|j|j}||kr|j t td i|jd 6|jd6dSn ||_||_||_dS(sbConverts the boot device keyword/values from the profile into the new xml format NiiRss$invalid device specified: %(device)sRitpreservetupdatesAignoring eeprom 'update' setting, as this action is not supportedspconflicting definition: rootdisk previously defined as '%(root_device)s' via keyword '%(rd_kw)s', ignoring entryt root_deviceR~(RR$t"_XMLProfileData__duplicate_keywordR=RRRRRRRRRRRRRRRRRR(R*R3R4RRteepromR((sconv.pyt__store_boot_device_entrytsV                   cCs |jdk r |j|dSt|dkrC|j|dS|j|ds|jttdi|dd6dS|d|_|j dk r|j |j }|j|kr|jttdi|jd6|j d6qn|j|_ ||_ dS( sjSet the profile root device value that we'll use if root device is specified by the user Niis$invalid device specified: %(device)sRstranslation conflict between devices specified for boot_device and root_device, using root_device define of '%(root_device)s', ignoring define of boot_device of '%(boot_device)s'Rt boot_device( RR$RR=RRRRRRRRR(R*R3R4R((sconv.pyt__store_root_device_entrys*         cCs|jdk r |j|dSt|dkrC|j|dS|dj|_|jttgkr|jt t dd|j _ d|_ tndS(szSet the profile partitioning value that we'll use if fdisk all or usedisk is specified by the user later NiisAunsupported profile, partitioning must be 'default' or 'explicit'(RR$RR=RRRtPARTITIONING_EXPLICITRRRR&R`RRX(R*R3R4((sconv.pyt__store_partitioning_entrys        cCst|dks$t|dkr5|j|dSxU|D]M}|j|rd|jj|q<|jttdi|d6dSq<WdS(sStore the usedisk devices specified by the user. We'll use these to create the root pool if paritioning default is specified. iiNs$invalid device specified: %(device)sR(R=RRRRRRR(R*R3R4R((sconv.pyt__store_usedisk_entrys$    cCs|dkrR|jttdi|d6d |j_d |j_d |_tS|dj }|d kr|j ||dd |j_d |_tS|dkr|j |d |j_d |j_d |_tSt S( sThe only profiles that are supported are install profiles The jumpstart scripts require it as the first keyword in the file. If the install_type is not initial_install reject the entire profile t install_typesPinvalid profile, first specified keyword must be install_type, got '%(keyword)s'R3itupgradet flash_installt flash_upgradetinitial_installN(RRR( RRRR$R&R`RaRRRRRR(R*R3R4R((sconv.pyt__is_valid_install_types,              cCs|jS(s0Returns the xml tree associated with this object(R(R*((sconv.pyR7scCs|tjtjtjgkr.td n||jksO|jtjkrV|jS|tjkr|jdtjgkr|jSn|tjkr|jdtjgkr|j|jSntt di|d6|jd6dS(sConvert the current tree to the specified architecute Supported architecutres are: common.ARCH_GENERIC common.ARCH_SPARC common.ARCH_X86 Conversion not support: SPARC to X86 s"unsupported architecture specifiedsHConversion from architecute %(req_arch) to %(cur_arch)s is not supportedtreq_archtcur_archN( RRRRRXRRR$t*_XMLProfileData__fetch_sparc_from_x86_treeR(R*R;((sconv.pyt fetch_tree<s !   cCstj|}d}t||}x|jtjD]k}|jtj}|dk r7x4|jtjD] }|j ||j |qnW|j |q7q7W|S(s=Converts a x86 manifest xml tree to a sparc manifest xml trees /auto_install/ai_instance/targetN( RRRR@RRR+R$R1RHR(R*RtcloneRttargetRt partitionR$((sconv.pyt__fetch_sparc_from_x86_tree^s  cCs_|jdkri}nt|jj}t|dkr[d|j_d|j_dS|S(sLFetch the keys that we need to process from the profile dictionary iN(RR$tsortedtkeysR=R&R`Ra(R*R((sconv.pyt __fetch_keysss   cCsl|jjtj|_|jdk r=|jj|jntjtj|_|jj d|jdS(s(Find and set the global xml entry pointsiN( RRRRRR$RHR RbR(R*((sconv.pyt__find_xml_entry_pointss Rtbootenvt client_archt client_swaptclustertdontuseR}tfilesystgeoRtlocalet num_clientsRLt partitioningRRt system_typetusediskcCsS|j}|dkr%d|_dSt}d}d}x|D] }|j|}|dkrftn|j}|j}|j}|dks|dks|dkrtt dit |d6t |d6t |d6n||j t <|r*|j ||sd|_dS|j|=t}n|dkrS|j|||j|=q>|dkr||j|||j|=q>|d kr|j|=|dk r|j|qG|}q>|d kry|j|||j|=WqGtk rdSXq>|d kr"|j|||j|=q>|d kr>|jtjsGdSq>q>W|j|dk r|j|j t <|j|j|jnt|jj}x|D]}|j|}|jj}|j}|j|j t sf