i'dWc@sdZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z ddl mZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZddlmZmZmZddlmZdefdYZdefdYZ defdYZ!dS(s;Transfer SVR4 checkpoint. Sub-class of the checkpoint classiN(tdir_size(tPopentCalledProcessErrortrun(tAbstractCheckpoint(t InstallEngine(tArgs(t Destination(tDir(tOrigin(t Publisher(tSoftware(tSource(tSVR4Spec(tACTIONtCONTENTSt SVR4_ARGS(t ProgressMont AbstractSVR4cBseZdZejZejjddZ dZ e e Z e dZ dZ dZdZdZdZd Zd Zd Zd Zd ZejdZdZdZdZi dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6ZdZd Zd!Z d"Z!d#Z"d$Z#e$d%Z%d&Z&e'd'Z(ej)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/RS(.sSubclass for transfer SVR4 checkpoint self.src can be either a local directory containing SVR4 package subdirectories, or it can be datastream file. Datastream files can be local (in the form of /dir/file or the URL form of file:///blah/datastream.d) or remote (in the URL form of http://blah/datastream.d). The local URL format is not efficient, but it works. In all cases, self.src can house multiple packages. self.dst is a filesystem (or directory during testing). tROOTts/system/volatile/s /svr4_adminis-n -a %s -d %s -R %ss-n -a %s -R %si s/usr/sbin/pkgadds/usr/sbin/pkgrms/usr/bin/pkgadms# PaCkAgE DaTaStReAms# end of headers(\w*)://([^/]*)((/.*)*)sLocal DirectorysLocal DatastreamsRemote DatastreamtmailtquittinstancetnochecktpartialtrunleveltidependtrdependtspacetsetuidtconflicttactiontbasedircCstt|j|d|_d|_d|_d|_t|_ t|_ d|_ t|_ d|_ t|_d|_g|_t|_dS(Ni(tsuperRt__init__tNonet datastreamtsrctdsttdoctFalsetdry_runtsync_dbt total_sizet give_progresst svr4_processt _cancel_eventtpmont_transfer_listt input_parsed(tselftname((ssvr4.pyR#js            cCstj|tjr?tjj|r3tj}qtj}nZytj |}|j Wn1t tj fk r|j jd|nXtj}|j jd||S(s0Returns type of package source LOCAL_DIR_TYPE : # /path/to/parent_of_pkg_subdirs LOCAL_DSTR_TYPE : # /path/to/datastream REMOTE_DSTR_TYPE : # http://url_to_datastream Some assumptions are made. For example, local datastream assumes that any file which is local and not a directory is a datastream. If this is not correct, pkgadd will fail later, but that's OK. Assumes datastream if file is remote, or is local and not a directory. Rejects a non-datastream remote request as pkgadd doesn't support it. local datastr url* Possible Notes (vs dir) 0 0 0 0 Remote dir doesn't make sense 0 0 1 0 Remote dir doesn't make sense 0 1 0 0 /net/... Treat as local** 0 1 1 1 -> remote implies datastream and url 1 0 0 1 -> local directory 1 0 1 0 Dir URL doesn't make sense 1 1 0 1 -> local datastream file 1 1 1 0 file:// not supported by pkgadd * starts with http:// or similar, vs a file path /path/to/file ** Not worth the effort to treat them as remote. s) Source %s doesn't exist or is unreadablesget_src_type returns %s(tostaccesstR_OKtpathtisdirRtLOCAL_DIR_TYPEtLOCAL_DSTR_TYPEturllib2turlopentcloset ValueErrort HTTPErrortloggerterrortREMOTE_DSTR_TYPEtdebug(R3t in_file_nametsrc_typetfd((ssvr4.pyt get_src_types    cCs<tjj|}|d kr7ttjd|n|jdj}|dkrst j |jd}n=|dkrt j |jd}nttjd|zz|j d|jd|j }|jd }yt|tj}Wn(tk r(|jjd |nXWd |jX|S( s4 Returns the size of an http or https URL file in KbsMalformed URL specified: %sithttpithttpss Non-http/https URL specified: %stHEADiscontent-lengthsInvalid size returned for %sN(RtURL_REtmatchR$tIOErrorterrnotEINVALtgrouptlowerthttplibtHTTPConnectiontHTTPSConnectiontrequestt getresponset getheadertintt BYTES_PER_KBR?RARBR>(R3turltre_matchtprotocoltconntresponsetsizetisize((ssvr4.pytget_size_via_https*         c Csd}t|d}|jj}|tjkrItd|n|jj}t}x|tjkryA|jdd\}}} t | t |dd||tlisttappendRDtjoin( R3tds_nametpkg_listR,tds_fdtlinetpkg_dicttpkg_nametpartsR`t bad_pkg_names((ssvr4.pytds_pkg_size_and_verifys< &        cCstjj|s%td|nd}t}x|D]}tjj||}tjjtjj|d stjjtjj|d r|j|q;|s;t|t j }|j j d||f||7}q;q;W|rtd|dj|fn|S(sVerifies local packages in form of directory tree. Checks size. Accommodates several package trees under a common parent. Checks that all packages in pkg_list are contained under parent dir. Returns combined size in Kb of desired packages. s%s is not a directoryitpkginfotpkgmaps)Found SVR4 pkg to install: %s, size: %sKbsAThe following packages under parent %s are missing or invalid: %ss, ( R5R8R9R?RlRntexistsRmRRRZRARD(R3t parentdirRpR,Rvtpkgtpkgroottpkg_size((ssvr4.pytnonds_pkg_size_and_verify s$   "" cCsO|jtt|jtjtj}|dkrBd}nt|_|S(s9Returns an estimate of the time this checkpoint will takeii( t_parse_input_onceRYtfloatR,Rt DEFAULT_SIZEtDEFAULT_PROG_ESTtTrueR-(R3tprogress_estimate((ssvr4.pytget_progress_estimate4s     cCs|jjd|j|jr6|jjddn||_z2|j|jtj |j |j Wd|j XdS(sExecute method for the SVR4 checkpoint module. Will read the input parameters and perform the specified transfer. s=== Executing %s Checkpoint ===sBeginning SVR4 transferiN( RAtinfoR4R-treport_progressR*Rtgenerate_admin_fileRt ADMIN_FILEtcheck_cancel_eventt _transfert_cleanup(R3R*((ssvr4.pytexecuteBs    cCs-|js)|j|jt|_ndS(sInsures _parse_input() and _validate_input() are called only once Note: This method assumes all calls to it are made by the same thread. N(R2t _parse_inputt_validate_inputR(R3((ssvr4.pyRZs   cCsUt|d@}x6tjjD]%\}}|j|d|dq"WWdQXdS(s+Generate the admin file from the ADMIN_DICTtwt=s N(ReRt ADMIN_DICTt iteritemstwrite(tfilenameRGtkeytvalue((ssvr4.pyRdscCs tdS(s;This method is required to be implemented by all subclassesN(tNotImplementedError(R3((ssvr4.pyRkscCs&t|_|jr"|jjndS(sCancel the transfer in progressN(RR/R.tkill(R3((ssvr4.pytcancelps  cCs|jr|jndS(sCheck the _cancel_event attribute to see if a cancel event has been requested. If it has, cleanup what has been done already N(R/R(R3((ssvr4.pyRvs cCs|jr.t|j_|jjd|_ntjjtj rVtj tj n|j rtj dd|j dg}y%|jjd|tj|Wqtk r}|jjd|qXndS(s/Method to perform any necessary cleanup needed.tsyncs-Rs-qsExecuting the pkgadm command %ss-pkgadm command failed with following error:%sN(R0RtdonetwaitR$R5R8RzRRtunlinkR+tPKGADMR'RARDRt check_callRtwarn(R3tcmdRB((ssvr4.pyR}s      cCs |jr@td|j|_|jj|j|jddnzx|jD]}|jt j d}|jt dkr|j |jj dtjg||jt}ny|jt dkr |j |jj dtjg||jt}n*|jjd |jt |j qM|jrS|jjd |nu|jjd ||j yt||_Wn/tk rd |_t|jjd nXt|_d |_|j qMWWd |jrt|j_|jjd |_nXd S(s5Method to transfer from the source to the destinationRAiidRdtinstallsInstalling SVR4 packagest uninstallsUninstalling SVR4 packagess!Transfer action, %s, is not valids0Would execute the following transfer command: %ss,Executing the following transfer command: %ss)SVR4 transfer error while adding packagesN(R-RRAR0t startmonitorR'R,R1tgetRRkRRRRtPKGADDRtPKGRMtwarningR*RDRR.RR$tOSErrort returncodeRR+RR(R3t trans_valtarglistR((ssvr4.pyRsN "                    cCs|jjd|jd kr.tdn|jsFtdn|jsb|jjdnx|jD]}|jt dkr|jt dkrtd|jt n|jt stdn|jt sltd qlqlWd S( scCheck the required input parameters and verify that they are set appropriately. sValidating SVR4 inputs"SVR4 destination must be specifiedsSVR4 source must be specifieds No transfers have been specifiedRRs.Transfer action "%s" is not avalid SVR4 actionsSVR4 args must be specifiedsSVR4 packages must be specifiedN( RARDR'R$R?R&R1RRRRR(R3R((ssvr4.pyRs   (0t__name__t __module__t__doc__tabctABCMetat __metaclass__R5tenvironRRtTMPDIRtADMIN_FILE_DIRRRZtDEFAULT_PKGADD_ARGStDEFAULT_PKGRM_ARGSRRRRRRhRjtretcompileRLR:R;RCRR#RHRbRwRRR)RRt staticmethodRtabstractmethodRRRRRR(((ssvr4.pyR2s^       3  6 )       @t TransferSVR4cBs eZdZdZdZRS(sHTransfer subclass uses checkpoint interface. Takes data from the DOC Relevant manifest fields look like this: SUNWpkg1 SUNWpkg2 Origin name can also be a datastream file, in the form of: cCstt|j|g|_tjj|_|jjd|j dt |_ t |j dkr}t d|j ndS(NR4t class_typeis=Only one value for Software node must be specified with name (R"RR#R1Rt get_instancetdata_object_cacheR(tget_descendantsR4R t soft_listtlenR?(R3R4((ssvr4.pyR#s  c Cstjj|_|jd}|jtjtdt}|djt j t dtdj |_ |jj |j |_ t|dkrtdn|jtjtdt}t|dkrtdn|djtjtdt}|djtjtdtdj}|jj ||_|j|j}|jdt}x<|D]4}|jdkr |tjkr|j|j|_nH|tjkr|j |j|j!|_n|j"|j|j!|_|j#j$dt%|jd |jnt&} |j| t'<|j!| t(<|jt)j*t)} t| dkr]d} n| s| j,t'dkrtj-|j.|j|j f| t/s0