ó i'dWc@sadZddlZddlZddlZddlZddlZddlZddlZddlj Z ddl m Z ddl m Z mZmZmZmZmZmZmZmZmZmZmZmZddlmZddlmZmZddlm Z ddl!m"Z"dd l#m$Z$dd l%m&Z'dd l(m)Z)m*Z*dd l+m,Z,dd l-m.Z.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7de8fd„ƒYZ9de8fd„ƒYZ:de:fd„ƒYZ;de:fd„ƒYZ<de:fd „ƒYZ=d!e=fd"„ƒYZ>d#„Z?d$„Z@d%„ZAd&„ZBd'„ZCd(„ZDdS()s archiveadm create-media iÿÿÿÿN(t OptionGroup( t_tApplicationDatatCalledProcessErrortrunt DC_PERS_LABELtDC_LABELt SetUIDasEUIDt with_spinnertSYSTEM_TEMP_DIRtPopentLockfilet LockfileErrortsystem_temp_path(tUnifiedArchive(t spinwritetverify_credentials(tDataObjectDict(tDistro(t InstallEngine(tINSTALL_LOGGER_NAME(t FilesystemtZpool(tSize(tTransferCPIOAttrs/usr/sbin/lofiadms/usr/sbin/mkfiles/usr/sbin/mounts/usr/sbin/newfss/usr/lib/fs/pcfs/mkfss /usr/bin/pkgs/usr/sbin/umounts/usr/sbin/zonenames archive.locktArchiveMediaCreatorcBs•eZdZddgZd„Zd„Zd„Zd„Zd„Zd„Z d „Z d „Z d „Z d „Z d „Zd„Zed„ƒZRS(s4 Class responsible for creating media from archives tisotusbcCsütjtƒ}|jdƒ|jtjj|ƒƒ|_|j ƒ|j |_ |j ƒ|j |j|j |j |j|jƒ|_ |jƒ|jpd|_|jƒ|jrË|jjƒ|_n d|_|jƒ|jr3tjj|jƒrtjj|jdƒ}qNtjj|jƒd}ntjjtjƒdƒ}tjjd||jfƒ|_|jƒttgƒjjƒdkrøy4t dƒt d ƒt!j"ƒd krËt#ƒnWqøt$k rô}|j%t&|ƒƒqøXndS( Ns(archiveadm: ArchiveMediaCreator:__init__trpoolRt AI_Archiveis%s.%stglobaltpcfstufsti386('tloggingt getLoggertILNtdebugt init_archivetostpathtabspathtuat validate_uatzonet validate_zonetinit_ai_sourcetsourcetkeytcerttvalidate_sourcetdatasettvalidate_datasett media_formattlowertvalidate_media_formatt media_pathtisdirtjointsplitexttgetcwdtvalidate_media_pathRtZONENAMEtstdouttstriptverify_fs_requirementstplatformt processort verify_grubt RuntimeErrort exit_errortstr(tselft archive_pathtoptionstloggerR8te((smedia.pyt__init__Gs>             cCsttd|ƒƒdS(s Displays a spinwrite message. s%s N(RR(RHtmessage((smedia.pyt show_infotscCs4tjjtd|ƒƒttd|ƒƒ‚dS(s+ Displays an error and exits create-media. sarchiveadm create-media: %s sarchiveadm create-media: %sN(tsyststderrtwriteRRE(RHRN((smedia.pyRFxscCsº|jjdjjtjƒkr<|jd|jjƒng|jjD]}|jj rI|j^qI}t |ƒs|jd|jjƒn|jj s¶|jd|jjƒndS(s. Validates the archive passed to this object. isEThe architecture of %s does not match the architecture of this systems%No global zones found in archive '%s's]%s contains non-root data. Media can only be created from archives containing root-only data.N( R*tarchive_objectstsystemtarchRBRCRFR(R,t is_globaltanyt root_only(RHtobjt global_zones((smedia.pyR+}s"     cCs g|jjD]}|jjr |jj^q }|jr{|j|kr|jd|j|jjdj|ƒfƒqnŒd|kr“d|_ntt|ƒdkrµ|d|_nRt|ƒdkrá|jd|jjƒn&|jd|jjdj|ƒfƒdS( s+ Validates the zone passed to this object. s9Zone '%s' is not a global zone in %s. Valid zones are: %ss, RiisNo global zones exist in %ss‰No host global zone exists in %s and more than one other global zone is present. Must use -g to select a global zone. Valid zones are: %sN( R*RSR,RVtnameRFR(R:tlen(RHRYtglobal_zone_names((smedia.pyR-‘s$      cCs8y|jjƒWn tk r3}|j|ƒnXdS(s- Validates the source passed to this object. N(R/tvalidateRERF(RHRL((smedia.pyR2²scCs-t|jƒjs)|jd|jƒndS(s. Validates the dataset passed to this object. s ZFS dataset '%s' does not exist.N(RR3texistsRF(RH((smedia.pyR4¹s cCsm|jtjkr)|jd|jƒn|jdkritjj|jjƒd kri|jdƒqindS( s3 Validates the media_format passed to this object. sInvalid media format: %sRiis.Archives larger than 4GB cannot use ISO formatNii@l(R5Rt MEDIA_FORMATSRFR'R(tgetsizeR*(RH((smedia.pyR7Às cCsûttjj|jƒƒdkr1|jdƒntjj|jƒ}tjj|ƒsl|jd|ƒntjj|ƒr’|jd|ƒnt ƒ.tj |tj ƒsÅ|jd|ƒnWdQXtjj|jƒr÷|jd|jƒndS(s1 Validates the media_path passed to this object. i s(Media name must be 32 characters or lesss$Output directory '%s' does not exists'%s' is a files'%s' is not writeableNs'%s' already exists( R\R'R(tbasenameR8RFtdirnameR_tisfileRtaccesstW_OK(RHt media_dir((smedia.pyR=Ìs! cCsþtjj|ƒs&|jd|ƒntjj|ƒrL|jd|ƒntj|tjƒsu|jd|ƒntjƒ}|j dƒ|j dddd|gƒt ƒ|j ƒ\}}WdQX|tj krèt|ƒn|jjjd tƒS( sL Instantiates and returns a UnifiedArchive object from archive_path sArchive '%s' does not exists'%s' is a directorys'%s' is not readablesInitiating media creation...tInstantiateUnifiedArchives#solaris_install/archive/checkpointstargsNt class_type(R'R(R_RFR9RetR_OKRt get_instanceROtregister_checkpointRtexecute_checkpointst EXEC_SUCCESSt fail_and_exittdoctvolatiletget_first_childR(RHRItengtstatust failed_cps((smedia.pyR&às"      c Csg|jD]C}|jj|kr dj|jjjjddƒdd!ƒ^q }t|ƒdkrr|d}n|j d|ƒ|rH|j dƒr| rµ|rµ|j dƒn| rÒ|rÒ|j dƒn| rð| rð|j d ƒnt ||||ƒS|s|r|j d ƒn|j d ƒr;t ||ƒSt |ƒSnQ|sT|rd|j d ƒn|j||ƒ} | rŒt| |jƒSt d |ƒSd S(s€ Instantiates an AISource object of the correct type based on the passed in ua, source, zone, key and cert. t.iiis8Source version was unable to be determined for zone '%s'thttpss*key option is required for an HTTPS sources2certificate option is required for an HTTPS sources<key and certificate options are required for an HTTPS sources-Credentials are only valid with HTTPS sourcesthttps$Credentials valid only with --sourceN(RSR,R[R:RTt os_versiontbranchtsplitR\RFt startswitht HTTPSSourcet IPSSourcet ISOSourcetget_source_from_archivet ArchiveSourceR(tNone( RHR*R/R,R0R1RYtversionstversiontarchive_source((smedia.pyR.ùs4P        cCs…d}x0|jD]%}|jj|kr|j}PqqW|dk r}tj|jƒ}|j|jƒj dkrvdS|jSdSdS(s| Attempts to get the AI source from the archive. If the source does not exist, this method returns None iN( RƒRSR,R[tai_mediattarfiletopenR(t getmembertsize(RHR*R,R‡RYtua_tar((smedia.pyR&s  c Cs‘tjtƒ}|jdƒtjƒ}|jdƒd|j|jj f}t t ƒ}y t |ƒút |ƒ}|jr|jdƒny|jƒWn$tk rÃ}|jd|ƒnXz–y|jj|ƒ}Wn&tk r}|jt|ƒƒnXt|jjdƒdƒ}t|jdƒdƒj} tjj|jjƒ} t|jd ƒƒj} | | d | kr™|jd |jƒni|jd ƒd 6|jd ƒd6tjj|jd ƒdƒd6tjj |j!ƒd6} |j"j#j$t%t&| ƒƒidd6dd6} |j"j'j$t%t(| ƒƒt)tjj*tjj+|j!ƒƒdƒ}|j"j#j$|ƒ|jdƒi|jjd6|jd ƒd6|jd ƒd6}|j,dddd|ƒt-j.ƒdkrÿ|j,ddd ƒnt/ƒ|j0ƒ\}}Wd!QX|tj1kr=t2|ƒn|jj3|ƒ|jd"ƒ|j4d#krŒ|jd$ƒ|j,d%d&d'ƒn |jd(ƒ|j,d%d)d*ƒtjj|jd ƒd+ƒ}tjj|ƒrtj5|ƒrt6t7|gƒqn|jd,|j!ƒt/ƒ|j0d-d%ƒ\}}Wd!QX|tj1krYt2|ƒnWd!|jd.ƒ|d!k r|jrtjj|jd ƒd+ƒ}tjj|ƒrtj5|ƒryt6t7|gƒWqþtk rú}|jt|ƒƒqþXqqn|jj3|ƒy|j3d/t9d0t:ƒWn-tk r]}|jd1|j|fƒnXXWd!QXWn$t;k rŒ}|jd2|ƒnXd!S(3s Creates media from the archive s,archiveadm: ArchiveMediaCreator:create_mediasPreparing build environment...s %s/archive_%ss$Build dataset must not already exists'Failed to create build area dataset: %st/itfreetusedgš™™™™™ñ?s/Insufficient free space in '%s' to create mediat mountpointt pkg_img_pathtba_buildttmpttmp_dirRgs boot/bios.imgsbios-eltorito-imgs boot/uefi.imgsuefi-eltorito-imgsAdding archive content...R†R3t ai_sourcetAddArchiveToISOs#solaris_install/archive/checkpointstkwargsR!s archive-bootssolaris_install/boot/boottArchiveISOImageBootMenuNsImage preparation completeRsCreating ISO image...s create-medias3solaris_install/distro_const/checkpoints/create_isot CreateISOsCreating USB image...s3solaris_install/distro_const/checkpoints/create_usbt CreateUSBtusrsFinalizing %s...t start_fromsCleaning up...tdry_runt recursives&Unable to destroy build dataset %s. %ss2An instance of create-media is already running: %s(<R"R#R$R%RRlROR3R*tuuidR t ARCHIVE_LOCKR RR_RFtcreateRR/ttransferRERGRR[R|Rtgett byte_valueR'R(RaR:RcR8RqRrtinsert_childrenRRt persistentRRR;RbRmRBRCRRnRoRptdestroyR5tlistdirRtUMOUNTRƒtFalsetTrueR (RHRKRtt build_datasett lockfile_pathtbuild_fsRLt ai_image_fstzpoolt zpool_spacet archive_sizet source_sizetd1td2tdistroR—RuRvt fs_usr_mount((smedia.pyt create_media>sÊ                                   (t__name__t __module__t__doc__R`RMRORFR+R-R2R4R7R=R&R.RRR¸(((smedia.pyRBs  -    !     - tAISourcecBsMeZdZejZd„Zejd„ƒZejd„ƒZ d„Z RS(s8 Abstract AISource class to be parent of all AI sources cCs ||_dS(N(R/(RHR/((smedia.pyRMÖscCstdƒ‚dS(s? Abstract method that ensures the AISource is in a good state. s#This method needs to be implementedN(tNotImplementedError(RH((smedia.pyR^ÙscCstdƒ‚dS(s~ Abstract method that transfers the contents of the source into the staging directory for media creation. s#This method needs to be implementedN(R½(RHtfs((smedia.pyR¢ÞscCsuyDttjj|jdƒƒ}|jrC|jdtdtƒnWn*t k rpt d|j dƒƒ‚nXdS(sZ Method that cleans up the temporary source in the staging directory. t tmp_pkg_imageRRžs#Unable to destroy source dataset %sRN( RR'R(R:R[R_R§RªR«RRER£(RHR¾R¯((smedia.pyR§ås  ( R¹RºR»tabctABCMetat __metaclass__RMtabstractmethodR^R¢R§(((smedia.pyR¼Òs   R€cBs eZdZd„Zd„ZRS(s@ AISource subclass that handles an AISource coming from an ISO. c CsNtjj|jƒ s/tj|jtjƒ rEtd|jƒ‚ntjdt ƒ}y t t dd|j|gƒWn$t k rtd|jƒ‚nXz‹d}tjjtjj|ddƒƒrÔd}n-tjjtjj|dd ƒƒrd }n|dkr#td |jƒ‚n|tjƒkrKtd |jƒ‚ntjj|d ƒ}tjj|ƒsˆtd|jƒ‚nt|dƒf}x\|jƒjƒD]H}|jdƒr­|jdƒddkrñtd|jƒ‚nPq­q­WWdQXy.tjj|dƒ}t td|gƒ}Wnt k rLtdƒ‚nX|jjƒ}tjdt ƒ} z}y#t t dddd|| gƒWnt k r³tdƒ‚n7Xtjj| dƒ} tjj| ƒsêtdƒ‚nWdt t| gdtjƒtj| ƒt td|gƒXWdt t|gƒtj|ƒXdS(Ns'%s' not found or not readabletdirs-FthsfssCannot mount '%s'.RBti86pcR!tsun4vtsparcs'Could not identify architecture of '%s'sBArchitecture of '%s' does not match the architecture of the systems .image_infos#.image_info does not exist in '%s'.trs IMAGE_TYPE=t=itAIs3'%s' is not a Solaris Automated Installer ISO images solaris.zlibs-as#Unable to verify ISO image provideds-otrossbin/archiveadms.Source ISO does not support archive operationst check_results-d(R'R(R_R/ReRkREttempfiletmkdtempR RtMOUNTRRƒR:RBRCR‰treadt splitlinesR}R|tLOFIADMR?R@R©R tANYtrmdir( RHRtiso_archtimage_info_pathtftlinet zlib_pathtptlofi_devt zlib_mounttcli((smedia.pyR^õsf  $ $   #  cCsyñttjj|jdƒƒ}|jƒtdƒ}|jdƒ|_d|_ dg|_ d|_ t j dtdd ƒ}td d |j|g}t|ƒ||_z2y|jƒWntk rÚtd ƒ‚nXWdtt|gƒXWntk rtd ƒ‚nX|S(NR¿s ISO TransferRtinstalls./s-pdbRÄtprefixt ai_iso_tmp_s-FRÅsFailed to transfer ISO contentssTransfer was interrupted(RR'R(R:R[R¡RR£tdsttactiontcontentst cpio_argsRÎRÏR RÐR/Rtsrctexecutet ExceptionRER©tKeyboardInterrupt(RHR¾R¯tnodettmpdirtcmd((smedia.pyR¢@s,          (R¹RºR»R^R¢(((smedia.pyR€òs KR‚cBs)eZdZd„Zd„Zd„ZRS(sE AISource subclass that handles an AI source coming from an archive. cCs#tt|ƒj|ƒ||_dS(N(tsuperR‚RMRI(RHR/RI((smedia.pyRMascCsˆtjj|jƒs+td|jƒ‚ntjj|jƒrVtd|jƒ‚ntj|jtjƒs„td|jƒ‚ndS(NsArchive '%s' does not exists'%s' is a directorys'%s' is not readable(R'R(R_RIRER9ReRk(RH((smedia.pyR^escCsƒy_tj|jƒ}ttjj|jdƒƒ}|jƒ|j |j |j dƒƒt dƒ}|j dƒ|_ d|_dg|_d|_tjdtdd ƒ}td d tjj|j dƒ|j ƒ|g}t|ƒ||_z2y|jƒWntk r td ƒ‚nXWdtt|gƒXtjtjj|j dƒ|j ƒƒWntk r~td ƒ‚nX|S(NR¿Rs ISO TransferRßs./s-pdbRÄRàRás-FRÅsFailed to transfer ISO contentssTransfer was interrupted(RˆR‰RIRR'R(R:R[R¡textractR/R£RRâRãRäRåRÎRÏR RÐRRæRçRèRER©tremoveRé(RHR¾RŒR¯RêRëRì((smedia.pyR¢os6           , (R¹RºR»RMR^R¢(((smedia.pyR‚^s  RcBs)eZdZd„Zd„Zd„ZRS(s> AISource subclass that handles an AI source coming from IPS. cCs#tt|ƒj|ƒ||_dS(N(RíRRMR…(RHR/R…((smedia.pyRM—scCsdS(N((RH((smedia.pyR^›sc Cs¹y|tjƒ}|jdddd||jdd|jgƒtƒ|jƒ\}}WdQX|tjkr{t |ƒnWnt k r›t dƒ‚nX|j j jdtƒjdS(NtDownloadAIPackages#solaris_install/archive/checkpointsRisTransfer was interruptedRjtai_image_dataset(RRlRmR/RƒR…RRnRoRpRéRERqRrRsRt data_dict(RHR¾RtRuRv((smedia.pyR¢Ÿs     (R¹RºR»RMR^R¢(((smedia.pyR”s  R~cBs)eZdZd„Zd„Zd„ZRS(sM IPSSource subclass that handles an AI source coming from an HTTPS repo. cCs/tt|ƒj||ƒ||_||_dS(N(RíR~RMR0R1(RHR/R…R0R1((smedia.pyRM¸s cCstj|jtjƒs.td|jƒ‚ntj|jtjƒs\td|jƒ‚nyt|j|j|jƒWntk r˜tdƒ‚nXdS(NsKey '%s' not foundsCertificate '%s' not foundsInvalid credentials(R'ReR0RkRER1RR/(RH((smedia.pyR^½s c Cs¿y‚tjƒ}|jdddd||j|j|j|jgƒtƒ|jƒ\}}WdQX|tj krt |ƒnWnt k r¡t dƒ‚nX|j jjdtƒjdS(NRðs#solaris_install/archive/checkpointsRisTransfer was interruptedRjRñ(RRlRmR/R0R1R…RRnRoRpRéRERqRrRsRRò(RHR¾RtRuRv((smedia.pyR¢És     (R¹RºR»RMR^R¢(((smedia.pyR~´s  cCs tdƒS(sE Initializes and returns usage string for 'create-media' subcommand. s÷ create-media [-g|--global-zone ] [-s|--source | ] [-k|--key ] [-c|--cert ] [-d|--dataset ] [-f|--format [usb | iso]] [-o|--output ](R(((smedia.pyt get_usageÞsc Cst|dd"ƒ}|jdddddtdƒƒ|jdd dd dtd ƒƒ|jd d dddtdƒƒ|jdddddtdƒƒ|jdddddtdƒƒ|jdddddtdƒddƒ|jdddd dtd!ƒƒ|j|ƒd"S(#s8 Sets up the options for the 'create-media' subcommand. sMedia Creation Optionss-gs --global-zonetdestR,thelps.optional global zone from which media is builts-ss--sourceR/s"optional ISO path or publisher URIs-ks--keyR0s&key for use with https repository URIss-cs--certR1s.certificate for use with https repository URIss-ds --datasetR3s1optional dataset under which media is constructeds-fs--formatR5s*format for media construction. USB or ISOtdefaulttUSBs-os--outputR8soptional path for final mediaN(RRƒt add_optionRtadd_option_group(tparsertgroup((smedia.pyt setup_optionsês"       cCsÇtjtƒ}d}xc|D][}tj|ƒ}xC|D];}|jtj}|dkrc|}n|jd|ƒq8WqWt |t ƒs·t j j td|ƒƒtd|ƒ‚n tdƒ‚dS(sjLog a set of failed checkpoints and exit, issuing the first failure's exception string to stderr. s'%s' checkpoint failedsarchiveadm create-media: %s s%ss*Execution failed due to keyboard interruptN(R"R#R$Rƒterrsvctget_errors_by_mod_idt error_datatES_DATA_EXCEPTIONR%t isinstanceRéRPRQRRRRE(RvRKttopt failed_cpterrorsterrRL((smedia.pyRps    cCsÆddg}||kr+td|ƒ‚ntjƒ}tjƒ\}}tj|ƒttdd|gƒttd|gƒ}|j j ƒ}|dkr½t dd|j d d ƒg}n'|dkrät |j d d ƒg}nt|d td d ƒƒ|dkr!tdd||g}n*|dkrKtdddd||g}nzFyt|ƒWn!tk rtd|ƒ‚nXtt|gƒWdtj|ƒttd|gƒtj|ƒXdS(s1Verify files can be mounted via fs_type in a zoneRR s+Filesystem type '%s' is not a required types-nt8ms-as-osnofdisk,size=8192tlofitrlofitstdins /dev/zeroRÉs-Ft nologgingsiFS type '%s' is not allowed via 'fs-allowed' property in the zone configuration. Media cannot be created.Ns-d(RERÎRÏtmkstempR'tunlinkRtMKFILERÓR?R@t PCFS_MKFStreplacetNEWFSR‰RÐRR©RÕ(tfs_typetrequired_fs_typest mount_pointt_noneR[RÛRÜRì((smedia.pyRAs<            cCsAtddg}yt|ƒWntk r<tdƒ‚nXdS(s7 Verify grub is installed if needed on i386 platforms. tinfossystem/boot/grubs/Required package system/boot/grub not installedN(tPKGRRRE(Rì((smedia.pyRDDs  cCs'|d}t||ƒ}|jƒdS(s2 Main point of entry for archiveadm create-media. iN(RR¸(RJRitarchivet media_creator((smedia.pytrun_create_mediaNs (ER»RÀR"R'RBRPRˆRÎtsolaris_install.errsvcRýtoptparseRtsolaris_installRRRRRRRRR R R R R tsolaris_install.archiveRtsolaris_install.archive.utilRRt%solaris_install.data_object.data_dictRt(solaris_install.distro_const.distro_specRtsolaris_install.engineRtsolaris_install.loggerRR$tsolaris_install.target.logicalRRtsolaris_install.target.sizeRtsolaris_install.transfer.cpioRRÓR RÐRRRR©R>R tobjectRR¼R€R‚RR~RóRüRpRARDR(((smedia.pytsR       Xÿ‘ l6 *   /