a 2ha@sddlmZddlmZddlmZddlmZmZddlmZm Z ddl Z ddl Z ddl Z ddl Z ddlZ ddlZ ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZe dZ!e "j#d kre "j#ndZ$e$%Z&d d Z'dbd d Z(dcddZ)ddZ*ddZ+ddZ,ddZ-ddZ.ddZ/ddZ0dd Z1d!d"Z2d#d$Z3d%d&Z4d'd(Z5d)d*Z6d+d,Z7d-d.Z8d/d0Z9d1d2Z:d3d4Z;d5d6Zd;d<Z?d=d>Z@d?d@ZAdAdBZBdCdDZCdddFdGZDdHdIejEfdJdKZFdLdMZGdNdOZHdPdQZIdRdSZJGdTdUdUeKZLGdVdWdWeMZNGdXdYdYeOZPdZd[ZQd\d]ZRd^d_ZSGd`dadaZTdS)e)print_function)absolute_import)unicode_literals)PY3 basestring)_ucdNdnfZyumcCst|dgt|dgt|dgt}|D]}||vr|WYd}~n d}~00dS)Ni)r8)rBmakedirsOSErrorerrnoZEEXISTrFisdir)Zdnamer/rrr ensure_dirs rOcCsDg}|}tj|\}}|s2|s$|s@|d|q@|d|q|S)z` Split path by path separators. Use os.path.join() to join the path back to string. r)rBrFsplitinsert)rFresultheadtailrrr split_paths rUcCs4z t|}Wnty*tt|}Yn0|dkSrA)r= TypeErrorlist)iterablelrrremptys   rZcCs,t|}z t|WSty&YdS0dS)zFReturns the first item from an iterable or None if it has no elements.Niternext StopIterationrXitrrrfirsts   racCs6t|}ztdd|DWSty0YdS0dS)Ncss|]}|dur|VqdSr<r).0itemrrr z!first_not_none..r[r_rrrfirst_not_nones  rfcCstt|Sr<)timefile_timestampfnrrrfile_agesrkcCs t|jSr<)rBstatst_mtimerirrrrhsrhcCs8zttdWSty2dtYS0dS)NrzUID: %s)pwdgetpwuidrBrCKeyErrorrrrrget_effective_logins rqcCs(|D]}||}|dur|Sq|S)z!Like dict.get() for nested dicts.N)get)ZdctkeysZ not_foundkrrrget_ins   rucsfdd}t||ggfS)Ncs|t| ||Sr<)boolr)Zaccrcrirrsplittersz!group_by_filter..splitter) functoolsreduce)rjrXrwrrirgroup_by_filters rzccs"|D]}||r|V|VqdS)z/Insert an item into an iterable by a condition.Nr)rcrX conditionZ original_itemrrr insert_ifsr|cCs*z t|Wnty YdS0dSdS)z&Test whether an iterator is exhausted.TFN)r]r^)iteratorrrr is_exhausteds   r~cCs*t|r|g}t|to(tdd|DS)Ncss|]}t|td@VqdS)z*[?N)r)rbprrrrdrez"is_glob_pattern..)is_string_type isinstancerWany)patternrrris_glob_patternsrcCstrt|tSt|tSdSr<)rrr)r)objrrrrs rcsfdd}|S)zDecorator to get lazy attribute initialization. Composes with @property. Force reinitialization by deleting the . csfdd}|S)Ncs<z t|WSty6|}t|||YS0dSr<)getattrAttributeErrorr)rval)attrnamerjrr cached_getters    z6lazyattr..get_decorated..cached_getterr)rjrrrir get_decoratedszlazyattr..get_decoratedr)rrrrrlazyattrs rcGstt|g|RS)zLike functools.map(), but return a list instead of an iterator. This means all side effects of fn take place even without iterating the result. rWmap)rjseqrrrmapall srcCs8tdt|}tjjs4td}|r4||}|S)z6Convert time into locale aware datetime string object.z%cr) rgstrftime localtimer rrlocale getlocaledecode)Z timestamptZcurrent_locale_settingrrrnormalize_times   rc Cszxd}ddt|D}t|dkrt|d}td||&}|}t|dkWdWS1sj0YWdSttfyYdS0dS)zDecide 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|]}|dr|qS)ZAC)r)rbZnoderrr &rezon_ac_power..rz {}/{}/onlinerN) rBrEr=openformatreadintr( ValueError)Z ps_folderZac_nodesZac_nodeZ ac_statusdatarrr on_ac_powers ,rcCsz ddl}Wnty YdS0z0|}|dd}||d}|dd}Wn|jyhYdS0|dkrvdS|dvrdS|d vrd Std |dS) zDecide 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.PropertiesZMetered)rT)Fz&Unknown value for metered property: %r)dbus ImportErrorZ SystemBusZ get_objectZ InterfaceZGetZ DBusExceptionr)rZbusproxyZifaceZmeteredrrron_metered_connection1s(   rcCs&t|\}}tj||t||fS)zUse a predicate to partition entries into false entries and true entries. Credit: Python library itertools' documentation. ) itertoolsteer r filterfalsefilter)ZpredrXt1t2rrr partitionNsrcCs&zt|Wnty Yn0dSr<)shutilrmtreerLrFrrrrHWs rHc#sBtfdd}t||}||V||}|s6q>|Vq(dS)zSplit 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. csttfdd|S)Ncs|kSr<r)r/ separatorrrgrez4split_by..next_subsequence..)tupler takewhile)r`rrrnext_subsequencefsz"split_by..next_subsequenceN)objectr|)rXr{rZmarkedZ subsequencerrrsplit_by]s   rcCs||r|t|dSdSr<)rr=)r>prefixrrr strip_prefixus rFcCsL|st|tjrt|dSt|dWdn1s>0YdS)z{Create an empty file if it doesn't exist or bump it's timestamps. If no_create is True only bumps the timestamps. Na)rBaccessF_OKutimer)rFZ no_createrrrtouch{s  rwritec Cszh|dkr||nP|dkr(|n>|dkrD|||n"|dkrZt||dn td|Wn@ty}z(tdt|j t |WYd}~n d}~00dS)NrflushZ write_flushprint)rzUnsupported type: z{}: {}) rrrrr(r*criticalrtype__name__r )tpmsgoutr/rrr_terminal_messengers    rcCsjd}t|dk}t|ddD]H\}}|rB|dtdd|7}n|dtdd7}|d|7}q|S) z Format string about problems in resolve :param resolve_problems: list with list of strings (output of goal.problem_rules()) :return: string rr)r$z ZProblemz %d: z: z - )r= enumeraterrG)Zresolve_problemsrZcount_problemsiZrsrrr_format_resolve_problemss rcCsX|d}|dur4|dkr4||d7}||d|d|S)N-0:.)NEVRA)teZnevrarrr _te_nevras rc Cstd|D]@}|}d}|dur,|j}dt||||}t|q|D]2}dt||j|j|j |j | }t|qTdS)NzLogging transaction elementsz@RPM element: '{}', Key(): '{}', Key state: '{}', Failed() '{}': z^SWDB element: '{}', State: '{}', Action: '{}', From repo: '{}', Reason: '{}', Get reason: '{}') r*debugKeystaterrFailedr)actionZ from_reporeasonZ get_reason)rpm_transactionswdb_transactionrpm_eltsiZ tsi_staterrrr_log_rpm_trans_with_swdbs   rc CsHtjjtjjtjjtjjtjjh}dd|D}d}d}|D]}t|}|}|dusbt |ds|D]4} | j tjj krzqf| j |vrqft | |krf| }qqf|dust |dsttd|d}q<|rtjj|_ d}q.Fpkgz%TransactionItem not found for key: {}Tz)TransactionSWDBItem not found for key: {}z#Errors occurred during transaction.)r% transactionZ TransactionItemAction_DOWNGRADEDZTransactionItemAction_OBSOLETEDTransactionItemAction_REMOVEZTransactionItemAction_UPGRADEDZ!TransactionItemAction_REINSTALLEDrrhasattrrZTransactionItemState_UNKNOWNrr)r*rrrrTransactionItemState_ERRORZTransactionItemState_DONErr) rrZrevert_actionsZ cached_tsiZ el_not_foundr+rZte_nevrarZ tsi_candidaterrr_sync_rpm_trans_with_swdbsJ    rc@s$eZdZddZddZddZdS)tmpdircCsdtjj}tj|d|_dS)Nz%s-)r)r constZPREFIXr5ZmkdtemprF)selfrrrr__init__s ztmpdir.__init__cCs|jSr<rrrrr __enter__sztmpdir.__enter__cCst|jdSr<)rHrF)rexc_type exc_value tracebackrrr__exit__sztmpdir.__exit__N)r __module__ __qualname__rrrrrrrrsrcs(eZdZdZfddZddZZS)BunchzDictionary with attribute accessing syntax. In DNF, prefer using this over dnf.yum.misc.GenericHolder. Credit: Alex Martelli, Doug Hudgeon cs tt|j|i|||_dSr<)superrr__dict__)rargskwds __class__rrrszBunch.__init__cCst|Sr<)idrrrr__hash__szBunch.__hash__)rrr__doc__rr __classcell__rrrrrs rcs,eZdZfddZddZddZZS) MultiCallListcstt|||dSr<)rrrextend)rrXrrrrszMultiCallList.__init__csfdd}|S)Ncsfdd}tt|S)Ncst|}|iSr<)r)vmethod)rr9whatrr call_what s z8MultiCallList.__getattr__..fn..call_whatr)rr9rrr)rr9rrj sz%MultiCallList.__getattr__..fnr)rrrjrrr __getattr__ szMultiCallList.__getattr__csfdd}tt||S)Ncst|dSr<)r)rcrrrrsettersz)MultiCallList.__setattr__..setterr)rrrr rr r __setattr__szMultiCallList.__setattr__)rrrrr r rrrrrrs rc Cshtgggggggggggd }|D]<}|jtjjkrF|j|q$|jtjjkrb|j |q$|jtjj kr|j tjj kr|j |nD|j tjjkr|j|n(|j tjjkr|j|n |j|q$|jtjjkr|j|q$|jtjjkrH|j tjjkr|j|n*|j tjjkr:|j|n |j|q$|jtjjkr$|j|q$|S)N) downgradederased erased_clean erased_dep installedinstalled_group installed_depinstalled_weak reinstalledupgradedfailed)rrr%rrrrrZTransactionItemAction_DOWNGRADEr ZTransactionItemAction_INSTALLrZTransactionItemReason_GROUPrZ TransactionItemReason_DEPENDENCYrZ%TransactionItemReason_WEAK_DEPENDENCYrrZTransactionItemAction_REINSTALLrrZTransactionItemReason_CLEANrrrZTransactionItemAction_UPGRADEr)rr2rrrr _make_listssJ rc sfdd}tj|}jd|d\}}||}g}td|jftd|jftd|j|j |j |j ftd|j ftd |ftd |j |j|jftd |jffD]&\} } ||| t| t|d q|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}|dkrz|S|j|jk|j|jkS)zCompares two transaction items or packages by nevra. Used as a fallback when tsi does not contain package object. r)nameepochversionreleasearch) rhawkeyZNEVRArrrrZevr_cmpZsack)Zitem1Zitem2retZnevra1Znevra2baserr_tsi_or_pkg_nevra_cmpPsz7_post_transaction_output.._tsi_or_pkg_nevra_cmpF)Zreport_problemsrZUpgradedZ DowngradedZ InstalledZ ReinstalledZSkippedZRemovedr)key)r utilrZ_skipped_packagesunionrrr rrrrrrrrrrsortedrx cmp_to_key) r!rZaction_callbackr"Z list_bunchZskipped_conflictsZskipped_brokenZskippedrrZtsisrr r_post_transaction_outputFs:           r(cCs|r|StdS)Nz )r)Z input_namerrr_name_unset_wrapperysr)c@sdeZdZdZdZddZeddZeddZ d d Z d d Z ed dZ eddZ ddZdS) _BootcSystemz/usricCs^|sttdddl}||_|ddddlm}||_|jj |_ |j |_ dS)NzNot running on a bootc system.rOSTreez1.0)r+)is_bootc_systemr&rgiZ_giZrequire_versionZ gi.repositoryr+_OSTreeZSysrootZ new_defaultZ_sysrootZrequire_booted_deployment_booted_deployment)rr-r+rrrrs    z_BootcSystem.__init__cCsd}tj|S)zYReturns true is the system is managed as an immutable container, false otherwise.z/run/ostree-booted)rBrFisfile)Z ostree_bootedrrrr,sz_BootcSystem.is_bootc_systemcCst|jtjS)z-Returns true if and only if /usr is writable.)rBrusrW_OK)clsrrr is_writablesz_BootcSystem.is_writablecCs |jSr<)r/Z get_unlockedrrrr_get_unlocked_statesz _BootcSystem._get_unlocked_statecCs||jjjkS)zReturns true if and only if the bootc system is unlocked in a transient state, i.e. a overlayfs is mounted as read-only on /usr. Changes can be made to the overlayfs by remounting /usr as read/write in a private mount namespace.)r5r.DeploymentUnlockedState TRANSIENTrrrris_unlocked_transientsz"_BootcSystem.is_unlocked_transientc Cstd}||jdkr"tddddd|jg}ztj|dd}|WnTt yvt j t d |dYn,tjyt j t d |j|jYn0dS) Nrz!Failed to unshare mount namespaceZmountz--options-source=disablez-oz remount,rwTtextz%s: command not found.z$Failed to mount %s as read/write: %s)ctypesZCDLLZunshare CLONE_NEWNSrLr1 subprocessruncheck_returncodeFileNotFoundErrorr exceptionsErrorrCalledProcessErrorstderr)r3ZlibcZ mount_commandcompleted_processrrr_set_up_mountnss   z_BootcSystem._set_up_mountnscCsxgd}ztj|dd}|WnPtyLtjtd|dYn(tjyrtjtd|j Yn0dS)N)ZostreeZadminZunlockz --transientTr9z.%s: command not found. Is this a bootc system?rzFailed to unlock system: %s) r=r>r?r@r rArBrrCrD)Zunlock_commandrErrr_unlocks  z_BootcSystem._unlockcCs|}|jjj|jjj|jjj|jjjf}||vrFttd|j |jjj|jjjf}||vrdn6||jjjkr| | n||jjjkr| dS)z+Set up a writable overlay on bootc systems.z"Unhandled bootc unlocked state: %sN) r5r.r6ZNONEZ DEVELOPMENTr7ZHOTFIXrrZ value_nickrGrF)rZbootc_unlocked_stateZvalid_bootc_unlocked_statesZwritable_unlocked_statesrrr make_writables& z_BootcSystem.make_writableN)rrrr1r<r staticmethodr, classmethodr4r5r8rFrGrHrrrrr*~s    r*)N)NNr1)F)UZ __future__rrrrrrZdnf.i18nrr argparser;r Z dnf.callbackZ dnf.constZ dnf.pycomprMrxrrrZloggingrBrnrr=sysr5rgZ libdnf.repor%Zlibdnf.transactionZ getLoggerr*ArgumentParserprogZ MAIN_PROGupperZMAIN_PROG_UPPERr r0r;r@rDrJrOrUrZrarfrkrhrqrurzr|r~rrrrrrrrrHrrrstdoutrrrrrrrdictrrWrrr(r)r*rrrrs              ( -3