U
    Ld8                     @   s   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m	Z	 d dl
mZ d dlmZ eeZdZdZd	d
dZdZdZdZddddgZG dd dejZdd Zd!ddZedfddZd"ddZd#dd ZdS )$    N)distroshelpers)log)subputil)HostnameConf)PER_INSTANCE   )zapt-getz(--option=Dpkg::Options::=--force-confoldz*--option=Dpkg::options::=--force-unsafe-ioz--assume-yesz--quietZ	eatmydataauto)commandenableda8  # This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
'/etc/network/interfaces.d/50-cloud-initz/etc/default/localez/var/lib/dpkg/lock-frontendz/var/lib/dpkg/lockz/var/cache/apt/archives/lockz/var/lib/apt/lists/lockc                       s   e Zd ZdZdddZed eded edd	dZd
d Zdd Zd/ddZ	dd Z
 fddZdd Zdd Zdd Zd0ddZdd Zd d! Zd1d"d#Zefd$d%Zd2d&d'Zd(d) Zd*d+ Zeeeed,d-d.Z  ZS )3Distroz/etc/hostnamer   z/etc/netplan/50-cloud-init.yaml)eninetplanr   )Zeni_pathZ
eni_headerr   T)Znetplan_pathZnetplan_headerZpostcmdsc                 C   s4   t j| ||| t|| _d| _d| _d | _d S )NZdebianzen_US.UTF-8)	r   r   __init__r   ZRunners_runnerZosfamilydefault_localesystem_locale)selfnameZcfgpaths r   :/usr/lib/python3/dist-packages/cloudinit/distros/debian.pyr   N   s
    zDistro.__init__c                 C   s    | j st | _ | j r| j S | jS )z9Return the default locale if set, else use default locale)r   read_system_localer   r   r   r   r   
get_localeX   s    zDistro.get_localeNLANGc           	      C   s   |st }|std|  }tj|}| jr2dnd}| | kpN| pN|}| p\|p\|}|rrt|||d nt	
d|| j| |rt|||d d| _dS )zeApply specified locale to system, regenerate if specified locale
        differs from system default.zFailed to provide locale value.FT)keynamez9System has '%s=%s' requested '%s', skipping regeneration.N)LOCALE_CONF_FN
ValueErrorr   ospathexistsr   lowerregenerate_localeLOGdebugupdate_locale_conf)	r   localeZout_fnr   Zdistro_localeZconf_fn_existsZsys_locale_unsetZ
need_regenZ	need_confr   r   r   apply_localed   s0    zDistro.apply_localec                 C   s   |    | jd|d d S )Ninstall)pkgs)update_package_sourcespackage_command)r   pkglistr   r   r   install_packages   s    zDistro.install_packagesc                    s   t   t j||S N)_maybe_remove_legacy_eth0super_write_network_state)r   argskwargs	__class__r   r   r4      s    zDistro._write_network_statec                 C   sT   d }z|  |}W n tk
r&   Y nX |s4td}|| t|t|d d S )N   )_read_hostname_confIOErrorr   Zset_hostnamer   
write_filestr)r   hostnamefilenameconfr   r   r   _write_hostname   s    
zDistro._write_hostnamec                 C   s   |  | j}| j|fS r1   )_read_hostnamehostname_conf_fn)r   Zsys_hostnamer   r   r   _read_system_hostname   s    zDistro._read_system_hostnamec                 C   s   t t|}|  |S r1   )r   r   	load_fileparse)r   r@   rA   r   r   r   r;      s    zDistro._read_hostname_confc                 C   s:   d }z|  |}|j}W n tk
r,   Y nX |s6|S |S r1   )r;   r?   r<   )r   r@   defaultr?   rA   r   r   r   rC      s    

zDistro._read_hostnamec                 C   s   dS )Nz	127.0.1.1r   r   r   r   r   _get_localhost_ip   s    zDistro._get_localhost_ipc                 C   s   t j|| |d d S )N)tzZtz_file)r   Zset_etc_timezoneZ_find_tz_file)r   rJ   r   r   r   set_timezone   s    zDistro.set_timezonec              
   C   sz   |dkrt }|D ]d}tj|s"qt|dB}zt|tjtjB  W n" t	k
rh   Y W 5 Q R   dS X W 5 Q R X qdS )ztDetermines if another process holds any apt locks.

        If all locks are clear, return True else False.
        NwFT)
APT_LOCK_FILESr!   r"   r#   openfcntllockfZLOCK_EXZLOCK_NBOSError)r   Z
lock_fileslockZhandler   r   r   _apt_lock_available   s     zDistro._apt_lock_availablec                 C   s   t   }td t   | |k r|  s6t d qtd z.d|d|d f }tjtj|tj|dW S  tj	k
r   |  r td t d Y qX qt
d	d
S )zWait for apt install to complete.

        short_cmd: Name of command like "upgrade" or "install"
        subp_kwargs: kwargs to pass to subp
        zWaiting for apt lock   zapt lock availablezapt-%s [%s] r5   )Zlogfuncmsgfuncr6   z*Another process holds apt lock. Waiting...zCould not get apt lockN)timer&   r'   rS   sleepjoinr   Zlog_timer   ZProcessExecutionErrorTimeoutError)r   	short_cmdsubp_kwargsZtimeoutZ
start_timeZlog_msgr   r   r   _wait_for_apt_command   s0    



zDistro._wait_for_apt_commandc           	      C   s   |dkrg }t j }d|d< | dt}t|dtd |dtd }|t| dt	 |r|t
|tr||| n|rt
|tr|| |}|dkr| d	d
}|| td|}|| | j|||ddd dS )aY  Run the given package command.

        On Debian, this will run apt-get (unless APT_GET_COMMAND is set).

        command: The command to run, like "upgrade" or "install"
        args: Arguments passed to apt itself in addition to
              any specified in APT_GET_COMMAND
        pkgs: Apt packages that the command will apply to
        NZnoninteractiveZDEBIAN_FRONTENDZapt_get_wrapperr   r   Zapt_get_commandZupgradeZapt_get_upgrade_subcommandzdist-upgrade%s=%sF)r5   envcapture)r\   r]   )r!   environcopyZ
get_optionAPT_GET_WRAPPER_get_wrapper_prefixgetextendlistAPT_GET_COMMAND
isinstancer>   appendr   Zexpand_package_listr^   )	r   r   r5   r,   eZwcfgcmdZsubcmdr/   r   r   r   r.      s6    


 


zDistro.package_commandc                 C   s   | j jd| jdgtd d S )Nzupdate-sourcesupdate)Zfreq)r   runr.   r   r   r   r   r   r-   $  s    zDistro.update_package_sourcesc                 C   s   t  S r1   )r   Zget_dpkg_architecturer   r   r   r   get_primary_arch,  s    zDistro.get_primary_arch)layoutmodelvariantoptionsc                 C   s^   d ddd| dd| dd| dd| ddd	dg	}tjd
|ddd | dd d S )N
z'# This file was generated by cloud-initr9   z
XKBMODEL=""zXKBLAYOUT="zXKBVARIANT="zXKBOPTIONS="zBACKSPACE="guess"z/etc/default/keyboardr:   rL   )r@   ZcontentmodeZomodeZrestartzconsole-setup)rZ   r   r=   Zmanage_service)r   rq   rr   rs   rt   contentsr   r   r   
set_keymap/  s&    



zDistro.set_keymap)Nr   )N)N)NN)__name__
__module____qualname__rD   Znetwork_conf_fnNETWORK_FILE_HEADERZrenderer_configsr   r   r*   r0   r4   rB   rE   r;   rC   rI   rK   rS   APT_LOCK_WAIT_TIMEOUTr^   r.   r-   rp   r>   ry   __classcell__r   r   r7   r   r   <   s<   

$


,
.r   c                 C   sP   t | trt| g} t|sDt| dkrH| d rHt| d rH| S g S d S )Nr
   r   )rj   r>   r   Zis_truer$   r   Zwhich)rm   rw   r   r   r   re   R  s    


re   "/etc/network/interfaces.d/eth0.cfgc                 C   s   t j| sdS d}zPt| }ddg}dd | D }||krVt|  d|  }n|d|   }W n  tk
r   |d	|   }Y nX t	| dS )
aO  Ubuntu cloud images previously included a 'eth0.cfg' that had
    hard coded content.  That file would interfere with the rendered
    configuration if it was present.

    if the file does not exist do nothing.
    If the file exists:
      - with known content, remove it and warn
      - with unknown content, leave it and warn
    Nz(Dynamic networking config may not apply.z	auto eth0ziface eth0 inet dhcpc                 S   s   g | ]}| d s| qS )#)
startswithstrip).0fr   r   r   
<listcomp>p  s    
 z-_maybe_remove_legacy_eth0.<locals>.<listcomp>zremoved %s with known contentsz* '%s' exists with user configured content.z" %s exists, but could not be read.)
r!   r"   r#   r   rF   
splitlinesZdel_file	Exceptionr&   Zwarning)r"   Zbmsgrx   Zknown_contentslinesrV   r   r   r   r2   ^  s     


r2   r   c                 C   sD   d}| st d|  tj| r@t| }t|}||d}|S )z.Read system default locale setting, if presentr9   zInvalid path: %s)r    r!   r"   r#   r   rF   Zload_shell_contentrf   )sys_pathr   Zsys_valZlocale_contentZsys_defaultsr   r   r   r   ~  s    

r   c                 C   s4   t d|||  tjdd| d|| f gdd dS )zUpdate system locale configz%Updating %s with locale setting %s=%szupdate-localez--locale-file=r_   Fra   N)r&   r'   r   r)   r   r   r   r   r   r(     s       
r(   c                 C   s@   |   dkrtd||  dS td|  tjd| gdd dS )z
    Run locale-gen for the provided locale and set the default
    system variable `keyname` appropriately in the provided `sys_path`.

    )czc.utf-8posixz$%s=%s does not require rengenerationNzGenerating locales for %sz
locale-genFr   )r$   r&   r'   r   r   r   r   r   r%     s
    r%   )r   )r   )r   )rO   r!   rX   Z	cloudinitr   r   r   Zloggingr   r   Z"cloudinit.distros.parsers.hostnamer   Zcloudinit.settingsr   Z	getLoggerrz   r&   r~   ri   rd   r}   ZNETWORK_CONF_FNr   rM   r   re   r2   r   r(   r%   r   r   r   r   <module>
   s:   
	  
 
