
    ܍~c`             
       	   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZ
d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlmZmZ d dlmZmZ d dlmZm Z  d dl!m"Z"m#Z# d dl$m%Z%m&Z&m'Z'm(Z(m)Z) d dl*m+Z+ d dl,m-Z- d d	l,m.Z/ d d
l,m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 d dl7m8Z8 da9 e/j:        e;          Z<e
j=        diZ>dej?        z   ej@        z   ZAdZBdZCd ZD e"            dd            ZE e"            dd            ZFddZGddZHd ZId ZJd ZK G d d          ZL G d deM          ZN G d deM          ZOd ZPdd ZQdd!ZRdd"ZSdd$ZTdd%ZUdd&d'e'fd(ZVd) ZWd* ZXd+ ZYdd-ZZd. Z[d/e\d'e]fd0Z^d1 Z_d,d,de/j`        d,fd2Za e"            d3             Zb e"            d4             Zc e"            d5             Zd e"            d6             Ze e"            d7             Zf e"            d8             Zgdd:Zhdd;Zidd<Zjdd=Zk e"            d>             Zld? Zm e"            d@             ZnddAZoddBZpdC ZqddDZrdd'e]fdEZse jt        dF             Zue jt        dG             ZvdH ZwdI ZxddLZyddMZzde]ffdNZ{ddPZ|dd&d'e]fdQZ}dd&d'e]fdRZ~ddSZddTZdU Z edVg dW          ZddXZddZZd[ Zd\ Zd] Zd^ Zd_ Zd` Z	 ddbZ	 ddcZ	 dddZ	 ddeZ	 ddfZddgZdh Zdi ZddjZ e"            dk             Zdl ZddnZddoZddpZdq Zdr Zds ZddtZdu Zdv Zdw ZddyZe]ffdzZd{ Zd| Zdd}Ze jt        d~             Zd Z	 ddZd Zd ZddZd Zd Zd Z e"            d             Zd Zd Z	 dd9ddeded'dfdZd Zd Zde\d'efdZde\d'efdZde\d'e\fdZde\d'e\fdZde\d'e(e\         fdZ	 	 	 dd,ddZd ZddZd ZddZddZd Zd Zd Zd Z e"            d             Zd ZddZd Zd Zd Ze<d9fdZd Zd Zd Zd Zd Zd Zd Ze<d9fdZde\d'efdZ e)d          Z	 	 	 dde%def         d'efdZd Zdde
j        j=        fdZddZd ZddZdÄ ZddĄZdń ZdƄ ZddǄZddɄZdʄ Zdd˄Zd̄ ZddτZe# G dЄ d edg dҢ                                ZdS )    N)	b64decode	b64encode)deque
namedtuple)EACCESENOENT)	lru_cachetotal_ordering)CallableDequeDictListTypeVar)parse)importer)log)mergerssafeyamlsubp
temp_utils
type_utils
url_helperversion)CFG_BUILTIN_z_-.())true1onyes)off0nofalsec                      t          t          t          t          j                    j                            d          d d                             S )N.   )tuplemapintosunamereleasesplit     0/usr/lib/python3/dist-packages/cloudinit/util.pykernel_versionr1   C   s:    S"(**,22377;<<===r/   c                 f    t          j         ddgd|           }|j                                        S )zReturn the sanitized string output by `dpkg --print-architecture`.

    N.B. This function is wrapped in functools.lru_cache, so repeated calls
    won't shell out every time.
    dpkgz--print-architectureTcapturetarget)r   stdoutstrip)r6   outs     r0   get_dpkg_architecturer:   G   s=     )	'($v  C :r/   c                 z  	 ddddd}i 		 t          j         ddgd| 	          }|j                                        D ]<}|                    d
          \  }}}||v r|                                	||         <   =	fd|                                D             }t          |          r.t                              dd	                    |                     nb# t           j
        $ rP}t                              d|           t          d |                                D                       	Y d }~nd }~ww xY w	S )Ncodenamedescriptionidr,   )CodenameDescriptionzDistributor IDReleaselsb_releasez--allTr4   :c                     g | ]}|v|	S r.   r.   ).0kdatas     r0   
<listcomp>zlsb_release.<locals>.<listcomp>d   s    ===q}}1}}}r/   z.Missing fields in lsb_release --all output: %s,z#Unable to get lsb_release --all: %sc              3      K   | ]}|d fV  	dS )UNAVAILABLENr.   rE   vs     r0   	<genexpr>zlsb_release.<locals>.<genexpr>m   s'      >>1Q&>>>>>>r/   )r   r7   
splitlines	partitionr8   valueslenLOGwarningjoinProcessExecutionErrordict)
r6   fmapr9   linefnamer   valmissingerrrG   s
            @r0   rB   rB   T   s^    $	 D D?i0$vNNNJ))++ 	0 	0D NN3//ME1c}}$'IIKKT%[!====dkkmm===w<< 	KK@!!  
 % ? ? ?93???>>>>>>>? Ks   CC D8(AD33D8utf-8c                 Z    t          | t                    r| S |                     |          S N)
isinstancestrdecode)blobencodings     r0   decode_binaryrf   r   s+    $ ;;x   r/   c                 Z    t          | t                    r| S |                     |          S r`   )ra   bytesencode)textre   s     r0   encode_textrk   y   s+    $ ;;x   r/   c                 p    t          |           }	 |                    d          S # t          $ r |cY S w xY wNr^   )r   rc   UnicodeDecodeError)sourcedecodeds     r0   b64drq      sL     G~~g&&&   s   & 55c                     t          | t                    s|                     d          } t          |                               d          S rm   )ra   rh   ri   r   rc   )ro   s    r0   b64ers      sC     fe$$ (w''V##G,,,r/   c                    |                      d          }|                                 dk    rRt          |t                    r=|                                 }|r|j        r|j        }nd}|                    |d          S |S )NTrc   rj   r^   surrogateescape)get_payloadget_content_maintypera   rh   get_charsetinput_codecrc   )partcte_payloadcharsetre   s       r0   fully_decoded_payloadr~      s     ""$"//K  ""f,,U2 2, ""$$ 	w* 	*HHH!!(,=>>>r/   c                   "    e Zd ZddZd Zd ZdS )SeLinuxGuardFc                     	 t          j        d          | _        n# t          $ r
 d | _        Y nw xY w|| _        || _        d S )Nselinux)r   import_moduler   ImportErrorpath	recursive)selfr   r   s      r0   __init__zSeLinuxGuard.__init__   sS    	 #1)<<DLL 	  	  	 DLLL	 	"s    00c                 J    | j         r| j                                         rdS dS NTF)r   is_selinux_enabledr   s    r0   	__enter__zSeLinuxGuard.__enter__   s+    < 	DL;;== 	45r/   c                 |   | j         r| j                                         sd S t          j                            | j                  sd S t          j                            | j                  }	 t          j        |          }| j                             ||t          j	                            n# t          $ r Y d S w xY wt                              d|| j                   	 | j                             || j                   d S # t          $ r-}t                              d|| j        |           Y d }~d S d }~ww xY w)Nz,Restoring selinux mode for %s (recursive=%s)r   z,restorecon failed on %s,%s maybe badness? %s)r   r   r*   r   lexistsrealpathlstatmatchpathconstatST_MODEOSErrorrS   debugr   
restoreconrT   )r   	excp_type
excp_valueexcp_tracebackr   statses          r0   __exit__zSeLinuxGuard.__exit__   s\   | 	4<#B#B#D#D 	Fwty)) 	Fw	**	HTNNEL%%dE$,,?@@@@ 	 	 	FF	 			:N	
 	
 	

	L##DDN#CCCCC 	 	 	KK>	        	s*   .?B. .
B<;B<!!D 
D;"D66D;NF)__name__
__module____qualname__r   r   r   r.   r/   r0   r   r      sF        # # # #      r/   r   c                       e Zd ZdS )MountFailedErrorNr   r   r   r.   r/   r0   r   r              Dr/   r   c                       e Zd ZdS )DecompressionErrorNr   r.   r/   r0   r   r      r   r/   r   c                 l   t          j                    }|dk    rl	  | |i | t          j        d           d S # t          $ r@ t	          t
          dt          j        |                      t          j        d           Y d S w xY wt
                              d|t          j        |                      d S )Nr   z&Failed forking and calling callback %s   z(Forked child %s who will run callback %s)	r*   fork_exit	ExceptionlogexcrS   r   obj_namer   )child_cbargskwargsfids       r0   fork_cbr      s    
'))C
axx		Hd%f%%%HQKKKKK 	 	 	8#H--  
 HQKKKKKK	 			6))	
 	
 	
 	
 	
s   9 ABBc                     t          | t                    r| du S t          }|rt          |          |z   }t	          |                                                                           |v rdS dS r   )ra   boolTRUE_STRINGSlistrb   lowerr8   r[   addons	check_sets      r0   is_truer      sl    # d{I -OOf,	
3xx~~9,,t5r/   c                     t          | t                    r| du S t          }|rt          |          |z   }t	          |                                                                           |v rdS dS NFT)ra   r   FALSE_STRINGSr   rb   r   r8   r   s      r0   is_falser      sl    # e|I -OOf,	
3xx~~9,,t5r/   c                 X    | sdS t          | t                    r| S t          | |          S NF)ra   r   r   )r[   r   s     r0   translate_boolr     s8      u# 
3r/       c                     t          j                    st          j        t          j        z   d                    fdt          d|           D                       S )N c                 :    g | ]}                               S r.   )choice)rE   _xrselect_froms     r0   rH   zrand_str.<locals>.<listcomp>  s%    EEEbAHH[))EEEr/   r   )randomSystemRandomstringascii_lettersdigitsrU   range)strlenr   r   s    `@r0   rand_strr     s]    A ;*V]:77EEEEEE!V4D4DEEEFFFr/   c                 H    |sd}	 t          d          dz   |z   }|| vrn|S )Nr   T   )r   r   )r   )
dictionarypostfixnewkeys      r0   rand_dict_keyr     sH     ###c)G3## Mr/   instance_data_filereturnc          	         ddl m}m}m} 	 t	          |           }n*# t
          $ r}|j        t          k    ri cY d}~S  d}~ww xY w|rt          j	        
                    |          rm	  ||| |          }t                              d||            nB# |$ r Y n;|$ r4}t                              d||t          |                     Y d}~nd}~ww xY w|i S t          |i           S )z>Read a yaml config with optional template, and convert to dictr   )JinjaLoadErrorNotJinjaErrorrender_jinja_payload_from_fileNz?Applied instance data in '%s' to configuration loaded from '%s'z:Could not apply Jinja template '%s' to '%s'. Exception: %sdefault)!cloudinit.handlers.jinja_templater   r   r   	load_fileIOErrorerrnor   r*   r   existsrS   r   rT   repr	load_yaml)rZ   r   r   r   r   config_filer   s          r0   	read_confr   "  s            &&   7fIIIIII	  bgnn-?@@ 	88" K
 II1"	     	 	 	 D 	 	 	KK "Q       	 	["----s9    
A>A>A()B CC*CCc                  .    t          t          |            S r`   )sorted
uniq_merge)listss    r0   uniq_merge_sortedr   T  s    *e$%%%r/   c                      g }| D ]_}t          |t                    r3|                                                    d          }d |D             }|                    |           `t          |          S )NrI   c                     g | ]}||S r.   r.   )rE   as     r0   rH   zuniq_merge.<locals>.<listcomp>f  s    ---A1-a---r/   )ra   rb   r8   r-   extend	uniq_list)r   combined_lista_lists      r0   r   r   `  s{    M % %fc"" 	.\\^^))#..F-----FV$$$$]###r/   c                    t                                           D ]\  }}|                     ||          } g }| D ] }|t          vr|                    |           !|D ]}|                     |d          } |                                 } | S )Nr   )FN_REPLACEMENTSitemsreplace
FN_ALLOWEDappendr8   )fnrF   rM   removalss       r0   clean_filenamer  k  s    !''))  AZZ1H  JOOA  ZZ2	BIr/   Tc                    	 t          j        t          |                     }t          j        t          j        d dd|                    5 }|r-t          |                                          cd d d            S |                                cd d d            S # 1 swxY w Y   d S # t          $ r+}|r| cY d }~S t          t          |                    |d }~ww xY w)Nrbr   )ioBytesIOrk   
contextlibclosinggzipGzipFilerf   readr   r   rb   )rG   quietrc   bufghr   s         r0   decomp_gzipr  x  s>   4jT**++dD!S A ABB 	!b !$RWWYY//	! 	! 	! 	! 	! 	! 	! 	!
 wwyy	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	!  4 4 4 	4KKKKKK$SVV,,!3	4sT   A
B) #B/B) <BB) B  B) #B $B) )
C3C6C<CCc                 Z   | sdS |                      dd          }|d                                         }t          |          dk    r|d                                         }nd }|r|dk    s|                                dk    rd }|r|dk    s|                                dk    rd }||fS )NNNrC   r   r   r&   z-1none)r-   r8   rR   r   )ug_pair	ug_partedugs       r0   extract_usergroupr    s     |c1%%I!A
9~~aL   T		QWWYY&00 T		QWWYY&00q6Mr/   root_dirc                    t                      }t          j        t          j                            | d                    D ]}}t          j                            |          s"t          j                            |          dd         }|                                }|r|                    d          dk    r|||<   ~|S )Nz*.pyr   r%   )	rW   globr*   r   rU   isfilebasenamer8   find)r  entriesrZ   modnames       r0   get_modules_from_dirr!    s    ffG27<<&99:: % %w~~e$$ 	'""5))!B$/--// 	%w||C((B..$GENNr/   c                     t          | d          5 }|                    |           |                                 d d d            d S # 1 swxY w Y   d S )Nw)openwriteflush)conpathrj   wfhs      r0   write_to_consoler)    s    	gs		 s		$		                 s   *AAAc                 8   |rt           j                            |            |rd}d}t          j                            |          rj	 t          ||            d}nV# t          $ rI d}t           j                            | d           |r |	                    t          j        |           Y nw xY w|r!|st           j                            |            |rD| d         dk    r |	                    || d d                    d S |	                    ||            d S d S )Nz/dev/consoleFTzFailed to write to /dev/console
r  )sysstderrr%  r*   r   r   r)  r   r7   r   loggingWARNING)	rj   consoler-  r   	log_levelfallback_to_stdoutr'  writing_to_console_workedconsole_errors	            r0   	multi_logr5    sO     
 # $)!7>>'"" 	<< $///,0)) < < < A
  M!5!5!5666 <GGGO];;;	<  	#&? 	# JT"""
 %8tGGItCRCy)))))GGIt$$$$$	% %s   A AB.-B.c                  ,    dt          j                    v S )NLinuxplatformsystemr.   r/   r0   is_Linuxr;    s    ho''''r/   c                  f    dt          j                    v rdS t          j                    dk    rdS dS )NBSDT	DragonFlyFr8  r.   r/   r0   is_BSDr?    s7    !!!!tK''t5r/   c                  2    t                      d         dk    S )Nvariantfreebsdsystem_infor.   r/   r0   
is_FreeBSDrE        ==#y00r/   c                  2    t                      d         dk    S )NrA  	dragonflyrC  r.   r/   r0   is_DragonFlyBSDrI    s    ==#{22r/   c                  2    t                      d         dk    S )NrA  netbsdrC  r.   r/   r0   	is_NetBSDrL    s    ==#x//r/   c                  2    t                      d         dk    S )NrA  openbsdrC  r.   r/   r0   
is_OpenBSDrO    rF  r/   Fc                 8    || vr|S t          | |                   S r`   )r   yobjkeyr   s      r0   get_cfg_option_boolrT    s"    
$$s)$$$r/   c                 j    || vr|S | |         }t          |t                    st          |          }|S r`   )ra   rb   )rR  rS  r   r[   s       r0   get_cfg_option_strrV    s;    
$
s)Cc3 #hhJr/   c                 @    t          t          | ||                    S )Nr   )r)   rV  rQ  s      r0   get_cfg_option_intrX    s     !$W===>>>r/   c                    | sd} t           j                            |           si S t          |           }d}d|v rd}t	          j        ||          }|r|                                }d|d         v r|d         |d<   |d                                                             d          d         |d<   |d         d	k    rd
|d<   |d         |d         |d         dS i S )zReturn a dictionary of distro info fields from /etc/redhat-release.

    Dict keys will align with /etc/os-release keys:
        ID, VERSION_ID, VERSION_CODENAME
    z/etc/redhat-releasezA(?P<name>.+) release (?P<version>[\d\.]+) \((?P<codename>[^)]+)\)	Virtuozzoz)(?P<name>.+) release (?P<version>[\d\.]+)namer<   z linuxr   zred hat enterpriseredhatr   )ID
VERSION_IDVERSION_CODENAME)	r*   r   r   r   rematch	groupdictr   rP   )release_fileredhat_releaseredhat_regexra  groups        r0   _parse_redhat_releaserg    s     -,7>>,'' 	|,,N	#  n$$CH\>22E 
!! %-'' %fE*f++--77AA!Df=000$E&M-	* %j 1
 
 	

 Ir/   c                     d} d}d}i }d}t           j                            d          rt          t	          d                    }|sd}t                      }|r|                    dd          } |                    dd          }d| v sd| v rt          j                    }n| d	k    r|                    d
d          }n|| dk    r|s|                    d
d          }n]|                    dd          }|sEt          j
        d|                    dd                    }|r|                                d         }| dk    rd} nt                      r9t          j                                                    } t          j                    }n~d}	 t          j                    }n# t"          $ r Y nw xY wd }|D ]}|rd}|st$                              d           n-# d }|D ]}|rd}|st$                              d           w w xY w|S | ||fS )Nr   F/etc/os-releaseTr]  r^  slessusephotonPRETTY_NAME	virtuozzor_  z[^ ]+ \((?P<codename>[^)]+)\)VERSIONr<   rhelr\  )r   r   r   r   zPUnable to determine distribution, template expansion may have unexpected results)r*   r   r   load_shell_contentr   rg  getr9  machiner`  ra  rb  r?  r:  r   r,   distr   rS   rT   )	distro_namedistro_versionflavor
os_releaseos_release_rhelra  rt  foundentrys	            r0   get_linux_distror|  3  s   KNFJO	w~~'(( F'	2C(D(DEE
 -*,,
 - nnT2..#b99[  Fk$9$9
 %''FFH$$^^M266FFK'''^^M266FF^^$6;;F ;4NN9b11   ;"__..z:F&  "K	 o''--//!)++	=??DD 	 	 	D	 E   E <   E   E <   
 00s*   F" !G "
F/,G .F//G *Hc                     | d                                          }d}|dk    rA| d         d                                          }|dv r|}n |dv rd}n|d	k    rd
}n|dv rd}n	d}n|dv r|}|S )Nr:  unknownlinuxrt  r   )	almalinuxalpinearchcentos
cloudlinuxdebian	eurolinuxfedoramarinermiraclelinux	openeuleropenmandrivarl  rp  rockyrk  rn  )ubuntu	linuxmintmintr  r\  rp  )opensusezopensuse-tumbleweedzopensuse-leaprj  sle_hpcrk  )windowsdarwinrB  rK  rN  rH  )r   )infor:  rA  
linux_dists       r0   _get_variantr  q  s    (^!!##FG&\!_**,,
 
 
 
& !GG:::GG8##GG 
 
 
 GGGG	  
 
 Nr/   c                     t          j                     t          j                    t          j                    t          j                    t	          t          j                              t                      d} t          |           | d<   | S )N)r9  r:  r,   pythonr+   rt  rA  )r9  r:  r,   python_versionr   r+   r|  r  )r  s    r0   rD  rD    ss     %''/###%%)++hn&&'' "" D #4((DOKr/   c                     || vr|S | |         g S | |         }t          |t                    rd |D             }|S t          |t                    st          |          }|gS )a  
    Gets the C{key} config option from C{yobj} as a list of strings. If the
    key is present as a single string it will be returned as a list with one
    string arg.

    @param yobj: The configuration object.
    @param key: The configuration key to get.
    @param default: The default to return if key is not found.
    @return: The configuration option as a list of strings or default if key
        is not found.
    Nc                     g | ]}|S r.   r.   rL   s     r0   rH   z'get_cfg_option_list.<locals>.<listcomp>  s    ar/   )ra   r   rb   )rR  rS  r   r[   cvals        r0   get_cfg_option_listr    sx     $Cy	
s)C# 3c3 #hh5Lr/   c                     t          |t                    r|                    d          }| }|D ]}||vr|c S ||         }|S )a  Return the value of the item at path C{keyp} in C{yobj}.

    example:
      get_cfg_by_path({'a': {'b': {'num': 4}}}, 'a/b/num') == 4
      get_cfg_by_path({'a': {'b': {'num': 4}}}, 'c/d') == None

    @param yobj: A dictionary.
    @param keyp: A path inside yobj.  it can be a '/' delimited string,
                 or an iterable.
    @param default: The default to return if the path does not exist.
    @return: The value of the item at keyp."
        is not found./)ra   rb   r-   )rR  keypr   curtoks        r0   get_cfg_by_pathr    s[     $ zz#
C  c>>NNN#hJr/   c                 P    t          | |          \  }}t          ||           ||fS r`   )get_output_cfgredirect_output)cfgmodeoutfmterrfmts       r0   fixup_outputr    s1    %c400VVFF###Fr/   c                    t          t          j                            d                    rt                              d           d S |st          j        }|st          j        }d }| r6t                              d||            | 	                    dd          \  }}|dk    s|dk    rd	}|dk    rd
}t          ||          }nB|dk    r*t          j        |dt          j        |          }	|	j        }nt          d| z            |r9t          j        |                                |                                           || k    rWt                              d||            t          j        |                                |                                           d S |rt                              d||           |	                    dd          \  }}|dk    s|dk    rd	}|dk    rd
}t          ||          }nB|dk    r*t          j        |dt          j        |          }	|	j        }nt          d|z            |r=t          j        |                                |                                           d S d S d S )N_CLOUD_INIT_SAVE_STDOUTz5Not redirecting output due to _CLOUD_INIT_SAVE_STDOUTc                      t          j        d           	 t          j        d          j        } t          j        |            dS # t          $ r Y dS w xY w)a  Reconfigure umask and group ID to create output files securely.

        This is passed to subprocess.Popen as preexec_fn, so it is executed in
        the context of the newly-created process.  It:

        * sets the umask of the process so created files aren't world-readable
        * if an adm group exists in the system, sets that as the process' GID
          (so that the created file(s) are owned by root:adm)
           admN)r*   umaskgrpgetgrnamgr_gidsetgidKeyError)group_ids    r0   set_subprocess_umask_and_gidz5redirect_output.<locals>.set_subprocess_umask_and_gid  sd     		 |E**1H
 Ih	  	 	 	DD	s   A 
AAzRedirecting %s to %s r   >>>abwb|T)shellstdin
preexec_fnz"Invalid type for output format: %sz!Invalid type for error format: %s)r   r*   environrr  rS   r   r,  r7   r-  r-   r$  
subprocessPopenPIPEr  	TypeErrordup2fileno)
r  r  o_outo_errr  r  argowithnew_fpprocs
             r0   r  r    s   rz~~78899 		IJJJ 
 
     &  		(%888ll3**s3;;$$,,Es{{#u%%FFS[[# o7	  D ZFF@6IJJJ 	5GFMMOOU\\^^444VII,eV<<<GFMMOOU\\^^444F 5		(%888ll3**s3;;$$,,Es{{#u%%FFS[[# o7	  D ZFF?&HIII 	5GFMMOOU\\^^44444)5 5&	5 	5r/   c                     |rt          |           } i }| D ]W}|rSt          j        |          }|st          j                    }t          j        |          }|                    ||          }X|S r`   )reversedr   dict_extract_mergersdefault_mergers	constructmerge)srcsreverse
merged_cfgr  mergers_to_applymergers         r0   mergemanydictr  J  s     ~~J 7 7 	7&;C@@# =#*#:#<#< &'788Fj#66Jr/   c              #      K   t          j                    }	 t          j        |            | V  t          j        |           d S # t          j        |           w xY wr`   )r*   getcwdchdir)ndircurrs     r0   r  r  Y  sO      9;;D




s   A Ac              #      K   t          j        |           }	 |V  t          j        |           d S # t          j        |           w xY wr`   )r*   r  )n_mskolds     r0   r  r  c  sD      
(5//C			
s	   2 Ac                 4    d                     | |d|          S )Nz{0:{fill}{align}{size}}^)fillalignsize)format)rj   r  max_lens      r0   centerr  l  s(    $++4s ,   r/   c                 d    t                               d|            t          j        |            d S )NzRecursively deleting %s)rS   r   shutilrmtreer   s    r0   del_dirr  r  s-    II'...
M$r/   r      c                     	 t          |||          \  }}}|| d<   || d<   || d<   dS # t          j        $ r!}|j        t          j        k    rY d }~dS  d }~ww xY w)N	user-datavendor-data	meta-dataTF)read_seededr   UrlErrorcode	NOT_FOUND)r  baseexttimeoutmdudvdr   s           r0   read_optional_seedr  {  s    	"4g66R[ ][t   6Z)))55555s   $( AAAAc                    i }| sddg}nft           j                            |                     d          d          t           j                            |                     d          d          g}t          |          }d |D             }d }|D ]a}t           j                            t           j                            |d                    r"t           j                            |d          } nbd }|D ]a}t           j                            t           j                            |d                    r"t           j                            |d          } nb|r|r||d<   ||d	<   n|r||d<   |S )
Nz/var/lib/cloud/data/sslz /var/lib/cloud/instance/data/sslrG   sslc                 T    g | ]%}|t           j                            |          #|&S r.   )r*   r   isdir)rE   ds     r0   rH   z%fetch_ssl_details.<locals>.<listcomp>  s0    JJJA1Jq9I9IJaJJJr/   zcert.pemzkey.pem	cert_filekey_file)r*   r   rU   get_ipath_cur	get_cpathr   r  )pathsssl_detailsssl_cert_pathsr  r  r  s         r0   fetch_ssl_detailsr    s}   K 	
%.
 GLL,,V44e<<GLL00%88
  //NJJJJJNI  7>>"',,q*5566 	Q
33IE	 H  7>>"',,q)4455 	w||Ay11HE	  -X -#,K "*J	 -#,K r/   c                 6   |}t          |           } 	 t                              dt          |           |           t	          j        |           }|t                              d           |}n8t          ||          s(t          d|dt          j	        |          d          |}n# t          j
        t          t          f$ r}d}d }t          |d          r!t          |d          rt          |d          }n0t          |d          r t          |d          rt          |d          }|r,|d	                    |j        d
z   |j        d
z   |          z  }n|d                    |          z  }t                              |           Y d }~nd }~ww xY w|S )NzKAttempting to load yaml from string of length %s with allowed root types %sz-loaded blob returned None, returning default.zYaml load allows z root types, but got  insteadzFailed loading yaml blobcontext_markproblem_markz5. Invalid format at line {line} column {col}: "{err}"r   )rY   colr]   z. {err})r]   )rf   rS   r   rR   r   loadra   r  r   r   	YAMLError
ValueErrorhasattrgetattrr  rY   columnrT   )rd   r   allowedloaded	convertedr   msgmarks           r0   r   r     s   FD!		6II		
 	
 	
 M$''	IIEFFFIIIw// 	)77J/	::::<   	:6   (1n%% 	.'!^*D*D 	.1n--DDQ'' 	.GA~,F,F 	.1n--D 	+GNNQDK!O O  CC 9###***CC  Ms   BB* *FCFF
   c                    |                      d          dk    r| d|z   z  }| d|z   z  }| d|z   z  }n| d|}| d|}| d|}t          j        |||          }d }	|                                r#t	          t          |j                  i           }	t          j        |||          }
d }|
                                r|
j        }d }	 t          j        |||          }|                                r|j        }nRt                              d           n7# t          j	        $ r%}t                              d	|           Y d }~nd }~ww xY w|	||fS )
Nz%sr   r  r  r  )r  retriesr   zError in vendor-data responsez!Error in vendor-data response: %s)
r  r   read_file_or_urlokr   rf   contentsrS   r   r  )r  r  r  r  file_retriesud_urlvd_urlmd_urlmd_respr  ud_respr  r  vd_respr   s                  r0   r  r    s   yy!s*+,-s*+!T;;4!T==##6!T;;4)  G 
Bzz|| D}W%566CCC)  G 
Bzz|| 	B
7-GW
 
 
 ::<< 	7!BBII56666  : : :		5q99999999: B<s   D   E/EEc          	          t          t          j                   d          }d |D             } fd|D             }g }|D ]}	 |                    t	          t          j                             |          |                     F# t          $ r6}|j        t          k    rt                              d |           Y d}~d}~ww xY wt          |          S )zRead configuration directory.Tr  c                 <    g | ]}|                     d           |S )z.cfg)endswithrE   fs     r0   rH   zread_conf_d.<locals>.<listcomp>  s)    4441F!3!34Q444r/   c                     g | ]A}t           j                            t           j                            |                    ?|BS r.   )r*   r   r  rU   )rE   r/  confds     r0   rH   zread_conf_d.<locals>.<listcomp>  s<    HHH1UA0F0F!G!GHQHHHr/   r   z,REDACTED config part %s/%s for non-root userN)r   r*   listdirr   r   r   rU   r   r   r   rS   rT   r  )r1  r   confscfgsr   r   s   `     r0   read_conf_dr5    s    2:e$$d333E 54444E IHHHHHHE D  	KKGLL++'9       	 	 	w&  BE2  	 s   AB		
C	,CC	c                   t                      }i }	 t          | |          }|                    |           nB# t          $ r5}|j        t
          k    rt                              d|            Y d}~nd}~ww xY wd}d|v rh|d         }|r]t          |t                    s't          d| dt          j        |                    t          |                                          }n't          j                            |  d          r|  d}|rEt          j                            |          r&t#          ||          }|                    |           t'          |          S )	a  Read yaml file along with optional ".d" directory, return merged config

    Given a yaml file, load the file as a dictionary. Additionally, if there
    exists a same-named directory with .d extension, read all files from
    that directory in order and return the merged config. The template
    file is optional and will be applied to any applicable jinja file
    in the configs.

    For example, this function can read both /etc/cloud/cloud.cfg and all
    files in /etc/cloud/cloud.cfg.d and merge all configs into a single dict.
    r   z)REDACTED config part %s for non-root userNr   conf_dzConfig file z( contains 'conf_d' with non-string type z.d)r   r   r   r   r   r   rS   rT   ra   rb   r  r   r   r8   r*   r   r  r5  
appendleftr  )cfgfiler   r4  r  r   r1  	confd_cfgs          r0   read_conf_with_confdr;    s    DC4FGGG
 	C	  N N N7fKKCWMMMN E3H 	+eS)) +iww
 3E : : :<  
 E

((**	'~~~	&	&  #u%% #:LMMM		"""s   9 
A8+A33A8c                 <    t          t          |                     S )Ncmdline)r   read_cc_from_cmdliner=  s    r0   read_conf_from_cmdliner@  C  s    )':::;;;r/   c                    | t                      } d}d}t          |          }t          |          }t          |           }g }|                     |          }|dk    r|                     |||z             }|dk     r|}|                    t	          j        | ||z   |                                                                       dd                     |                     |||z             }|dk    d                    |          S )Nzcc:end_ccr   z\nr+  )	get_cmdlinerR   r  r   r   unquotelstripr   rU   )	r>  	tag_begintag_endbegin_lend_lclentokensbeginends	            r0   r?  r?  H  s    --IG)nnGLLEw<<DFLL##E
1**ll7EGO4477CM'%'/C"78??AABBJJt 	
 	
 	

 Ye44 1** 99Vr/   c                     |                      d          }|dk    s| |dz
           dk    r| S |                     dd          S )Nr+  r   r   z
)r  r   )r"  poss     r0   dos2unixrQ  j  sJ    
--

C
axx8C!G$,,FD)))r/   HostnameFqdnInfo)hostnamefqdn
is_defaultc                    d}d| v r3| d         }t          | d|                    d          d                   }nd| v rK| d                             d          dk    r,| d         }| d         d|                    d                   }nB|                    d|          j        }d| v r	| d         }n|                    |	          \  }}t          |||          S )
a  Get hostname and fqdn from config if present and fallback to cloud.

    @param cfg: Dictionary of merged user-data configuration (from init.cfg).
    @param cloud: Cloud instance from init.cloudify().
    @param metadata_only: Boolean, set True to only query cloud meta-data,
        returning None if not present in meta-data.
    @return: a namedtuple of
        <hostname>, <fqdn>, <is_default> (str, str, bool).
        Values can be none when
        metadata_only is True and no cfg or metadata provides hostname info.
        is_default is a bool and
        it's true only if hostname is localhost and was
        returned by util.get_hostname() as a default.
        This is used to differentiate with a user-defined
        localhost hostname.
    FrT  rS  r%   r   NT)rT  metadata_only)rW  )rV  r-   r  get_hostnamerS  rR  )r  cloudrW  rU  rT  rS  s         r0   get_hostname_fqdnrZ  x  s   " J}}6{%c:tzz#q7IJJZ!5!5c!:!:Q!>!> z?D:'73'78HH %% &    S  z?','9'9"/ (: ( ($* HdJ777r/   
/etc/hostsc                 j   d}	 t          |                                          D ]|}|                    d          }|dk    r
|d|         }|                                }|s>|                                }t          |          dk     rf| |dd         v r
|d         } n}n# t          $ r Y nw xY w|S )a  
    For each host a single line should be present with
      the following information:

        IP_address canonical_hostname [aliases...]

      Fields of the entry are separated by any number of  blanks  and/or  tab
      characters.  Text  from a "#" character until the end of the line is a
      comment, and is ignored. Host  names  may  contain  only  alphanumeric
      characters, minus signs ("-"), and periods (".").  They must begin with
      an  alphabetic  character  and  end  with  an  alphanumeric  character.
      Optional aliases provide for name changes, alternate spellings, shorter
      hostnames, or generic hostnames (for example, localhost).
    N#r      r&   r   )r   rO   r  r8   r-   rR   r   )rS  filenamerT  rY   hashpostokss         r0   get_fqdn_from_hostsrb    s     Dh''2244 	 	DiinnG!||AgI::<<D 
 ::<<D4yy1}}48##Aw $    Ks   BB# #
B0/B0c           	      n   t           t                      }d}i }|D ]}	 t          j        |dddt          j        t          j                  }g ||<   |D ]I\  }}}}	}
||                             |	d|
d                    |                    |
d                    J# t          j        t          j	        f$ r Y w xY w|a |rt                              d|           	 t          j        | d          }|d         d         d         }|t           v rdS dS # t          j        t          j	        f$ r Y dS w xY w)	a  determine if a url is resolvable, return a boolean
    This also attempts to be resilent against dns redirection.

    Note, that normal nsswitch resolution is used here.  So in order
    to avoid any utilization of 'search' entries in /etc/resolv.conf
    we have to append '.'.

    The top level 'invalid' domain is invalid per RFC.  And example.com
    should also not exist.  The '__cloud_init_expected_not_found__' entry will
    be resolved inside the search list.
    N)zdoes-not-exist.example.com.zexample.invalid.!__cloud_init_expected_not_found__r   : zdetected dns redirection: %s   FT)_DNS_REDIRECT_IPsetsocketgetaddrinfoSOCK_STREAMAI_CANONNAMEr   addgaierrorerrorrS   r   )r[  badipsbadnames
badresultsinameresult_fam_stype_protocnamesockaddraddrs               r0   is_resolvabler{    s~    

 
 
	 
	E	+4Av'96;N  %'
5!?E , ,;T665(u%,,-LMMMJJx{++++, OV\2   ! 	BII4jAAA#D$//ay|A###5tOV\*   uus$   A>BB<;B<2D D43D4c                  ,    t          j                    } | S r`   )ri  gethostname)rS  s    r0   rX  rX    s    !##HOr/   c                 d    	 t          j        |           d         S # t           j        $ r Y d S w xY wNr   )ri  gethostbyaddrherror)ips    r0   r  r    sA    #B''**=   tts    //c                 |    t          t          j        d| z   t          t	          j        |           j        f          S )z5determine if this url is resolvable (existing or ip).zResolving URL: )logfuncr  funcr   )log_timerS   r   r{  r   urlparserS  )urls    r0   is_resolvable_urlr    s<    	#nS!!*,	   r/   c                     | dS t                               d|            | D ]A}	 t          |          rt                               d|           |c S 2# t          $ r Y >w xY wdS )zc
    Search through a list of mirror urls for one that works
    This needs to return quickly.
    Nz%search for mirror in candidates: '%s'zfound working mirror: '%s')rS   r   r  r   )
candidatescands     r0   search_for_mirrorr    s    
 tII5zBBB  	 && 		6===  	 	 	D	4s   +A
A! A!c                  L   t          t          j                            d                    rdS t	          t          j                  5 } t          j        |                                 t          j	                                                   ddd           dS # 1 swxY w Y   dS )z
    reopen stdin as /dev/null so even subprocesses or other os level things get
    /dev/null as input.

    if _CLOUD_INIT_SAVE_STDIN is set in environment to a non empty and true
    value then input will not be closed (useful for debugging).
    _CLOUD_INIT_SAVE_STDINN)
r   r*   r  rr  r$  devnullr  r  r,  r  )fps    r0   close_stdinr  #  s     rz~~67788 	bj		 1R
		SY--//0001 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1s   ABB Bdevicec                 H   g }| s)t          j         d          t          j         d          z   S |                     d          r*|                     d          }d d|z   d|z   fD             }n5| dk    rt          j         d          }n| dk    rt          j         d          }|S )	Nz/dev/msdosfs/*z/dev/iso9660/*LABEL=c                 P    g | ]#}t           j                            |          !|$S r.   r*   r   r   )rE   ps     r0   rH   z*find_devs_with_freebsd.<locals>.<listcomp>9  s<     
 
 
w~~a  

 
 
r/   z/dev/msdosfs/z/dev/iso9660/	TYPE=vfatTYPE=iso9660)r  
startswithrE  )criteriaoformattagno_cacher   devlistlabels          r0   find_devs_with_freebsdr  1  s     G Iy)**TY7G-H-HHH8$$ 
.))
 
%-/FG
 
 

 
[	 	 ),--	^	#	#),--Nr/   c                    g }d }d }| rT|                      d          r|                     d          }|                      d          r|                     d          }t          j        g ddg          }|j                                        D ][}	|s|rt          j        d|	gddg          \  }
}|rd|z  |
vr-|d	k    rd
|
vr8|dk    rd
|
v rC|                    d|	z              \|S )Nr  zTYPE=sysctl-nzhw.disknamesr   rcs	mscdlabelr   z
label "%s"iso9660zISO filesystemvfat/dev/)r  rE  r   r7   r-   r   )r  r  r  r  r   r  r  _typer9   devmscdlabel_outr   s               r0   find_devs_with_netbsdr  E  s>    GEE -x(( 	.OOH--Ew'' 	-OOG,,E
)4441#
>
>
>Cz!! 	& 	& 	IE 	I#y+s);!QHHHM1 	,.=@@I"2-"G"GF??/=@@w}%%%%Nr/   c                    t          j         g ddg          }g }|j                                                            d          D ]t}|                    d          s|dk    r|                    |d d         dz              |                    d	          s |                    |d d         d
z              ud |D             S )Nr  r   r  rI   rC   zfd0:r  r   cdic                     g | ]}d |z   S r  r.   rE   r  s     r0   rH   z*find_devs_with_openbsd.<locals>.<listcomp>l      )))AGaK)))r/   )r   r7   rstripr-   r-  r   r  )r  r  r  r  r   r9   r  r{  s           r0   find_devs_with_openbsdr  ^  s     )4441#
>
>
>CG""$$**3// - -~~c"" 	F??uSbSzC'(((%% 	-NN5":+,,,))))))r/   c                 2   t          j         g ddg          }d t          |j                                        d          D             }| dk    rd |D             }n.| d	v rd
 |D             }n| rt                              d|            d |D             S )N)r  r  z
kern.disksr   r  c                 f    g | ].}|                     d           |                     d          ,|/S )r  vnr  r  s     r0   rH   z/find_devs_with_dragonflybsd.<locals>.<listcomp>s  sP       ||D!! +,,,t*<*<	  r/   Tr+  r  c                 f    g | ].}|                     d           s|                     d          ,|/S r  acdr  r  s     r0   rH   z/find_devs_with_dragonflybsd.<locals>.<listcomp>z  sM     
 
 
!,,t"4"4
89U8K8K

 
 
r/   )zLABEL=CONFIG-2r  c                 f    g | ].}|                     d           |                     d          ,|/S r  r  r  s     r0   rH   z/find_devs_with_dragonflybsd.<locals>.<listcomp>~  sP     
 
 
LL&&
 +,,,u*=*=

 
 
r/   zUnexpected criteria: %sc                     g | ]}d |z   S r  r.   r  s     r0   rH   z/find_devs_with_dragonflybsd.<locals>.<listcomp>  r  r/   )r   r   r7   r-   rS   r   )r  r  r  r  r   r9   r  s          r0   find_devs_with_dragonflybsdr  o  s     )222
<
<
<C 
((**D999  G >!!
 

 
 
 
4	4	4
 

 
 

 
 7		+X666))))))r/   c                 @   t                      rt          | ||||          S t                      rt          | ||||          S t	                      rt          | ||||          S t                      rt          | ||||          S dg}g }| r|                    d| z             |r|                    d|z             |r|	                    ddg           |r|                    d|z             |r|                    |           ||z   }	 t          j
        |ddg	          \  }}	n0# t          j        $ r}
|
j        t          k    rd
}n Y d}
~
nd}
~
ww xY wg }|                                D ]-}|                                }|r|                    |           .|S )z
    find devices matching given criteria (via blkid)
    criteria can be *one* of:
      TYPE=<filesystem>
      LABEL=<label>
      UUID=<uuid>
    blkidz-t%sz-s%s-c	/dev/nullz-o%sr   r&   r  r   N)rE  r  rL  r  rO  r  rI  r  r   r   r   rV   r   r   rO   r8   )r  r  r  r  r   
blk_id_cmdoptionscmdr9   _errr   r  rY   s                r0   find_devs_withr    s    || 	
%hhMMM	 
$XwXtLLL	 
%hhMMM			 
*gsHd
 
 	
 JG , 	v*+++
 'v~&&& , 	k*+++ + 	v)*** t
w
Ci!Q000dd%   7fCC CCCC G   ! !zz|| 	!NN4   Ns   D* *E9EEc                 h   | g } nt          |           } g d}|r|                    ddg           |                    |            t          j        |dd          }i }|j                                        D ]8}|                    d          \  }}}t          |          ||<   |||         d	<   9|S )
zGet all device tags details from blkid.

    @param devs: Optional list of device paths you wish to query.
    @param disable_cache: Bool, set True to start with clean cache.

    @return: Dict of key value pairs of info for the device.
    N)r  -ofullr  r  Tr   )r5   rc   rC   DEVNAME)r   r   r   r7   rO   rP   rq  )	devsdisable_cacher  r9   retrY   r  r   rG   s	            r0   r  r    s     |Dzz
!
!
!C (

D+&'''JJt
 )Ci
8
8
8C
C
%%'' " "~~c**Q%d++C!CJr/   c                     t                               d| |           t          | d          5 }|                    |          cd d d            S # 1 swxY w Y   d S )NzPeeking at %s (max_bytes=%s)r  )rS   r   r$  r
  )rZ   	max_bytesifhs      r0   	peek_filer    s    II,eY???	eT		 #cxx	""# # # # # # # # # # # # # # # # # #s   AAAc                 H    g }| D ]}||v r|                     |           |S r`   )r   )in_listout_listr  s      r0   r   r     s<    H  ==OOAOr/   c                    t                               d| |           t          j                    }	 t	          | d          5 }t          |||           d d d            n# 1 swxY w Y   n+# t          $ r}|s |j        t          k    r Y d }~nd }~ww xY w|	                                }t                               dt          |          |            |rt          |          S |S )NzReading from %s (quiet=%s)r  )chunk_cbzRead %s bytes from %s)rS   r   r  r  r$  pipe_in_outr   r   r   getvaluerR   rf   )rZ   read_cbr  rc   ofhr  r   r"  s           r0   r   r     s3   II*E5999
*,,C% 	4#S73333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4    	7f 
 ||~~HII%s8}}e<<< X&&&s;   A, A A,  A$$A, 'A$(A, ,
B6BBc                  R   t                      rc	 t          d          } |                     dd          d d         }ni# t          $ r'}t                              d|           d}Y d }~n=d }~ww xY w	 t          d                                          }n# t          $ r d}Y nw xY w|S )Nz/proc/1/cmdline r  r  z"failed reading /proc/1/cmdline: %sr   z/proc/cmdline)is_containerr   r   r   rS   rT   r8   )r"  r>  r   s      r0   _get_cmdliner  
  s    ~~ 	 !233H&&vs33CRC8GG 	 	 	KK<a@@@GGGGGG		006688GG 	 	 	GGG	 Ns'   -> 
A/A**A/3!B B$#B$c                  ^    dt           j        v rt           j        d         S t                      S )NDEBUG_PROC_CMDLINE)r*   r  r  r.   r/   r0   rC  rC    s'    rz))z.//>>r/      c                     d}	 |                      |          }t          |          dk    rn5|                    |           |t          |          z  }|r ||           ^|                                 |S r  )r
  rR   r%  r&  )in_fhout_fh
chunk_sizer  bytes_pipedrG   s         r0   r  r  $  s    K&zz*%%t99>>LL3t99$K &%%%& LLNNNr/   c                     |dv r|dv rd S t                               d| ||           t          j        | ||           d S )N)Nr  z%Changing the ownership of %s to %s:%s)rS   r   r*   chown)rZ   uidgids      r0   	chownbyidr  3  sO    
jSJ..II5uc3GGGHUCr/   c                     d}d}	 |rt          j        |          j        }|rt          j        |          j        }n%# t          $ r}t          d|z            |d }~ww xY wt          | ||           d S )Nr  zUnknown user or group: %s)	pwdgetpwnampw_uidr  r  r  r  r   r  )rZ   userrf  r  r  r   s         r0   chownbynamer  ;  s    
C
C@ 	,,t$$+C 	-,u%%,C @ @ @1Q788a?@eS#s   6= 
AAAc                 4   d d g}| rd| vr|S | d         }||v r	||         }nd|vr|S |d         }t          |t                    r||g}t          |t                    r<t          |          dk    r|d         |d<   t          |          dk    r|d         |d<   t          |t                    rd|v r|d         |d<   d|v r|d         |d<   |d         dk    r|d         |d<   g d}t          t          |                    D ]}||         s||                                         }d}|D ]I}	|                    |	          r2|	d	|t          |	          d                                          }d
} nJ|sdd	|                                }|||<   |S )Noutputallr   r   ro  z&1)r  r  r  Fr  Tr  )	ra   rb   r   rR   rW   r   rE  r  r8   )
r  r  r  outcfgmodecfgswlistr  r[   rz  ss
             r0   r  r  Q  s   ,C (#%%
]Fv~~,J - '3 !  '4    w<<!QZCFw<<!QZCF '4   &wX&CFgW%CF 1v~~QAF3s88__  1v 	!fmmoo 	 	A~~a   !"CAM$7$7$9$9$9:  	0!TT399;;;/CAJr/   c                    g }| rt          | t                    s|S |                     d          }|r|                    |           t	          | d          D ]}|st          j        d|          }|s|                    d          }|                                }t          |          dk    r|                    |           oddg|dd         k    r|                    |d                    t          t          |                    S )	zReturn a list of log file paths from the configuration dictionary.

    @param cfg: The cloud-init merged configuration dictionary.
    def_log_fileNz (?P<type>\||>+)\s*(?P<target>.*)r6   r   teez-ar&   )ra   rW   rr  r   r  r`  ra  rf  r-   rR   r   rh  )r  logsdefault_logfmtra  r6   partss          r0   get_config_logfilesr    s   
 D jd++ ''.))K !K   c4(( " " 	<cBB 	X&&u::??KKT]eBQBi''KKa!!!D		??r/   c                 ~    |r | j         |g|R   t          j                    }|dk    rd } | j        |g|R d|i d S )NNNNexc_info)rT   r,  r	  r   )r   r  r   r	  s       r0   r   r     sl    
   C$ |~~H%%%CIc,t,,,H,,,,,r/   c                     t          j        |          }|                    t          |                      |                                }|
|d|         S |S r  )hashlibnewupdaterk   	hexdigest)rd   routinemlenhasherdigests        r0   	hash_blobr    sU    [!!F
MM+d##$$$Faf~r/   c                 V    	 t          j        |           rdS d S # t          $ r Y dS w xY wr   )r  r  r  r[  s    r0   is_userr    J    < 	4	 	   uu    
((c                 V    	 t          j        |           rdS d S # t          $ r Y dS w xY wr   )r  r  r  r  s    r0   is_groupr    r  r  c                 h    t                               d| |           t          j        | |           d S )NzRenaming %s to %s)rS   r   r*   renamesrcdests     r0   r  r    s1    II!3---Ic4r/     c                 0    | D ]}t          ||           d S r`   )
ensure_dir)dirlistr  r  s      r0   ensure_dirsr$    s.      1d r/   c                    t          j        t          |                     }t          |t	          |                    sBd                    d |D                       }t          d|dt          |          d          |S )Nz, c                 ,    g | ]}t          |          S r.   )rb   )rE   ts     r0   rH   zload_json.<locals>.<listcomp>  s    #?#?#?qCFF#?#?#?r/   (z) root types expected, got r  )jsonloadsrf   ra   r'   rU   r  type)rj   
root_typesrp   expected_typess       r0   	load_jsonr.    s    jt,,--GguZ0011 
#?#?J#?#?#?@@i~~tG}}}}.
 
 	
 Nr/   c                     	 d                     t          |                     S # t          $ r% d                     t          |                     cY S w xY w)z1Handler for types which aren't json serializable.z
ci-b64:{0}z)Warning: redacted unserializable type {0})r  rs   AttributeErrorr+  )_objs    r0   json_serialize_defaultr2    sa    N""4::... N N N:AA$t**MMMMMNs   !$ ,AAc                 >    t          j        | dddt                    S )z%Return data in nicely formatted json.r   T)rI   re  )indent	sort_keys
separatorsr   )r)  dumpsr2  )rG   s    r0   
json_dumpsr8    s*    :&   r/   c                 <   t           j                            |           slt          t           j                            |           d          5  t          j        |            d d d            n# 1 swxY w Y   t          | |           d S t          | |           d S )NTr   )r*   r   r  r   dirnamemakedirschmod)r   r  s     r0   r"  r"    s    7== "'//$//4@@@ 	 	K	 	 	 	 	 	 	 	 	 	 	 	 	 	 	dD 	dDs   A//A36A3c              #      K   	 | V  | rd| g}t          j         |           d S d S # | rd| g}t          j         |           w w xY w)Numount)r   )r>  
umount_cmds     r0   	unmounterr@    ss      " 	""F+JIj!!!!!	" 	"6 	""F+JIj!!!!	"s	   & Ac                     i } 	 t           j                            d          r$t          d                                          }d}n/t          j        d          }|j                                        }d}d}|D ]}	 |dk    r|                                \  }}}}	}
}nit          j	        ||          }|
                    d          }|
                    d          }|
                    d          }|
                    d          }	n# t          $ r Y w xY w|                    d	d
          }|||	d| |<   t                              d| |           n,# t          t           f$ r t#          t          d           Y nw xY w| S )Nz/proc/mountsr  mountz*^(/dev/[\S]+) on (/.*) \((.+), .+, (.+)\)$r   r&   r^  rf  z\040r  )fstype
mountpointoptszFetched %s mounts from %szFailed fetching mount points)r*   r   r   r   rO   r   r7   r-   r`  searchrf  r   r   rS   r   r   r   r   )mounted
mount_locsmethodr9   mountrempliner  mprC  rE  _freq_passnoms                r0   mountsrP    s   G"47>>.)) 	">22==??JFF)G$$C..00JF?  	 	F
V##>Dllnn;S"fdE77	'622A''!**CBWWQZZF771::D    GS))B   GCLL
 			-w????W 4 4 4s2333334Ns7   A8E =BD	E 	
DE D?E &E?>E?c                 8   t          |t                    r|g}nat          |t          t          f          rt          |          }n5|d}n0t	          d                    t          |                              t                      r|dg}nAt                      r0|g d}t          |          D ]\  }}|dk    rd||<   |dv rd	||<   nd
g}t                      }t          j                    5 }d}	t          j                            |           |v r,|t          j                            |                    d         }
nd}|D ]}d}
	 g d}|r|                    d|g           |                    |            |                    |           t%          j        ||           |}	|}
 nQ# t&          t(          f$ r=}t*                              d| |d                    |          |           |}Y d}~d}~ww xY w|
st1          d| d|d|          |
                    d          s|
dz  }
t5          |	          5  | ||
          }n ||
|          }|cddd           cddd           S # 1 swxY w Y   	 ddd           dS # 1 swxY w Y   dS )a2  
    Mount the device, call method 'callback' passing the directory
    in which it was mounted, then unmount.  Return whatever 'callback'
    returned.  If data != None, also pass data to callback.

    mtype is a filesystem type.  it may be a list, string (a single fsname)
    or a list of fsnames.
    Nz6Unsupported type provided for mtype parameter: {_type})r  auto)ufscd9660msdosr  rT  )r  msdosfsrU  r   FrD  )rB  r  roz-t)
update_envzbFailed to mount device: '%s' with type: '%s' using mount command: '%s', which caused exception: %sr  zFailed mounting z to z	 due to: r  )ra   rb   r   r'   r  r  r+  r;  r?  	enumeraterP  r   tempdirr*   r   r   r   r   r   r   r   rS   r   rU   r   r-  r@  )r  callbackrG   mtypeupdate_env_for_mountmtypesindexrG  tmpdr>  rD  failure_reasonmountcmdexcr  s                  r0   mount_cbrd  8  s    % 
	ED%=	)	) 	
e	DKK5kk L  
 
 	
 zz >XF	 
>///F%f-- 	( 	(LE5	!! (u+++ 'u		( hhG				 +7F##w.. !1!1&!9!9:<HJJ!N ) )!
)444H 7 u666OOF+++OOD)))Ih3GHHHH!F!%JE) 
) 
) 
)II5 **   &)NNNNNN
)  &&vvttt^^5   ""3'' 	#Jv 	 	|hz**hz400	 	 	 	 	 	 	M+ + + + + + + +L	 	 	 	 	 	 	 	 	M+ + + + + + + + + + + + + + + + + +sc   1AJ
A!F-+J-G;>3G61J6G;;AJI6J6I:	:J=I:	>JJJc                  4    t          j        t                    S r`   )obj_copydeepcopyr   r.   r/   r0   get_builtin_cfgrh    s    [)))r/   c                 v    t                               d|            t          j                            |           S )NzTesting if a link exists for %s)rS   r   r*   r   islinkr  s    r0   is_linkrk    s+    II/6667>>$r/   c                    t                               d||            |rt          j                            |          ryt          j                            t          j                            |          dt          d          z             }t          j        | |           t          j	        ||           d S t          j        | |           d S )Nz$Creating symbolic link from %r => %rtmpr   )
rS   r   r*   r   r   rU   r:  r   symlinkr   )ro   linkforcetmp_links       r0   sym_linkrr    s    II4dFCCC &&  7<< 5 5ux{{7JKK

68$$$

8T"""Jvtr/   c                     t                               d|            	 t          j        |            d S # t          $ r}|j        t          k    r|Y d }~d S d }~ww xY w)NzAttempting to remove %s)rS   r   r*   unlinkr   r   r   )r   r   s     r0   del_fileru    sr    II'...
	$   7fG s   3 
AAAc                 h    t                               d| |           t          j        | |           d S )NzCopying %s to %s)rS   r   r  copyr  s     r0   rw  rw    s1    II #t,,,
KTr/   c                  z    	 t          j        dt          j                              } n# t          $ r d} Y nw xY w| S )Nz%a, %d %b %Y %H:%M:%S %z??)timestrftimegmtimer   )tss    r0   time_rfc2822r~    sJ    ]5t{}}EE   Is   &) 88c                     ddl ddld}  G fddj                  }                    j                            d                    }                                }                    |          |_         |            }|	                    d| z   
                    |          
                    |          dd          dk    r|j        |j        d	z  z   S t          d
          )zUse sysctlbyname(3) via ctypes to find kern.boottime

    kern.boottime is of type struct timeval. Here we create a
    private class to easier unpack it.

    @return boottime: float to be compatible with linux
    r   N    c                   4    e Zd Zd j        fd j        fgZdS )boottime.<locals>.timevaltv_sectv_usecN)r   r   r   c_int64_fields_)ctypess   r0   timevalr    s'        v~.FN0KLr/   r  cs   kern.boottimer  g    .Az/Unable to retrieve kern.boottime on this system)r  ctypes.util	StructureCDLLutilfind_libraryc_size_tsizeofvaluesysctlbynamebyrefr  r  RuntimeError)
NULL_BYTESr  libcr  r  r  s        @r0   boottimer    s#    MMMJM M M M M M M&" M M M ;;v{//4455D??Dw''DJ
'))Cz)LLLL	
 	
 	 	 zCK)333
H
I
IIr/   c                  ^   d} d}	 t           j                            d          r.d}t          d          }|r|                                d         } n1d}t          t          j                    t                      z
            } n(# t          $ r t          t          d|z             Y nw xY w| S )Nry  r~  z/proc/uptimer   r  z&Unable to read uptime using method: %s)r*   r   r   r   r-   rb   rz  r  r   r   rS   )
uptime_strrI  r"  s      r0   uptimer    s    JFG7>>.)) 	7#F 00H 1%^^--a0
FTY[[8::566J G G Gs<vEFFFFFGs   A>B "B*)B*c                 ,    t          | |dd            d S )Nr  )omoder  
write_file)r   contents     r0   append_filer    s    tWDt444444r/     )preserve_moder  r  c                .    t          | dd||           d S )Nr   r  )r  r  r  r  r  )r   r  r  s      r0   ensure_filer    s0     b4}     r/   c                 R    	 t          |           S # t          t          f$ r Y d S w xY wr`   )r)   r  r  )possible_ints    r0   safe_intr    s<    <   	"   tts    &&c                     t          |          }| rA|rAt          |           5  t          j        | |           d d d            d S # 1 swxY w Y   d S d S d S r`   )r  r   r*   r<  )r   r  	real_modes      r0   r<  r<    s    I &	 &$ 	& 	&HT9%%%	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	& 	&& & & &s   AA
A
grp_namec                     d}	 t          j        |           j        }n+# t          $ r t                              d|            Y nw xY w|S )zt
    Returns the group id of a group name, or -1 if no group exists

    @param grp_name: the name of the group
    r  z"Group %s is not a valid group name)r  r  r  r  rS   r   )r  r  s     r0   get_group_idr    sb     CBl8$$+ B B B		6AAAAABJs    %AAr   c                 X    t          j        t          j         |           j                  S )z
    Returns the octal permissions of the file/folder pointed by the path,
    encoded as an int.

    @param path: The full path of the file/folder.
    )r   S_IMODEr*   st_moder  s    r0   get_permissionsr    s     <-...r/   c                 f    t          j        |           }t          j        |j                  j        S )zw
    Returns the owner of the file/folder pointed by the path.

    @param path: The full path of the file/folder.
    )r*   r   r  getpwuidst_uidpw_namer   sts     r0   	get_ownerr  %  &     
B<	""**r/   c                 f    t          j        |           }t          j        |j                  j        S )zw
    Returns the group of the file/folder pointed by the path.

    @param path: The full path of the file/folder.
    )r*   r   r  getgrgidst_gidgr_namer  s     r0   	get_groupr  /  r  r/   usernamec                    g }t          j                    D ]%}| |j        v r|                    |j                   &t          j        |           j        }|                    t          j        |          j                   |S )zp
    Returns a list of all groups to which the user belongs

    @param username: the user we want to check
    )	r  getgrallgr_memr   r  r  r  pw_gidr  )r  groupsrf  r  s       r0   get_user_groupsr  9  sv     F ) )u|##MM%-(((
,x
 
 
'C
MM#,s##+,,,Mr/   r  )ensure_dir_existsc          	         |r!	 t          |           }n# t          $ r Y nw xY w|r,t          t          j                            |                      d|                                v rt          |          }d}nt          |          }d}	 d|z  }n# t          $ r d|z  }Y nw xY wt                              d| ||t          |          |           t          |           5  t          | |          5 }|                    |           |                                 ddd           n# 1 swxY w Y   ddd           n# 1 swxY w Y   t#          | |           dS )	a  
    Writes a file with the given content and sets the file mode as specified.
    Restores the SELinux context if possible.

    @param filename: The full path of the file to write.
    @param content: The content to write to the file.
    @param mode: The filesystem mode to set on the file.
    @param omode: The open mode used when opening the file (w, wb, a, etc.)
    @param preserve_mode: If True and `filename` exists, preserve `filename`s
                          current mode instead of applying `mode`.
    @param ensure_dir_exists: If True (the default), ensure that the directory
                              containing `filename` exists before writing to
                              the file.
    brh   
charactersz%oz%rzWriting to %s - %s: [%s] %s %sr  N)r  r   r"  r*   r   r:  r   rk   rf   r  rS   r   rR   r   r$  r%  r&  r<  )	r_  r  r  r  r  r  
write_typemode_rfhs	            r0   r  r  I  s   0  	"8,,DD 	 	 	D	  .27??8,,---
ekkmmg&&

((!
   II(G   
8	$	$	$  (E"" 	bHHWHHJJJ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	               
(DsT    
!!B B$#B$#E4*D*E*D.	.E1D.	2EEEc                     t          j        |           D ]`}t           j                            | |          }t           j                            |          rt          |           Qt          |           adS )z
    Deletes all contents of a directory without deleting the directory itself.

    @param dirname: The directory whose contents should be deleted.
    N)r*   r2  r   rU   r  r  ru  )r:  nodenode_fullpaths      r0   delete_dir_contentsr    st     
7## $ $Wd337=='' 	$M""""]####$ $r/   r]  createdc                     t          j                    }t          |           }|d|                                d|z  }|dt	                      z  z  }|S )Nr  z by cloud-init v. z on %s)r   version_stringrb   titler~  )comment_charr  ci_verheaders       r0   make_headerr    sT    #%%FF
F4::<<<<@@F
h''FMr/   c                 j    t           j                            t          j        j        | g|R            S r`   )r*   r   abspathrU   )r  r	  s     r0   abs_joinr    s*    7??27<5u555666r/   c           	      t   t          | t          t          f          s$t          dt	          j        |           z            d}|r|dz  }ddz  }d}| D ]}t          |t          t          f          r`g }|D ];}|                    dt          |                              d|          z             <|d		                    |          d
}|dz  }~t          |t                    r||d
}|dz  }|t          dt	          j        |          d|          t                              d|           |S )Nz8Input to shellify was type '%s'. Expected list or tuple.r   z
#!/bin/sh
z%s%s%s%s)'\r  r  r   z'%s'r  r  r+  r   zUnable to shellify type 'z&'. Expected list, string, tuple. Got: zShellified %s commands.)ra   r'   r   r  r   r   r   rb   r   rU   rS   r   )cmdlist
add_headerr  escaped	cmds_mader   fixedr/  s           r0   shellifyr    s{   gt}-- 
F"7++-
 
 	

 G != 00GI   dT5M** 	E F FVs1vv~~c7'C'CDEEEE")'388E????;GNIIc"" 
	")'4440GNII\)'06666>  
 II'333Nr/   c                     |r,|                      |          r| t          |          d          } |r-|                     |          r| d t          |                    } | S r`   )r  rR   r-  )rY   prefixsuffixs      r0   strip_prefix_suffixr    sg     #$//&)) #CKKMM" $$--'' $Ns6{{lN#Kr/   c                     t          j        | d                   dS 	 t          j         |            n# t           j        $ r Y dS w xY wdS )Nr   FT)r   whichrV   )r  s    r0   _cmd_exits_zeror    sY    z#a&!u	#%   uu4s   3 AAc                  $    t          g d          S )N)zsystemd-detect-virtz--quietz--containerr  r.   r/   r0   _is_container_systemdr    s    LLLMMMr/   c                  "    t          dg          S )Nzlxc-is-containerr  r.   r/   r0   _is_container_old_lxcr    s    ./000r/   c                      t                      sdS g d} t          j        | d                   dS t          j        |           \  }}|                                dk    S )NF)r  z-qnzsecurity.jail.jailedr   r   )rE  r   r  r8   )r  r9   r   s      r0   _is_container_freebsdr    s[    << u
3
3
3Cz#a&!uYs^^FC99;;#r/   c                  J   t           t          t          f} | D ]} |            r dS 	 t          d          }d|v rdS d|v rdS n# t          t
          f$ r Y nw xY wt          j                            d          r!t          j                            d          sdS 	 t          d          
                                }|D ]K}|                    d          r4|                                                    d	d          \  }}|d
k    r dS Ln# t          t
          f$ r Y nw xY wdS )zH
    Checks to see if this code running in a container of some sort
    Tr   	containerLIBVIRT_LXC_UUIDz/proc/vzz/proc/bcz/proc/self/statuszVxID:rC   r!   F)r  r  r  get_proc_envr   r   r*   r   r  r   rO   r  r8   r-   )checkshelperpid1envlinesrY   _keyr[   s          r0   r  r    st    	F   688 	44	
	 q//'!!4((4 )W    
w}}Z   z)B)B t	-..99;; 	  	 Dw''  "jjll00a88s#::44		 
 W    5s/   A A AAA,D 
D D D c                  @    t           j                            d          S )z2Check to see if we are running in a lxd container.z/dev/lxd/sockr  r.   r/   r0   is_lxdr  	  s    7>>/***r/   r   c                 x   t           j                            dt          |           d          }	 t	          |d          }n# t
          t          f$ r i cY S w xY wi }d\  }}|rd\  }}|                    ||          }|                    |          D ]%}|s|                    |d          \  }	}
|	r|
||	<   &|S )aH  
    Return the environment in a dict that a given process id was started with.

    @param encoding: if true, then decoding will be done with
                     .decode(encoding, errors) and text will be returned.
                     if false then binary will be returned.
    @param errors:   only used if encoding is true.z/procr  Fru   )r     =)r  =r   )	r*   r   rU   rb   r   r   r   rc   r-   )pidre   errorsr   r"  envnullequalr  r[  r[   s              r0   r  r  	  s     
gs3xx	3	3BR...W   			 C!KD% 5#e??8V44~~d##   	iiq))s 	CIJs   A AAc                     i }|                                  D ]6}	 |                     dd          \  }}n# t          $ r |}d}Y nw xY w|||<   7|S )Nr  r   T)r-   r  )kvstringr  r  rS  r[   s        r0   keyval_str_to_dictr  :	  sy    
C~~  	3**JS## 	 	 	CCCC	 CJs   4AAc                     |                      d          r
| dd          } t          j                            d| z            S )Nr  r  z/sys/class/block/%s/partition)r  r*   r   r  )r  s    r0   is_partitionr	  F	  s?    !! 7>>9FBCCCr/   c                    t          |t                    s|g}g }|D ]}t          |t                    r|                    |           -t          |t          t          f          rt          |          dk     st          |          dk    rt          d          t          |          dk    r.|d         r&|                    | t	          |          z             |                    |d                    t          d          |S )Nr   r&   z Invalid package & version tuple.r   zInvalid package type.)ra   r   rb   r   r'   rR   r  )version_fmtpkgspkglistpkgs       r0   expand_package_listr  M	  s    dD!! vG 8 8c3 	NN3cE4=)) 	83xx!||s3xx!||"#EFFF3xx1}}Q}{U3ZZ7888NN3q6"""" 6777Nr/   c                    d |                      d          D             }d}d}d}d}t          |          D ]\  }	}
|
                                 }t          |          dk     r+|                    d|	dz   t          |          |
            dS |d         }d |                     d          D             }t          |          t          |          k    rt	          t          |          t          |                    }|d	|         |d	|         k    r|"t          |          t          |          k    r	 |                    d
          }	n,# t          $ r |                    d|	dz   |
           Y  dS w xY w	 ||	dz            }||	dz            }n,# t          $ r |                    d|	dz   |
           Y  dS w xY w|}|}|d         }|r|r|r
|r|r||||fS n|r	|r|r|||fS dS )zRReturn the mount information for PATH given the lines from
    /proc/$$/mountinfo.c                     g | ]}||S r.   r.   rE   r   s     r0   rH   z$parse_mount_info.<locals>.<listcomp>l	  s    555115Q555r/   r  Nr  z$Line %d has two few columns (%d): %sr   rf  c                     g | ]}||S r.   r.   r  s     r0   rH   z$parse_mount_info.<locals>.<listcomp>	  s    GGGaQGGGGr/   r   -z,Did not find column named '-' in line %d: %sr&   z/Too few columns after '-' column in line %d: %sr  )r-   rY  rR   r   minr_  r  
IndexError)r   mountinfo_linesr   get_mnt_optspath_elementsdevpthfs_typematch_mount_pointmatch_mount_point_elementsr  rY   r  mount_pointmount_point_elementsxmount_optionss                   r0   parse_mount_infor"  h	  s    65

3555MFG!%_-- 9! 9!4

 u::??II6As5zz4   44AhGG;+<+<S+A+AGGG #$$s='9'999 ())3}+=+=>>!$ac(::: &1c&7
 7
$%%7& 7& 
	C  AA 	 	 	II>At   444			AElG1q5\FF 	 	 	IIA1q5$   444		 (%9"a 8 	Gg 	G"3 	G 	GG%6FF 	8g 	8"3 	8G%6774s$   =E$E<;E< F$G ?G c                     t          d                                          D ]/}|                                dd         \  }}}|| k    r|||fc S 0dS )z<On older kernels there's no /proc/$$/mountinfo, so use mtab.	/etc/mtabNr^  )r   rO   r-   )r   rY   r  r  r  s        r0   
parse_mtabr%  	  sj    +&&1133 0 0'+zz||BQB'7$W$7K//// 4r/   c                    |                      d          }t          |          dk    r|d         S |d         dv r| dd          }t          j        g d          \  }}|                     d          D ]?}|                                 }t          |          dk    r|d         |k    r
|d         } n@t          |          S t                              d	|            d S )
Nr  r^  r&   )r  gptrS  r  )glabelstatusz-sr+  r   z)Unexpected input in find_freebsd_part: %s)r-   rR   r   rb   rS   rT   )fssplittedtarget_labelr{   r  labelsr   s          r0   find_freebsd_partr.  	  s    xx}}H
8}}{	!/	/	/!""vy!;!;!;<<tjj&& 	 	FLLNNE5zzA~~%(l":":Qx4yy?DDDDDr/   c                     |                      d          }t          |          dk    r|d         dk    r|d         S t                              d|            d S )Nr  r^  r   r  r&   z.Unexpected input in find_dragonflybsd_part: %s)r-   rR   rS   rT   )r*  r+  s     r0   find_dragonflybsd_partr0  	  sU    xx}}H
8}}hqkU22{DbIIIIIr/   c                     d }|                     d          D ]U}|                                 }t          |          dk    r,t          j                            |d         | z             r|} nV|S )Nr+  r&   r   )r-   rR   r*   r   r   )r   mnt_list
path_foundrY   r   s        r0   get_path_dev_freebsdr4  	  si    Jt$$  

u::>>bgnnU1X_==>JEr/   c                 4   t          j         dd| gddg          \  }}t          |          r/t          j         ddg          \  }}t          | |          }|d S |}|                                }t	          |d                   }d|z   |d         |d         fS )NrB  z-pr   r   r  r  r&   )r   rR   r4  r-   r.  )r   rt  r]   r2  r3  r  
label_parts          r0   get_mount_info_freebsdr7  	  s    Iwd3!Q@@@MVS
3xx )WdO443)$99
4
,,..C"3q6**JZQQ//r/   c                 *   t           j                            d          st                              d           d S 	 t          j        dd| g          \  }}n9# t
          j        $ r'}t                              d| |           Y d }~d S d }~ww xY wt          |          rd S d}|	                    d          D ]Y}t          j        ||          rB| |vr>d|vr:|	                                d	         }t                              d
| |           |c S Zd S )Nz/dev/zfsz"Cannot get zpool info, no /dev/zfszpoolr)  z$Unable to get zpool status of %s: %sz.*(ONLINE).*r+  stater   zfound zpool "%s" on disk %s)r*   r   r   rS   r   r   rV   rT   rR   r-   r`  rF  )r9  zpoolstatusr]   r   rY   disks         r0   get_device_info_from_zpoolr=  	  s3   7>>*%% 		6777t!Y5'ABBcc%   :E3GGGttttt 3xx tA!!$''  9Q 	%t"3"3t8K8K::<<?DII3UDAAAKKK	 s   A B'B		Bc                 4   t          j         dg          \  }}|                                }d}t                      rd}|D ]}t          j        ||          }|s|                    d          }|                    d          }|                    d          }	|	|                    d          }	t                              d|||	           t          j        d	|          }
|
s%t                      r|	d
k    rt          |           c S || k    r||	|fc S d S )NrB  zH^(/dev/[\S]+|.*zroot\S*?) on (/[\S]*) (?=(?:type)[\s]+([\S]+)|\(([^,]*))zA^(/dev/[\S]+|\S*?) on (/[\S]*) (?=(?:type)[\s]+([\S]+)|\(([^,]*))r   r&   r^  rf  z?found line in mount -> devpth: %s, mount_point: %s, fs_type: %sz^(/dev/.+)p([0-9])$zfs)
r   rO   rI  r`  rF  rf  rS   r   rE  r7  )r   mountoutputr  rH  regexrY   rO  r  r  r  devms              r0   parse_mountrC  
  sL   )WI..[$''))J	. 
  
2 	  0 0IeT"" 	ggajj ''!**?ggajjG		M		
 	
 	
 y.77 	0
 	0E)9)9)$/////D  7K//// !4r/   c                 L   dt          j                    z  }t           j                            |          r3t	          |                                          }t          | |||          S t           j                            d          rt          |           S t          |           S )Nz/proc/%s/mountinfor$  )	r*   getpidr   r   r   rO   r"  r%  rC  )r   r   r  mountinfo_pathr  s        r0   get_mount_inforG  2
  s    : *BIKK7N	w~~n%% !.))4466eS,???		$	$ !$4   r/   optc                 X    t          | d          ^ }}||                    d          v S )NTr  rI   rG  r-   )r   rH  r   mnt_optss       r0   has_mount_optrM  Y
  s/    !$T:::LQ(..%%%%r/   Tr  .c                    |g }|i }t          j                     }d }|r-	 t          t                                }n# t          $ r Y nw xY w	  ||i |}t          j                     |z
  }	d }
|0	 t          t                                |z
  }
n# t          $ r Y nw xY wd|	z  }|r#t	          |
t                    r	|d|
z  z  }n|dz  }	  | ||z              n# t
          $ r Y nw xY w# t          j                     |z
  }	d }
|0	 t          t                                |z
  }
n# t          $ r Y nw xY wd|	z  }|r#t	          |
t                    r	|d|
z  z  }n|dz  }	  | ||z              w # t
          $ r Y w w xY wxY w|S )Nz took %0.3f secondsz (%0.2f)z (N/A))rz  floatr  r  ra   r   )r  r  r  r   r   
get_uptimestartustartr  deltaudeltatmsgs               r0   r  r  a
  s0    |~IKKEF 	688__FF 	 	 	D	dD#F##	e#vxx61    %u, 	!&5** !
V++ 	GC$J 	 	 	D	! 	e#vxx61    %u, 	!&5** !
V++ 	GC$J 	 	 	D	Js   = 
A
	A
C* 1B 
BBC 
C'&C'*E?D%$E?%
D2/E?1D22-E? E/.E?/
E<9E?;E<<E?c                 `    |                      dd          }t          |          dk    r|S | d fS )Nr%   r   )rsplitrR   )dottedra  s     r0   expand_dotted_devnamerZ  
  s3    ==a  D
4yy1}}~r/   c                 r   |g }|g }g }i }||z   D ]_}	 t          | |z   |z   dd          ||<   # t          $ r4}|j        t          k    r ||v r|                    |           Y d }~Xd }~ww xY wt          |          r6t          d                    d                    |                              |S )NF)r  rc   zMissing required files: {files}rI   )files)	r   r   r   r   r   rR   r  r  rU   )r  requiredoptionaldelimr\   r  r/  r   s           r0   pathprefix2dictr`  
  s     G
C  " "	"te|a/uUKKKCFF 	" 	" 	"w&  H}}q!!!		" 7|| 
-44388G;L;L4MM
 
 	
 Js   1
A/*A**A//proc/meminfoc                 x   ddddd}dddd	}i }t          |                                           D ]}	 |                                \  }}}n)# t          $ r |                                \  }}d
}Y nw xY w|rt	          |          ||         z  ||<   c||v r!t	          |          ||         z  |||         <   |S )Nr     r      @)kBmBBgBtotalfree	available)z	MemTotal:zMemFree:zMemAvailable:rg  )r   rO   r-   r  r)   )	meminforawmplierskmapr  rY   rS  r  units	            r0   read_meminforq  
  s     %au==G$ D
 C'""--// 	8 	8	#zz||C 	 	 	JCDDD	  	85zzGDM1CHHD[[ ZZ'$-7CS	NJs   A#A32A3c                    | }|                      d          r
| dd         } dddddd	}| }d}|D ]1}|                      |          r|}| d
t          |                    }2	 t          |          }n%# t          $ r}t          d|z            |d}~ww xY w|d
k     rt          d|z            t	          |||         z            S )z^Convert human string or integer to size in bytes
    10M => 10485760
    .5G => 536870912
    rg  Nr  r   r  rc  rd  l        )rg  KMGrN  r   z'%s' is not valid input.z'%s': cannot be negative)r-  rR   rP  r  r)   )r  size_inrn  nummplierrO  r   s          r0   human2bytesry  
  s   
 G}}S CRCyEEFFG
CF $ $== 	$FqCFF7{#CFCjj F F F3g=>>AEF Qww3g=>>>sWV_$%%%s   #A3 3
B=BBc                 |    | t          j                    d         } | dk    p| d         dk    o| dd         dk    }|S )z$Return True if platform is x86-basedNrf  x86_64r   r  r&   86)r*   r+   )
uname_archx86_arch_matchs     r0   is_x86r  
  sO    XZZ]
8+ 17ABB4!7  r/   c                     t           j        d d         dk     r&t          j        t	          j        |                     S t          j        |           S )Nr&   )r&      )r,  version_infoemailmessage_from_filer  StringIOmessage_from_string)r   s    r0   r  r  
  sE    
f$$&r{6':':;;;$V,,,r/   c                    t          j         ddg| d          }t                      }|j                                        D ]}	 |                    d d          \  }}}n# t
          $ r Y *w xY w|                    d          s|                    d          r)|                    t          j	        dd	|                     |S )
Nz
dpkg-queryz--listT)r6   r5   r&   hiiiz:.*r   )
r   rh  r7   rO   r-   r  r  rm  r`  sub)r6   r9   	pkgs_instrY   r:  r  r   s          r0   get_installed_packagesr  
  s    
)\8,VT
J
J
JCI
%%'' 2 2	"jjq11OUC 	 	 	H	D!! 	2U%5%5d%;%; 	2MM"&C00111s   A
A,+A,c                     d} 	 t          t          | d                    }|                    dd                                          dk    rdS n3# t          $ r&}t
                              d| |           Y d }~nd }~ww xY wt                      }d|v rdS t          d	d          }d|                                v rdS t          j	        
                    d
          rdS dS )Nri  Tr  r]  r   zubuntu-corez!Unexpected error loading '%s': %sz
snap_core=z/etc/system-image/channel.iniz/etc/system-image/config.d/F)rq  r   rr  r   r  rS   rT   rC  r*   r   r  )orpathorinfor   r>  r  s        r0   system_is_snappyr    s    FD#IfD$A$A$ABB::dB%%''=884 9 D D D7CCCCCCCCD mmGwt7tDDDG''t	w}}233 t5s   A
A 
BA<<Bc                    d }|                                  D ]#}|                    d          r|dd          } n$|d S |                    d          r|S |                    d          rd|t          d          d          z   S |                    d          r,d|t          d          d                                          z   S |                    d          rhd	|t          d          d                                          z   }t          j                            |          r|S t          |          }|r|d
         S |S d|z   S )Nzroot=r  r  r  z/dev/disk/by-label/zUUID=z/dev/disk/by-uuid/z	PARTUUID=z/dev/disk/by-partuuid/r   )r-   r  rR   r   r*   r   r   r  )r>  rz  r  
disks_pathresultss        r0   rootdev_from_cmdliner    sn   E}}  >>'"" 	GEE	 }t   !! >$uS]]__'===   D#eCLLNN&;&A&A&C&CCC$$ $uS-=-=-?-?'@'F'F'H'HH 	 7>>*%% 	 '' 	1: U?r/   c                 x    d }i } ||           D ](}|                     dd          \  }}|s|}|s|r|||<   )|S )zGiven shell like syntax (key=value
key2=value2
) in content
    return the data in dictionary form.  If 'add_empty' is True
    then add entries in to the returned dictionary for 'VAR='
    variables.  Set their value to empty_val.c                 .    t          j        | d          S )NT)comments)shlexr-   )rd   s    r0   _shlex_splitz(load_shell_content.<locals>._shlex_splitC  s    {4$////r/   r  r   )r-   )r  	add_empty	empty_valr  rG   rY   rS  r  s           r0   rq  rq  =  ss    0 0 0 DW%%  ZZQ''
U 	E 	 	DIKr/         ?c                    t          |           }d}	 |t          d |D                       z  }t          |          dk    rt                              d|||            g S |dk    rt                              d|||            ||z   |k    rnt	          j        |           ||z  }t                              d|||           |S )Nr   Tc                 P    g | ]#}t           j                            |          !|$S r.   r  r.  s     r0   rH   z"wait_for_files.<locals>.<listcomp>U  s+    :::1q(9(9:Q:::r/   z)%sAll files appeared after %s seconds: %sz6%sWaiting up to %s seconds for the following files: %sz*%sStill missing files after %s seconds: %s)rh  rR   rS   r   rz  sleep)flistmaxwaitnaplenlog_preneedwaiteds         r0   wait_for_filesr  Q  s    u::DF:::::;;;t99>>II;	   IQ;;IIH	   F?W$$
6&), II4gw   Kr/   c                 r    t          | d          }|d                             d          }|d         dk    S )z1Check whether the given mount point is mounted rwTrJ  r  rI   r   rwrK  )r  rt  
mount_optss      r0   mount_is_read_writer  p  s:    Kd;;;F!!#&&Ja=D  r/   c                    t          j        d          sdS ddg}| r:t          j                            |           rdS |                    d| z  g           |r|                    d|z  g           t          j         |          S )zAInvoke udevadm settle with optional exists and timeout parametersudevadmNsettlez--exit-if-exists=%sz--timeout=%s)r   r  r*   r   r   r   )r   r  
settle_cmds      r0   udevadm_settler  w  s    :i    	X&J <7>>&!! 	F069:;;; 6>G345559Z   r/   c                 f   d}	 t          d| z  d          }|rct          j        dt          |                    }|r#t	          |                    d                    }nt                              d| |           n3# t          $ r&}t                              d| |           Y d	}~nd	}~ww xY w|S )
z-
    Return the parent pid of a process.
    r   z/proc/%s/statTr  z ^\d+ \(.+\) [RSDZTtWXxKPI] (\d+)r   z6Unable to match parent pid of process pid=%s input: %sz Failed to load /proc/%s/stat. %sN)	r   r`  rF  rb   r)   rf  rS   rT   r   )r   ppidr"  rO  r   s        r0   get_proc_ppidr    s     D@_s2$??? 
		=s8}}MMA 1771::L  
  @ @ @6Q????????@Ks   A9A> >
B.B))B.r   	Error:
{}c                     t          |                    |           t          j                   |rt          j        |           |S )a   
    Print error to stderr and return or exit

    @param msg: message to print
    @param rc: return code (default: 1)
    @param fmt: format string for putting message in (default: 'Error:
 {}')
    @param sys_exit: exit when called (default: false)
    )file)printr  r,  r-  exit)r  rcr  sys_exits       r0   ro  ro    s=     
#**S//
++++ Ir/   c                   `     e Zd Zd fd	Zedefd            Zd Zd Zd Z	d Z
d	efd
Z xZS )Versionr  c                 \    t          t          |                               | ||||          S )zPDefault of -1 allows us to tiebreak in favor of the most specific
        number)superr  __new__)clsmajorminorpatchrev	__class__s        r0   r  zVersion.__new__  s+     Wc""**3ueSIIIr/   r   c           
      h     | t          t          t           |j        d                               S Nr%   )r   r(   r)   r-   )r  r   s     r0   from_strzVersion.from_str  s-    sT#c=7=#5#5667799r/   c                 4    d|                      |          k    S )Nr   )_compare_versionr   others     r0   __gt__zVersion.__gt__  s    D))%0000r/   c                     | j         |j         k    o/| j        |j        k    o| j        |j        k    o| j        |j        k    S r`   r  r  r  r  r  s     r0   __eq__zVersion.__eq__  sH    J%+% &
ek)&
ek)& EI%		
r/   c              #   x   K   | j         | j        | j        | j        fD ]}|dk    rt	          |          V   dS dS )z)Iterate over the version (drop sentinels)r  N)r  r  r  r  rb   )r   ns     r0   __iter__zVersion.__iter__  sQ      *dj$*dh? 	 	ABww!ff		 	r/   c                 ,    d                     |           S r  )rU   r   s    r0   __str__zVersion.__str__  s    xx~~r/   r   c                     | |k    rdS | j         |j         k    rdS | j        |j        k    rdS | j        |j        k    rdS | j        |j        k    rdS dS )z
        return values:
            1: self > v2
            -1: self < v2
            0: self == v2

        to break a tie between 3.1.N and 3.1, always treat the more
        specific number as larger
        r   r   r  r  r  s     r0   r  zVersion._compare_version  sg     5==1:##1:##1:##18ei1rr/   )r  r  r  r  )r   r   r   r  classmethodrb   r  r  r  r  r  r)   r  __classcell__)r  s   @r0   r  r    s        J J J J J J
 :s : : : [:1 1 1
 
 
            r/   r  r  r`   )r^   )r   N)TTr   )r   r  )r   r   r  )r   r   r  r  r   )r[  )Nr  NFNr   r   )r  N)r   r  )r  )r  r  F)r]  r  )T)r^   r   )NNF)ra  F)FN)r  r   )r   r  F)r  rw  rf  r  r  r  r  r  r  r)  r*   os.pathr9  r  r   r`  r  r  ri  r   r   r  r,  rz  base64r   r   collectionsr   r   r   r   r   	functoolsr	   r
   typingr   r   r   r   r   urllibr   	cloudinitr   r   r.  r   r   r   r   r   r   r   cloudinit.settingsr   rg  	getLoggerr   rS   sepr   r   r   r   r   r   r1   r:   rB   rf   rk   rq   rs   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  rb   rW   r!  r)  DEBUGr5  r;  r?  rE  rI  rL  rO  rT  rV  rX  rg  r|  r  rD  r  r  r  r  r  contextmanagerr  r  r  r  r  r  r   r  r5  r;  r@  r?  rQ  rR  rZ  rb  r{  rX  r  r  r  r  r  r  r  r  r  r  r  r   r   r  rC  r  r  r  r  r  r   r  r  r  r  r$  r.  r2  r8  r"  r@  rP  rd  rh  rk  rr  ru  r~  r  r  r  r)   r   r  r  r<  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r  r"  r%  r.  r0  r4  r7  r=  rC  rG  rM  rN  r  rZ  r   r`  rq  ry  r  r  r  r  r  rq  r  r  r  r  ro  r  r.   r/   r0   <module>r     sd             



   				  				   



  				          



  ' ' ' ' ' ' ' ' ) ) ) ) ) ) ) )                 / / / / / / / / 7 7 7 7 7 7 7 7 7 7 7 7 7 7             $ $ $ $ $ $                  + * * * * * g!! FC v}$v';;
)+> > > 	 	 	 	    :! ! ! !! ! ! !  - - -  &+ + + + + + + +\	 	 	 	 	y 	 	 		 	 	 	 	 	 	 	
 
 
*             G G G G    ,0 ,. ,. ,.D ,. ,. ,. ,.d& & &$ $ $
 
 
4 4 4 4    	3 	4 	 	 	 	   m)% )% )% )%X ( ( (    1 1 1 3 3 3 0 0 0 1 1 1% % % %   ? ? ? ?% % % %P :1 :1 :1z1 1 1h 
 
 
   6   0  &N5 N5 N5 N5b $              
 
 
 
   B !4' % % % %P% % % %P .2   d    < 9= ) ) ) ) ) ) )X< < < <
   D* * * :&&&  (8 (8 (8 (8V% % % %P, , ,^  
      &1 1 1 EI   * EI   4 EI* * * *$ EI* * * *4 EI= = = =@   ># # #     &   $        
 
 
 
,7 7 7t  4- - -$            
 !%w    N N N      " " "% % %R CGU U U Up* * *
     
	 	 	 	    
   J J JD  &5 5 5
 6;  /3	     & & &3 3    /# /# / / / /+C +C + + + ++C +C + + + +c d3i    & 

6 6 6 6 6 6r$ $ $   7 7 7" " " "J     N N N1 1 1   * * *Z+ + +
   <	 	 	D D D  6 14% K K K K\  E E E"J J J  0 0 0  (+ + +\ !u $! $! $! $!N&S &T & & & &
 GCLL 
+ + 36
+ + + + +\   $($bgk    6   0& & &:   - - -     0  >   (   >! ! !! ! ! !$  .    4 4 4 4 4jj$F$F$FGG 4 4 4 4 4r/   