o
    3'Ûfò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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#   Ú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ñd}t ¡ d d }|d dkrÌtj d|› d¡sÌt d¡ t	 	g d¢¡ tdd„ |D ƒƒ}g d¢}|D ]}|  |¡rë| d| dd¡t|| ƒf g¡ qÒt	 	|¡ d}|r‰|  dt¡}tj d ¡rQt	 
|¡rQt|ƒ}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( |rut d)d* |¡¡ t%|ƒ |r‡t 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   ÚinitÚ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)Údata)Únetwork_addressÚnetwork_portÚstorage_backendÚstorage_create_deviceÚstorage_create_loopÚstorage_poolÚtrust_passwordÚunameé   r3   Úlvmz/lib/modules/z"/kernel/drivers/md/dm-thin-pool.kozqcloud-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    | ]	}|d kr|V  qdS )r3   Nr!   )Ú.0Úkeyr!   r!   r"   Ú	<genexpr>   s   € ÿzhandle.<locals>.<genexpr>)r   r)   z--autoz--%s=%sÚ_ú-zdebconf-communicater$   z/etc/default/lxd-bridgezSetting lxd debconf via %sÚ
c                 S   s   g | ]
\}}d ||f ‘qS )z	set %s %sr!   )r?   ÚkÚvr!   r!   r"   Ú
<listcomp>¬   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_initr=   ÚattachzCreating lxd bridge: %sú z!Setting up default lxd bridge: %sz*Unable to configure lxd bridge without %s.)&ÚgetÚLOGÚdebugr   r   r   r   r   r#   r   ÚwhichÚProcessExecutionErrorÚRuntimeErrorÚget_required_packagesÚlenÚdistroÚinstall_packagesÚwarningr   Úsystem_infoÚosÚpathÚexistsÚtupleÚextendÚreplacer   Ú_DEFAULT_NETWORK_NAMEÚbridge_to_debconfr   ÚitemsÚ	ExceptionÚlogexcÚdel_fileÚbridge_to_cmdÚmaybe_cleanup_defaultÚboolÚ_lxc)r$   r%   r&   r'   Úlxd_cfgr   r   r   ÚeÚpackagesÚexcÚ	init_keysÚkernelÚcmdrE   Ú
dconf_commrH   Údebconfr0   Ú
cmd_createÚ
cmd_attachr!   r!   r"   ÚhandleD   sØ   
ÿ
ÿÿ
ÿþ€ÿ
€þ
ÿÿÿÿ
ÿ€
ÿÿýÿÿÿ

ü
ÿüÿÿrs   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-bridger+   zlxd/bridge-nameÚexistingÚtruezlxd/use-existing-bridger$   Ú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")rL   rQ   )r   rp   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 )#Nrt   ru   )NNr$   Únetworkzattach-profiler>   Úeth0rw   ry   r„   r=   rz   r{   zipv4.address=%s/%sr   rx   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=)rL   r^   rQ   r   )r   Úbridge_namerq   rr   Ú
dhcp_ranger‡   r!   r!   r"   rd     sX   
ÿÿ
ÿþ€
ÿÿ
€

rd   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)rX   ÚenvironrL   r   Úlist)rn   Úenvr!   r!   r"   rg   B  s
   ý"rg   r>   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^   rg   rM   rN   r   rP   Ú	exit_code)
rH   rI   r=   rJ   r–   Únic_nameÚfail_assume_enoentÚ	succeededÚmsgri   r!   r!   r"   re   K  s<   

€ý
€ýûre   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 installr3   Ú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   rM   rV   rL   r   rO   )r   r   rj   Ústorage_driversÚpreseed_cfgr6   r!   r!   r"   rR   s  s0   ÿÿ
€


rR   )r>   r†   )"Ú__doc__ÚloggingrX   Útypingr   r   r¤   Ú	cloudinitr   r   Úcloudinit.cloudr   Úcloudinit.configr   Úcloudinit.config.schemar   Úcloudinit.settingsr	   Ú	getLoggerr   rM   r^   r   Ú__annotations__r#   r   r’   rs   r_   rd   rg   re   r   rR   r!   r!   r!   r"   Ú<module>   s4   
ü# 1<

ÿ(