o
    m[hÁ5  ã                
   @   s  U d Z ddlZddlZddlmZm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 ddlmZ e e¡Zd	Zd
dgedgdœZeed< dd„ Zdd„ Zdededededdf
dd„Zdd„ Zdd„ Zdd„ Z	!d(d"d#„Z d$e!d%edee fd&d'„Z"dS ))z>LXD: configure lxd with ``lxd init`` and optionally lxd-bridgeé    N)ÚListÚTuple)ÚsubpÚutil)ÚCloud)ÚConfig)Ú
MetaSchema)ÚPER_INSTANCEÚlxdbr0Úcc_lxdÚubuntuÚlxd)ÚidÚdistrosÚ	frequencyÚactivate_by_schema_keysÚmetac                 C   sÂ   g }t | tƒs| dt| ƒj› d�¡ t |tƒs$| dt|ƒj› d�¡ t |tƒs5| dt|ƒj› d�¡ |rV| s;|rV| r@dgng }||rHdgng 7 }| dd |¡› �¡ |r_td	 |¡ƒ‚d
S )z…Validate user-provided lxd network and bridge config option values.

    @raises: ValueError describing invalid values provided.
    z/lxd.init config must be a dictionary. found a 'ú'z1lxd.bridge config must be a dictionary. found a 'z.lxd.preseed config must be a string. found a 'zlxd.initz
lxd.bridgezMUnable to configure LXD. lxd.preseed config can not be provided with key(s): z, z. N)Ú
isinstanceÚdictÚappendÚtypeÚ__name__ÚstrÚjoinÚ
ValueError)Úinit_cfgÚ
bridge_cfgÚpreseed_strÚerrorsÚincompat_cfg© r!   ú9/usr/lib/python3/dist-packages/cloudinit/config/cc_lxd.pyÚsupplemental_schema_validation!   s<   
ÿÿ
ÿÿ
ÿÿÿÿÿr#   c                 C   sª   d}g d¢}|D ]}|   |¡r!| d| dd¡t| | ƒf g¡ qzt |¡ W dS  tjyT   | d dkr9‚ t d¡ t g d	¢¡ d
d„ |D ƒ}t |¡ Y dS w )z�Set up lxd if init config is given.

    :param init_cfg: dict of lxd init configuration options to provide
        to `lxd init --auto`
    )Únetwork_addressÚnetwork_portÚstorage_backendÚstorage_create_deviceÚstorage_create_loopÚstorage_poolÚtrust_password)r   Úinitz--autoz--%s=%sÚ_ú-r&   ÚlvmzqCloud-init doesn't use thinpool by default on Ubuntu due to LP #1982780. This behavior will change in the future.)ÚlxcÚstorageÚcreateÚdefaultr.   zlvm.use_thinpool=falsec                 S   s   g | ]	}|  d ¡s|‘qS )z--storage-backend)Ú
startswith)Ú.0Úxr!   r!   r"   Ú
<listcomp>q   s    z#handle_init_cfg.<locals>.<listcomp>N)ÚgetÚextendÚreplacer   r   ÚProcessExecutionErrorÚLOGÚinfo)r   Ú	init_keysÚcmdÚkÚnew_cmdr!   r!   r"   Úhandle_init_cfgD   s(   

$€ÿÿçrA   ÚnameÚcfgÚcloudÚargsÚreturnc              
   C   s‚  |  d¡}|st d| ¡ d S t|tƒstdt|ƒj› d�ƒ‚|  di ¡}|  dd¡}|  di ¡}t|||ƒ t	 
d¡sZz	t	 	g d	¢¡ W n t	jyY } ztd
| ƒ|‚d }~ww t||ƒ}	t|	ƒr‡z|j |	¡ W n t	jy† }
 zt d|	|
¡ W Y d }
~
d S d }
~
ww t	 	g d¢¡ |r›t	j	g d¢|d� d S |r¡t|ƒ d}|�r6|  dt¡}tj d¡rþt	 
|¡rþt|ƒ}zt d|¡ d dd„ | ¡ D ƒ¡d }t	j	dg|d� W n tyê   t td| ¡ Y nw t d¡ t d¡ t	 	g d¢¡ d S t|ƒ\}}t|t |ƒt |ƒt |ƒd� |�r"t dd |¡¡ t!|ƒ |�r4t dd |¡¡ t!|ƒ d S d S |�r?td| ƒ‚d S )Nr   z8Skipping module named %s, not present or disabled by cfgz*lxd config must be a dictionary. found a 'r   r+   ÚpreseedÚ Úbridge)ÚsnapÚinstallr   z#Failed to install lxd from snap: %sz!failed to install packages %s: %s)r   Ú	waitreadyz--timeout=300)r   r+   z	--preseed)Údatazdebconf-communicaterB   z/etc/default/lxd-bridgezSetting lxd debconf via %sÚ
c                 S   s   g | ]
\}}d ||f ‘qS )z	set %s %sr!   )r4   r?   Úvr!   r!   r"   r6   ³   s    zhandle.<locals>.<listcomp>zFailed to run '%s' for lxd withz Running dpkg-reconfigure for lxd)zdpkg-reconfigurer   z--frontend=noninteractive)Únet_nameÚdid_initr1   ÚattachzCreating lxd bridge: %sú z!Setting up default lxd bridge: %sz*Unable to configure lxd bridge without %s.)"r7   r;   Údebugr   r   r   r   r   r#   r   Úwhichr:   ÚRuntimeErrorÚget_required_packagesÚlenÚdistroÚinstall_packagesÚwarningrA   Ú_DEFAULT_NETWORK_NAMEÚosÚpathÚexistsÚbridge_to_debconfr   ÚitemsÚ	Exceptionr   ÚlogexcÚdel_fileÚbridge_to_cmdÚmaybe_cleanup_defaultÚboolÚ_lxc)rB   rC   rD   rE   Úlxd_cfgr   r   r   ÚeÚpackagesÚexcÚ
dconf_commrP   ÚdebconfrM   Ú
cmd_createÚ
cmd_attachr!   r!   r"   Úhandlex   s®   
ÿ
ÿÿ
ÿþ€ÿ
€þÿÿýÿÿÿ

ü
ÿüÿÿrq   c                 C   sX  i }|   d¡dkrd|d< d|d< |S |   d¡dkr+d|d< d|d	< |   d
¡|d< |S |   d¡dkr£d|d< |   d
¡rB|   d
¡|d< |   d¡rvd|d< |   d¡|d< |   d¡|d< |   d¡|d< |   d¡|d< |   d¡|d< |   dd¡|d< |   d¡r•d|d< |   d¡|d< |   d¡|d< |   dd¡|d< |   d ¡r¡|   d ¡|d!< |S td"|   d¡ ƒ‚)#NÚmodeÚnoneÚfalsezlxd/setup-bridgerH   zlxd/bridge-nameÚexistingÚtruezlxd/use-existing-bridgerB   ÚnewÚipv4_addresszlxd/bridge-ipv4zlxd/bridge-ipv4-addressÚipv4_netmaskzlxd/bridge-ipv4-netmaskÚipv4_dhcp_firstzlxd/bridge-ipv4-dhcp-firstÚipv4_dhcp_lastzlxd/bridge-ipv4-dhcp-lastÚipv4_dhcp_leaseszlxd/bridge-ipv4-dhcp-leasesÚipv4_natzlxd/bridge-ipv4-natÚipv6_addresszlxd/bridge-ipv6zlxd/bridge-ipv6-addressÚipv6_netmaskzlxd/bridge-ipv6-netmaskÚipv6_natzlxd/bridge-ipv6-natÚdomainzlxd/bridge-domainúinvalid bridge mode "%s")r7   rV   )r   rn   r!   r!   r"   r`   Ü   sN   )Ù$Þ

ÿÿÿ
ÿ
þr`   c                 C   s¢  |   d¡dkr	dS |   dt¡}g }dd|ddg}|   d¡d	kr#d |fS |   d¡d
kr3td|   d¡ ƒ‚dd|g}|   d¡r||   d¡r|| d|   d¡|   d¡f ¡ |   dd¡dkr^| d¡ |   d¡r{|   d¡r{d|   d¡|   d¡f }| d| ¡ n| d¡ |   d¡r§|   d¡r§| d|   d¡|   d¡f ¡ |   d¡dkr¦| d¡ n| d¡ |   d¡r»| d|   d¡ ¡ |   d d!¡}|d!krÍ| d"|› �¡ ||fS )#Nrr   rs   )NNrB   Únetworkzattach-profiler2   Úeth0ru   rw   r‚   r1   rx   ry   zipv4.address=%s/%sr}   rv   zipv4.nat=truerz   r{   z%s-%szipv4.dhcp.ranges=%szipv4.address=noner~   r   zipv6.address=%s/%sr€   zipv6.nat=truezipv6.address=noner�   zdns.domain=%sÚmtuéÿÿÿÿzbridge.mtu=)r7   r\   rV   r   )r   Úbridge_namero   rp   Ú
dhcp_ranger…   r!   r!   r"   re     sX   
ÿÿ
ÿþ€
ÿÿ
€

re   c                 C   sB   dt j dd¡t j dd¡dœ}tjdgt| ƒ dg |d	� d S )
NÚCÚHOMEz/rootÚUSERÚroot)ÚLC_ALLrŠ   r‹   r/   z--force-local)Ú
update_env)r]   Úenvironr7   r   Úlist)r>   Úenvr!   r!   r"   rh   I  s
   ý"rh   r2   r„   c           
   
   C   s&  | t ks|sdS d}d}|rUd}ztdd| |gƒ t || ||¡ W n" tjyD }	 z|	jdkr2|	‚t || ||¡ W Y d}	~	nd}	~	ww d}tdd	| gƒ t || |¡ |r‘d
}ztddd||gƒ t ||||¡ W dS  tjy� }	 z|	jdkr}|	‚t ||||¡ W Y d}	~	dS d}	~	ww dS )a   Newer versions of lxc (3.0.1+) create a lxdbr0 network when
    'lxd init --auto' is run.  Older versions did not.

    By removing any that lxd-init created, we simply leave the add/attach
    code intact.

    https://github.com/canonical/lxd/issues/4649Nz"failed. Assuming it did not exist.z
succeeded.z/Detach of lxd network '%s' from profile '%s' %srƒ   zdetach-profileé   zDeletion of lxd network '%s' %sÚdeletez+Removal of device '%s' from profile '%s' %sÚprofileÚdeviceÚremove)r\   rh   r;   rT   r   r:   Ú	exit_code)
rP   rQ   r1   rR   r”   Únic_nameÚfail_assume_enoentÚ	succeededÚmsgrj   r!   r!   r"   rf   R  s<   

€ý
€ýûrf   r   r   c              
   C   sä   g }g }i }d| v r|  | d ¡ |r1d|v r1zt |¡}W n tjttfy0   t d¡ Y nw | dg ¡D ]}| d¡rE|  |d ¡ q7d|v rTt	 
d¡sT|  d¡ d|v rbt	 
d¡sb|  d	¡ d
|v rpt	 
d¡sp|  d¡ |S )z&identify required packages for installr&   Ústorage_poolsz|lxd.preseed string value is not YAML.  Unable to determine required storage driver packages to support storage_pools config.ÚdriverÚzfszzfsutils-linuxr.   ÚlvcreateÚlvm2Úbtrfsz
mkfs.btrfszbtrfs-progs)r   ÚyamlÚ	safe_loadÚ	YAMLErrorÚ	TypeErrorr   r;   r[   r7   r   rU   )r   r   rk   Ústorage_driversÚpreseed_cfgr)   r!   r!   r"   rW   z  s0   ÿÿ
€


rW   )r2   r„   )#Ú__doc__Úloggingr]   Útypingr   r   r¢   Ú	cloudinitr   r   Úcloudinit.cloudr   Úcloudinit.configr   Úcloudinit.config.schemar   Úcloudinit.settingsr	   Ú	getLoggerr   r;   r\   r   Ú__annotations__r#   rA   r   r�   rq   r`   re   rh   rf   r   rW   r!   r!   r!   r"   Ú<module>   s4   
ü#4d1<

ÿ(