3
g
]0                 @   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&j'  e!j(  e&j)  e&j*  e&j+ e&j,dg e%e&j-  e&j.  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 )CacheExceptionLockingFailedN)r	   r
   r   r   r   r   r   r   ,   s   r   c               @   s   e Zd ZdS )CacheExceptionDpkgInterruptedN)r	   r
   r   r   r   r   r   r   0   s   r   c              C   s   d} d}t j d }xrtjd| D ]`}|d| krF|t jj|7 }q$|jddks$|jddks$|jddkrtq$q$| t jj|7 } q$W | dkrtjd d} |dkrtj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?-   r   g?i p  i  i   i  i   i   i   i   )osunameglobpathgetsizefindloggingwarning)ZkernelZinitrdZkverfZinitrd_bufferr   r   r   #estimate_kernel_initrd_size_in_boot4   s0    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 )N)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dqd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dd Zdd Zdrdd Zd!d" Zdsd#d$Zdtd%d&Zdud'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zdvd8d9Zdwd:d;Z dxd<d=Z!dyd>d?Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+edRdS Z,dTdU Z-dVdW Z.edXdY Z/dZd[ Z0d\d] Z1d^d_ Z2d`da Z3edbdc Z4ddde Z5dfdg Z6dhdi Z7djdk Z8dldm Z9dzdodpZ:dS ){MyCacher      NTc             C   s  g | _ g | _|| _|| _d| _d| _|| _| jjdd| _d| _	|ryt
j  | j  d| _W n> tk
r } z"dt|krt|t|W Y d d }~X nX tjj| | |jdd| _tdd	gtdd
j d j | _| j  |jdddkodtjkrt
jjdd t
jjdd d S )NFDistroMetaPkgsr   Tz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_blacklistr   r   communicatestripr   _initAptLoggetr   environset)r!   r4   r0   r1   Zprogressr2   er   r   r   r"   v   s6    

zMyCache.__init__c             C   s6   x0| D ](}|j rq|jjtjkr|jddd qW dS )z! honor the dselect install state F)	auto_instauto_fixN)is_installed_pkgZselected_stater8   ZSELSTATE_INSTALLmark_install)r!   pkgr   r   r   _apply_dselect_upgrade   s
    
zMyCache._apply_dselect_upgradec             C   sR   t  }xF| D ]>}|j s"|jj r|jj| jks>|jj| jkr|j|j qW |S )zB return the packages not downloadable packages in reqreinst state )	rE   	candidatedownloadablerJ   Z
inst_state	ReInstReqHoldReInstReqaddname)r!   	reqreinstrL   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j| }|j||r|| j  ddd	gt| }|j j| | j	  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, z/usr/bin/dpkgz--removez--force-remove-reinstreqTF)
rU   lenr   joinZaskYesNoQuestionrelease_locklistZgetTerminalcallget_lock)r!   r0   rT   headerZsummarycmdr   r   r   fix_req_reinst   s    
zMyCache.fix_req_reinstc             C   s   | j jddd}tjj|s&tj| tj jd| tj jdd tjtjj	|dtj
tjB tjB d| _tjj }d	| }tj| j|jd
 tj jdd tj jdd tj 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)r4   getWithDefaultr   r   existsmakedirsr8   rE   openrW   O_RDWRO_CREATO_APPENDlogfddatetimenowwriteencode)r!   Zlogdirrh   r\   r   r   r   rB      s    


zMyCache._initAptLogc             C   sZ   t | dr"tj| j tj| j tjd| _tjd| _tj| jd tj| jd d S )N
old_stdoutr   r   )hasattrr   closerk   
old_stderrdupdup2rf   )r!   r   r   r   _startAptResolverLog   s    
zMyCache._startAptResolverLogc             C   s4   t jd t jd t j| jd t j| jd d S )Nr   r   )r   fsyncrp   rk   rn   )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 j    | |}| d j  |S )Nr   )rq   rs   )argskwargsres)r   r   r   wrapper   s    
z(MyCache.withResolverLog.<locals>.wrapperr   )r   rw   r   )r   r   withResolverLog   s    zMyCache.withResolverLogc             C   s,   t j| j}t j }|j|| j| j |jS )z< get the size of the packages that are required to download )r8   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 )ry   Zusr_size)r!   r   r   r   additional_required_space   s    z!MyCache.additional_required_spacec             C   s   | j jdkS )z is the cache broken r   )ry   Zbroken_count)r!   r   r   r   	is_broken  s    zMyCache.is_brokenc             C   s:   t jjdd }t j|| _| jdk r6d| }t|d S )NzDir::State::Listsr2   r   zCan not lock '%s' )r8   r4   find_dirr[   r7   r   )r!   rS   rF   r   r   r   r:     s
    
zMyCache.lock_lists_dirc             C   s    | j dkrtj| j  d| _ d S )Nr   r   r-   )r7   r   rm   )r!   r   r   r   unlock_lists_dir  s    
zMyCache.unlock_lists_dirc             C   sH   | j   tjj| |}| 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!   	fprogressrv   r   r   r   r     s    
zMyCache.updatec             C   s,   t jd | jr| j  tjj| || d S )Nzcache.commit())r   infor2   rX   r=   r>   commit)r!   r   Z	iprogressr   r   r   r   !  s    
zMyCache.commitc             C   sN   | j rJytj  d| _ W n0 tk
rH } ztjd|  W Y d d }~X nX d S )NFzfailed to SystemUnLock() (%s) )r2   r8   Zpkgsystem_unlockr;   r   debug)r!   pkgSystemOnlyrF   r   r   r   rX   '  s    
zMyCache.release_lockc             C   sN   | j sJytj  d| _ W n0 tk
rH } ztjd|  W Y d d }~X nX d S )NTzfailed to SystemLock() (%s) )r2   r8   r9   r;   r   r   )r!   r   rF   r   r   r   r[   /  s    
zMyCache.get_lockc             C   sB   |r| j j|j}n|jj}|dkr<tjd|j|f  dS |jS )z* check if the given pkg can be downloaded Nz1no version information for '%s' (useCandidate=%s)F)ry   get_candidate_verrJ   Zcurrent_verr   r   rS   rO   )r!   rL   ZuseCandidateverr   r   r   rO   7  s    zMyCache.downloadablec             C   s   |j o| jj|jS )z$ check if the pkg is auto-removable )rI   ry   
is_garbagerJ   )r!   rL   r   r   r   pkg_auto_removableB  s    zMyCache.pkg_auto_removablec             C   s
   | j j S )z^ try to fix broken dependencies on the system, may throw
            SystemError when it can't)ry   
fix_broken)r!   r   r   r   r   G  s    zMyCache.fix_brokenc             C   sP   g | _ g | _x>| j D ]2}|js&|jr4| j j|j |jr| jj|j qW dS )z* create a snapshot of the current changes N)r.   r/   get_changesmarked_installmarked_upgradeappendrS   marked_delete)r!   rL   r   r   r   create_snapshotL  s    zMyCache.create_snapshotc             C   s   | j j  d S )N)ry   Zinit)r!   r   r   r   clearV  s    zMyCache.clearc             C   sb   t j| j}| | j  x| jD ]}| | }|j  q W x$| jD ]}| | }|jddd q@W dS )z restore a snapshot F)rH   rG   N)r8   ActionGroupry   r   r/   mark_deleter.   rK   )r!   actiongrouprS   rL   r   r   r   restore_snapshotY  s    zMyCache.restore_snapshotc             C   s   | j jdd}xx|D ]p}|| kr<| | jr<tjd|  dS d}x,| j j|dD ]}||| kof| | jM }qPW |rtjd|  dS qW tj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)r4   r5   rI   r   r   )r!   r6   key
deps_foundrL   r   r   r   need_server_modeg  s    

zMyCache.need_server_modec             C   sJ   | j rFytjd | j  W n( tk
rD   |jtdtd 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!   r0   r   r   r   sanity_check  s    


zMyCache.sanity_check c             C   sP   t jd||f  || krL| | j  | | jp8| | jsLt jd|  dS dS )NzInstalling '%s' (%s)z Installing/upgrading '%s' failedFT)r   r   rK   r   r   r   )r!   rL   reasonr   r   r   rK     s    zMyCache.mark_installc             C   sP   t jd||f  || krL| | jrL| | j  | | jsLt jd|  dS dS )NzUpgrading '%s' (%s)zUpgrading '%s' failedFT)r   r   rI   mark_upgrader   r   )r!   rL   r   r   r   r   r     s    
zMyCache.mark_upgradec             C   s*   t jd||f  || kr&| | j  d S )NzRemoving '%s' (%s))r   r   r   )r!   rL   r   r   r   r   mark_remove  s    zMyCache.mark_removec             C   s2   t jd||f  || kr.| jj| | jd d S )NzPurging '%s' (%s)T)r   r   ry   r   rJ   )r!   rL   r   r   r   r   
mark_purge  s    zMyCache.mark_purgec             C   s,   || kr(| | j r(| | jr(| j|| d S )N)rI   r   rK   )r!   pkgnamer   r   r   r   _keep_installed  s    

zMyCache._keep_installedc             C   s  x"| j jddD ]}| j|d qW xR| jD ]H}|| kr,| | jsL| | jr,x&| j j|dD ]}| j|d|  q\W q,W | j jdddkrtjd xT| j jdd	D ]B}x<| D ]4}|j	r|j	j
r|jr|j|kr| j|jd
|  qW qW x| jD ]}|| kr| | js| | jrxd| j j|d	D ]R}xJ| D ]B}|j	r0|j	j
r0|jr0|j|kr0| j|jd||f  q0W q&W qW d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)r4   r5   r   r6   rI   r   rC   r   r   rN   rO   r   sectionrS   )r!   r   r   r   rL   r   r   r   keep_installed_rule  s.    




zMyCache.keep_installed_rulec             C   s   xd| j fd| jfd| jfd| jfgD ]\}}x(| jjdd| D ]}||d|  qBW xX| jD ]N}|| kr`| | js| | jr`x,| jj|d| D ]}||d||f  qW q`W q&W | j	s| j
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)rK   r   r   r   r4   r5   r6   rI   r   r3   r1   Zrun)r!   ZruleactionrL   r   r   r   r   post_upgrade_rule  s    

zMyCache.post_upgrade_rulec       	      C   s   t jd t }| jjdd}| jjdd}| jjdd}x| D ]}x|D ]~}d||f }xl|D ]d}|jj|r`|jj|r`|j	r`|jd|| j
f krt jd|j  q`t jd	|j  |j|j q`W qJW q@W t jd
|  |S )NzidentifyObsoleteKernels()ZKernelRemovalZVersionZ	BaseNamesZTypesz%s-%s-z%s-%szskipping running kernel %szremoving obsolete kernel '%s'z"identifyObsoleteKernels found '%s')r   r   rE   r4   rC   r5   rS   
startswithendswithrI   r   rR   )	r!   Zobsolete_kernelsversionZ	basenamestypesrL   basebasenametyper   r   r   identifyObsoleteKernels  s&    



zMyCache.identifyObsoleteKernelsc             C   s6  t jd yddlm} W n2 ttfk
rL } zt jd|  dS d}~X nX y|dd}x<|jD ]$}|| krb| | jrb| j	|d	 P qbW t j
d
 dS |j }t jd|  || krt jd|  dS | | jp| | j s| | j  t j
d|  dS W n2 tk
r0 } zt jd|  W Y dd}~X 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oldPackagesrI   r   r   ZselectDriverr   r   r   rK   	Exception)r!   r   rF   ZnvZ	oldDriverZdriverr   r   r   checkForNvidia  s4    


 zMyCache.checkForNvidiac             C   s(   x"| D ]}|j jdr|jrdS qW dS )Nzlinux-headers-TF)rS   r   rI   )r!   rL   r   r   r   _has_kernel_headers_installed7  s
    
z%MyCache._has_kernel_headers_installedc             C   s   t jd| j  y| jjd\}}}W n. tk
rT } zt jd|  dS d}~X nX tdgtdj d }d	|kr~t j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   r@   )r!   r   ZbuildZflavourrF   r   r   r   r   checkForKernel>  s    
zMyCache.checkForKernelc             C   s   d}| j jdd}x| D ]}|jjj|j}|rL|jdkrLtjd|j	  q|j
r|j
jr|jpd|j r|j	|krd|j	kr|j
j|kr| j|j	d|  qW d S )	Nrequiredr)   RemoveEssentialOkr   zPackage %s has no priority set:z;priority in required set '%s' but not scheduled for install)r   )r4   r5   _pcachery   r   rJ   Zpriorityr   r   rS   rN   rO   rI   r   rK   )r!   needremoveEssentialOkrL   r   r   r   r   checkPriorityN  s    


zMyCache.checkPriorityc             C   sX   d}x:|j  r>|d dkr"|j  |j  tjd |d7 }qW |jdd |j  d S )Nr      g{Gz?r   T)Zfinished)lockedZpulseProgressprocessEventstimeZsleep)r!   r0   r2   ir   r   r   	updateGUIc  s    

zMyCache.updateGUIc          !   C   sR  t j }|j  t j| j| j|fd}|j  yh| jd | j  | j	  t
 r\tjd n| j  | j  | j  | j| |s| j| | j  W n tk
r } z|j  |j  td}| jjdddkr|td7 }n4| jjddd	kr| jjdd
dkr|td7 }|r*|td7 }n|td7 }|td7 }| j  |jtd| t|}tjd| | j  dS d }~X nX |j  |j  g }	g }
x| j D ]}|jrq|jr>|
j |j! xl|j"j#D ]`}t$j%|j&|j'j(dk rx@|j)D ]6\}}|j*j+j,|}|r|j- r|	j |j! P qW qW q|j.j/}d}x|D ]}||j0O }qPW |s|	j |j! qW y&| jj1dd}|rtjd dS W n& t2j3k
r } zW Y d d }~X nX t4|
dkr|
j5  tjddj|
  t4|	dkrN|	j5  tjddj|	  | j  |jtdtddj|	 | j  dS dS )N)targetrt   Tz5skipping kernel checks because we run inside a chrootzBAn 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.zIf 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.
)6	threadingZLockacquireZThreadr   r0   startZupgrader   r   r   r   r   r   r   r   _keepBaseMetaPkgsInstalled_installMetaPkgs_verifyChangesr;   releaserW   r   r4   rC   rs   r   r<   rq   r   r   Zmarked_downgrader   rS   rJ   version_listr8   Zversion_compareZver_str	installedr   	file_listr   rz   Z
find_indexZ
is_trustedrN   originstrusted
getbooleanconfigparserNoOptionErrorrV   sort)r!   r0   Z
serverModer3   r2   trF   ZdetailsZ	error_msgZ	untrustedZ	downgraderL   r   ZverFileIterindexZ	indexfiler   r   originbr   r   r   distUpgraden  s    





zMyCache.distUpgradec             C   s   t jjd}| jjdd}x| j D ]}|jrZ| j|jrZtj	d|j t
td|j |jr$|jjdkr$|jj|dfkr$|j|kr$tj	d|j t
td	|j q$W | jjdd
}xb|D ]Z}|jd\}}|| kr| | jr| | jj|kr| | js| | jrt
td| qW d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')r8   r4   r   r5   r   r   _inRemovalBlacklistrS   r   r   r;   r   rJ   Z	essentialr   Zarchitecturer   rN   r   r   r   )r!   Z	main_archr   rL   ZbadVersionsZbvr   r   r   r   r   r     s*    


zMyCache._verifyChangesc             C   sn   |j jj|j}|dkr(td|j dS |jdkrHtd| jj   dS |jjd\}}|j 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   ry   r   rJ   printrS   r   popr{   lookup)r!   rL   r   r   r   r   r   r   _lookupPkgRecord  s    
zMyCache._lookupPkgRecordc             C   s   i }t  }x| D ]}| j|s0tjd|j  qxl|jjjjdD ]X}|j	drBxH|t
dd  jdD ].}|j }||krt  ||< || j|j qhW qBW qW x@|D ]8}d}x || D ]}| | jsd}P qW |r|j| qW |S )Nz&no PkgRecord found for '%s', skipping r   zTask:,TF)rE   r   r   r   rS   r   r{   recordr   r   rV   rA   rR   rI   )r!   tasksZinstalled_tasksrL   linetaskr   r   r   r   r   installedTasks1  s,    





zMyCache.installedTasksc             C   s   t jd x| D ]}|js|jr"q| j| t|jjdoB|jjjsVt j	d|j
  qxZ|jjjjdD ]F}|jdrhx6|tdd  jdD ]}|j }||kr|j  qW qhW qW dS )Nzrunning installTasksr   zcan not find Record for '%s'r   zTask:r   T)r   r   r   rI   r   rl   r   r{   r   r   rS   r   r   rV   rA   rK   )r!   r   rL   r   r   r   r   r   installTasksJ  s    



zMyCache.installTasksc             C   s(   x"| j jddD ]}| j|d qW d S )Nr)   BaseMetaPkgsz%base meta package keep installed rule)r4   r5   r   )r!   r0   rL   r   r   r   r   [  s    z"MyCache._keepBaseMetaPkgsInstalledc                s   fdd}j jdd x"j jddD ]}| j  q,W x| D ]t}y:|kr| jr| jrtjd|  | j  W qF tk
r } ztj	d||f  W Y d d }~X qFX qFW | stjd   xΈ D ]}d	}x.j j|d
D ]}||ko
| jM }qW |rtjd|  y| j  W nP tt
fk
r } z.tjd||f  |jtd| td dS d }~X nX tjd|| jf  P qW | sdj dd }|jtdtd| d f  dS d	S )Nc                 sZ   xT D ]L} | kr|  }|j r6|jr6tjd|j  |j rD|j sN|  jrdS qW 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)rI   r   r   r   rS   r   )r   rL   )r6   r!   r   r   metaPkgInstalleda  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'z, 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.r-   r-   )r4   r5   rK   rI   Zis_upgradabler   r   r   r;   r   KeyErrorr   r   r   rW   )r!   r0   r   rL   r   rF   r   Z	meta_pkgsr   )r6   r!   r   r   _  sL    


(


zMyCache._installMetaPkgsc             C   s:   x4| j D ]*}tj|j|rtjd||f  dS qW dS )Nz blacklist expr '%s' matches '%s'TF)r?   recompilematchr   r   )r!   r   exprr   r   r   r     s
    zMyCache._inRemovalBlacklistc       	      C   s  |j | jrtjd|  dS | j|r:tjd|  dS x>| jjddD ],}|| krJ| | j|krJtjd|  dS qJW || krdS y| jjdd}W n( t	j
k
r } z
d}W Y d d }~X nX tj| j}| | j  yr| | j|d	 | jj  xR| j D ]F}|j|ks*|j|ks*| j|jr tjd
|  | j  dS q W W nF ttfk
r } z$tjd|t||f  | j  dS d }~X nX dS )Nz skipping running kernel pkg '%s'Fz#skipping '%s' (in removalBlacklist)r)   r   z'skipping '%s' (in KeepInstalledSection)TZPurgeObsoletes)purgez,package '%s' has unwanted removals, skippingz3_tryMarkObsoleteForRemoval failed for '%s' (%s: %s))r   r   r   r   r   r4   r5   r   r   r   r   r8   r   ry   r   r   r0   r   r   rS   r   r;   r   r   repr)	r!   r   Zremove_candidatesforeign_pkgsr   r   rF   r   rL   r   r   r   tryMarkObsoleteForRemoval  sD    

z!MyCache.tryMarkObsoleteForRemovalc             C   s4   t  }x(| D ] }|jr| j|s|j|j qW |S )z1 get all package names that are not downloadable )rE   rI   anyVersionDownloadablerR   rS   )r!   Zobsolete_pkgsrL   r   r   r   _getObsoletesPkgs  s    

zMyCache._getObsoletesPkgsc             C   s    x|j jD ]}|jr
dS q
W dS )zA helper that checks if any of the version of pkg is downloadable TF)rJ   r   rO   )r!   rL   r   r   r   r   r     s    zMyCache.anyVersionDownloadablec             C   s8   t  }x,| D ]$}|jr| jj|jr|j|j qW |S )z1 get all package names that are not downloadable )rE   rI   ry   r   rJ   rR   rS   )r!   Zunused_dependenciesrL   r   r   r   _getUnusedDependencies  s
    
zMyCache._getUnusedDependenciesc          
   C   s   t  }| jjdd}tjj|rZt|,}x$|D ]}|jds0|j|j	  q0W W dQ R X t  }xF|D ]>}|| krtqf| | }|j
 sf| jj|jsf|jrqf|j| qfW 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#N)rE   r4   rC   r   r   r`   rb   r   rR   rA   rI   ry   Zis_auto_installedrJ   r   rY   )r!   Z	demotionsZdemotions_fileZdemotions_fr   Zinstalled_demotionsZdemoted_pkgnamerL   r   r   r   get_installed_demoted_packages  s$    



z&MyCache.get_installed_demoted_packagesc             C   s   t  }xz| D ]r}|jr| j|r|js(qd}x@|jjD ]4}||jkrR|j|krRd}||jkr6|j|kr6d}q6W |r|j|j qW |S )zm get all packages that are installed from a foreign repo
            (and are actually downloadable)
        TF)	rE   rI   rO   rN   r   archiver   rR   rS   )r!   Zallowed_originZfromDistZtoDistr   rL   Zforeignr   r   r   r   _getForeignPkgs  s     




zMyCache._getForeignPkgsFc                st  G dd dt } fdd}g  i }i }tdv}xn|D ]f}y|j \}}	}
}}}W n6 tk
r } ztjd||f  w8W Y dd}~X nX |	 kr8 j|	 q8W W dQ R X  jtdd	 t	j
jd
}d}t| do| j
jdddr| j
jdd}tjj|stj| tjd|  xdddd||ddgD ]}tjj|}||}tjj|rntj|}|j|j }ntjd|  d}||krtjd||| f  |||  ||< n&tjd||f  |||< ||||< q0W ~tjd|  d}xJ| D ]B}tjd|jr|js|jrtjd|jtf  |d7 }qW |t |d t  }d}t| dr| j
jdddrtjd  | j
jdd}x*| D ]"}|js|jr||jj 7 }qW d}|rx2| D ]*}|j!r|js|j"r||j#j 7 }qW tjd!|  x|| j$fd| j%fd-d|fd0d3||fd|fgD ]h\}}|dk rHq2tjj|}tjd'|||| || j&f  ||  j&|8  _&||  j'|7  _'q2W i }x|D ]}|| j&dk rt	j(t)t*|| j&d }t+|t,r|j-t.j/ }t	j(|| j'}t+|t,r|j-t.j/ }t0|||||||< qW t|dkrptj1d(d)d* |D   t2t3|j4 dS )4z
        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 )Nr   )freer   )r!   ZinitialFreer   r   r   r"   <  s    z2MyCache.checkFreeSpace.<locals>.FreeSpace.__init__N)r	   r
   r   r$   r"   r   r   r   r   	FreeSpace:  s   r  c                s    x D ]}| j |r|S qW 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)mountedr   r   
make_fs_id@  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/r4   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: %s2   i   /tmp   
   z dir '%s' needs '%s' of '%s' (%f)zNot enough free space: %sc             S   s   g | ]}t |qS r   )r<   ).0r   r   r   r   
<listcomp>  s    z*MyCache.checkFreeSpace.<locals>.<listcomp>i      )r  r  i     P )r  r  i (     )r  r  )5objectrb   r   
ValueErrorr   r   r   r   rV   r8   r4   r   rl   r_   rC   r   r   r`   ra   realpathstatvfsf_bavailf_frsizer   r   r   rS   r   r   KERNEL_SIZEINITRD_SIZErN   Zinstalled_sizerI   r   r   r|   r}   r  r   Zsize_to_strfloatabs
isinstancebytesdecodelocalegetpreferredencodingr   r   r%   rY   values)r!   Zsnapshots_in_user  r	  Zmnt_mapZfs_freeZmountsr   ZwhatwhereZfsZoptionsar   rF   Z
archivedirZaufs_rw_dirr  Zfs_idstr  Zkernel_countrL   Zspace_in_bootZrequired_for_aufsZrequired_for_snapshotsr   sizeZrequired_listZfree_at_leastZfree_neededr   )r  r   checkFreeSpace1  s    	











 


zMyCache.checkFreeSpace)NT)N)T)T)T)r   )r   )r   )r   )F);r	   r
   r   rP   rQ   r"   rM   propertyrU   r^   rB   rq   rs   rx   r|   r}   r~   r:   r   r   r   rX   r[   rO   r   r   r   r   r   r   r   rK   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  r)  r   r   r   r   r'   q   sp   
%	








	

"* L3r'   __main__)DistUpgradeConfig)DistUpgradeViewZfoo.zubuntu-desktop)/r=   r8   r   r"  r   r   r   r   rg   r   r   
subprocessr   r   ZDistUpgradeGettextr   r   r   Zutilsr   r   r   r   r   r   r  r  r  r   r%   r>   r'   r	   sysZDistUpgradeConfigParserr,  r-  r   cr)  exitr   r   r   r   r   r   r   r   r   r   <module>   sX   !
	        g
