3 ©ft`—Oã@svddlmZddlmZddlmZddlmZmZddlmZm Z ddl Z ddl Z ddl Z ddl Z ddlZ ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZejdƒZe j ƒj!d krþe j ƒj!ndZ"e"j#ƒZ$d d „Z%d^d d „Z&d_dd„Z'dd„Z(dd„Z)dd„Z*dd„Z+dd„Z,dd„Z-dd„Z.dd „Z/d!d"„Z0d#d$„Z1d%d&„Z2d'd(„Z3d)d*„Z4d+d,„Z5d-d.„Z6d/d0„Z7d1d2„Z8d3d4„Z9d5d6„Z:d7d8„Z;d9d:„Z„Z>d?d@„Z?dAdB„Z@dCdD„ZAd`dFdG„ZBdHdIejCfdJdK„ZDdLdM„ZEdNdO„ZFdPdQ„ZGdRdS„ZHGdTdU„dUeIƒZJGdVdW„dWeKƒZLGdXdY„dYeMƒZNdZd[„ZOd\d]„ZPdS)aé)Úprint_function)Úabsolute_import)Úunicode_literalsé)ÚPY3Ú basestring)Ú_ÚucdNÚdnfZyumcCsÀt|dgƒt|dgƒt|dgƒtƒ}x�|D]ˆ}||kr>q0|j|ƒtjjj|ƒd}|jdƒrr|jj|ƒq0|rŒ|d krŒ|jj|ƒq0|j d ƒr¬|j j|d d …ƒq0|j j|ƒq0Wd S)a¨ Categorize :param values list into packages, groups and filenames :param namespace: argparse.Namespace, where specs will be stored :param values: list of specs, whether packages ('foo') or groups/modules ('@bar') or filenames ('*.rmp', 'http://*', ...) To access packages use: specs.pkg_specs, to access groups use: specs.grp_specs, to access filenames use: specs.filenames Ú filenamesÚ grp_specsÚ pkg_specsrz.rpmÚhttpÚftpÚfileÚhttpsú@rN)rrrr) ÚsetattrÚsetÚaddr ÚpycompZurlparseÚendswithr ÚappendÚ startswithr r )Ú namespaceÚvaluesZtmp_setÚvalueZschemes©rú/usr/lib/python3.6/util.pyÚ _parse_specs7s        rcCs¾|dkrtjjƒ}tjj|||ƒ}tjj|jƒr6|jSt |j gƒ}|j d|ƒ|j ƒg}yt jjjt jj|ƒdƒWnBtk r¶}z&|jr˜tt|ƒƒ‚tjt|ƒƒWYdd}~XnX|jS)NrT)r ÚcallbackZNullDownloadProgressÚrepoZRemoteRPMPayloadÚosÚpathÚexistsZ local_pathÚsumZ download_sizeÚstartZ_librepo_targetÚlibdnfZ PackageTargetZdownloadPackagesZVectorPPackageTargetÚ RuntimeErrorÚstrictÚIOErrorÚstrÚloggerÚerror)ÚurlÚconfZprogressZploadZest_remote_sizeZtargetsÚerrrÚ_urlopen_progressWs      r1úw+bcKs trd|kr|jddƒtj|f|Ž}y<|r@|jj||jƒƒn tjj j |rR|j nd||jƒƒWn.t k r�}zt t|ƒƒ‚WYdd}~XnX|jdƒ|S)z| Open the specified absolute url, return a file object which respects proxy setting even for non-repo downloads ÚbÚencodingzutf-8Nr)rÚ setdefaultÚtempfileZNamedTemporaryFileZ_repoZ downloadUrlÚfilenor'r!Z DownloaderZ downloadURLZ_configr(r*r+Úseek)r.r/r!ÚmodeÚkwargsZfor0rrrÚ_urlopenhs  $ r;cCs |j|ƒr|dt|ƒ …}|S)N)rÚlen)ÚsÚrrrrÚrtrim|s r?cCs tjƒdkS)Nr)r"ÚgeteuidrrrrÚ am_i_root‚srAcCs.x(tj|ƒD]}tjj||ƒ}t|ƒq WdS)zBRemove all files and dirs under `path` Also see rm_rf() N)r"Úlistdirr#ÚjoinÚrm_rf)r#ÚentryZcontained_pathrrrÚ clear_dir†srFcCsXytj|dd�Wn@tk rR}z$|jtjks>tjj|ƒ rB|‚WYdd}~XnXdS)Nií)r9)r"ÚmakedirsÚOSErrorÚerrnoZEEXISTr#Úisdir)Zdnamer0rrrÚ ensure_dir�s rKcCsJg}|}xÀsz!first_not_none..)rWrXrY)rTrZrrrÚfirst_not_none½s r_cCstjƒt|ƒS)N)ÚtimeÚfile_timestamp)ÚfnrrrÚfile_ageÅsrccCs tj|ƒjS)N)r"ÚstatÚst_mtime)rbrrrraÈsrac Cs4ytjtjƒƒdStk r.dtjƒSXdS)NrzUID: %s)ÚpwdÚgetpwuidr"r@ÚKeyErrorrrrrÚget_effective_loginËsricCs(x"|D]}|j|ƒ}|dkr|SqW|S)z!Like dict.get() for nested dicts.N)Úget)ZdctÚkeysZ not_foundÚkrrrÚget_inÑs   rmcs‡fdd„}tj||ggfƒS)Ncs|tˆ|ƒƒ j|ƒ|S)N)Úboolr)Zaccr])rbrrÚsplitterÚsz!group_by_filter..splitter)Ú functoolsÚreduce)rbrTror)rbrÚgroup_by_filterÙs rrccs&x |D]}||ƒr|V|VqWdS)z/Insert an item into an iterable by a condition.Nr)r]rTÚ conditionZ original_itemrrrÚ insert_ifßs rtc Cs*y t|ƒWntk r dSXdSdS)z&Test whether an iterator is exhausted.TFN)rXrY)ÚiteratorrrrÚ is_exhaustedæs  rvcCs*t|ƒr|g}t|tƒo(tdd„|DƒƒS)Ncss|]}t|ƒtdƒ@VqdS)z*[?N)r)r\Úprrrr^òsz"is_glob_pattern..)Úis_string_typeÚ isinstancerSÚany)ÚpatternrrrÚis_glob_patternïsr|cCstrt|tƒSt|tƒSdS)N)rryr+r)Úobjrrrrxôs rxcs‡fdd„}|S)z…Decorator to get lazy attribute initialization. Composes with @property. Force reinitialization by deleting the . cs‡‡fdd„}|S)Nc s8y t|ˆƒStk r2ˆ|ƒ}t|ˆ|ƒ|SXdS)N)ÚgetattrÚAttributeErrorr)r}Úval)ÚattrnamerbrrÚ cached_getters   z6lazyattr..get_decorated..cached_getterr)rbr‚)r�)rbrÚ get_decoratedÿszlazyattr..get_decoratedr)r�rƒr)r�rÚlazyattrús r„cGstt|f|žŽƒS)zžLike functools.map(), but return a list instead of an iterator. This means all side effects of fn take place even without iterating the result. )rSÚmap)rbÚseqrrrÚmapall sr‡cCs8tjdtj|ƒƒ}tjjs4tjƒd}|r4|j|ƒ}|S)z6Convert time into locale aware datetime string object.z%cr) r`ZstrftimeZ localtimer rrÚlocaleZ getlocaleÚdecode)Z timestampÚtZcurrent_locale_settingrrrÚnormalize_times   r‹cCszy\d}dd„tj|ƒDƒ}t|ƒdkrZ|d}tdj||ƒƒ�}|jƒ}t|ƒdkSQRXdSttfk rtdSXdS)z†Decide whether we are on line power. Returns True if we are on line power, False if not, None if it can not be decided. z/sys/class/power_supplycSsg|]}|jdƒr|‘qS)ZAC)r)r\Znoderrrú &szon_ac_power..rz {}/{}/onlinerN) r"rBr<ÚopenÚformatÚreadÚintr*Ú ValueError)Z ps_folderZac_nodesZac_nodeZ ac_statusÚdatarrrÚ on_ac_powers r“cCsœy ddl}Wntk r dSXy0|jƒ}|jddƒ}|j|dƒ}|jddƒ}Wn|jk rhdSX|dkrvdS|dkr‚d S|dkrŽd Std |ƒ‚dS)z�Decide whether we are on metered connection. Returns: True: if on metered connection False: if not None: if it can not be decided rNzorg.freedesktop.NetworkManagerz/org/freedesktop/NetworkManagerzorg.freedesktop.DBus.PropertiesZMeteredréTééFz&Unknown value for metered property: %r)rr”)r•r–)ÚdbusÚ ImportErrorZ SystemBusZ get_objectZ InterfaceZGetZ DBusExceptionr‘)r—ZbusÚproxyZifaceZmeteredrrrÚon_metered_connection1s&  ršcCs&tj|ƒ\}}tjj||ƒt||ƒfS)z…Use a predicate to partition entries into false entries and true entries. Credit: Python library itertools' documentation. )Ú itertoolsÚteer rÚ filterfalseÚfilter)ZpredrTZt1Zt2rrrÚ partitionNsrŸc Cs(ytj|ƒWntk r"YnXdS)N)ÚshutilZrmtreerH)r#rrrrDWsrDc#sFtƒ‰‡fdd„}tˆ||ƒ}||ƒVx||ƒ}|s8P|Vq*WdS)z«Split an iterable into tuples by a condition. Inserts a separator before each item which meets the condition and then cuts the iterable by these separators. csttj‡fdd„|ƒƒS)Ncs|ˆkS)Nr)r0)Ú separatorrrÚgsz4split_by..next_subsequence..)Útupler›Ú takewhile)rZ)r¡rrÚnext_subsequencefsz"split_by..next_subsequenceN)Úobjectrt)rTrsr¥ZmarkedZ subsequencer)r¡rÚsplit_by]s   r§cCs|j|ƒr|t|ƒd…SdS)N)rr<)r=ÚprefixrrrÚ strip_prefixus r©Fc Cs8|stj|tjƒrtj|dƒSt|dƒ�WdQRXdS)z{Create an empty file if it doesn't exist or bump it's timestamps. If no_create is True only bumps the timestamps. NÚa)r"ÚaccessÚF_OKÚutimer�)r#Z no_createrrrÚtouch{s  r®ÚwriteÚcCs¬yh|dkr|j|ƒnP|dkr(|jƒn>|dkrD|j|ƒ|jƒn"|dkrZt||d�n td|ƒ‚Wn>tk r¦}z"tjdjt|ƒj t |ƒƒƒWYdd}~XnXdS)Nr¯ÚflushZ write_flushÚprint)rzUnsupported type: z{}: {}) r¯r±r²r‘r*r,ÚcriticalrŽÚtypeÚ__name__r )ÚtpÚmsgÚoutr0rrrÚ_terminal_messenger†s    r¹cCsnd}t|ƒdk}xXt|dd�D]H\}}|rD|dtdƒd|7}n|dtdƒd7}|dj|ƒ7}qW|S) zž Format string about problems in resolve :param resolve_problems: list with list of strings (output of goal.problem_rules()) :return: string r°r)r&z ZProblemz %d: z: z - )r<Ú enumeraterrC)Zresolve_problemsr·Zcount_problemsÚiZrsrrrÚ_format_resolve_problems˜s r¼cCsX|jƒd}|jƒdk r4|jƒdkr4||jƒd7}||jƒd|jƒd|jƒS)Nú-Ú0ú:Ú.)ÚNÚEÚVÚRÚA)ZteZnevrarrrÚ _te_nevraªs rÆcCs”tjdƒxH|D]@}|jƒ}d}|dk r.|j}djt|ƒ|||jƒƒ}tj|ƒqWx:|D]2}djt|ƒ|j|j|j |j |j ƒƒ}tj|ƒqZWdS)NzLogging transaction elementsz@RPM element: '{}', Key(): '{}', Key state: '{}', Failed() '{}': z^SWDB element: '{}', State: '{}', Action: '{}', From repo: '{}', Reason: '{}', Get reason: '{}') r,ÚdebugÚKeyÚstaterŽrÆÚFailedr+ÚactionZ from_repoÚreasonZ get_reason)Úrpm_transactionÚswdb_transactionÚrpm_elÚtsiZ tsi_stater·rrrÚ_log_rpm_trans_with_swdb±s    rÑc CsVtjjtjjtjjtjjtjjh}dd„|Dƒ}d}d}x¼|D]´}t|ƒ}|jƒ}|dksft |dƒ r¢x:|D]2} | j tjj kr€ql| j |krŒqlt | ƒ|krl| }PqlW|dks¶t |dƒ rÐtjtdƒj|ƒƒd}q>|jƒrètjj|_ d}q>tjj|_ q>Wx6|D].}|j tjj krütjtdƒjt |ƒƒƒd}qüW|�rBtjtdƒƒ|�rRt||ƒdS) NcSsg|]}|‘qSrr)r\rÐrrrrŒÈsz-_sync_rpm_trans_with_swdb..FZpkgz%TransactionItem not found for key: {}Tz)TransactionSWDBItem not found for key: {}z#Errors occurred during transaction.)r'Ú transactionZ TransactionItemAction_DOWNGRADEDZTransactionItemAction_OBSOLETEDÚTransactionItemAction_REMOVEZTransactionItemAction_UPGRADEDZ!TransactionItemAction_REINSTALLEDrÆrÈÚhasattrrÉZTransactionItemState_UNKNOWNrËr+r,r³rrŽrÊÚTransactionItemState_ERRORZTransactionItemState_DONErÇrÑ) rÍrÎZrevert_actionsZ cached_tsiZ el_not_foundr-rÏZte_nevrarÐZ tsi_candidaterrrÚ_sync_rpm_trans_with_swdbÂsH       rÖc@s$eZdZdd„Zdd„Zdd„ZdS)ÚtmpdircCsdtjj}tj|d�|_dS)Nz%s-)r¨)r ÚconstZPREFIXr6Zmkdtempr#)Úselfr¨rrrÚ__init__ìs ztmpdir.__init__cCs|jS)N)r#)rÙrrrÚ __enter__ðsztmpdir.__enter__cCst|jƒdS)N)rDr#)rÙÚexc_typeÚ exc_valueÚ tracebackrrrÚ__exit__ósztmpdir.__exit__N)rµÚ __module__Ú __qualname__rÚrÛrßrrrrr×êsr×cs(eZdZdZ‡fdd„Zdd„Z‡ZS)ÚBunchzšDictionary with attribute accessing syntax. In DNF, prefer using this over dnf.yum.misc.GenericHolder. Credit: Alex Martelli, Doug Hudgeon cstt|ƒj||Ž||_dS)N)ÚsuperrârÚÚ__dict__)rÙÚargsÚkwds)Ú __class__rrrÚþszBunch.__init__cCst|ƒS)N)Úid)rÙrrrÚ__hash__szBunch.__hash__)rµràráÚ__doc__rÚréÚ __classcell__rr)rçrrâös râcs,eZdZ‡fdd„Zdd„Zdd„Z‡ZS)Ú MultiCallListcstt|ƒjƒ|j|ƒdS)N)rãrìrÚÚextend)rÙrT)rçrrrÚszMultiCallList.__init__cs‡‡fdd„}|S)Ncs‡‡‡fdd„}tt|ˆƒƒS)Ncst|ˆƒ}|ˆˆŽS)N)r~)ÚvÚmethod)rår:ÚwhatrrÚ call_what s z8MultiCallList.__getattr__..fn..call_what)rSr…)rår:rñ)rÙrð)rår:rrb sz%MultiCallList.__getattr__..fnr)rÙrðrbr)rÙrðrÚ __getattr__ szMultiCallList.__getattr__cs‡‡fdd„}tt||ƒƒS)Ncst|ˆˆƒdS)N)r)r])r€rðrrÚsettersz)MultiCallList.__setattr__..setter)rSr…)rÙrðr€rór)r€rðrÚ __setattr__szMultiCallList.__setattr__)rµràrárÚròrôrërr)rçrrìs rìc Csntgggggggggggdœ ƒ}�xF|D�]<}|jtjjkrJ|jj|ƒq(|jtjjkrf|j j|ƒq(|jtjj krÖ|j tjj kr�|j j|ƒnD|j tjjkr¬|jj|ƒn(|j tjjkrÈ|jj|ƒn |jj|ƒq(|jtjjkrò|jj|ƒq(|jtjjk�rL|j tjjk�r |jj|ƒn*|j tjjk�r>|jj|ƒn |jj|ƒq(|jtjjkr(|jj|ƒq(W|S)N) Ú downgradedÚerasedÚ erased_cleanÚ erased_depÚ installedÚinstalled_groupÚ installed_depÚinstalled_weakÚ reinstalledÚupgradedÚfailed)rârÉr'rÒrÕrÿrrËZTransactionItemAction_DOWNGRADErõZTransactionItemAction_INSTALLrÌZTransactionItemReason_GROUPrúZ TransactionItemReason_DEPENDENCYrûZ%TransactionItemReason_WEAK_DEPENDENCYrürùZTransactionItemAction_REINSTALLrýrÓZTransactionItemReason_CLEANr÷røröZTransactionItemAction_UPGRADErþ)rÒr3rÐrrrÚ _make_listssH rc s܇fdd„}tjj|ƒ}ˆjd|d�\}}|j|ƒ}g}xžtdƒ|jftdƒ|jftdƒ|j|j |j |j ftdƒ|j ftd ƒ|ftd ƒ|j |j|jftd ƒ|jfgD]&\} } |j|| t| tj|ƒd �ƒƒq®W|S) alReturns a human-readable summary of the results of the transaction. :param action_callback: function generating output for specific action. It takes two parameters - action as a string and list of affected packages for this action :return: a list of lines containing a human-readable summary of the results of the transaction cs’|j|jk|j|jk}|dkr$|Stj|j|j|j|j|jd�}tj|j|j|j|j|jd�}|j|ˆjƒ}|dkrz|S|j|jk|j|jkS)z…Compares two transaction items or packages by nevra. Used as a fallback when tsi does not contain package object. r)ÚnameÚepochÚversionÚreleaseÚarch) rÚhawkeyZNEVRArrrrZevr_cmpZsack)Zitem1Zitem2ÚretZnevra1Znevra2)ÚbaserrÚ_tsi_or_pkg_nevra_cmpPsz7_post_transaction_output.._tsi_or_pkg_nevra_cmpF)Zreport_problemsrÒZUpgradedZ DowngradedZ InstalledZ ReinstalledZSkippedZRemovedrÊ)Úkey)r ÚutilrZ_skipped_packagesÚunionrrþrõrùrúrürûrýrörør÷rÿríÚsortedrpÚ cmp_to_key) rrÒZaction_callbackr Z list_bunchZskipped_conflictsZskipped_brokenZskippedr¸rËZtsisr)rrÚ_post_transaction_outputFs(       r)N)NNr2)F)QZ __future__rrrrrrZdnf.i18nrr Úargparser Z dnf.callbackZ dnf.constZ dnf.pycomprIrprr›rˆZloggingr"rfr Úsysr6r`Z libdnf.repor'Zlibdnf.transactionZ getLoggerr,ÚArgumentParserÚprogZ MAIN_PROGÚupperZMAIN_PROG_UPPERrr1r;r?rArFrKrQrVr[r_rcrarirmrrrtrvr|rxr„r‡r‹r“ršrŸrDr§r©r®Ústdoutr¹r¼rÆrÑrÖr¦r×ÚdictrârSrìrrrrrrÚs„              ( -