o
    x[hda  ã                   @   sœ   d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZmZ d dl	m
Z
mZmZmZmZ d dlmZ d dlmZmZ e  e¡ZdZG dd	„ d	e
jƒZdS )
é    N)Údatetime)ÚAnyÚDictÚOptional)ÚdistrosÚhelpersÚ	lifecycleÚsubpÚutil)ÚHostnameConf)Ú
PER_ALWAYSÚPER_INSTANCEa7  # 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}

c                       sn  e Zd ZdZdZdZdZdZdeedœiZ	dZ
d	Zd
d„ Zdd„ ZdIdd„Zdejfdd„Zdd„ Zdd„ Zdd„ ZdIdd„Zdd„ Zdeded ed!efd"d#„Zd$d%„ ZdJd&d'„Zd(d)œd*d+„Zed,d-„ ƒZd.ef‡ fd/d0„Z‡ fd1d2„Z d3ef‡ fd4d5„Z!‡ fd6d7„Z"dI‡ fd8d9„	Z#dKd<d=„Z$e%d>d?„ ƒZ&e'dd@œdAedBedCefdDdE„ƒZ(e%dFed.e)e fdGdH„ƒZ*‡  Z+S )LÚDistrozpy3-pipz/usr/share/bkeymaps/z&/etc/profile.d/50-cloud-init-locale.shz/etc/network/interfacesz/etc/shadowÚeni)Úeni_pathÚ
eni_headerz/var/lib/dhcpzdhclient\.leasesc                 C   s6   t j | |||¡ t |¡| _d| _d| _d|d< d S )NzC.UTF-8ÚalpineÚsshdÚssh_svcname)r   r   Ú__init__r   ÚRunnersÚ_runnerÚdefault_localeÚosfamily)ÚselfÚnameÚcfgÚpaths© r   ú:/usr/lib/python3/dist-packages/cloudinit/distros/alpine.pyr   .   s
   zDistro.__init__c                 C   s   | j S )zgThe default locale for Alpine Linux is different than
        cloud-init's DataSource default.
        )r   ©r   r   r   r   Ú
get_locale8   s   zDistro.get_localeNc                 C   sB   |s| j }|s
| j}ddddd| ddg}t |d |¡d¡ d S )	Nú#z?# This file is created by cloud-init once per new instance bootzexport CHARSET=UTF-8zexport LANG=%szexport LC_COLLATE=CÚ Ú
é¤  )r   Úlocale_conf_fnr
   Ú
write_fileÚjoin)r   ÚlocaleÚout_fnÚlinesr   r   r   Úapply_locale>   s   ù	zDistro.apply_localeÚpkglistc                 C   s   |   ¡  | jd|d� d S )NÚadd)Úpkgs)Úupdate_package_sourcesÚpackage_command)r   r-   r   r   r   Úinstall_packagesQ   s   zDistro.install_packagesc                 C   sx   d }z|   |¡}W n ty%   t | jdd¡}|rnt d¡ Y d S Y nw |s,tdƒ}| |¡ t 	|t
|ƒd¡ d S )NÚcreate_hostname_fileTz8create_hostname_file is False; hostname file not createdr#   r%   )Ú_read_hostname_confÚIOErrorr
   Úget_cfg_option_boolÚ_cfgÚLOGÚinfor   Úset_hostnamer'   Ústr)r   ÚhostnameÚfilenameÚconfr3   r   r   r   Ú_write_hostnameU   s&   ÿÿûû
zDistro._write_hostnamec                 C   s   |   | j¡}| j|fS ©N)Ú_read_hostnameÚhostname_conf_fn)r   Úsys_hostnamer   r   r   Ú_read_system_hostnamek   s   
zDistro._read_system_hostnamec                 C   s   t t |¡ƒ}| ¡  |S r@   )r   r
   Úload_text_fileÚparse)r   r=   r>   r   r   r   r4   o   s   zDistro._read_hostname_confc                 C   s8   d }z
|   |¡}|j}W n	 ty   Y nw |s|S |S r@   )r4   r<   r5   )r   r=   Údefaultr<   r>   r   r   r   rA   t   s   

ÿzDistro._read_hostnamec                 C   ó   dS )Nz	127.0.1.1r   r    r   r   r   Ú_get_localhost_ip   s   zDistro._get_localhost_ipÚlayoutÚmodelÚvariantÚoptionsc                 C   sÒ   |sd}t  |¡ t|ƒ‚tj | j|¡}tj |¡s(d| }t  |¡ t|ƒ‚|s5d}t  |¡ t|ƒ‚tj |d| ¡}tj |¡sQd| }t  |¡ t|ƒ‚|rXt  	d¡ |r_t  	d¡ t
 
d||g¡ d S )	NzKeyboard layout not specified.z,Keyboard layout directory %s does not exist.zKeyboard variant not specified.z
%s.bmap.gzz(Keyboard variant file %s does not exist.z+Keyboard model is ignored for Alpine Linux.z.Keyboard options are ignored for Alpine Linux.zsetup-keymap)r8   ÚerrorÚRuntimeErrorÚosÚpathr(   Úkeymap_pathÚisdirÚisfileÚwarningr	   )r   rJ   rK   rL   rM   ÚmsgÚkeymap_layout_pathÚkeymap_variant_pathr   r   r   Ú
set_keymap‚   s>   
ÿÿ

ÿÿÿ


zDistro.set_keymapc                 C   s   t j||  |¡d� d S )N)ÚtzÚtz_file)r   Úset_etc_timezoneÚ_find_tz_file)r   rZ   r   r   r   Úset_timezone¤   s   zDistro.set_timezonec                 C   sš   |d u rg }dg}|  d¡ |rt|tƒr|  |¡ n|r't|tƒr'| |¡ |r.|  |¡ |dkr9| ddg¡ t d|¡}| |¡ tj|dd� d S )	NÚapkz--quietÚupgradez--update-cachez--availablez%s-%sF)Úcapture)ÚappendÚ
isinstancer;   ÚlistÚextendr
   Úexpand_package_listr	   )r   ÚcommandÚargsr/   Úcmdr-   r   r   r   r1   §   s   



zDistro.package_commandF)Úforcec                C   s$   | j jd| jdg|rtntd� d S )Nzupdate-sourcesÚupdate)Úfreq)r   Úrunr1   r   r   )r   rj   r   r   r   r0   À   s   

üzDistro.update_package_sourcesc                 C   s   | j sddg| _ | j S )z7Allow distro to determine the preferred ntp client listÚchronyÚntp)Ú_preferred_ntp_clientsr    r   r   r   Úpreferred_ntp_clientsÈ   s   
zDistro.preferred_ntp_clientsÚreturnc                    sn  t  |¡rt d|¡ dS d|v rt d¡ |d= t d¡r(tƒ j|fi |¤ŽS | 	dd¡}dd	g}d
dddddœ}ddi}| 
d¡}|r{t|tƒrP| d¡}nt|tƒratjd|› d�ddd� dd„ |D ƒ}d |¡|d< | 
d¡r{| |d ¡ |r•|r•|D ]}t  |¡s”|  |¡ t d||¡ q�d|v r¡t|d ƒ|d< g ddddœ}	t| ¡ ƒD ]B\}
}|
|v rÇ|rÇt|tƒrÇ| ||
 |g¡ q®|
|	v rã|rãt|tƒrã|
dkrÞ| d¡|	|
< q®||	|
< q®|
|v rð|rð| ||
 ¡ q®| 
d ¡sü| 
d¡�r| d!¡ | |¡ t d"|¡ zt |¡ W n tj�y) } zt d#|¡ |‚d}~ww |	d D ]+}t d$|¡ zt d%||g¡ W �q. tj�yY } z
t  td&||¡ |‚d}~ww |	d' �rjtƒ j||	d' dd(� |	d) }|	d* }d}| j}zt  |¡}W n t�y“ } zt d+|¡ |‚d}~ww d}| ¡ D ]}| d,¡}|d- |k�r¬|} n�qš|�r-d.}d.|d/< d.|d0< d.|d1< d2}|du�rät  !|¡t  !d3¡ j"}t|ƒ|d4< |d.k�rà|d5 }|d6 }|du�rú||d7< |d.k�rö|d5 }|d8 }| #|d, |¡¡}t d9||¡ zt j$||d:dd;� W dS  t%�y, } z	t  td<|¡ |‚d}~ww t  td=||¡ dS )>zü
        Add a user to the system using standard tools

        On Alpine this may use either 'useradd' or 'adduser' depending
        on whether the 'shadow' package is installed.

        Returns False if user already exists, otherwise True.
        z!User %s already exists, skipping.FÚselinux_userz0Ignoring selinux_user parameter for Alpine LinuxÚuseraddÚcreate_groupsTÚadduserz-Dz-gz-hz-Gz-sú-u)ÚgecosÚhomedirÚprimary_groupÚshellÚuidÚsystemz-SÚgroupsú,z	The user z) has a 'groups' config value of type dictz22.3z=Use a comma-delimited string or array instead: group1,group2.)Ú
deprecatedÚdeprecated_versionÚextra_messagec                 S   s   g | ]}|  ¡ ‘qS r   )Ústrip)Ú.0Úgr   r   r   Ú
<listcomp>  s    z#Distro.add_user.<locals>.<listcomp>rz   z created group '%s' for user '%s'r|   N)r~   Ú
expiredateÚinactiveÚpasswdÚno_create_homez-HzAdding user %szFailed to create user %szAdding user to group %sÚaddgroupz!Failed to add user %s to group %sr‰   )Úhashedr‡   rˆ   ú&Failed to read %s file, file not foundú:r   r#   é   é   é   zpassword agingz
1970-01-01é   z & zacct expiration dateé   zinactivity periodzUpdating %s for user %sÚw©ÚomodeÚpreserve_modeúFailed to update %s filezFailed to update %s for user %s)&r
   Úis_userr8   r9   rU   r	   ÚwhichÚsuperÚadd_userÚpopÚgetrc   r;   ÚsplitÚdictr   Ú	deprecater(   rb   Úis_groupÚcreate_groupÚdebugÚsortedÚitemsre   ÚProcessExecutionErrorÚlogexcÚ
set_passwdÚ	shadow_fnrE   ÚFileNotFoundErrorÚ
splitlinesr   ÚfromisoformatÚdaysÚreplacer'   r5   )r   r   Úkwargsru   Úadduser_cmdÚadduser_optsÚadduser_flagsr~   ÚgroupÚunsupported_busybox_valuesÚkeyÚvalÚeÚ
addn_groupr‡   rˆ   Úshadow_contentsÚshadow_fileÚoriginal_lineÚlineÚnew_line_partsÚupdate_typer®   ©Ú	__class__r   r   rœ   Ð   s  
	

û



ü



€üÿþ
€

€þÿÿ€ü

ÿ€þ
þ
ÿý



ÿÿ÷€þÿzDistro.add_userc              
      óŒ   t j d¡rdt  d¡vrtƒ  |¡S dd|g}ztj|ddgd�\}}t d|¡r-W d	S W dS  tj	yE } z	t
 td
|¡ |‚d}~ww )zL
        Lock the password of a user, i.e., disable password logins
        ú/usr/bin/passwdÚbbsuidr‰   z-lr   é   ©Úrcszis already lockedTz&Failed to disable password for user %sN)rP   rQ   ÚislinkÚreadlinkr›   Úlock_passwdr	   ÚreÚsearchr§   r
   r¨   r8   )r   r   ri   Ú_outÚerrr¸   rÀ   r   r   rÊ   ª  s    ÿ
ÿ€þzDistro.lock_passwdr   c              
      rÂ   )zM
        Unlock the password of a user, i.e., enable password logins
        rÃ   rÄ   r‰   rw   r   rÅ   rÆ   zis already unlockedTz%Failed to unlock password for user %sN)rP   rQ   rÈ   rÉ   r›   Úunlock_passwdr	   rË   rÌ   r§   r
   r¨   r8   )r   r   ri   Ú_rÎ   r¸   rÀ   r   r   rÏ   Æ  s    ÿ
	ÿ€þzDistro.unlock_passwdc              
      sB  t j d¡rdt  d¡vrtƒ  |¡S d }| j}zt |¡}W n t	y3 } zt
 d|¡ |‚d }~ww d }| ¡ D ]}| d¡}|d |krQt
 d|¡ |} nq:|r˜|d dkr�d|d< | |d |¡d	¡}t
 d
|¡ ztj||ddd� W d S  ty� } z	t t
d|¡ |‚d }~ww t
 d|¡ d S t t
d|¡ d S )NrÃ   rÄ   r�   rŽ   r   z'Found /etc/shadow line matching user %sé   Ú0rÅ   zExpiring password for user %sr”   Tr•   r˜   z'Password for user %s is already expiredzFailed to set 'expire' for %s)rP   rQ   rÈ   rÉ   r›   Úexpire_passwdrª   r
   rE   r«   r8   rU   r¬   rŸ   r¤   r¯   r(   r'   r5   r¨   )r   Úuserrº   r»   r¸   r¼   r½   r¾   rÀ   r   r   rÓ   ä  sV   ÿ€þ
ýÿü€þzDistro.expire_passwdc                    sÔ   t  d¡rtƒ  ||¡S d|g}|sg }t |¡r t d|¡ nzt   |¡ t d|¡ W n t j	y>   t 
td|¡ Y nw t|ƒdkrf|D ] }t |¡sVt d||¡ qGt   d||g¡ t d||¡ qGd S d S )	NÚgroupaddr‹   z(Skipping creation of existing group '%s'zCreated new group %szFailed to create group %sr   zCUnable to add group member '%s' to group '%s'; user does not exist.zAdded user '%s' to group '%s')r	   rš   r›   r£   r
   r¢   r8   rU   r9   r§   r¨   Úlenr™   )r   r   ÚmembersÚgroup_add_cmdÚmemberrÀ   r   r   r£     s4   


ÿ
üôzDistro.create_groupÚpoweroffÚnowc              
   C   sd   |dg}|dkr|dg7 }|S z|  tt|ƒd ƒ¡ W |S  ty1 } ztd|f ƒ|‚d }~ww )Nz-drÛ   rÒ   é<   z?power_state[delay] must be 'now' or '+m' (minutes). found '%s'.)rb   r;   ÚintÚ
ValueErrorÚ	TypeError)r   ÚmodeÚdelayÚmessagerg   r¸   r   r   r   Úshutdown_command@  s"   

øúÿÿý€ÿzDistro.shutdown_commandc                   C   rH   )z1
        Alpine uses OpenRC, not systemd
        Fr   r   r   r   r   Úuses_systemdZ  s   zDistro.uses_systemdrÆ   ÚactionÚserviceÚ
extra_argsc          	   
   G   s¢   ddg}ddg}t |ƒ|dg t |ƒ|dg t |ƒd|g t |ƒd|g t |ƒ|dg t |ƒ|dg t |ƒ|dg t |ƒ|d	g d
œ}t || ƒ}tj|d|d�S )a<  
        Perform the requested action on a service. This handles OpenRC
        specific implementation details.

        OpenRC has two distinct commands relating to services,
        'rc-service' and 'rc-update' and the order of their argument
        lists differ.
        May raise ProcessExecutionError
        z
rc-servicez	--nocolorz	rc-updateÚstopÚstartÚdelr.   ÚrestartÚstatus)rè   ré   ÚdisableÚenablerë   Úreloadz
try-reloadrì   T)ra   rÇ   )rd   r	   )	r   rå   ræ   rÇ   rç   Úinit_cmdÚ
update_cmdÚcmdsri   r   r   r   Úmanage_servicea  s   ø
zDistro.manage_serviceÚblockdevc                 C   sô   t j | ¡}|  d¡rjt  t  | ¡j¡}t  t  | ¡j¡}t  d¡�@}|D ]5}|j	 d¡rZt  
|j¡}t |j¡rZt  t  |j¡j¡|krZt  t  |j¡j¡|krZt j |j¡} nq%W d  ƒ n1 sew   Y  | d¡rxt d| |¡ |S dS )a  Returns underlying block device for a mapped device.

        If it is mapped, blockdev will usually take the form of
        /dev/mapper/some_name

        If blockdev is a symlink pointing to a /dev/dm-* device, return
        the device pointed to. Otherwise, return None.
        z/dev/mapperz/dev/zdm-Nz/dev/dm-z$%s is a mapped device pointing to %s)rP   rQ   ÚrealpathÚ
startswithÚmajorÚstatÚst_rdevÚminorÚscandirr   ÚlstatÚS_ISBLKÚst_moder8   r¤   )rô   rõ   r÷   rú   ÚitÚdeventryÚresr   r   r   Úget_mapped_device}  s2   

ÿÿ€ô
ÿzDistro.get_mapped_devicer@   )NN)rÚ   rÛ   N),Ú__name__Ú
__module__Ú__qualname__Úpip_package_namerR   r&   Únetwork_conf_fnrª   ÚNETWORK_FILE_HEADERÚrenderer_configsÚdhclient_lease_directoryÚdhclient_lease_file_regexr   r!   r,   r   ÚPackageListr2   r?   rD   r4   rA   rI   r;   rY   r^   r1   r0   Úpropertyrq   Úboolrœ   rÊ   rÏ   rÓ   r£   rã   Ústaticmethodrä   Úclassmethodró   r   r  Ú__classcell__r   r   rÀ   r   r       sZ    
ÿ


"

 [9
#
ÿÿÿÿ r   )ÚloggingrP   rË   rø   r   Útypingr   r   r   Ú	cloudinitr   r   r   r	   r
   Ú"cloudinit.distros.parsers.hostnamer   Úcloudinit.settingsr   r   Ú	getLoggerr  r8   r  r   r   r   r   r   Ú<module>   s   

