
    x[hVH                        % S r SSKrSSKrSSKrSSKrSSKrSSKJrJrJ	r	J
r
Jr  SSKJrJrJr  SSKJr  SSKJr  SSKJr  SSKJr  S	S
/\/ S.r\\S'   SrSrSrSrSrSr\R@                  " \!5      r"S r#S r$S r%S7S jr&S7S jr'S\(S\	\(   S\\(\(4   S\)4S jr*S8S jr+S\(S\(SS4S  jr,S9S! jr-S" r.S\
\\(   \\(\(4   \\(   4   4S# jr/S$\\	\\	\(            S\\(\(4   S%\\(\(4   S&\\	\(      S'\S\\\(      4S( jr0S$\\\(      S\\\(      4S) jr1S$\\\(      S*\(S\\(\(4   S%\\(\(4   S'\S\\\(      4S+ jr2S,\\\(      S\\\(      4S- jr3S,\\\(      SS4S. jr4S/\)S0\)S1\\(   SS4S2 jr5S3\(S4\S'\S5\6SS4
S6 jr7g):z-Mounts: Configure mount points and swap files    N)DictListOptionalTuplecast)performancesubputil)Cloud)Config)
MetaSchema)PER_INSTANCE	cc_mountsall)iddistros	frequencyactivate_by_schema_keysmetaz&^([x]{0,1}[shv]d[a-z][0-9]*|sr[0-9]+)$z^.+:.*z
/etc/fstabzcomment=cloudconfig   i   @c                     U S;   a  gS H2  nU R                  U5      (       d  M  U R                  S5      S:X  d  M2    g   g)N)amirootswapT)	ephemeralebs:F)
startswithfind)nameenumnames     </usr/lib/python3/dist-packages/cloudinit/config/cc_mounts.pyis_meta_device_namer$   ,   s@    && )??8$$32)= )     c                 F    [         R                  " [        U 5      (       a  gg)NTF)rematchNETWORK_NAME_FILTER)r!   s    r#   is_network_devicer*   8   s    	xx#T**r%   c                     [        U5      SU< 3SU< 3/nU H3  nU < U< 3n[        R                  R                  U5      (       d  M1  Us  $    g )Npz-part)strospathexists)device_pathpartition_numberpotential_suffixessuffixpotential_partition_devices        r#   _get_nth_partition_for_devicer6   ?   sU    !#%'
 %/:F%C"77>>455-- % r%   c                    [         R                  R                  U 5      R                  S5      S   n[         R                  R	                  SU5      nUbO  [         R                  R	                  U[         R                  R                  U5      R                  S5      S   5      n[         R                  R                  U5      $ )N/r   z/sys/block/)r.   r/   realpathsplitjoinr0   )r1   partition_pathdevice_namesys_paths       r#   _is_block_devicer?   L   s    ''"";/55c:2>Kww||M;7H!77<<bgg&&~6<<SA"E
 77>>(##r%   c                    [         R                  SU 5        U nUS:X  a  Sn[         R                  S5        [        U 5      (       a  U $ [        R                  " U5      u  pEUnU(       a,  UR                  XD5      nXd:w  a  [         R                  SXd5        [        U5      (       aC  U" U5      nU(       d  g UR                  S5      (       d  SU< 3n[         R                  SXd5        O&[        R                  " [        U 5      (       a  SU< 3nS nUc  [        US	5      nO[        XE5      nUc  g [        XG5      (       a  Ub  U$ U$ g )
Nz+Attempting to determine the real name of %sr   
ephemeral0z2Adjusted mount option from ephemeral to ephemeral0zMapped device alias %s to %sr8   z/dev/zMapped metadata name %s to %s   )LOGdebugr*   r
   expand_dotted_devnamegetr$   r   r'   r(   DEVICE_NAME_FILTERr6   r?   )	startnametransformeraliasesdevnamer1   r2   origr<   s           r#   sanitize_devnamerM   V   s-   II;YG G+		FG##$($>$>w$G!KDkk+;II4dH;''!+.%%c**'24K		14E88&	22'24KN6{AF6
 !44%!!r%   original	sanitized
fstab_devsreturnc                     X:w  a  [         R                  SX5        Uc  [         R                  SU 5        gX;   a  [         R                  SUX!   5        gg)z*Get if the sanitized device name is valid.zchanged %s => %sz+Ignoring nonexistent default named mount %sFz&Device %s already defined in fstab: %sT)rC   rD   )rN   rO   rP   s      r#   sanitized_devname_is_validrS      sW     		$h:		?J		 		4!	

 r%   c           	         U c  [         R                  " 5       S   n U S-  nSXS.nUc  Uc  UnOrU(       af  [        R                  " U5      nUR                  UR
                  -  nXdS'   Uc  [        [        US-  5      U5      nOXS-  :  a  [        US-  5      nOUc  UnXS'   U S[        -  :  a  U nODU S	[        -  :  a
  S[        -  nO-[        [        R                  " U [        -  5      5      [        -  n[        Xq5      nXS
'   0 n	UR                  5        H.  u  p[        U[        5      (       a  SU[        -  -  X'   M*  XU
'   M0     [        R!                  SU	S
   U	S   U	S   U	S   U	S   5        U$ )Ntotal   na)availmax_inmemrX      g?max   sizez%s MBzCsuggest %s swap for %s memory with '%s' disk given max=%s [max=%s]'rZ   rY   )r
   read_meminfor.   statvfsf_frsizef_bfreeminintGBroundmathsqrtitems
isinstanceMBrC   rD   )memsizemaxsizefsyssugg_maxinfor`   rX   minsizer^   pinfokvs               r#   suggested_swapsizeru      ss   ##%g.{HW=D|	**T"  7??2W?#eai.(3G&%#+&G	KR	27	b&		'B,/025w DLE

a!b&)EH!H	  IIMfeghe Kr%   fnamer^   c                   ^^ SmUU4S jn[         R                  R                  U 5      n[        R                  " U5        [        R
                  " U5      S   mTS:X  a3  [        R                  " SSSU /5        [        R                  " SS	U /5        TS
:X  a#  [        R                  " 5       S:  a
  U" XS5        O
 U" XS5        [         R                  R                  U 5      (       a  [        R                  " U S5         [        R                  " SU /5        g! [        R                   a!    [        R                  S5        U" XS5         Nf = f! [        R                   a    [        R                  " U 5        e f = f)zSize is in MiB.z6Failed to create swapfile '%s' of size %sMB via %s: %sc                 j  > [         R                  SU TU5        US:X  a
  SSSU-  U /nO*US:X  a  SSSU -  SS	U-  /nO[        R                  " S
5      e [        R                  " USS9  g ! [        R                   a3  n[         R	                  TXX$5        [
        R                  " U 5        e S nAff = f)Nz3Creating swapfile in '%s' on fstype '%s' using '%s'	fallocatez-lz%sMddzif=/dev/zerozof=%szbs=1Mzcount=%sz:Missing dependency: 'dd' and 'fallocate' are not availableT)capture)rC   rD   r	   ProcessExecutionErrorrp   r
   del_file)rv   r^   methodcmdeerrmsgfstypes        r#   create_swap$create_swapfile.<locals>.create_swap   s    		A		
 [ edlE:Ct^%T!C ,,L 	IIc4()) 	HHVU&4MM% 	s   A+ +B2?.B--B2rB   btrfstruncatez-s0chattrz+Cxfs)r[      rz   ry   z4fallocate swap creation failed, will attempt with ddi  mkswapN)r.   r/   dirnamer
   
ensure_dirget_mount_infor	   kernel_versionr|   rC   rp   r0   chmodr}   )rv   r^   r   swap_dirr   r   s       @@r#   create_swapfiler      s1    FF< wwu%HOOH  *1-F		:tS%01		8T5)*4..07:E&	+[1
 
ww~~e

5% 		8U#$ )) 	+HHKLT*	+ %% es   =	D E 2EE,E?c                    [         R                  R                  U 5      n[        U5      R	                  5       S:X  a9   [
        R                  " 5       S   n[
        R                  " U5        [        X2US9n[        [        US-  5      5      nU(       d  [        R                  S5        g[        R                  " S5         [        X5        SSS5        U $ ! [         a    [        R                  S5         gf = f! , (       d  f       U $ = f)	z
fname: full path string of filename to setup
size: the size to create. set to "auto" for recommended
maxsize: the maximum size
autorU   z)Not creating swap: failed to read meminfoN)rn   rm   rl   r   z'Not creating swap: suggested size was 0zSetting up swap file)r.   r/   r   r-   lowerr
   r_   IOErrorrC   rD   r   ru   rd   r   Timedr   )rv   r^   rm   r   rl   mibsizes         r#   setup_swapfiler     s     wwu%H
4yF"	'')'2G
 	!!G
 #den%&G		;<			1	2' 
3 L#  	IIAB	 
3	2 Ls   C  C;C87C8;
D
c                 .   [        U [        5      (       d  [        R                  S5        gU R	                  SS5      nU R	                  SS5      nU R	                  SS5      nU(       a  U(       d  [        R                  S5        g[        R                  R                  U5      (       a  [        R                  R                  S	5      (       d  [        R                  S
U5        U$  [        R                  " S	5      R                  5        H6  nUR                  US-   5      (       d  M  [        R                  SU5        Us  $    [        R                  SU5         [        U[        5      (       a  US:w  a  [        R                  " U5      n[        U[        5      (       a  [        R                  " U5      n[!        XUS9$ ! [         a    [        R                  SU5        Us $ f = f! [         a   n[        R                  SU5         SnAgSnAff = f)zYhandle the swap config, calling setup_swap if necessary.
return None or (filename, size)
z%input for swap config was not a dict.Nfilenamez	/swap.imgr^   r   rm   zno need to setup swapz/proc/swapsz:swap file %s exists, but no /proc/swaps exists, being safe zswap file %s already in usez+swap file %s exists, but not in /proc/swapsz.swap file %s exists. Error reading /proc/swapsr   )rv   r^   rm   zfailed to setup swap: %s)rj   dictrC   warningrF   rD   r.   r/   r0   r
   load_text_file
splitlinesr   	Exceptionr-   human2bytesr   )swapcfgrv   r^   rm   liner   s         r#   handle_swapcfgr   /  s    gt$$;<KK
K0E;;vq!Dkk)T*GU		)*	ww~~eww~~m,,IIL L
	++M:EEG??53;//II;UC L H IICUK3dC  TV^##D)Dgs##&&w/GEgFF  	KK@% L		  3.223s7   '>G )G G A%G* "G'&G'*
H4HHc                  `   / n 0 n/ n[         R                  R                  [        5      (       a}  [        R
                  " [        5      R                  5        HQ  n[        U;   a  UR                  U5        M   UR                  5       nU(       d  M9  X1US   '   U R                  U5        MS     XU4$ )aW  Parse /etc/fstab.

Parse fstab, ignoring any lines containing "comment=cloudconfig".
:return: A 3-tuple containing:
    - A list of lines exactly as they appear in fstab
    - A dictionary with key being the first token in the line
      and value being the entire line
    - A list of any lines that were ignored due to "comment=cloudconfig"
r   )
r.   r/   r0   
FSTAB_PATHr
   r   r   MNT_COMMENTappendr:   )fstab_linesrP   fstab_removedr   tokss        r#   parse_fstabr   _  s     KJM	ww~~j!!''
3>>@Dd"$$T*::<Dt&*47#""4( A M11r%   mountsdevice_aliasesdefault_fieldscloudc                    / nU  H  n[        U[        5      (       d  [        R                  SU5        M0  [	        US   5      n[        XtR                  US9n[        XxU5      (       a
  U/USS -   n	OUn	[        U	5       H  u  pUc  X:   X'   M  [	        X   5      X'   M!     X[        U	5      S -  n	UR                  U	5        M     U$ )zSanitize mounts to ensure we can work with devices in config.

Specifically:
 - Ensure the mounts configuration is a list of lists
 - Transform and sanitize device names
 - Ensure all tokens are strings
 - Add default options to any lines without options
z%Mount option not a list, ignoring: %sr   rJ   rB   N)rj   listrC   r   r-   rM   device_name_to_devicerS   	enumeratelenr   )r   rP   r   r   r   updated_linesr   startsanitized_devnameupdated_lineindextokens               r#   sanitize_mounts_configurationr   y  s     M$%%KK?FDG,..
 &e
KK-.ab9LL &l3LE}&4&;#&),*=&>#	 4 	s<'8':;;\*5 6 r%   c                     / n/ nU SSS2    HR  nUS   b	  US   U;   a/  [         R                  SUS   5        UR                  US   5        MA  UR                  U5        MT     USSS2   $ )zRemove any entries that have a device name that doesn't exist.

If the second field of a mount line is None (not the string, the value),
we skip it along with any other entries that came before it that share
the same device name.
Nr   rB   r   z$Skipping nonexistent device named %s)rC   rD   r   )r   actlistdev_denylistr   s       r#   remove_nonexistent_devicesr     su     GLtt7?d1g5II<d1gFQ(NN4   4R4=r%   default_mount_optionsc                 b  ^	 [         R                  " U 5      nSSSUSS// SQ4 H  m	T	S   n[        XdR                  US9n[	        XgU5      (       d  M/  [        [        U5      T	S'   [        U	4S	 jU  5       5      nU(       a  [        R                  S
U5        Mv  UR                  T	5        M     U$ )zwAdd default mounts to the user provided mount configuration.

Add them only if no other entry has the same device name
rA   z/mntr   r   2)r   noner   swr   r   r   r   c              3   8   >#    U  H  oS    TS    :H  v   M     g7f)r   N ).0cfgmdefault_mounts     r#   	<genexpr>,add_default_mounts_to_cfg.<locals>.<genexpr>  s       %
4:DG}Q''Fs   z-Not including %s, already previously included)copydeepcopyrM   r   rS   r   r-   anyrC   rD   r   )
r   r   rP   r   r   
new_mountsr   rO   default_already_existsr   s
            @r#   add_default_mounts_to_cfgr     s     v&J	vv'<c3G0 a $..
	 *%JGG  Y/a!$ %
4:%
 "
 "IIEuM-()* r%   r   c                 d    U  Vs/ s H  nUSS US    S[          3/-   USS -   PM      sn$ s  snf )z=Add "comment=cloudconfig" to the mount options of each entry.N   ,r[   )r   )r   entrys     r#   add_commentr     sQ     E 	bq	az;-011E!"I=  s   %-c                 d    [        S U  5       5      (       a  [        R                  " SS/5        gg)z1Call 'swapon -a' if any entry has a swap fs type.c              3   0   #    U  H  oS    S:H  v   M     g7f)rV   r   Nr   )r   r   s     r#   r   *activate_swap_if_needed.<locals>.<genexpr>  s     
37%8v7s   swapon-aN)r   r	   )r   s    r#   activate_swap_if_neededr     s)    

37
333		8T"# 4r%   uses_systemdchanges_madedirsc                 h   SnU(       a  SnOa[         R                  " 5       R                  5        Vs1 s H  nSU;   d  M  US   iM     nn[        [	        U5      R                  U5      5      nU(       a9  [        R                  " SS/5        U (       a  [        R                  " SS/5        gggs  snf )	zCall 'mount -a' if needed.

If changes were made, always call 'mount -a'. Otherwise, call 'mount -a'
if any of the directories in the mount list are not already mounted.
FT
mountpointmountr   	systemctlzdaemon-reloadN)r
   r   valuesboolset
differencer	   )r   r   r   do_mountvalmount_pointss         r#   mount_if_neededr     s     H {{}++-
-s" C- 	 

 D	,,\:;		7D/"II{O45  
s   
B/ 	B/r!   cfgargsc                    UR                   R                  5       nU(       a  SOSnSSSUSS/nUR                  SU5      nUR                  S/ 5      n[        R	                  S	U5        [        5       u  pnUR                  S
0 5      n[        XXU5      n[        XXU5      n[        U5      n[        U5      n[        UR                  S0 5      5      nU(       a  UR                  USSSSS/5        U(       d  [        R	                  S5        gU Vs/ s H  nSR                  U5      PM     nnU Vs/ s H#  nUS   R                  S5      (       d  M  US   PM%     nnU H  n [        R                  " U5        M     U Vs/ s H  nUR%                  SS5      PM     nnU Vs/ s H  nUR%                  SS5      PM     nnU Vs/ s H  nUU;  d  M  SU 3PM     snU Vs/ s H  nUU;  d  M  SU 3PM     sn-   nU	R'                  U5        SSR                  U	5      -  n[        R(                  " [*        U5        U(       a  [        R	                  SU5        O[        R	                  S5        [-        U5        [/        U[1        U5      U5        gs  snf s  snf ! [          a!    [        R"                  " [        SU5         GMh  f = fs  snf s  snf s  snf s  snf )z Handle the mounts configuration.zBdefaults,nofail,x-systemd.after=cloud-init-network.service,_netdevzdefaults,nobootwaitNr   r   r   mount_default_fieldsr   zmounts configuration is %sr   r   r   r   z No modifications to fstab needed	rB   r8   z Failed to make '%s' config-mountr   z- z+ z%s

zChanges to fstab: %szNo changes to /etc/fstab made.)distror   rF   rC   rD   r   r   r   r   r   r   r   r;   r   r
   r   r   logexcreplaceextend
write_filer   r   r   r   )r!   r   r   r   r   r   hardcoded_defaultsr   r   r   rP   r   r   updated_cfgswapfiler   	cfg_linesdr   nsaddssdropsdropaddsopscontentss                             r#   handler    s    <<,,.L  	M"  f.CS#N*-'' 2+N 36''(B2GFII*F3-8]*K]WW-r2N/NEK ,JK -[9Kk*Kcggfb12HHffdCEF
 			45/:;{e5!{I;%>+Q1)=DAaD+D>	DOOA  ,559aQYYtS!9E5,9:Mqaiic"MF:$*@FDd%.?KbKF@#D#ss&'8
"SE
eD D y!		+..HOOJ)		($/		23K(L$t*d37 <>
  	DKK?CC	D 6:@ DsH   J2J	J$JK$K
K	K#
K1	K&K	K	)N)NNN)NN)8__doc__r   loggingrg   r.   r'   typingr   r   r   r   r   	cloudinitr   r	   r
   cloudinit.cloudr   cloudinit.configr   cloudinit.config.schemar   cloudinit.settingsr   r   __annotations__rG   r)   r   r   rk   re   	getLogger__name__rC   r$   r*   r6   r?   rM   r-   r   rS   ru   r   r   r   r   r   r   r   r   r   r   r   r  r   r%   r#   <module>r     s   4    	 	 4 4 - - ! # . + w!	j  ?  
#

!	
$.b&sm9=c3h	&6r;3 ;c ;d ;|<-`2U49d38nd3i?@ 24+$x}-./+S#X+ cN+ #'	+
 + 
$s)_+\tDI 4S	? &!cO!! S#X! cN	!
 ! 
$s)_!Hd3i T$s)_ $T$s)_ $ $66&*626s)6	62E4 E46 E4% E4t E4 E4r%   