i'dWc@sdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z m Z m Z mZddlmZddlmZmZmZmZddlmZdd lmZdd lmZdd lmZdd lm Z m!Z!m"Z"m#Z#dd l$m%Z%ddl&m'Z'm(Z(ddl)m*Z*m+Z+m,Z,m-Z-m.Z.dZ/dZ0dZ1de2fdYZ3de2fdYZ4defdYZ5dej6fdYZ7dS(s>Transfer ARCHIVE checkpoint. Sub-class of the checkpoint classiN(t LooseVersion(tsleep(tApplicationDatatPopentCalledProcessErrortrun(tUnifiedArchive(ttrusted_enabledtpkg_get_publisherst SystemInfotcurl_build_credential_opts(tBootMods(t InstallEngine(tAbstractCheckpoint(tTarget(t ArchiveSpectFiletSoftwaretSource(tALT_POOL_DATASET(tbe_listtbe_mount(tBE_NAMEt BE_MOUNTPOINTtBOOT_ENVIRONMENTt FilesystemtZpools /usr/bin/pkgs /usr/sbin/zfss/usr/sbin/zpooltArchiveTransferErrorcBseZdZddZRS(s>Exception raised when Archive Transfer fails unexpectedly cCstt|jd|dS(NsArchive Transfer Error: %s(tsuperRt__init__(tselftmsg((s archive.pyR>sN(t__name__t __module__t__doc__tNoneR(((s archive.pyR:stArchiveTransformErrorcBseZdZddZRS(sFException raised when Archive Transform is invalid or unsupported cCstt|jd|dS(Ns!Archive Transform unsupported: %s(RR$R(RR((s archive.pyRGsN(R R!R"R#R(((s archive.pyR$CstTransferArchivecBs eZdZidd6ed6ZdZdZdZdZ dZ dZ ee e e gZ d Z d Zd Zd Zd ZdZddZdZdZedZdZdZdZdZdZdZdZdZdZdZ dZ!RS( sfARCHIVE Transfer class to take input from the DOC. It implements the checkpoint interface. tzonenamet show_stdouttgzipstransform-typesglobal-to-globalsglobal-to-nonglobalsnonglobal-to-globalsnonglobal-to-nonglobalsorg.opensolaris.libbe:activesorg.opensolaris.libbe:parentbesorg.opensolaris.libbe:uuidscom.oracle.libbe:nbe_handletzonedscom.oracle:boot-pools/acCs tt|j|||_d|_d|_d|_d|_d|_ g|_ d|_ d|_ t |_d|_t|_t |_t |_tjj|_|jjdt|_|jjd|jdtdtd|_d|_d|_d|_ dS(Nit class_typetnametnot_found_is_err(!RR%Rt_be_mountpointR#tarchivettransformationt_deployable_objt_deployable_obj_namet _active_be_dst _transfer_opstsrct _app_datatFalset give_progresst _progress_pcttdictt_pool_space_usetdry_runt _cancel_eventR t get_instancetdata_object_cachet_doctget_descendantsRt soft_listR+tTruet soft_nodetalt_pool_datasett root_poolt _origin_rpool(RR+t be_mountpoint((s archive.pyRks.                cCs t|_dS(sCancel the transfer in progressN(RBR<(R((s archive.pytcancelscCs|jr|jndS(sCheck to see if a cancel event of the transfer is requested. If so, cleanup changes made to the system and raise an exception. N(R<t_cleanup(R((s archive.pytcheck_cancel_events cCs|jjd|jzZ|jr8|jjddn||_|j|jjd|j|jWd|j XdS(sExecute method for the ARCHIVE transfer checkpoint module. Will read the input parameters and perform the specified transfer. s=== Executing %s Checkpoint ===sBeginning archive transferisTransfer archiveN( tloggertdebugR+R7treport_progressR;t _parse_inputt _transferRJRI(RR;((s archive.pytexecutes    cCst|_d}|S(sNReturns an estimate of the time this checkpoint will take. i,(RBR7(Rtprogress_estimate((s archive.pytget_progress_estimates cCs2|jjdx|jD]}|jqWdS(s/Method to perform any necessary cleanup needed.s Cleaning upN(RKRLR3tcleanup(Rttransfer((s archive.pyRIscCs|jjd|jjjdt|_|jjjtj}|sXt dn|j dt dddt }g|D]}|j r}|^q}}|st dn|d|_|jr|jjjt|_n|j|j|jd S( scMethod to read the parameters from the DOC and place them into the local lists. sParsing the Data Object CacheR*s#No desired target tree found in DOCt max_depthiR,sNo root Zpool specified in DOCiN(RKRLR?t persistenttget_first_childRR5RtDESIREDt RuntimeErrorR@RRBtis_rootREt data_dicttgetRRDt _parse_srct_parse_transfer_nodet_parse_unified_archives(Rttargettzpoolstpooltrpools((s archive.pyRNs$ "     cCsi|jjdt}|dkr0tdn|jdkrUtd|jn|jd|_dS(sParse the DOC for the attributes that are specific for each transfer specified. Create a list with the attributes for each transfer. R*s'No Archived deployable system specifiedtinstalls/'%s' is not a valid action for unified archivesiN(RCRWRR#t ValueErrortactiontcontentsR1(RRT((s archive.pyR^s cCs|jjd|jjtjt}|dkrCtdn|jtj t}|dkrstdn|j |_ dS(s$Parse the DOC Source object sReading the ARCHIVE sources*One ARCHIVE image source must be specifieds%An ARCHIVE file URI must be specifiedN( RKRLRCRWRt SOURCE_LABELR#ReRt FILE_LABELtfile_uriR4(Rtsourcetua_file((s archive.pyR]s  cCs|jjd|jjdt}x-|D]%}|j|jkr,||_Pq,q,W|jsttd|jnx|jj D](}|j j |j kr||_ PqqW|j dkr t|jj dkst|jj d|_ |jj dj j |_ ntd|j |jf|j jjtjkrktd|j j j |j jjfn|j j}|jjd tg|D]}|j^qtd |D}t}|j d kr|jd krtj|_qstj|_nr|jd krC|j j jd kr4tj|_qstj |_n0|j j jd krgtj|_n tj!|_|j|j"j#tj$<|jtj!tjgkrt%d j&j'}|j jj&j'} t(| t(|krtd qn|j jj)rW|jtjtj gkr+tdn|j j j* rWt+ rWtdqWn|j j jdkr|jtj krtdn|jtj krx3|j,D]} | j-dkrPqqWtdn|jj.j/t0j1} g| jdt2dddt3D]} | j4r | ^q d|_5|jtj!tjgkr|j"j#d} x|D]Y}||j5j kr~q`n| j6|}|d krtd|n|j7|q`Wn+g|D]} | |j5j ks| ^q}|jj.j/t0j8}|jdt2dddt3}g|D]} | j4s(| j ^q(}x-|D]%}||krMtd|qMqMWxV|D]N}|j9d tj:gkrtd|j9|jfn|j;|j5j kr|j<j }n9|jtj!tjgkr| j6|j;}n |j;}|j=j6|d kr?d|j=|7:stglobals solaris-kzsAArchive and host versions incompatible: archive version is highers6Transforms of Trusted Solaris archives are not allowedsJDeploying labeled zone failed: Trusted Solaris must be enabled in the hostt solaris10s9Transforms of 'solaris10' brand zone archives not allowedtIPSsoIPS publishers are required for nonglobal-to-global transform deployments. Please provide an IPS specification.RUiR,t delegationss;Could not identify required delegated dataset for pool '%s'sGUnified archive stream can not be received. Missing required zpool '%s'sKUnexpected archive stream compresssion type type '%s' in archive stream: %stssl_keytssl_certtca_certthttp_auth_tokenR;N(HRKRLR?R@RtpathR4R.RYtarchive_objectstzoneR+R1R0tlentAssertionErrortsystemtarchtplatformt processorRet zfs_streamststrtsnapshottsetRDR#R%t TRANSFORM_G2GR/tTRANSFORM_G2NGtbrandtTRANSFORM_NG2GtTRANSFORM_NG2NGR5R[tTRANSFORM_TYPER t os_versiontbranchRttrustedt is_globalRRAt tran_typeRVRWRtORIGINRRBRZRFR\taddRXt compressiontCOMPRESSION_GZIPRnRER:tspacetTransferArchiveStreamt credentialstkeytcerttcacertRxR;R3tappend(Rt uarchivestuarchivetarch_objt stream_listRpt stream_poolstrequired_poolsthost_ost archive_ostswtoriginRbRtt pool_nametdelegated_datasetR`Ratavailable_poolst required_poolttarget_pool_nameRT((s archive.pyR_ s       #           %        c Cs|jjdt}t}d}d}|j r|jrxm|jjD]Y\}}tdddddd|g}t|}t |j }|||<||7}qQWnt } x(|j D]} | j | j| qWt} d} xY| rL|jr t} n| } x| D]} | r*Pn| js| j| | jdkr|jjd | jj| j|jjd | j|jjd t} | } PqqqW| rx| D]} t| _qWt } n|j r?|jr?x|jjD]\}}tdddddd|g}t|}t |j }|||}d ||}|d krqqn|j| s|||kr|||<|jjd|||qqWd}x/|jjD]\}}||||7}qW||}d |ko|jknr?|jjd|||_q?ntdqW| r~|jj d| rt!| jqn|jj d|j"dS(s1Execute and monitor the Archive transfer sTransferring Archive inputiR\s-Hs-ps-otvaluetuseds.Stream '%s' transfer from archive '%s' failed.s Reason: %ssTerminating all other transfersidicsProgress of %s: %d%%sTransferring contentsisArchive transfer canceledsArchive transfer completedN(#RKRLR9R;R7R:titemstZFSRtlongtstdouttlistR3tstartRR6R#R<RBtis_alivetremovet returncodeterrorRpRturitstderrtkillR\R8RMRtinfoRt_setup_bootenv(Rt initial_usedt received_pctt total_spacet target_nameRtcmdtused_cmdRtactive_transfersRTtcancel_transferst bad_transfert transferstaddedtpercenttweighted_pct_multpt weighted_pct((s archive.pyROs                         cCsd}|jjd|jj}|jj|jjkrq|jdkr\|jjd}n |jd}||jj}||jj|_ |jj dkrt j d|j }|dk rt t|jdd}|jd||_ tjj|j }nJt j d|j r?|j d 7_ |d 7}n|j d 7_ |d 7}|jjd t}|sttjg}|jjj|n|djdkr||d_qn|j |jjd   -     !   c  2RcBskeZdZdZdZdZdZd d d d edZ dZ dZ dZ d Z d ZRS( sArchive dataset stream transfer class. Handles transferring and receiving an archive stream from local file and remote http[s] paths onto a local ZFS dataset. Runs specified transfer in a separate thread. s /usr/bin/curls/usr/bin/gzcats /usr/sbin/zfsic Cs&tt|j| |_||_t|_||_||_||_ ||_ | |_ ||_ ||_ ||_d|_t|_d|_|jd|_d|_t|_t|_|jtjkrtd|jng|_g|_g|_|jr|jn |jdS(sClass constructoris+'%s' is not a valid archive transform valueN( RRRR;RR6t _completedt_loggert_ssl_keyt _ssl_certt_ca_certt_http_auth_tokentrecipient_datasetRpR R#tcreated_snapnamet_clone_transfert_clone_stagingt_check_clone_transferRRRtrunningR%RRet _recv_cmdt _curl_cmdt_uncompress_cmdt_init_clone_cmdst_init_archive_cmds( RRRRpR RKRuRvRwRxR;((s archive.pyRs:                        cCsK|jjtdg|jtjtjgkrT|jjd|jjdn:|jtjtj gkr|jjdn t d|jj|j |j jt j|j jdtj|jjdks|jdk r|j jt|j|j|j|jn|jjtjkrG|jjt jndS(sNInitialize the set of command lines used for Unified Archive transfer treceives-Fs-ds$unable to determine transform actions-sSthttpsN(R!textendRR R%RRRRRR$RR"RtCURLturlparseRtschemeRR#R RRRRpRRR#tGZCAT(R((s archive.pyR%s*     cCs#|jjtdd|jgdS(sIInitialize the ZFS command line used for direct clone deployment R&s-FN(R!R(RR(R((s archive.pyR$scCsztjj}xd|jdtD]P}|jjdkr"t|_|jdt dddtdj |_ Pq"q"WdS(s:Check for direct clone transfer, initialize state if foundR*tCLONERUiR,iN( R R=tdocR@RRtupperRBRRt _staging_dirR(RR.R((s archive.pyRs c Cs|js dS|jjjddd}|jd|}|jjd||jstj j }|j dt dddd}|r|d j jd }|dk rt|}t|jd }|jr|jjd |j|jd tqqntdd|g}yt|Wqtk r} tddddd|g} xtdD]v} |jjd|y>t| |jjd||jjd|t|Wntk rtdq^XPq^W| qXndS(sRecursively deletes the archive stream snapshots that get created as a result of successfully receiving the snapshot stream Nt@is'Destroying received snapshots under: %sR*RUit max_countiRtrollbacks Destroying rollback snapshot: %sR;tdestroys-rRs-Hs-oR+s -tsnapshoti s!Checking for received snapshot %ssLocated snapshot %ssDestroying received snapshot %s(RRpRRRRRLR;R R=R.R@RR[R\R#RtsnapnameRt full_nameR4R6RRRRR( Rt snaplabeltcreated_snapshotR.tapp_datatactive_datasettbe_dstrb_snapt destroy_cmdtcpetcheck_snapshotR((s archive.pyRSsN              c Cs$|jjd|jj|jd}d}|j rq|jrqt|jj dks\t zt j j |j|jj dj}t j|t j}tj|jd|dtj}|jjd|jj|j|j|jjdWd|dk rM|jdkrM|jdkrM|jjd |jj|jqMnX|jjd |jj|jdSz|jst|jdtjdtj}t|jdtjd |jdtj}nx_t|jj D]K\}}|j}|j|jd}d ||f} |j } | j!| |jg|jjd |dt|jj |j|j|||jst| d |jdtj} xS| jdkr|j"r|jjd|j|j| jdSt#dqW| jdkr | j$j%} | jt&j'kr|jdk rw|jdkr|jj(d|j|j|_|j$j%|_$qq|jdk r|jdkr|jj(d|j|j|_|j$j%|_$qqn| |_$| j|_|jjd|j|jdS|jjd|j|jqqW|jjd|jj|jt)|_*Wd|dk r|jj+|jdkr|jdkr|jjd|jj|jqn|dk r|jj+|jdkr|jdkr|jjd |jj|jqnXdS(s4Executes the dataset stream transfer in a new threads'Commencing transfer of stream: %s to %siitstdinRsStreaming %s to %ssStream completeNsKilling stream receiver for %ss1Completed transfer of direct stream: '%s' from %sRs-r %s-%ss?Transferring stream file [%d/%d]: '%s' from %s (range: %d - %d)s0Terminating transfer of stream file '%s' from %ss#Error receiving ZFS stream file: %ss'Error decompressing ZFS stream file: %ss,Failed transfer of stream file: '%s' from %ss/Completed transfer of stream file: '%s' from %ss*Completed transfer of stream: '%s' from %ss"Killing stream uncompressor for %s(,RRRpR+RR#R;RR|tfilesR}RRyR RtopentO_RDONLYRt check_callR!tPIPERLtwaitRtpollt terminateRR#R@t enumeratetoffsettsizeR"R(RRRtreadRtCURL_WRITE_ERRRRBRtclose( Rtreceivert uncompressort stream_fifotfdtindext streamfiletlothit range_argtcurl_cmdtcurlert curler_err((s archive.pyR8s     !                            !    !  N(R R!R"R)R,RRMR#R6RR%R$RRSR(((s archive.pyRs ' )  >(8R"RRRt threadingR*tdistutils.versionRttimeRtsolaris_installRRRRtsolaris_install.archiveRtsolaris_install.archive.utilRRR R tsolaris_install.boot.boot_specR tsolaris_install.engineR t!solaris_install.engine.checkpointR t Checkpointtsolaris_install.targetRtsolaris_install.transfer.infoRRRRt)solaris_install.target.instantiation_zoneRtsolaris_install.target.libbeRRtsolaris_install.target.logicalRRRRRRRRt ExceptionRR$R%tThreadR(((s archive.pyts8     """(  B