o
    qÇÊi-6  ã                
   @   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 )zSet 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|||ƒ z	t	 	g d	¢¡ W n( t	j
yh   z	t	 	g d
¢¡ W n t	j
ye } ztd| ƒ|‚d }~ww Y n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}|rG|  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 |r3t dd |¡¡ t!|ƒ |rEt dd |¡¡ t!|ƒ d S d S |rPt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Úlistr   )rJ   Ú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   r:   ÚRuntimeErrorÚget_required_packagesÚlenÚdistroÚinstall_packagesÚwarningrA   Ú_DEFAULT_NETWORK_NAMEÚosÚpathÚexistsÚwhichÚ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_commrQ   ÚdebconfrN   Ú
cmd_createÚ
cmd_attachr!   r!   r"   Úhandlex   s¶   
ÿ
ÿÿÿþ€ÿÿý
€þÿÿýÿÿÿ

ü
ÿüÿÿrr   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   ro   r!   r!   r"   ra   ß   sN   )Ù$Þ

ÿÿÿ
ÿ
þra   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 )#Nrs   rt   )NNrB   Únetworkzattach-profiler2   Úeth0rv   rx   rƒ   r1   ry   rz   zipv4.address=%s/%sr~   rw   zipv4.nat=truer{   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_namerp   rq   Ú
dhcp_ranger†   r!   r!   r"   rf     sX   
ÿÿ
ÿþ€
ÿÿ
€

rf   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   rK   )r>   Úenvr!   r!   r"   ri   L  s
   ý"ri   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\   ri   r;   rU   r   r:   Ú	exit_code)
rQ   rR   r1   rS   r”   Únic_nameÚfail_assume_enoentÚ	succeededÚmsgrk   r!   r!   r"   rg   U  s<   

€ý
€ýûrg   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   r`   )r   r   rl   Ústorage_driversÚpreseed_cfgr)   r!   r!   r"   rW   }  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   rK   rr   ra   rf   ri   rg   r   rW   r!   r!   r!   r"   Ú<module>   s4   
ü#4g1<

ÿ(