
    x[h5              
          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j$                  e      Zd	Zd
dgedgdZeed<   d Zd Zdededededdf
dZd Zd Zd Z	 ddZ de!dedee   fdZ"y)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                    g }t        | t              s(|j                  dt        |       j                   d       t        |t              s(|j                  dt        |      j                   d       t        |t
              s(|j                  dt        |      j                   d       |r8| s|r4| rdgng }||rdgng z  }|j                  ddj                  |              |rt        d	j                  |            y
)zValidate 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_cfgs        9/usr/lib/python3/dist-packages/cloudinit/config/cc_lxd.pysupplemental_schema_validationr$   !   s   
 Fh%h((),	

 j$'j!**+1.	

 k3'k"++,A/	
 J'/
|R*"<!YY|457	
 6*++     c           
         d}g d}|D ]H  }| j                  |      s|j                  d|j                  dd      dt        | |         g       J 	 t	        j                  |       y# t        j
                  $ rt | d   dk7  r t        j                  d	       t	        j                  g d
       |D cg c]  }|j                  d      r| nc c}w }}t	        j                  |       Y yw xY 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--_-=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defaultr2   zlvm.use_thinpool=falsez--storage-backendN)	getextendreplacer   r   ProcessExecutionErrorLOGinfo
startswith)r   	init_keyscmdkxnew_cmds         r#   handle_init_cfgrC   D   s    "I $C N<<?JJQYYsC%8#hqk:JKLMN		#%% %&%/D	
 					
 "K6I)J1KKK 			'3s%   A+ +AC27CCC21C2namecfgcloudargsreturnc           
      <   |j                  d      }|st        j                  d|        y t        |t              s"t        dt        |      j                   d      t        j                  |       |j                  di       }|j                  dd      }|j                  di       }t        |||       t        j                  d      s	 t        j                  g d	       t        ||      }	t!        |	      r	 |j"                  j%                  |	       t        j                  g d       |rt        j                  g d|       y |rt)        |       d}|r|j                  dt*              }t,        j.                  j1                  d      rt        j                  |      rt3        |      }	 t        j                  d|       dj5                  |j7                         D cg c]  \  }}d|d| c}}      dz   }t        j                  dg|       t        j<                  d       t        j                  d       t        j                  g d       y t?        |      \  }}tA        |tC        |      tC        |      tC        |             |r0t        j                  ddj5                  |             tE        |       |r1t        j                  ddj5                  |             tE        |       y y |rt        d|z         y # t        j                  $ r}t        d
|z        |d }~ww xY w# t        j                  $ r!}
t        j'                  d|	|
       Y d }
~
y d }
~
ww xY wc c}}w # t8        $ r! t        j:                  t        d|z         Y w xY w)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-communicaterD   z/etc/default/lxd-bridgezSetting lxd debconf via %s
zset  zFailed to run '%s' for lxd withz Running dpkg-reconfigure for lxd)zdpkg-reconfigurer   z--frontend=noninteractive)net_namedid_initr5   attachzCreating lxd bridge: %sz!Setting up default lxd bridge: %sz*Unable to configure lxd bridge without %s.)#r7   r;   debugr   r   r   r   r   r   wait_for_snap_seededr$   r   whichr:   RuntimeErrorget_required_packageslendistroinstall_packageswarningrC   _DEFAULT_NETWORK_NAMEospathexistsbridge_to_debconfr   items	Exceptionlogexcdel_filebridge_to_cmdmaybe_cleanup_defaultbool_lxc)rD   rE   rF   rG   lxd_cfgr   r    r   epackagesexc
dconf_commrS   debconfr@   vrP   
cmd_create
cmd_attachs                      r#   handleru   x   s   ggenG		F	
 	gt$g''(+
 	

 	e${{62&H++i,KXr*J"8ZE::e	II01
 %X{;H
8}	LL))(3
 	II34		.[A! 'J>>&*?@77>>34:

 (
3G		6
CII:A--/J$!Q1-J   		01= MM34 II89IINO &3:%>"J
!!hJ'J'	 		3SXXj5IJZ 		7*9M Z 	  
8:E
 	
 
O )) 	59	 )) 	KK;XsK	8 K
  :ZGsT   L
 :L4 04M1 $M+
6#M1 
L1L,,L14M(M##M(+M1 1&NNc                 x   i }| j                  d      dk(  rd|d<   d|d<   |S | j                  d      dk(  r d|d<   d|d	<   | j                  d
      |d<   |S | j                  d      dk(  r3d|d<   | j                  d
      r| j                  d
      |d<   | j                  d      r~d|d<   | j                  d      |d<   | j                  d      |d<   | j                  d      |d<   | j                  d      |d<   | j                  d      |d<   | j                  dd      |d<   | j                  d      rBd|d<   | j                  d      |d<   | j                  d      |d<   | j                  dd      |d<   | j                  d       r| j                  d       |d!<   |S t        d"| j                  d      z        )#Nmodenonefalsezlxd/setup-bridgerK   zlxd/bridge-nameexistingtruezlxd/use-existing-bridgerD   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   rY   )r   rq   s     r#   rc   rc      s   G~~f'&-"#%'!"R NO 
	:	-&-"#-3)*%/^^F%;!"H NE 
	5	(&,"#>>&!)3)?G%&>>.))/G%&1;1OG-.1;1OG-.4>NN!5G01 4>>> 4G/0 6@^^"6G12 .8^^J-OG)*>>.))/G%&1;1OG-.1;1OG-.-7^^G.G)* >>(#+5>>(+CG'(
 N 5
v8NNOOr%   c                    | j                  d      dk(  ry| j                  dt              }g }dd|ddg}| j                  d      d	k(  rd |fS | j                  d      d
k7  rt        d| j                  d      z        dd|g}| j                  d      r| j                  d      r|j                  d| j                  d      d| j                  d             | j                  dd      dk(  r|j                  d       | j                  d      r\| j                  d      rK| j                  d      d| j                  d      }|j                  d|z         n|j                  d       | j                  d      rl| j                  d      r[|j                  d| j                  d      d| j                  d             | j                  d      dk(  r#|j                  d       n|j                  d       | j                  d      r#|j                  d | j                  d      z         | j                  d!d"      }|d"k7  r|j                  d#|        ||fS )$Nrw   rx   )NNrD   networkzattach-profiler6   eth0rz   r|   r   r5   r}   r~   zipv4.address=/r   r{   zipv4.nat=truer   r   r0   zipv4.dhcp.ranges=%szipv4.address=noner   r   zipv6.address=r   zipv6.nat=truezipv6.address=noner   zdns.domain=%smtuzbridge.mtu=)r7   r_   rY   r   )r   bridge_namers   rt   
dhcp_ranger   s         r#   rh   rh     s-   ~~f'..)>?KJ-{IvNJ~~f+Z~~f&5
v8NNOOX{3J~~n%*..*H~~n-z~~n/MO	

 >>*f-7o.>>+,2
 01/0J 3j@A-.~~n%*..*H~~n-z~~n/MO	

 >>*%/o. 	-.~~h/JNN8,DDE ..
#C
byKu-.z!!r%   c                     dt         j                  j                  dd      t         j                  j                  dd      d}t        j                  dgt	        |       z   dgz   |	       y )
NCHOMEz/rootUSERroot)LC_ALLr   r   r3   z--force-local)
update_env)r`   environr7   r   list)r?   envs     r#   rk   rk   J  sS    

vw/

vv.C
 	IIugS	!_$55#Fr%   c                 J   | t         k7  s|syd}d}|rQd}	 t        dd| |g       t        j                  || ||       d}t        dd| g       t        j                  || |       |r,d
}	 t        ddd||g       t        j                  ||||       yy# t        j
                  $ r3}	|	j                  d	k7  r|	t        j                  || ||       Y d}	~	pd}	~	ww xY w# t        j
                  $ r3}	|	j                  d	k7  r|	t        j                  ||||       Y d}	~	yd}	~	ww xY w)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-profilezDeletion of lxd network '%s' %sdelete   z+Removal of device '%s' from profile '%s' %sprofiledeviceremove)r_   rk   r;   rV   r   r:   	exit_code)
rS   rT   r5   rU   r   nic_namefail_assume_enoent	succeededmsgrm   s
             r#   ri   ri   S  s-    ((=I?
	0)-xABIIc8Wi8 4C)Xx01IIc8Y/;	B)Xx(CDIIc8Wi8	  )) 	B{{aIIc8W.@AA	B )) 	B{{aIIc8W.@AA	Bs/   'B )(C C&)CCD"/)DD"r   r    c                 b   g }g }i }d| v r|j                  | d          |rd|v r	 t        j                  |      }|j                  dg       D ](  }|j                  d      s|j                  |d          * d|v r&t        j                  d      s|j                  d       d|v r&t        j                  d      s|j                  d	       d
|v r&t        j                  d      s|j                  d       |S # t        j                  t        t
        f$ r t        j                  d       Y w xY w)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-linuxr2   lvcreatelvm2btrfsz
mkfs.btrfszbtrfs-progs)r   yaml	safe_load	YAMLError	TypeErrorr   r;   r^   r7   r   rX   )r   r    rn   storage_driverspreseed_cfgr,   s         r#   rZ   rZ   {  s   H "$OKH$x(9:;+5	..5K $< ;H%""<#9:; 

5(9()

:(>/!$**\*B&O 	:6 	KK1	s   C8 83D.-D.)r6   r   )#__doc__loggingr`   typingr   r   r   	cloudinitr   r   cloudinit.cloudr   cloudinit.configr   cloudinit.config.schemar	   cloudinit.settingsr
   	getLoggerr   r;   r_   r   __annotations__r$   rC   r   r   ru   rc   rh   rk   ri   r   rZ    r%   r#   <module>r      s    E  	     ! # . +g!   z %w	j  ,F1hb
 b
6 b
% b
t b
 b
J.b9"xG EK%BPD s tCy r%   