ó Ûê…^c@s=dZddlZddlZddlZddlZddlZddlmZddlm Z m Z ddl m Z ddl mZddlm Z mZmZmZmZmZmZmZmZdad „Zeed „ƒZd „Zd e fd „ƒYZd„Zde fd„ƒYZd„Z d„Z!dS(s\ This module provides classes and functions used to download and manage debuginfos. iÿÿÿÿN(tPopen(t_tYumBase(tDownloadBaseCallback(t YumBaseError( Rtlog1tlog2t RETURN_OKtRETURN_FAILUREtRETURN_CANCEL_BY_USERtverboset ask_yes_not error_msgtcsqddl}tjƒ‰tjƒ‰|jdƒ‰ˆjˆkrUˆjˆkrUˆS‡‡‡‡fd†}|S(s· Ensures that the function is called using abrt's uid and gid Returns: Either an unchanged function object or a wrapper function object for the function. iÿÿÿÿNtabrtcsMtjˆjƒtjˆjƒˆ||Ž}tjˆƒtjˆƒ|S(só Wrapper function around the called function. Sets up uid and gid to match abrt's and after the function finishes rolls its uid and gid back. Returns: Return value of the wrapped function. (tostsetegidtpw_gidtseteuidtpw_uid(targstkwargstretval(Rt current_gidt current_uidtfn(s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytwrapped)s   (tpwdRtgetuidtgetgidtgetpwnamRR(RRR((RRRRs</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytensure_abrt_uids   cCs%|d|}td||ƒtd|ƒtdƒj|ƒGH|d}yt|dƒ}Wn+tk r‰} tdƒj|| ƒGHtSXtd|gd |d d ƒ} | jƒ} | d krðtd ƒ|std|ƒt j |ƒqn"|j ƒtdƒj|ƒGHtS|j ƒt|dƒ}tdƒjd|ƒGHd} ddg} |r•x |D]}| d|d7} qaWdd| j ƒg} ntddƒ=}t| d|d d d|d |d|ƒ}|jƒ} WdQX| d kr tdƒt j |ƒntdƒj|ƒGHtSdS( sþ Unpacks a single rpm located in tmp_dir into destdir. Arguments: package_file_name - name of the rpm file files - files to extract from the rpm tmp_dir - temporary directory where the rpm file is located destdir - destination directory for the rpm package extraction keeprpm - check if the user wants to delete rpms from the tmp directory exact_files - extract only specified files Returns: RETURN_FAILURE in case of a serious problem t/sExtracting %s to %ss%ssExtracting cpio from {0}s/unpacked.cpiotwbsCan't write to '{0}': {1}trpm2cpiotstdouttbufsizeiÿÿÿÿiscpio written OKskeeprpms = False, removing %ssCan't extract package '{0}'trbs$Caching files from {0} made from {1}s unpacked.cpioR tcpios-idut.t s /dev/nulltwtcwdtstdintstderrNsfiles extracted OKsCan't extract files from '{0}'( RRRtformattopentIOErrorRRtwaitRtunlinktclosetstrip(tpackage_file_nametfilesttmp_dirtdestdirtkeeprpmt exact_filestpackage_full_pathtunpacked_cpio_patht unpacked_cpiotexR"tretcodet file_patternst cpio_argstfilenametnullR&((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyt unpack_rpmCsN            cCsetraytjtƒWqatk r]}|jtjkr^ttdƒjt|ƒƒq^qaXndS(s* Removes the temporary directory. sCan't remove '{0}': {1}N( tTMPDIRtshutiltrmtreetOSErrorterrnotENOENTR RR-(R=((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytclean_up‰s tMyDownloadCallbackcBs eZdZd„Zd„ZRS(sR This class serves as a download progress handler for yum's progress bar. cCs5||_d|_d|_d|_tj|ƒdS(sx Sets up instance variables Arguments: total_pkgs - number of packages to download iN(t total_pkgstdownloaded_pkgstlast_pctt last_timeRt__init__(tselfRL((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyRPšs     cCsYt|dƒ}||jkr-tdƒdS||_tjjƒr¨tjjd|jd|j||fƒ|dkrHt dƒj |jd|j||ƒGHqHn t j ƒ}|j dkrÏ||_ n|dksý|j |ksý||j dkrHt dƒj |jd|j||ƒGH||_ |dkrHd|_ qHntjj ƒdS( s A method used to update the progress Arguments: name - filename frac - progress fracment (0 -> 1) fread - formated string containing BytesRead ftime - formated string containing remaining or elapsed time ids-percentage is the same, not updating progressNs&Downloading (%i of %i) %s: %3u%%is$Downloading ({0} of {1}) {2}: {3:3}%ii(tintRNRtsysR#tisattytwriteRMRLRR-ttimeROtflush(RQtnametfractfreadtftimetpcttt((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytupdateProgress¨s*      !  .   (t__name__t __module__t__doc__RPR^(((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyRK•s cCs(tdƒj|j|jƒGHidd6S(s0 A callback function for mirror errors. sOProblem '{0!s}' occured while downloading from mirror: '{1!s}'. Trying next oneitfail(RR-t exceptiontmirror(t callBackObj((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytdownloadErrorCallback×s tDebugInfoDownloadcBsMeZdZdeed„Zd„Zd„Zed„ƒZ ed„Z RS(s> This class is used to manage download of debuginfos. s*debug*cCs¸d|_||_||_|a||_||_||_tj|ƒ|j ƒt dƒGHy|j ƒWn;t k r©}|j ƒt dƒj|ƒGHtdƒnX|j ƒdS(NiÿÿÿÿsInitializing yums7Error initializing yum (YumBase.doConfigSetup): '{0!s}'i(t old_stdouttcachedirttmpdirRDtkeeprpmstnoninteractivet repo_patternRRPt mute_stdoutRt doConfigSetupRt unmute_stdoutR-texit(RQtcachettmpRmt keep_rpmsRlR=((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyRPçs"          cCs1tdkr-tj|_tddƒt_ndS(sJ Links sys.stdout with /dev/null and saves the old stdout is /dev/nullR)N(R RSR#RhR.(RQ((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyRns  cCs6tdkr2|jdkr*|jt_q2dGHndS(s@ Replaces sys.stdout by stdout saved using mute iiÿÿÿÿs ERR: unmute called without mute?N(R RhRSR#(RQ((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyRp s cCsœtjj|jƒsLytj|jƒWqLtk rH}d|GHtSXntjj|jƒs˜ytj|jƒWq˜tk r”}d|GHtSXntS(NsCan't create tmpdir: %ssCan't create cachedir: %s( RtpathtexistsRjtmakedirsRGRRiR(RQR=((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytsetup_tmp_dirss  cCs­d}d}d}d}|s"tS|jƒs=tdƒGHtSxn|jjƒD]]}y!|jƒ|jj|jƒWqMtk r©}tdƒj |jt |ƒƒGHqMXqMWtdƒGHxõ|jj d|j ƒD]Û} y’|jj | jƒ} |jjdt | jƒƒtd| ƒt| dtƒyt| d tƒWn)ttfk rh}|GHtd ƒGHnXWqÒtk r¬}td ƒj | j|ƒGH|jj| jƒqÒXqÒWtd ƒGHy|jjd dddƒWn'tk r}tdƒj |ƒGHnXy|jjd dddƒWn'tk rI}tdƒj |ƒGHnXg} i} xÛ|D]Ó} td| ƒ|jj| ƒ}|r|d| jƒkr¶| |dj| ƒnI| g| |d<|t|djƒ7}|t|djƒ7}|d7}td| |dƒq]td| ƒ| j| ƒq]Wt|ƒ}|jj|ƒ|jj t!ƒt"dks~t#| ƒdkr›tdƒj t#| ƒƒGHnt"dks³|dkr1tdƒj |ƒGHtdƒj |d.|d/ƒ}|j$tkrt%|ƒ rtdƒGHt&S|j'ƒ}|t(kr.|St)j*|j+ƒ}t|j,|j-ƒd0}|d1|kr®tdƒj |j+|ƒ}|j$ r®t%|ƒ r®tdƒGHt&Snt)j*|j.ƒ}t|j,|j-ƒd2}|d3|kr1tdƒj |j.|ƒ}|j$ r.t%|ƒ r.tdƒGHt&Sq1nxø| j/ƒD]ê\}}||_0d|_1|j2dƒ}t)j3j4|ƒ}|j'ƒ}|t(kr™|S|j2dƒ}d4}|j6d ƒr|d!}td"|ƒyt7j8||j+ƒWqTt9k r}td#ƒj ||ƒGHq>qTXn6t)j3j:|j+|ƒ}||_;|j<d$|gƒ}|j=d%|j>d%|j?d&|j@}|d'}|rÕyt)jA|j+d(|ƒWnt9k r½nXtd)ƒj |ƒGHnItB|||j+|j.|jCd*|ƒ}|tkrtd+ƒGHtDƒtS|d7}q>W|jC r©t)j3jE|j+ƒr©td,ƒj |j+ƒGHyt)jF|j+ƒWq©t9k r¥tGtd-ƒj |j+ƒƒq©Xnt(S(5s¢ Downloads rpms into a temporary directory Arguments: package_files_dict - a dict containing {pkg: file list} entries total_pkgs - total number of packages to download download_exact_files - extract only specified files Returns: RETURN_OK if all goes well. RETURN_FAILURE in case it cannot set up either of the directories. is#Error: can't make cachedir, exitings'Can't disable repository '{0!s}': {1!s}sSetting up yum repositoriestpatterntthisreposenabled repo %stskip_if_unavailablet_asyncsACan't disable async download, the output might contain artifacts!sCan't setup {0}: {1}, disablings+Looking for needed packages in repositoriestmdtypetmetadatat cacheonlyis"Error retrieving metadata: '{0!s}'t filelistss#Error retrieving filelists: '{0!s}'syum whatprovides %ssfound pkg for %s: %ssnot found pkg for %ss+Can't find packages for {0} debuginfo filessPackages to download: {0}s;Downloading {0:.2f}Mb, installed size: {1:.2f}Mb. Continue?isDownload cancelled by usersKWarning: Not enough free space in tmp dir '{0}' ({1:.2f}Mb left). Continue?sMWarning: Not enough free space in cache dir '{0}' ({1:.2f}Mb left). Continue?t relativepatht remote_urlsfile:///iscopying from local repo: %ssCannot copy file '{0}': {1}tpkglistt-R's.rpmR sDownloading package {0} failedR9s&Unpacking failed, aborting download...s Removing {0}s/Can't remove %s, probably contains an error logiiiiiiN(HRt setCacheDirRtrepost listEnabledR2t disableRepotidRR-tstrt findReposRmt enableRepotdoSetupRtsetattrtTruetFalset NameErrortAttributeErrort populateSackRtpkgSackt searchFilestkeystappendtfloattsizet installedsizeRKtsetProgressBartsetMirrorFailureCallbackRfR tlenRlR R RxRRtstatvfsRjtf_bsizetf_bavailRit iteritemsRMRrt returnSimpleRutbasenametNonet startswithREtcopyRGtjoint localpatht downloadPkgsRXtversiontreleasetarchR1RCRkRJRvtrmdirR (RQR5tdownload_exact_filestinstalled_sizeRLttodownload_sizeRMtrepoR=trtridt not_foundtpackage_files_dicttdebuginfo_pathtpkgtdnlcbtquestionRtrest tmp_spacet cache_spacetremotetlocalt remote_pathterrtpkg_pathtpkg_nvraR4t unpack_result((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytdownload)s   (                           *      #( R_R`RaRRRPRnRpRRxRÄ(((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyRgâs  cCs,g|D]!}d||d |df^qS(s¥ Transforms build ids into a path. build_id1=${build_id:0:2} build_id2=${build_id:2} file="usr/lib/debug/.build-id/$build_id1/$build_id2.debug" s&%s/usr/lib/debug/.build-id/%s/%s.debugi((tpfxt build_idstb_id((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytbuild_ids_to_paths cCs.td|ƒ}g}xZ|D]R}td|ƒtjj|ƒrTtd|ƒqntd|ƒ|j|ƒqW|r‡|}g}n|Sxœ|D]”}td|ƒxd|D]\}||}td|ƒtjj|ƒrïtd|ƒq­ntd|ƒ|j|ƒq­W|r"|}g}q’|Sq’W|S(sÐ Checks for installed debuginfos. Arguments: build_ids - string containing build ids cache_dirs - list of cache directories Returns: List of missing debuginfo files. R s looking: %ss found: %ss not found: %ss looking in %s(RÈRRRuRvR—(RÆt cache_dirsR5tmissingR¶t cache_dirtcache_debuginfo_path((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pytfilter_installed_debuginfos s8             ("RaRSRRVRHREt subprocessRtyumRRt yum.callbacksRt yum.ErrorsRt reportclientRRRRR R R R RDRRRCRJRKRfRgRÈRÍ(((s</usr/lib64/python2.7/site-packages/reportclient/debuginfo.pyts*     @ ,E B ÿ