o
    w7e8                     @   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g d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--quiet	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/locale)z/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d2ddZ	dd Z
 fddZdd Zdd Zdd Zd3ddZdd Zd d! Zd3d"d#Zefd$d%Zd4d&d'Zd(d) Zd*d+ Zd,ed-ed.ed/efd0d1Z  ZS )5Distroz/etc/hostnamer   z/etc/netplan/50-cloud-init.yaml)eninetplanr   )eni_path
eni_headerr   T)netplan_pathnetplan_headerpostcmdsc                 C   s4   t j| ||| t|| _d| _d| _d | _d S )Ndebianzen_US.UTF-8)	r   r   __init__r   Runners_runnerosfamilydefault_localesystem_locale)selfname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rdnd}| | kp'| p'|}| p.|p.|}|r9t|||d n	t	
d|| j| |rPt|||d d| _dS 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   localeout_fnr(   distro_localeconf_fn_existssys_locale_unset
need_regen	need_confr"   r"   r#   apply_localed   s2   
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|i |S N)_maybe_remove_legacy_eth0super_write_network_state)r   argskwargs	__class__r"   r#   rD      s   zDistro._write_network_statec                 C   sR   d }z|  |}W n	 ty   Y nw |std}|| t|t|d d S )N   )_read_hostname_confIOErrorr   set_hostnamer   
write_filestr)r   hostnamefilenameconfr"   r"   r#   _write_hostname   s   
zDistro._write_hostnamec                 C   s   |  | j}| j|fS rA   )_read_hostnamehostname_conf_fn)r   sys_hostnamer"   r"   r#   _read_system_hostname   s   
zDistro._read_system_hostnamec                 C   s   t t|}|  |S rA   )r   r   	load_fileparse)r   rQ   rR   r"   r"   r#   rK      s   zDistro._read_hostname_confc                 C   s8   d }z
|  |}|j}W n	 ty   Y nw |s|S |S rA   )rK   rP   rL   )r   rQ   defaultrP   rR   r"   r"   r#   rT      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)tztz_file)r   set_etc_timezone_find_tz_file)r   r\   r"   r"   r#   set_timezone   s   zDistro.set_timezonec              
   C   s   |du rt }|D ]<}tj|sqt|d&}zt|tjtjB  W n t	y4   Y W d    dS w W d   n1 s?w   Y  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lockfLOCK_EXLOCK_NBOSError)r   
lock_fileslockhandler"   r"   r#   _apt_lock_available   s    zDistro._apt_lock_availablec                 C   s   t   }td t   | |k rY|  st d q	td zd|d|d f }tjtj|tj|dW S  tj	yP   |  rD td t d Y nw t   | |k st
d	)
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] rE   )logfuncmsgfuncrF   z*Another process holds apt lock. Waiting...zCould not get apt lock)timer0   r1   rl   sleepjoinr   log_timer   ProcessExecutionErrorTimeoutError)r   	short_cmdsubp_kwargstimeout
start_timelog_msgr"   r"   r#   _wait_for_apt_command   s4   



 zDistro._wait_for_apt_commandc           	      C   s   |du rg }t j }d|d< | dt}t|dtd |dtd }|t| dt	 |r>t
|tr>|| n|rJt
|trJ|| |}|dkrV| 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
        NnoninteractiveDEBIAN_FRONTENDapt_get_wrapperr   r   apt_get_commandupgradeapt_get_upgrade_subcommandzdist-upgrade%s=%sF)rE   envcapture)rx   ry   )r+   environcopy
get_optionAPT_GET_WRAPPER_get_wrapper_prefixgetextendlistAPT_GET_COMMAND
isinstancerO   appendr   expand_package_listr}   )	r   r   rE   r<   ewcfgcmdsubcmdr?   r"   r"   r#   r>      s4   






zDistro.package_commandc                 C   s   | j jd| jdgtd d S )Nzupdate-sourcesupdate)freq)r   runr>   r   r%   r"   r"   r#   r=   $  s   
zDistro.update_package_sourcesc                 C   s   t  S rA   )r   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-initrI   z
XKBMODEL=""zXKBLAYOUT="zXKBVARIANT="zXKBOPTIONS="zBACKSPACE="guess"z/etc/default/keyboardrJ   ra   )rQ   contentmodeomoderestartzconsole-setup)rt   r   rN   manage_service)r   r   r   r   r   contentsr"   r"   r#   
set_keymap/  s&   



zDistro.set_keymap)Nr'   rA   )NN)__name__
__module____qualname__rU   network_conf_fnNETWORK_FILE_HEADERrenderer_configsr   r&   r:   r@   rD   rS   rW   rK   rT   r[   r`   rl   APT_LOCK_WAIT_TIMEOUTr}   r>   r=   r   rO   r   __classcell__r"   r"   rG   r#   r   <   s>    

$



,."r   c                 C   sL   t | tr
t| g} t|s"t| dkr$| d r$t| d r$| S g S )Nr   r   )r   rO   r   is_truer.   r   which)r   r   r"   r"   r#   r   R  s   


&r   "/etc/network/interfaces.d/eth0.cfgc                 C   s   t j| sdS d}z(t| }ddg}dd | D }||kr+t|  d|  }n|d|   }W n tyA   |d	|   }Y nw 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   rX   
splitlinesdel_file	Exceptionr0   warning)r,   bmsgr   known_contentslinesrp   r"   r"   r#   rB   ^  s$   


rB   r'   c                 C   sD   d}| s
t d|  tj| r t| }t|}||d}|S )z.Read system default locale setting, if presentrI   zInvalid path: %s)r*   r+   r,   r-   r   rX   load_shell_contentr   )sys_pathr(   sys_vallocale_content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r   N)r0   r1   r   r3   r   r(   r"   r"   r#   r2     s   

r2   c                 C   s@   |   dv 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.   r0   r1   r   r   r"   r"   r#   r/     s
   r/   )r   )r'   )rd   r+   rr   	cloudinitr   r   r   loggingr   r   "cloudinit.distros.parsers.hostnamer   cloudinit.settingsr   	getLoggerr   r0   r   r   r   r   NETWORK_CONF_FNr)   rb   r   r   rB   r$   r2   r/   r"   r"   r"   r#   <module>   s4   	
  
 
