o
    >Ic                     @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZmZ ddlmZ ddlmZ ddlmZ G dd deZG d	d
 d
eZG dd deZdd Ze \ZZG dd deZG dd deZG dd de jZe dkrd dl!Z!ddl"m#Z# ddl$m$Z$ e%d ee#de$ dZ&e%e&'  e!(  e&)  e&*  e&j+ e&,dg e%e&-  e&.  dS dS )    N)PopenPIPE   )gettext)ngettext)inside_chrootc                   @      e Zd ZdS )CacheExceptionN__name__
__module____qualname__ r   r   >/usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeCache.pyr	   (       r	   c                   @   r   )CacheExceptionLockingFailedNr
   r   r   r   r   r   ,   r   r   c                   @   r   )CacheExceptionDpkgInterruptedNr
   r   r   r   r   r   0   r   r   c                  C   s   d} d}t  d }td| D ]/}|d| kr"|t j|7 }q|ddks7|ddks7|ddkr8q| t j|7 } q| dkrLtd d	} |dkrWtd
 d}| d7 } d}|d |krg|d }||7 }| |fS )zjestimate the amount of space used by the kernel and initramfs in /boot,
    including a safety margin
    r      z
/boot/*%s*z/boot/initrd.img-%sz
initrd.imgz.bakz.dpkg-z>estimate_kernel_initrd_size_in_boot() returned '0' for kernel?i   z>estimate_kernel_initrd_size_in_boot() returned '0' for initrd?i  
i   g?)osunameglobpathgetsizefindloggingwarning)kernelinitrdkverfinitrd_bufferr   r   r   #estimate_kernel_initrd_size_in_boot4   s4   r!   c                   @   s    e Zd ZdZdd Zdd ZdS )FreeSpaceRequiredz FreeSpaceRequired object:

    This exposes:
    - the total size required (size_total)
    - the dir that requires the space (dir)
    - the additional space that is needed (size_needed)
    c                 C   s   || _ || _|| _d S N)
size_totaldirsize_needed)selfr$   r%   r&   r   r   r   __init__`   s   
zFreeSpaceRequired.__init__c                 C   s   d| j | j| jf S )Nz@FreeSpaceRequired Object: Dir: %s size_total: %s size_needed: %s)r%   r$   r&   r'   r   r   r   __str__d   s   zFreeSpaceRequired.__str__N)r   r   r   __doc__r(   r*   r   r   r   r   r"   X   s    r"   c                   @      e Zd ZdZdd ZdS )NotEnoughFreeSpaceErrorzI
    Exception if there is not enough free space for this operation

    c                 C   s
   || _ d S r#   )free_space_required_list)r'   r.   r   r   r   r(   m   s   
z NotEnoughFreeSpaceError.__init__Nr   r   r   r+   r(   r   r   r   r   r-   h   s    r-   c                   @   s  e Zd ZdZdZdsddZdd Zed	d
 Zdd Z	dd Z
dd Zdd Zdd Zedd Zedd Zedd Zedd Zdd Zdd  Zdtd!d"Zd#d$ Zdud%d&Zdud'd(Zdud)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zdvd:d;Z dvd<d=Z!dvd>d?Z"dvd@dAZ#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+dRdS Z,edTdU Z-dVdW Z.dXdY Z/edZd[ Z0d\d] Z1d^d_ Z2d`da Z3dbdc Z4eddde Z5dfdg Z6dhdi Z7djdk Z8dldm Z9dndo Z:dwdqdrZ;dS )xMyCacher      NTc              
   C   s"  g | _ g | _|| _|| _d| _d| _|| _| jdd| _d| _	|rJzt
  |   d| _W n tyI } zdt|v rAt|t|d }~ww tj| | |dd| _| j| d| _tdd	gtdd
 d  | _|   |dddkrdtj vrt
j!dd t
j!dd d S )NFDistroMetaPkgsTzdpkg --configure -aRemovalDenylistFiler   z-r)stdoutuniversal_newlinesr   SourcesFromhardyRELEASE_UPGRADE_NO_RECOMMENDSzAPT::Install-Recommendstruez"APT::AutoRemove::SuggestsImportantfalse)"
to_install	to_removeviewquirkslockpartialUpgradeconfiggetlistmetapkgs
_listsLockapt_pkgpkgsystem_locklock_lists_dirSystemErrorstrr   r   aptCacher(   getListFromFileremoval_denylist_get_linux_metapackagelinux_metapackager   r   communicatestripr   _initAptLoggetr   environset)r'   rD   r@   rA   progressrB   er   r   r   r(   v   sF   


zMyCache.__init__c                 C   s2   | D ]}|j rq|jjtjkr|jddd qdS )z! honor the dselect install state F)	auto_instauto_fixN)is_installed_pkgselected_staterH   SELSTATE_INSTALLmark_installr'   pkgr   r   r   _apply_dselect_upgrade   s   zMyCache._apply_dselect_upgradec                 C   sJ   t  }| D ]}|jr|jjs"|jj| jks|jj| jkr"||j q|S )zB return the packages not downloadable packages in reqreinst state )	rX   	candidatedownloadabler^   
inst_state	ReInstReqHoldReInstReqaddname)r'   	reqreinstrc   r   r   r   req_reinstall_pkgs   s   zMyCache.req_reinstall_pkgsc                 C   s~   | j }t|dkr=tddt|}tddt|d| }|||r=|   g dt| }| | | 	  dS d	S )
z/ check for reqreinst state and offer to fix it r   zRemove package in bad statezRemove packages in bad statezThe package '%s' is in an inconsistent state and needs to be reinstalled, but no archive can be found for it. Do you want to remove this package now to continue?zThe packages '%s' are in an inconsistent state and need to be reinstalled, but no archives can be found for them. Do you want to remove these packages now to continue?, )z/usr/bin/dpkgz--removez--force-remove-reinstreqTF)
rm   lenr   joinaskYesNoQuestionrelease_locklistgetTerminalcallget_lock)r'   r@   rl   headersummarycmdr   r   r   fix_req_reinst   s&   
zMyCache.fix_req_reinstc                 C   s   | j ddd}tj|st| tj d| tj dd ttj	|dtj
tjB tjB d| _tj }d	| }t| j|d
 tj dd tj dd tj dd dS )z init logging, create log fileFilesLogDirz/var/log/dist-upgradezDir::LogzDir::Log::Terminalzapt-term.logzapt.logi  zLog time: %s
zutf-8zDebug::pkgProblemResolverr<   zDebug::pkgDepCache::MarkerzDebug::pkgDepCache::AutoInstallN)rD   getWithDefaultr   r   existsmakedirsrH   rX   openrp   O_RDWRO_CREATO_APPENDlogfddatetimenowwriteencode)r'   logdirr   rw   r   r   r   rU      s    


zMyCache._initAptLogc                 C   sZ   t | drt| j t| j td| _td| _t| jd t| jd d S )N
old_stdoutr   r   )hasattrr   closer   
old_stderrdupdup2r   r)   r   r   r   _startAptResolverLog   s   
zMyCache._startAptResolverLogc                 C   s4   t d t d t | jd t | jd d S )Nr   r   )r   fsyncr   r   r   r)   r   r   r   _stopAptResolverLog   s   

zMyCache._stopAptResolverLogc                    s    fdd}|S )z3 decorator to ensure that the apt output is logged c                     s*   | d     | i |}| d   |S Nr   )r   r   )argskwargsresr   r   r   wrapper   s   z(MyCache.withResolverLog.<locals>.wrapperr   )r   r   r   r   r   withResolverLog   s   zMyCache.withResolverLogc                 C   s,   t | j}t  }||| j| j |jS )z< get the size of the packages that are required to download )rH   PackageManager	_depcacheAcquireget_archives_list_recordsfetch_needed)r'   pmfetcherr   r   r   required_download   s   zMyCache.required_downloadc                 C   s   | j jS )z9 get the size of the additional required space on the fs )r   usr_sizer)   r   r   r   additional_required_space   s   z!MyCache.additional_required_spacec                 C   s    z| j jW S  ty   Y dS w )z< get the extra size needed to install the snap replacements r   )rA   extra_snap_spaceAttributeErrorr)   r   r   r   #additional_required_space_for_snaps  s
   
z+MyCache.additional_required_space_for_snapsc                 C   s   | j jdkS )z is the cache broken r   )r   broken_countr)   r   r   r   	is_broken  s   zMyCache.is_brokenc                 C   s:   t jdd }t || _| jdk rd| }t|d S )NzDir::State::ListsrB   r   zCan not lock '%s' )rH   rD   find_dirrv   rG   r   )r'   rk   rZ   r   r   r   rJ     s   
zMyCache.lock_lists_dirc                 C   s$   | j dkrt| j  d| _ d S d S )Nr   r4   )rG   r   r   r)   r   r   r   unlock_lists_dir  s   

zMyCache.unlock_lists_dirc                 C   sH   |    tj| |}|   |r|jrttd|dkr"tddS )zf
        our own update implementation is required because we keep the lists
        dir lock
        zThe server may be overloadedFzAapt.cache.update() returned False, but did not raise exception?!?N)r   rM   rN   updaterJ   release_file_download_errorIOError_)r'   	fprogressr   r   r   r   r   "  s   
zMyCache.updatec                 C   s,   t d | jr|   tj| || d S )Nzcache.commit())r   inforB   rr   rM   rN   commit)r'   r   	iprogressr   r   r   r   1  s   
zMyCache.commitc              
   C   sT   | j r(z
t  d| _ W d S  ty' } ztd|  W Y d }~d S d }~ww d S )NFzfailed to SystemUnLock() (%s) )rB   rH   pkgsystem_unlockrK   r   debugr'   pkgSystemOnlyrZ   r   r   r   rr   7     zMyCache.release_lockc              
   C   sT   | j s(z
t  d| _ W d S  ty' } ztd|  W Y d }~d S d }~ww d S )NTzfailed to SystemLock() (%s) )rB   rH   rI   rK   r   r   r   r   r   r   rv   ?  r   zMyCache.get_lockc                 C   sB   |r
| j |j}n|jj}|dkrtd|j|f  dS |jS )z* check if the given pkg can be downloaded Nz1no version information for '%s' (useCandidate=%s)F)r   get_candidate_verr^   current_verr   r   rk   rf   )r'   rc   useCandidateverr   r   r   rf   G  s   zMyCache.downloadablec                 C   s   |j o	| j|jS )z$ check if the pkg is auto-removable )r]   r   
is_garbager^   rb   r   r   r   pkg_auto_removableR  s   zMyCache.pkg_auto_removablec                 C   s
   | j  S )z^ try to fix broken dependencies on the system, may throw
            SystemError when it can't)r   
fix_brokenr)   r   r   r   r   W  s   
zMyCache.fix_brokenc                 C   sL   g | _ g | _|  D ]}|js|jr| j |j |jr#| j|j q
dS )z* create a snapshot of the current changes N)r>   r?   get_changesmarked_installmarked_upgradeappendrk   marked_deleterb   r   r   r   create_snapshot\  s   zMyCache.create_snapshotc                 C   s   | j   d S r#   )r   initr)   r   r   r   clearf  s   zMyCache.clearc                 C   sZ   t | j}| |   | jD ]
}| | }|  q| jD ]}| | }|jddd qdS )z restore a snapshot F)r\   r[   N)rH   ActionGroupr   r   r?   mark_deleter>   ra   )r'   actiongrouprk   rc   r   r   r   restore_snapshoti  s   


zMyCache.restore_snapshotc                 C   s   | j dd}|D ]8}|| v r| | jrtd|   dS d}| j |dD ]}||| v o2| | jM }q'|rAtd|   dS q	td dS )	ac  
        This checks if we run on a desktop or a server install.

        A server install has more freedoms, for a desktop install
        we force a desktop meta package to be install on the upgrade.

        We look for a installed desktop meta pkg and for key
        dependencies, if none of those are installed we assume
        server mode
        r2   r3   z@need_server_mode(): run in 'desktop' mode, (because of pkg '%s')FTKeyDependencieszIneed_server_mode(): run in 'desktop' mode, (because of key deps for '%s')z[need_server_mode(): can not find a desktop meta package or key deps, running in server mode)rD   rE   r]   r   r   )r'   rF   key
deps_foundrc   r   r   r   need_server_modew  s   
zMyCache.need_server_modec                 C   sL   | j r$ztd |   W dS  ty#   |tdtd Y dS w dS )zY check if the cache is ok and if the required metapkgs
            are installed
        z$Have broken pkgs, trying to fix themzBroken packageszYour system contains broken packages that couldn't be fixed with this software. Please fix them first using synaptic or apt-get before proceeding.FT)r   r   r   r   rK   errorr   )r'   r@   r   r   r   coherence_check  s   

	
zMyCache.coherence_check c                 K   sX   t d||f  || v r*| | jdi | | | js*| | js*t d|  dS dS )NzInstalling '%s' (%s)z Installing/upgrading '%s' failedFTr   )r   r   ra   r   r   r   r'   rc   reasonflagsr   r   r   ra     s   zMyCache.mark_installc                 C   sP   t d||f  || v r&| | jr&| |   | | js&t d|  dS dS )NzUpgrading '%s' (%s)zUpgrading '%s' failedFT)r   r   r]   mark_upgrader   r   r'   rc   r   r   r   r   r     s   
zMyCache.mark_upgradec                 K   s6   t d||f  || v r| | jdi | d S d S )NzRemoving '%s' (%s)r   )r   r   r   r   r   r   r   mark_remove     zMyCache.mark_removec                 C   s6   t d||f  || v r| j| | jd d S d S )NzPurging '%s' (%s)T)r   r   r   r   r^   r   r   r   r   
mark_purge  r   zMyCache.mark_purgec                 C   s8   || v r| | j r| | jr| || d S d S d S d S r#   )r]   r   ra   )r'   pkgnamer   r   r   r   _keep_installed  s   zMyCache._keep_installedc              	   C   s\  | j ddD ]}| |d q| jD ]"}|| v r5| | js#| | jr5| j |dD ]
}| |d|  q*q| j dddkrtd | j dd	D ] }| D ]}|j	rj|j	j
rj|jrj|j	j|krj| |jd
|  qOqK| jD ]<}|| v r| | js| | jr| j |d	D ]"}| D ]}|j	r|j	j
r|jr|j	j|kr| |jd||f  qqqodS dS )z[ run after the dist-upgrade to ensure that certain
            packages are kept installed r2   KeepInstalledPkgszDistro KeepInstalledPkgs rulez%s KeepInstalledPkgs ruleOptionswithNetworkTruez"Running KeepInstalledSection rulesKeepInstalledSectionz$Distro KeepInstalledSection rule: %sz %s KeepInstalledSection rule: %sN)rD   rE   r   rF   r]   r   rV   r   r   re   rf   r   sectionrk   )r'   r   r   r   rc   r   r   r   keep_installed_rule  sH   


	zMyCache.keep_installed_rulec                 C   s   | j s| jd dS dS )z. run before the upgrade was done in the cache PreDistUpgradeCacheN)rC   rA   runr)   r   r   r   pre_upgrade_rule  s   zMyCache.pre_upgrade_rulec                 C   s   d| j fd| jfd| jfd| jffD ]@\}}| jdd| D ]	}||d|  q| jD ]%}|| v rQ| | js<| | jrQ| j|d| D ]}||d||f  qEq,q| j	s^| j
d	 d
S d
S )z- run after the upgrade was done in the cache InstallUpgradeRemovePurger2   zPostUpgrade%szDistro PostUpgrade%s rulez%s PostUpgrade%s rulePostDistUpgradeCacheN)ra   r   r   r   rD   rE   rF   r]   r   rC   rA   r   )r'   ruleactionrc   r   r   r   r   post_upgrade_rule  s$   
zMyCache.post_upgrade_rulec              
   C   sD  t d zddlm} W n ttfy) } zt d|  W Y d}~dS d}~ww z]|dd}|jD ]}|| v rF| | jrF| 	|d	  n	q3t 
d
 W dS | }t d|  || vrht d|  W dS | | js| | js| |   t 
d|  W dS W dS W dS  ty } zt d|  W Y d}~dS d}~ww )zR
        this checks for nvidia hardware and checks what driver is needed
        znvidiaUpdate()r   )NvidiaDetectionz%NvidiaDetector can not be imported %sNFz./ubuntu-drivers-obsolete.pkgs)obsoletezold nvidia driverz1no old nvidia driver installed, installing no newznv.selectDriver() returned '%s'zno '%s' foundz,installing %s as suggested by NvidiaDetectorTz$NvidiaDetection returned a error: %s)r   r   NvidiaDetector.nvidiadetectorr   ImportErrorSyntaxErrorr   oldPackagesr]   r   r   selectDriverr   r   r   ra   	Exception)r'   r   rZ   nv	oldDriverdriverr   r   r   checkForNvidia  sF   



zMyCache.checkForNvidiac                 C   s&   | D ]}|j dr|jr dS qdS )Nzlinux-headers-TF)rk   
startswithr]   rb   r   r   r   _has_kernel_headers_installed/  s   z%MyCache._has_kernel_headers_installedc              
   C   s   t d| j  z| jd\}}}W n ty- } zt d|  W Y d}~dS d}~ww tdgtd d }d	|v rBt d
 dS )zd check for the running kernel and try to ensure that we have
            an updated version
        zKernel uname: '%s' -z/Can't parse kernel uname: '%s' (self compiled?)NFdmesg)r6   r   s   WARNING: NR_CPUS limitzUP kernel on SMP system!?!T)	r   r   r   splitr   r   r   r   rS   )r'   versionbuildflavourrZ   r   r   r   r   checkForKernel6  s   
zMyCache.checkForKernelc                 C   s   d}| j dd}| D ]@}|jj|j}|r%|jdkr%td|j	  q|j
rK|j
jrK|jsK|jsK|j	|vrKd|j	vrK|j
j|v rK| |j	d|  qd S )N)requiredr2   RemoveEssentialOkr   zPackage %s has no priority set:z;priority in required set '%s' but not scheduled for install)rD   rE   _pcacher   r   r^   priorityr   r   rk   re   rf   r]   r   ra   )r'   needremoveEssentialOkrc   r   r   r   r   checkPriorityF  s$   

zMyCache.checkPriorityc                 C   sZ   d}|  r!|d dkr|  |  td |d7 }|  s|jdd |  d S )Nr      g{Gz?r   T)finished)lockedpulseProgressprocessEventstimesleep)r'   r@   rB   ir   r   r   	updateGUI[  s   
zMyCache.updateGUIc              
   C   sr  t  }|  t j| j| j|fd}|  zzK|   | d | 	  | 
  t r3td n|   |   |   | | |sK| | |   | jrbttdddd | D  W nw ty } zktd}| jd	d
dkr|td7 }n| jd	d
dkr| jd	ddkr|td7 }|r|td7 }n|td7 }|td7 }|   |td| t|}td| |   W Y d }~W |  |  dS d }~ww W |  |  n	|  |  w g }	g }
|  D ]^}|j rq|j!r:|
"|j# |j$j%D ].}t&'|j(|j)j*dk r7|j+D ]\}}|j,j-.|}|r5|j/s5|	"|j#  nqq
q|j0j1}d}|D ]}||j2O }qB|sT|	"|j# qz| j3dd}|rhtd W dS W n t4j5yt   Y nw t6|
dkr|
7  tdd|
  t6|	dkr|	7  tdd|	  |   |tdtdd|	 |   dS dS ) N)targetr   Tz5skipping kernel checks because we run inside a chrootz!Broken packages after upgrade: %srn   c                 s   s"    | ]}|j s
|jr|jV  qd S r#   )is_inst_brokenis_now_brokenrk   ).0pr   r   r   	<genexpr>  s     z&MyCache.distUpgrade.<locals>.<genexpr>zBAn unresolvable problem occurred while calculating the upgrade.

 r   foreignPkgsr   zThis was likely caused by:
 * Unofficial software packages not provided by Ubuntu
Please use the tool 'ppa-purge' from the ppa-purge 
package to remove software from a Launchpad PPA and 
try the upgrade again.

False
devReleasezThis was caused by:
 * Upgrading to a pre-release version of Ubuntu
This is most likely a transient problem, 
please try again later.
z@This is most likely a transient problem, please try again later.zIf none of this applies, then please report this bug using the command 'ubuntu-bug ubuntu-release-upgrader-core' in a terminal. zIf you want to investigate this yourself the log files in '/var/log/dist-upgrade' will contain details about the upgrade. Specifically, look at 'main.log' and 'apt.log'.zCould not calculate the upgradezDist-upgrade failed: '%s'Fr   r2   AllowUnauthenticatedzAllowUnauthenticated set!z!Packages to downgrade found: '%s' z$Unauthenticated packages found: '%s'z"Error authenticating some packageszIt was not possible to authenticate some packages. This may be a transient network problem. You may want to try again later. See below for a list of unauthenticated packages.
)8	threadingLockacquireThreadr  r@   startr   upgrader  r   r   r   r   r  r   r   _keepBaseMetaPkgsInstalled_installMetaPkgs_verifyChangesr   rK   r   rp   rD   rV   r   r   rL   r   releaser   r   marked_downgrader   rk   r^   version_listrH   version_comparever_str	installedr  	file_listr  r   
find_index
is_trustedre   originstrusted
getbooleanconfigparserNoOptionErrorro   sort)r'   r@   
serverModerC   rB   trZ   details	error_msg	untrusted	downgraderc   r   verFileIterindex	indexfiler4  r5  originbr   r   r   distUpgradef  s   


 -




zMyCache.distUpgradec                 C   s  t jd}| jdd}|  D ]A}|jr,| |jr,t	d|j t
td|j |jrR|jjdkrR|jj|dfv rR|j|vrRt	d|j t
td	|j q| jdd
}|D ],}|d\}}|| v r| | jr| | jj|kr| | js| | jrt
td| q\dS )zy this function tests if the current changes don't violate
            our constraints (deny listed removals etc)
        zAPT::Architecturer2   r  zHThe package '%s' is marked for removal but it's in the removal deny listzJThe package '%s' is marked for removal but it is in the removal deny list.TallzDThe package '%s' is marked for removal but it's an ESSENTIAL packagez1The essential package '%s' is marked for removal.BadVersionsr   z*Trying to install deny listed version '%s')rH   rD   r   rE   r   r   _inRemovalDenylistrk   r   r   rK   r   r^   	essentialr0  architecturer   re   r  r   r   )r'   	main_archr  rc   badVersionsbvr   r   r   r   r   r*    s2   
zMyCache._verifyChangesc                 C   sn   |j j|j}|du rtd|j dS |jdu r$td| j   dS |jd\}}|j j	||f dS )a  
        helper to make sure that the pkg._records is pointing to the right
        location - needed because python-apt 0.7.9 dropped the python-apt
        version but we can not yet use the new version because on upgrade
        the old version is still installed
        NzNo candidate ver: FzNo file_list for: %s r   T)
r  r   r   r^   printrk   r1  popr   lookup)r'   rc   r   r   rA  r   r   r   _lookupPkgRecord  s   
zMyCache._lookupPkgRecordc           	      C   s   i }t  }| D ]C}| |std|j  q|jjjdD ]*}|	drI|t
dd  dD ]}| }||vr@t  ||< || |j q1qq|D ](}d}| jdd}||v r^d}|| D ]}| | jsmd} nqb|ru|| qM|S )	Nz&no PkgRecord found for '%s', skipping r!  Task:,Tr2   IgnoredTasksF)rX   rQ  r   r   rk   r  r   recordr   r   ro   rT   rj   rD   rE   r]   )	r'   tasksinstalled_tasksrc   linetaskr0  ignored_tasksr   r   r   r   installedTasks)  s:   




zMyCache.installedTasksc                 C   s   t d | D ]M}|js|jrq| | t|jjdr!|jjjs*t 	d|j
  q|jjjdD ]!}|drS|tdd  dD ]}| }||v rR|  qDq2qdS )Nzrunning installTasksrU  zcan not find Record for '%s'r!  rR  rS  T)r   r   r   r]   rQ  r   r  r   rU  r   rk   r   r   ro   rT   ra   )r'   rV  rc   rX  rY  r   r   r   installTasksE  s"   


zMyCache.installTasksc                 C   s$   | j ddD ]}| |d qd S )Nr2   BaseMetaPkgsz%base meta package keep installed rule)rD   rE   r   )r'   r@   rc   r   r   r   r(  V  s   z"MyCache._keepBaseMetaPkgsInstalledc                    s   fdd}j dd j ddD ]}|   q D ]:}z|v r>| jr>| jr>td|  |   W q  tyZ } zt	d||f  W Y d }~q d }~ww | std    D ]d}d	}j |d
D ]}||v o}| jM }qr|rtd|  z|   W n+ tt
fy } ztd||f  |td| td W Y d }~ dS d }~ww td|| jf   nqg| sd dd }|tdtd| d f  dS d	S )Nc                     sV    D ]&} | v r(|  }|j r|jrtd|j  |j r |jr%|  jr( dS qdS )zy
            internal helper that checks if at least one meta-pkg is
            installed or marked install
            z(metapkg '%s' installed but marked_deleteTF)r]   r   r   r   rk   r   )r   rc   rF   r'   r   r   metaPkgInstalled\  s   z2MyCache._installMetaPkgs.<locals>.metaPkgInstalledr2   r3   r]  zMarking '%s' for upgradez Can't mark '%s' for upgrade (%s)z$none of the '%s' meta-pkgs installedTr   z!guessing '%s' as missing meta-pkgz$failed to mark '%s' for install (%s)zCan't install '%s'zIt was impossible to install a required package. Please report this as a bug using 'ubuntu-bug ubuntu-release-upgrader-core' in a terminal.Fzmarked_install: '%s' -> '%s'rn   r   r4   zCan't guess meta-packagezYour system does not contain a %s or %s package and it was not possible to detect which version of Ubuntu you are running.
 Please install one of the packages above first using synaptic or apt-get before proceeding.)rD   rE   ra   r]   is_upgradabler   r   r   rK   r   KeyErrorr   r   r   rp   )r'   r@   r_  rc   r   rZ   r   	meta_pkgsr   r^  r   r)  Z  sd   


	zMyCache._installMetaPkgsc                 C   s8   | j D ]}t||rtd||f   dS qdS )Nzdenylist expr '%s' matches '%s'TF)rP   recompilematchr   r   )r'   r   exprr   r   r   rH    s   
zMyCache._inRemovalDenylistc           
   
   C   s  | | jrtd|  dS || jkrtd|  dS | |r+td|  dS | jddD ]}|| v rO| | jrO| | jj	|krOtd|   dS q2|| vrVdS z	| j
dd	}W n tjyk   d}Y nw t| j}| |   zF| | j|d
 | j  ||v rW dS |  D ]*}|j|vs|j|v s| |js|j| jkrtd||jf  |    W dS qW dS  ttfy }	 ztd|t|	|	f  |   W Y d }	~	dS d }	~	ww )Nz skipping running kernel pkg '%s'Fz skipping kernel metapackage '%s'z"skipping '%s' (in removalDenylist)r2   r   z'skipping '%s' (in KeepInstalledSection)TPurgeObsoletes)purgez8package '%s' produces an unwanted removal '%s', skippingz3_tryMarkObsoleteForRemoval failed for '%s' (%s: %s))endswithr   r   r   rR   rH  rD   rE   r0  r   r6  r7  r8  rH   r   r   r   r   r@   r  r   rk   r   rK   ra  r   repr)
r'   r   remove_candidatesforced_obsoletesforeign_pkgsr   rh  r   rc   rZ   r   r   r   tryMarkObsoleteForRemoval  s`   





z!MyCache.tryMarkObsoleteForRemovalc                 C   s0   t  }| D ]}|jr| |s||j q|S z1 get all package names that are not downloadable )rX   r]   anyVersionDownloadablerj   rk   )r'   obsolete_pkgsrc   r   r   r   _getObsoletesPkgs  s   
zMyCache._getObsoletesPkgsc                 C   s   |j jD ]}|jr dS qdS )zA helper that checks if any of the version of pkg is downloadable TF)r^   r-  rf   )r'   rc   r   r   r   r   rp    s
   zMyCache.anyVersionDownloadablec                 C   s4   t  }| D ]}|jr| j|jr||j q|S ro  )rX   r]   r   r   r^   rj   rk   )r'   unused_dependenciesrc   r   r   r   _getUnusedDependencies  s   zMyCache._getUnusedDependenciesc                 C   s   t  }| jdd}tj|r5t|}|D ]}|ds%||	  qW d   n1 s0w   Y  t  }|D ]}|| vrAq:| | }|j
rR| j|jsR|jrSq:|| q:t|S )z return list of installed and demoted packages

            If a demoted package is a automatic install it will be skipped
        r2   	Demotions#N)rX   rD   rV   r   r   r~   r   r   rj   rT   r]   r   is_auto_installedr^   r   rs   )r'   	demotionsdemotions_filedemotions_frX  installed_demotionsdemoted_pkgnamerc   r   r   r   get_installed_demoted_packages  s.   

z&MyCache.get_installed_demoted_packagesc                 C   s~   t  }| D ]7}|jr<| |r<|jsqd}|jjD ]}||jv r'|j|kr'd}||jv r3|j|kr3d}q|r<||j q|S )zm get all packages that are installed from a foreign repo
            (and are actually downloadable)
        TF)	rX   r]   rf   re   r4  archiverC  rj   rk   )r'   allowed_originfromDisttoDistrm  rc   foreignrC  r   r   r   _getForeignPkgs  s$   



zMyCache._getForeignPkgsFc                    sh  G dd dt } fdd}g  i }i }td>}|D ]3}z| \}}	}
}}}W n tyD } ztd||f  W Y d}~qd}~ww |	 vrN |	 qW d   n1 sYw   Y   jtdd	 t	j
d
}d}t| dr| j
dddr| j
dd}tj|st| td|  dddd||ddfD ]R}tj|}||}tj|rt|}|j|j }n	td|  d}||v rtd||| f  |||  ||< qtd||f  |||< ||||< q~td|  d}| D ] }td|jr|js|jrtd|jtf  |d7 }q|t |d t  }d}t| drX| j
dddrXtd  | j
dd}| D ]}|jsP|jrV||jj 7 }qFd}|r|| D ]}|j!rs|jsm|j"rs||j#j 7 }q_td!|  || j$fd| j%fd| j&fd"d|fd#d$||fd|ff	D ]4\}}|dk rqtj|}td%|||| || j'f  ||  j'|8  _'||  j(|7  _(qi }|D ]G}|| j'dk rt	)t*t+|| j'd }t,|t-r|.t/0 }t	)|| j(}t,|t-r	|.t/0 }t1|||||||< qt|dkr2t2d&d'd( |D   t3t4|5 dS ))z
        this checks if we have enough free space on /var, /boot and /usr
        with the given cache

        Note: this can not be fully accurate if there are multiple
              mountpoints for /usr, /var, /boot
        c                   @   r,   )z)MyCache.checkFreeSpace.<locals>.FreeSpacez@ helper class that represents the free space on each mounted fs c                 S   s   || _ d| _d S r   )freer
  )r'   initialFreer   r   r   r(   ?  s   
z2MyCache.checkFreeSpace.<locals>.FreeSpace.__init__Nr/   r   r   r   r   	FreeSpace=  s    r  c                    s     D ]}|  |r|  S qdS )z return 'id' of a directory so that directories on the
                same filesystem get the same id (simply the mount_point)
            /)r   )dmount_pointmountedr   r   
make_fs_idC  s
   
z*MyCache.checkFreeSpace.<locals>.make_fs_idz/proc/mountsz-line '%s' in /proc/mounts not understood (%s)NT)r   reversezDir::Cache::archivesz/tmp/rD   AufsEnabledFRWDirzcache aufs_rw_dir: %sr  /usrz/varz/bootz/homezdirectory '%s' does not existsr   zDir %s mounted on %szFree space on %s: %szfs_free contains: '%s'z%^linux-(image|image-debug)-[0-9.]*-.*z,%s (new-install) added with %s to boot spacer   g        z*taking aufs overlay into space calculationz&additional space for the snapshots: %s)r  i   )z/tmpi  P )r  i   z dir '%s' needs '%s' of '%s' (%f)zNot enough free space: %sc                 S   s   g | ]}t |qS r   )rL   )r  r  r   r   r   
<listcomp>  s    z*MyCache.checkFreeSpace.<locals>.<listcomp>)6objectr   r   
ValueErrorr   r   r   r9  ro   rH   rD   r   r   r}   rV   r   r   r~   r   realpathstatvfsf_bavailf_frsizer   rc  re  rk   r   r   KERNEL_SIZEINITRD_SIZEre   installed_sizer]   r   r0  r   r   r   r  r
  size_to_strfloatabs
isinstancebytesdecodelocalegetpreferredencodingr"   r   r-   rs   values)r'   snapshots_in_user  r  mnt_mapfs_freemountsrX  whatwherefsoptionsarD  rZ   
archivediraufs_rw_dirr  fs_idstr  kernel_countrc   space_in_bootrequired_for_aufsrequired_for_snapshotsr%   sizerequired_listfree_at_leastfree_neededr   r  r   checkFreeSpace4  s   	









 zMyCache.checkFreeSpace)NTr#   )T)r   )F)<r   r   r   rh   ri   r(   rd   propertyrm   rz   rU   r   r   r   r   r   r   r   rJ   r   r   r   rr   rv   rf   r   r   r   r   r   r   r   ra   r   r   r   r   r   r   r   r   r   r  r  r  rE  r*  rQ  r[  r\  r(  r)  rH  rn  rr  rp  rt  r}  r  r  r   r   r   r   r0   q   s    
'	














	
#*
 
L
9r0   __main__)DistUpgradeConfig)DistUpgradeViewfoo.zubuntu-desktop)/rM   rH   r   r  r   rc  r   r  r   r"  r7  
subprocessr   r   DistUpgradeGettextr   r   r   utilsr   r   r	   r   r   r!   r  r  r  r"   r-   rN   r0   r   sysDistUpgradeConfigParserr  r  rN  cr  exitr   r   r[  r\  r   r   r   r   r   r   <module>   s\   
!	        l