U
    ٪zc                     @   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 )    N)PopenPIPE   )gettext)ngettext)inside_chrootc                   @   s   e Zd ZdS )CacheExceptionN__name__
__module____qualname__ r   r   >/usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeCache.pyr   (   s   r   c                   @   s   e Zd ZdS )CacheExceptionLockingFailedNr	   r   r   r   r   r   ,   s   r   c                   @   s   e Zd ZdS )CacheExceptionDpkgInterruptedNr	   r   r   r   r   r   0   s   r   c                  C   s   d} d}t  d }td| D ]`}|d| krD|t j|7 }q"|ddks"|ddks"|ddkrrq"q"| t j|7 } q"| dkrtd d	} |dkrtd
 d}| d7 } d}|d |kr|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)ZkernelZinitrdZkverfZinitrd_bufferr   r   r   #estimate_kernel_initrd_size_in_boot4   s6    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                   @   s   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dvd'd(Zdwd)d*Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zdxd:d;Z dyd<d=Z!dzd>d?Z"d{d@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:d|dqdrZ;dS )}MyCacher      NTc              
   C   s0  g | _ g | _|| _|| _d| _d| _|| _| jdd| _d| _	|rzt
  |   d| _W n> tk
r } z dt|krt|t|W 5 d }~X Y nX tj| | |dd| _| j| d| _tdd	gtdd
 d  | _|   |dddkrdtj krt
j!dd t
j!dd d S )NFDistroMetaPkgsTzdpkg --configure -aZRemovalBlacklistFiler   z-r)stdoutZuniversal_newlinesr   ZSourcesZFromZhardyZRELEASE_UPGRADE_NO_RECOMMENDSzAPT::Install-Recommendstruez"APT::AutoRemove::SuggestsImportantZ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"   ZgetListFromFileremoval_blacklistZ_get_linux_metapackagelinux_metapackager   r   communicatestripr   _initAptLoggetr   environset)r!   r6   r2   r3   Zprogressr4   er   r   r   r"   v   s@    


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_pkgZselected_stater:   Z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s8|jj| jkr
||j q
|S )zB return the packages not downloadable packages in reqreinst state )	rH   	candidatedownloadablerM   Z
inst_state	ReInstReqHoldReInstReqaddname)r!   	reqreinstrP   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||   ddd	g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)
rY   lenr   joinZaskYesNoQuestionrelease_locklistZgetTerminalcallget_lock)r!   r2   rX   headerZ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 fileZFilesZ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)r6   getWithDefaultr   r   existsmakedirsr:   rH   openr\   O_RDWRO_CREATO_APPENDlogfddatetimenowwriteencode)r!   Zlogdirrm   ra   r   r   r   rE      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   closerp   
old_stderrdupdup2rk   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   fsyncru   rp   rs   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     | |}| d   |S Nr   )rv   rx   )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 )r:   ZPackageManager	_depcacheZAcquireZget_archives_list_recordsZfetch_needed)r!   ZpmZ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   Zusr_sizer#   r   r   r   additional_required_space   s    z!MyCache.additional_required_spacec                 C   s&   z
| j jW S  tk
r    Y dS X dS )z< get the extra size needed to install the snap replacements r   N)r3   Z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   Zbroken_countr#   r   r   r   	is_broken  s    zMyCache.is_brokenc                 C   s:   t jdd }t || _| jdk r6d| }t|d S )NzDir::State::Listsr4   r   zCan not lock '%s' )r:   r6   find_dirr`   r9   r   )r!   rW   rI   r   r   r   r<     s
    
zMyCache.lock_lists_dirc                 C   s    | j dkrt| j  d| _ d S )Nr   r-   )r9   r   rr   r#   r   r   r   unlock_lists_dir  s    
zMyCache.unlock_lists_dirc                 C   sH   |    tj| |}|   |r4|jr4ttd|dkrDt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   r?   r@   updater<   Z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   infor4   r]   r?   r@   commit)r!   r   Z	iprogressr   r   r   r   1  s    
zMyCache.commitc              
   C   sN   | j rJzt  d| _ W n0 tk
rH } ztd|  W 5 d }~X Y nX d S )NFzfailed to SystemUnLock() (%s) )r4   r:   Zpkgsystem_unlockr=   r   debugr!   ZpkgSystemOnlyrI   r   r   r   r]   7  s    
zMyCache.release_lockc              
   C   sN   | j sJzt  d| _ W n0 tk
rH } ztd|  W 5 d }~X Y nX d S )NTzfailed to SystemLock() (%s) )r4   r:   r;   r=   r   r   r   r   r   r   r`   ?  s    
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_verrM   Zcurrent_verr   r   rW   rS   )r!   rP   ZuseCandidateverr   r   r   rS   G  s    zMyCache.downloadablec                 C   s   |j o| j|jS )z$ check if the pkg is auto-removable )rL   r   
is_garbagerM   rO   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 ]2}|js$|jr2| j |j |jr| j|j qdS )z* create a snapshot of the current changes N)r0   r1   get_changesmarked_installmarked_upgradeappendrW   marked_deleterO   r   r   r   create_snapshot\  s    zMyCache.create_snapshotc                 C   s   | j   d S r   )r   Z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)rK   rJ   N)r:   ActionGroupr   r   r1   mark_deleter0   rN   )r!   actiongrouprW   rP   r   r   r   restore_snapshoti  s    


zMyCache.restore_snapshotc                 C   s   | j dd}|D ]p}|| kr<| | jr<td|   dS d}| j |dD ]}||| kod| | jM }qN|rt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
        r+   r,   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)r6   r7   rL   r   r   )r!   r8   key
deps_foundrP   r   r   r   need_server_modew  s    
zMyCache.need_server_modec                 C   sL   | j rHztd |   W n* tk
rF   |tdtd Y dS X 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   r=   errorr   )r!   r2   r   r   r   sanity_check  s    

zMyCache.sanity_check c                 K   sT   t d||f  || krP| | jf | | | jsP| | jsPt d|  dS dS )NzInstalling '%s' (%s)z Installing/upgrading '%s' failedFT)r   r   rN   r   r   r   r!   rP   reasonflagsr   r   r   rN     s    zMyCache.mark_installc                 C   sP   t d||f  || krL| | jrL| |   | | jsLt d|  dS dS )NzUpgrading '%s' (%s)zUpgrading '%s' failedFT)r   r   rL   mark_upgrader   r   r!   rP   r   r   r   r   r     s    
zMyCache.mark_upgradec                 K   s.   t d||f  || kr*| | jf | d S )NzRemoving '%s' (%s))r   r   r   r   r   r   r   mark_remove  s    zMyCache.mark_removec                 C   s2   t d||f  || kr.| j| | jd d S )NzPurging '%s' (%s)T)r   r   r   r   rM   r   r   r   r   
mark_purge  s    zMyCache.mark_purgec                 C   s,   || kr(| | j r(| | jr(| || d S r   )rL   r   rN   )r!   pkgnamer   r   r   r   _keep_installed  s    zMyCache._keep_installedc              	   C   sh  | j ddD ]}| |d q| jD ]D}|| kr&| | jsF| | jr&| j |dD ]}| |d|  qTq&| j dddkrdtd | j dd	D ]@}| D ]6}|j	r|j	j
r|jr|j	j|kr| |jd
|  qq| jD ]}|| kr| | js| | jr| j |d	D ]P}| D ]D}|j	r|j	j
r|jr|j	j|kr| |jd||f  qqqdS )z[ run after the dist-upgrade to ensure that certain
            packages are kept installed r+   ZKeepInstalledPkgszDistro KeepInstalledPkgs rulez%s KeepInstalledPkgs ruleOptionsZwithNetworkTruez"Running KeepInstalledSection rulesKeepInstalledSectionz$Distro KeepInstalledSection rule: %sz %s KeepInstalledSection rule: %sN)r6   r7   r   r8   rL   r   rF   r   r   rR   rS   r   sectionrW   )r!   r   r   r   rP   r   r   r   keep_installed_rule  s<    




zMyCache.keep_installed_rulec                 C   s   | j s| jd dS )z. run before the upgrade was done in the cache ZPreDistUpgradeCacheN)r5   r3   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 ]J}|| krX| | jsx| | jrX| j|d| D ]}||d||f  qqXq$| j	s| j
d	 d
S )z- run after the upgrade was done in the cache ZInstallZUpgradeZRemoveZPurger+   zPostUpgrade%szDistro PostUpgrade%s rulez%s PostUpgrade%s ruleZPostDistUpgradeCacheN)rN   r   r   r   r6   r7   r8   rL   r   r5   r3   r   )r!   ZruleactionrP   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k
rT } zt d|  W Y dS d}~X Y nX z|dd}|jD ]&}|| krh| | jrh| 	|d	  qqht 
d
 W dS | }t d|  || krt d|  W dS | | js
| | js
| |   t 
d|  W dS W n2 tk
r> } zt d|  W 5 d}~X Y nX dS )zR
        this checks for nvidia hardware and checks what driver is needed
        znvidiaUpdate()r   )NvidiaDetectionz%NvidiaDetector can not be imported %sFNz./ubuntu-drivers-obsolete.pkgs)Z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   ZNvidiaDetector.nvidiadetectorr   ImportErrorSyntaxErrorr   ZoldPackagesrL   r   r   ZselectDriverr   r   r   rN   	Exception)r!   r   rI   ZnvZ	oldDriverZdriverr   r   r   checkForNvidia  s4    




 zMyCache.checkForNvidiac                 C   s&   | D ]}|j dr|jr dS qdS )Nzlinux-headers-TF)rW   
startswithrL   rO   r   r   r   _has_kernel_headers_installed/  s    z%MyCache._has_kernel_headers_installedc              
   C   s   t d| j  z| jd\}}}W n6 tk
r\ } zt d|  W Y dS d}~X Y nX tdgtd d }d	|krt 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?)FNdmesg)r.   r   s   WARNING: NR_CPUS limitzUP kernel on SMP system!?!T)	r   r   r   splitr   r   r   r   rC   )r!   versionZbuildZflavourrI   r   r   r   r   checkForKernel6  s    
zMyCache.checkForKernelc                 C   s   d}| j dd}| D ]}|jj|j}|rJ|jdkrJtd|j	  q|j
r|j
jr|js|js|j	|krd|j	kr|j
j|kr| |j	d|  qd S )N)Zrequiredr+   RemoveEssentialOkr   zPackage %s has no priority set:z;priority in required set '%s' but not scheduled for install)r6   r7   _pcacher   r   rM   Zpriorityr   r   rW   rR   rS   rL   r   rN   )r!   needremoveEssentialOkrP   r   r   r   r   checkPriorityF  s&    
zMyCache.checkPriorityc                 C   sT   d}|  r<|d dkr |  |  td |d7 }q|jdd |  d S )Nr      g{Gz?r   T)Zfinished)lockedZpulseProgressprocessEventstimesleep)r!   r2   r4   ir   r   r   	updateGUI[  s    

zMyCache.updateGUIc              
   C   sn  t  }|  t j| j| j|fd}|  zz| 	  | 
d |   |   t rhtd n|   |   |   | | |s| | |   | jrttdddd | D  W n tk
r } ztd}| jd	d
dkr|td7 }n4| jd	d
dkr:| jd	ddkr:|td7 }|rN|td7 }n|td7 }|td7 }|   |td| t|}td| |   W Y W dS d }~X Y nX W 5 |  |  X g }	g }
|  D ]}|j rq|j!rl|
"|j# |j$j%D ]^}t&'|j(|j)j*dk r|j+D ]8\}}|j,j-.|}|r*|j/s*|	"|j#  qq*qq|j0j1}d}|D ]}||j2O }q||s|	"|j# qz(| j3dd}|rtd W dS W n t4j5k
r   Y nX t6|
dkr|
7  tdd|
  t6|	dkrj|	7  tdd|	  |   |tdtdd|	 |   dS dS ) N)targetrz   Tz5skipping kernel checks because we run inside a chrootz!Broken packages after upgrade: %srZ   c                 s   s    | ]}|j s|jr|jV  qd S r   )Zis_inst_brokenZis_now_brokenrW   ).0pr   r   r   	<genexpr>  s       z&MyCache.distUpgrade.<locals>.<genexpr>zBAn unresolvable problem occurred while calculating the upgrade.

 r   Z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.

FalseZ
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   r+   Z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	threadingZLockacquireZThreadr   r2   startreleaser\   r   Zupgrader   r   r   r   r   r   r   r   _keepBaseMetaPkgsInstalled_installMetaPkgs_verifyChangesr   r=   r   r6   rF   rx   r   r>   rv   r   r   Zmarked_downgrader   rW   rM   version_listr:   Zversion_compareZver_str	installedr   	file_listr   r   Z
find_indexZ
is_trustedrR   originstrusted
getbooleanconfigparserNoOptionErrorr[   sort)r!   r2   Z
serverModer5   r4   trI   ZdetailsZ	error_msgZ	untrustedZ	downgraderP   r   ZverFileIterindexZ	indexfiler   r   originbr   r   r   distUpgradef  s    


$ 
 


zMyCache.distUpgradec                 C   s  t jd}| jdd}|  D ]}|jrX| |jrXt	d|j t
td|j |jr"|jjdkr"|jj|dfkr"|j|kr"t	d|j t
td	|j q"| jdd
}|D ]Z}|d\}}|| kr| | jr| | jj|kr| | js| | jrt
td| qdS )zx this function tests if the current changes don't violate
            our constrains (blacklisted removals etc)
        zAPT::Architecturer+   r   zHThe package '%s' is marked for removal but it's in the removal blacklistzJThe package '%s' is marked for removal but it is in the removal blacklist.TallzDThe package '%s' is marked for removal but it's an ESSENTIAL packagez1The essential package '%s' is marked for removal.ZBadVersionsr   z*Trying to install blacklisted version '%s')r:   r6   r   r7   r   r   _inRemovalBlacklistrW   r   r   r=   r   rM   Z	essentialr   Zarchitecturer   rR   r   r   r   )r!   Z	main_archr   rP   ZbadVersionsZbvr   r   r   r   r   r     s6    
zMyCache._verifyChangesc                 C   sn   |j j|j}|dkr(td|j dS |jdkrHt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   rM   printrW   r   popr   lookup)r!   rP   r   r   r   r   r   r   _lookupPkgRecord  s    
zMyCache._lookupPkgRecordc           	      C   s   i }t  }| D ]}| |s.td|j  q|jjjdD ]T}|	dr>|t
dd  dD ].}| }||krt  ||< || |j qbq>q|D ]P}d}| jdd}||krd}|| D ]}| | jsd} qq|r|| q|S )	Nz&no PkgRecord found for '%s', skipping r   Task:,Tr+   ZIgnoredTasksF)rH   r   r   r   rW   r   r   recordr   r   r[   rD   rV   r6   r7   rL   )	r!   tasksZinstalled_tasksrP   linetaskr   Zignored_tasksr   r   r   r   installedTasks)  s2    



zMyCache.installedTasksc                 C   s   t d | D ]}|js|jr q| | t|jjdrB|jjjsTt 	d|j
  q|jjjdD ]B}|drd|tdd  dD ]}| }||kr|  qqdqdS )Nzrunning installTasksr   zcan not find Record for '%s'r   r   r   T)r   r   r   rL   r   rq   r   r   r   r   rW   r   r   r[   rD   rN   )r!   r   rP   r   r   r   r   r   installTasksE  s    


zMyCache.installTasksc                 C   s$   | j ddD ]}| |d qd S )Nr+   BaseMetaPkgsz%base meta package keep installed rule)r6   r7   r   )r!   r2   rP   r   r   r   r   V  s    z"MyCache._keepBaseMetaPkgsInstalledc                    s   fdd}j dd j ddD ]}|   q* D ]t}z:|kr|| jr|| jr|td|  |   W q@ tk
r } zt	d||f  W 5 d }~X Y q@X q@| std    D ]}d	}j |d
D ]}||ko| jM }q|rtd|  z|   W nZ tt
fk
r~ } z6td||f  |td| td W Y  dS d }~X Y nX td|| jf   qq| sd dd }|tdtd| d f  dS d	S )Nc                     sV    D ]L} | kr|  }|j r4|jr4td|j  |j r@|jrJ|  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)rL   r   r   r   rW   r   )r   rP   r8   r!   r   r   metaPkgInstalled\  s    z2MyCache._installMetaPkgs.<locals>.metaPkgInstalledr+   r,   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'rZ   r   r-   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.)r6   r7   rN   rL   Zis_upgradabler   r   r   r=   r   KeyErrorr   r   r   r\   )r!   r2   r   rP   r   rI   r   Z	meta_pkgsr   r   r   r   Z  sX    &

	zMyCache._installMetaPkgsc                 C   s8   | j D ],}t||rtd||f   dS qdS )Nz blacklist expr '%s' matches '%s'TF)rA   recompilematchr   r   )r!   r   exprr   r   r   r     s
    
zMyCache._inRemovalBlacklistc           
   
   C   s  | | jrtd|  dS || jkr:td|  dS | |rVtd|  dS | jddD ]:}|| krd| | jrd| | jj	|krdtd|   dS qd|| krdS z| j
dd	}W n tjk
r   d}Y nX t| j}| |   z| | j|d
 | j  ||krW dS |  D ]^}|j|ks^|j|ks^| |js^|j| jkr&td||jf  |    W dS q&W nN ttfk
r }	 z*td|t|	|	f  |   W Y dS d }	~	X Y nX dS )Nz skipping running kernel pkg '%s'Fz skipping kernel metapackage '%s'z#skipping '%s' (in removalBlacklist)r+   r   z'skipping '%s' (in KeepInstalledSection)TZPurgeObsoletes)purgez8package '%s' produces an unwanted removal '%s', skippingz3_tryMarkObsoleteForRemoval failed for '%s' (%s: %s))endswithr   r   r   rB   r   r6   r7   r   r   r   r   r   r:   r   r   r   r   r2   r   r   rW   r   r=   r  r   repr)
r!   r   Zremove_candidatesZforced_obsoletesforeign_pkgsr   r  r   rP   rI   r   r   r   tryMarkObsoleteForRemoval  sZ    






z!MyCache.tryMarkObsoleteForRemovalc                 C   s0   t  }| D ] }|jr
| |s
||j q
|S z1 get all package names that are not downloadable )rH   rL   anyVersionDownloadablerV   rW   )r!   Zobsolete_pkgsrP   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)rM   r   rS   )r!   rP   r   r   r   r   r    s    zMyCache.anyVersionDownloadablec                 C   s4   t  }| D ]$}|jr
| j|jr
||j q
|S r  )rH   rL   r   r   rM   rV   rW   )r!   Zunused_dependenciesrP   r   r   r   _getUnusedDependencies  s
    zMyCache._getUnusedDependenciesc              	   C   s   t  }| jdd}tj|rVt|(}|D ]}|ds.||	  q.W 5 Q R X t  }|D ]<}|| krnq`| | }|j
r`| j|js`|jrq`|| q`t|S )z return list of installed and demoted packages

            If a demoted package is a automatic install it will be skipped
        r+   Z	Demotions#)rH   r6   rF   r   r   re   rg   r   rV   rD   rL   r   Zis_auto_installedrM   r   r^   )r!   Z	demotionsZdemotions_fileZdemotions_fr   Zinstalled_demotionsZdemoted_pkgnamerP   r   r   r   get_installed_demoted_packages  s(    

z&MyCache.get_installed_demoted_packagesc                 C   s~   t  }| D ]n}|jr
| |r
|js&q
d}|jjD ]4}||jkrN|j|krNd}||jkr2|j|kr2d}q2|r
||j q
|S )zm get all packages that are installed from a foreign repo
            (and are actually downloadable)
        TF)	rH   rL   rS   rR   r   archiver   rV   rW   )r!   Zallowed_originZfromDistZtoDistr	  rP   Zforeignr   r   r   r   _getForeignPkgs  s$    

zMyCache._getForeignPkgsFc                    sh  G dd dt } fdd}g  i }i }tdx}|D ]l}z| \}}	}
}}}W n< tk
r } ztd||f  W Y q6W 5 d}~X Y nX |	 kr6 |	 q6W 5 Q R X  jtdd	 t	j
d
}d}t| dr| j
dddr| j
dd}tj|st| td|  dddd||ddfD ]}tj|}||}tj|rpt|}|j|j }ntd|  d}||krtd||| f  |||  ||< n&td||f  |||< ||||< q2~td|  d}| D ]B}td|jr|js|jrtd|jtf  |d7 }q|t |d t  }d}t| dr| j
dddrtd  | j
dd}| D ]"}|js|jr||jj 7 }qd}|r| D ]*}|j!r|js|j"r||j#j 7 }qtd!|  || j$fd| j%fd| j&fd"d|fd#d$||fd|ff	D ]h\}}|dk rBq,tj|}td%|||| || j'f  ||  j'|8  _'||  j(|7  _(q,i }|D ]}|| j'dk rt	)t*t+|| j'd }t,|t-r|.t/0 }t	)|| j(}t,|t-r|.t/0 }t1|||||||< qt|dkrdt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                   @   s   e Zd ZdZdd ZdS )z)MyCache.checkFreeSpace.<locals>.FreeSpacez@ helper class that represents the free space on each mounted fs c                 S   s   || _ d| _d S ry   )freer   )r!   Z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   )dZmount_pointZmountedr   r   
make_fs_idB  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/r6   ZAufsZEnabledFZ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   )r>   )r   r   r   r   r   
<listcomp>  s     z*MyCache.checkFreeSpace.<locals>.<listcomp>)6objectrg   r   
ValueErrorr   r   r   r   r[   r:   r6   r   rq   rd   rF   r   r   re   rf   realpathstatvfsf_bavailf_frsizer   r  r  rW   r   r   KERNEL_SIZEINITRD_SIZErR   Zinstalled_sizerL   r   r   r   r   r   r  r   Zsize_to_strfloatabs
isinstancebytesdecodelocalegetpreferredencodingr   r   r&   r^   values)r!   Zsnapshots_in_user  r  Zmnt_mapZfs_freeZmountsr   ZwhatwhereZfsZoptionsar   rI   Z
archivedirZaufs_rw_dirr  Zfs_idstr  Zkernel_countrP   Zspace_in_bootZrequired_for_aufsZrequired_for_snapshotsr   sizeZrequired_listZfree_at_leastZfree_neededr   r  r   checkFreeSpace3  s    	







 zMyCache.checkFreeSpace)NT)N)T)T)T)r   )r   )r   )r   )F)<r
   r   r   rT   rU   r"   rQ   propertyrY   rc   rE   rv   rx   r   r   r   r   r   r<   r   r   r   r]   r`   rS   r   r   r   r   r   r   r   rN   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
  r  r  r  r  r  r0  r   r   r   r   r)   q   s   
'	













	

#*
 
L
9r)   __main__)DistUpgradeConfig)DistUpgradeViewZfoo.zubuntu-desktop)/r?   r:   r   r)  r   r  r   r   rl   r   r   
subprocessr   r   ZDistUpgradeGettextr   r   r   Zutilsr   r   r   r   r   r   r"  r#  r  r   r&   r@   r)   r
   sysZDistUpgradeConfigParserr3  r4  r   cr0  exitr   r   r   r   r   r   r   r   r   r   <module>   sX   !
	        k
