o
    x[hó  ã                   @   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mZmZm	Z	m
Z
mZmZmZ d dlmZmZmZ d dlmZmZ d dlmZmZ e e¡ZdZg d¢ZdZd	ee d
e	e fdd„Z G dd„ deƒZ!dS )é    N)ÚAnyÚIterableÚListÚMappingÚOptionalÚSequenceÚcast)ÚhelpersÚsubpÚutil)ÚPackageManagerÚUninstalledPackages)Ú
PER_ALWAYSÚPER_INSTANCE)zapt-getz(--option=Dpkg::Options::=--force-confoldz*--option=Dpkg::options::=--force-unsafe-ioz--assume-yesz--quiet)z/var/lib/dpkg/lock-frontendz/var/lib/dpkg/lockz/var/cache/apt/archives/lockz/var/lib/apt/lists/locké   ÚcfgÚreturnc                 C   s†   | sd}dg}n|   d¡}|   d¡}t|tƒr|g}n	t|tƒs$tdƒ‚t |¡s:t|ƒ ¡ dkrA|rAt 	|d ¡rAt
tt |ƒS g S )a9  Parse the 'apt_get_wrapper' section of cloud-config.

    apt_get_wrapper may be defined in cloud-config:
      apt_get_wrapper:
        enabled: true
        command: ["eatmydata"]

    The function takes the value of "apt_get_wrapper" and returns the list
    of arguments to prefix to the apt-get command.
    ÚautoÚ	eatmydataÚenabledÚcommandz,apt_wrapper command must be a string or listr   )ÚgetÚ
isinstanceÚstrÚlistÚ	TypeErrorr   Úis_trueÚlowerr
   Úwhichr   r   )r   r   r   © r   úJ/usr/lib/python3/dist-packages/cloudinit/distros/package_management/apt.pyÚget_apt_wrapper)   s   




"r!   c                
       sÜ   e Zd ZdZddddœdejdee deee  dee f‡ fd	d
„Z	e
dejdedd fdd„ƒZdefdd„Zddœdd„Zejdd�dd„ ƒZdee fdd„Zdedefdd„Zd$dd„Zd d!„ Zefd"d#„Z‡  ZS )%ÚAptÚaptr   N©Úapt_get_wrapper_commandÚapt_get_commandÚapt_get_upgrade_subcommandÚrunnerr%   r&   r'   c                   sN   t ƒ  |¡ |d u rt| _|d u rd}t|ƒt| jƒ | _|| _ddi| _d S )Nzdist-upgradeÚDEBIAN_FRONTENDÚnoninteractive)ÚsuperÚ__init__ÚAPT_GET_COMMANDr&   ÚtupleÚapt_commandr'   Úenvironment)Úselfr(   r%   r&   r'   ©Ú	__class__r   r    r,   M   s   ÿzApt.__init__r   r   c                 C   s&   t |t| d¡ƒ| d¡| d¡d�S )NÚapt_get_wrapperr&   r'   r$   )r"   r!   r   )Úclsr(   r   r   r   r    Úfrom_configa   s   ÿúzApt.from_configc                 C   s   t t | jd ¡ƒS )Nr   )Úboolr
   r   r&   ©r1   r   r   r    Ú	availablel   s   zApt.availableF)Úforcec                C   s$   | j jd| jdg|rtntd� d S )Nzupdate-sourcesÚupdate)Úfreq)r(   ÚrunÚrun_package_commandr   r   )r1   r:   r   r   r    Úupdate_package_sourceso   s   

üzApt.update_package_sourcesé   )Úmaxsizec                 C   s   t   ddg¡j}t| ¡ ƒS )Nz	apt-cacheÚpkgnames)r
   ÚstdoutÚsetÚ
splitlines)r1   Úrespr   r   r    Úget_all_packagesw   s   zApt.get_all_packagesÚpkglistc                    s   ‡ fdd„|D ƒS )Nc                    s.   g | ]}t  d |¡d  d¡ˆ  ¡ vr|‘qS )z/|=r   z-^)ÚreÚsplitÚrstriprG   )Ú.0Úpkgr8   r   r    Ú
<listcomp>ˆ   s    ÿþz0Apt.get_unavailable_packages.<locals>.<listcomp>r   )r1   rH   r   r8   r    Úget_unavailable_packages�   s   
þzApt.get_unavailable_packagesc                    sd   |   ¡  t dt|ƒ¡}|  dd„ |D ƒ¡‰ ˆ rt dˆ ¡ ‡ fdd„|D ƒ}|r0| jd|d� ˆ S )Nú%s=%sc                 S   s   g | ]	}|  d ¡d ‘qS )ú=r   )rJ   )rL   Úxr   r   r    rN   “   s    z(Apt.install_packages.<locals>.<listcomp>zXThe following packages were not found by APT so APT will not attempt to install them: %sc                    s   g | ]}|ˆ vr|‘qS r   r   )rL   Úp©Úunavailabler   r    rN   ›   s    Úinstall)Úpkgs)r?   r   Úexpand_package_listr   rO   ÚLOGÚdebugr>   )r1   rH   Ú
to_installr   rT   r    Úinstall_packages�   s   ÿýzApt.install_packagesc                 C   s�   |d u rg }t | jƒ}|rt|tƒr| |¡ n|r$t|t ƒr$| |¡ |dkr+| j}| |¡ t d|¡}| |¡ | j	|| j
ddœd� d S )NÚupgraderP   F)ÚargsÚ
update_envÚcapture)Úsubp_kwargs)r   r/   r   r   ÚappendÚextendr'   r   rX   Ú_wait_for_apt_commandr0   )r1   r   r^   rW   Úfull_commandrH   r   r   r    r>       s$   



ý
ÿzApt.run_package_commandc              
   C   s‚   t D ]<}tj |¡sqt|dƒ�&}zt |tjtjB ¡ W n t	y.   Y W d  ƒ  dS w W d  ƒ n1 s9w   Y  qdS )ztDetermines if another process holds any apt locks.

        If all locks are clear, return True else False.
        ÚwNFT)
ÚAPT_LOCK_FILESÚosÚpathÚexistsÚopenÚfcntlÚlockfÚLOCK_EXÚLOCK_NBÚOSError)r1   ÚlockÚhandler   r   r    Ú_apt_lock_available¸   s   üÿþ€zApt._apt_lock_availablec                 C   sž   t  ¡ }t d¡ t  ¡ | |k rK|  ¡ st  d¡ q	t d¡ z	tjdi |¤ŽW S  tjyB   |  ¡ r6‚ t d¡ t  d¡ Y nw t  ¡ | |k stdƒ‚)zWWait for apt install to complete.

        subp_kwargs: kwargs to pass to subp
        zWaiting for APT lockr@   zAPT lock availablez*Another process holds APT lock. Waiting...zCould not get APT lockNr   )	ÚtimeÚ	monotonicrY   rZ   rs   Úsleepr
   ÚProcessExecutionErrorÚTimeoutError)r1   ra   ÚtimeoutÚ
start_timer   r   r    rd   È   s"   



òùzApt._wait_for_apt_command)NN)Ú__name__Ú
__module__Ú__qualname__Únamer	   ÚRunnersr   r   r   r,   Úclassmethodr   r6   r7   r9   r?   Ú	functoolsÚ	lru_cacherG   r   rO   r   r\   r>   rs   ÚAPT_LOCK_WAIT_TIMEOUTrd   Ú__classcell__r   r   r2   r    r"   J   s4    úþü
ûú


	
ÿr"   )"rl   r�   Úloggingrh   rI   rt   Útypingr   r   r   r   r   r   r   Ú	cloudinitr	   r
   r   Ú4cloudinit.distros.package_management.package_managerr   r   Úcloudinit.settingsr   r   Ú	getLoggerr{   rY   r-   rg   rƒ   Údictr   r!   r"   r   r   r   r    Ú<module>   s    $
!