o
    3'f                     @   s  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 d dl
mZ d dl
mZ d dl
mZ d dl
mZ d dl
mZ d d	l
mZ d d
l
mZ d dl
mZ d dl
mZ d dl
mZ d dl
mZ d dlmZ d dlmZ d dlmZ d dlmZ d dl
mZ d dl m!Z! d dl"m#Z#m$Z$m%Z%m&Z& dZ'dZ(e#e$e%dZ)dddddZ*e+e,Z-dWdd Z.d!Z/d"d# Z0dXd$d%Z1d&d' Z2e-j3fd(e	e4gdf fd)d*Z5d+d, Z6d-efd.d/Z7d0d1 Z8dYd3d4Z9dZd6ee:e4f fd7d8Z;d9d: Z<d;d< Z=d=d> Z>d?d@ Z?dAdB Z@dCdD ZAdEdF ZBdGejCfdHdIZDdJdK ZEdLdM ZFdXdNdOZGdPdQ ZHdRdS ZIe,dTkrMdUejJvr>dVejJdU< eGejKZLeLrOeMeL dS dS dS )[    N)TupleCallable)netinfo)signal_handler)sources)socket)stages)
url_helper)util)version)warnings)	reporting)atomic_helper)	lifecycle)read_cfg_paths)cc_set_hostname)Modules)validate_cloudconfig_schema)log)events)PER_INSTANCE
PER_ALWAYSPER_ONCECLOUD_CONFIGzOCloud-init v. {version} running '{action}' at {timestamp}. Up {uptime} seconds.zcloud_%s_modules)instancealwaysoncezLocal StagezNetwork StagezConfig StagezFinal Stage)
init-localinitmodules-configmodules-final c                 C   sV   | r
t jd|   t jd t jd tjt jd t jd t jd d S )N%s
z<------------------------------------------------------------
)file)sysstderrwrite	traceback	print_excmsg r,   4/usr/lib/python3/dist-packages/cloudinit/cmd/main.pyr)   O   s   r)   a  Triggering cloud-init boot stages outside of intial system boot is not a fully supported operation which can lead to incomplete or incorrect configuration. As such, cloud-init is deprecating this feature in the future. If you currently use cloud-init in this way, please file an issue describing in detail your use case so that cloud-init can better support your needs: https://github.com/canonical/cloud-init/issues/newc                 C   sH   | j rt }d|kr|  rtjd| ddtd td|| d S )N   z5Unsupported configuration: boot stage called by PID [z] outside of systemdz24.3
deprecateddeprecated_versionextra_messagez!PID [%s] started cloud-init '%s'.)	is_linuxosgetppiduses_systemdr   	deprecateDEPRECATE_BOOT_STAGE_MESSAGELOGinfo)distrobootstage_nameppidr,   r,   r-   log_ppidd   s   r>   c                 C   s&   |st | }tjd| ddtd |S )Nr"   FT)consoler&   r   )welcome_formatr
   	multi_logr9   )actionr+   r,   r,   r-   welcomes   s   rC   c                 C   s   t jt t t | dS )N)r   uptime	timestamprB   )WELCOME_MSG_TPLformatr   version_stringr
   rD   time_rfc2822rB   r,   r,   r-   r@   z   s   r@   loggerc                 C   sj   t tj s/| d tt j}t | tj  W d   dS 1 s(w   Y  dS | d dS )zj
    reopen stdin as /dev/null to ensure no side effects

    logger: a function for logging messages
    zClosing stdinNz"Not closing stdin, stdin is a tty.)r4   isattyr%   stdinfilenoopendevnulldup2)rK   fpr,   r,   r-   close_stdin   s   "rS   c                 C   sT   g }| j r| j D ]}|tj|j q| jr(| jD ]}|tj|j q|S N)
main_filesappendr4   pathrealpathnamefiles)argsfn_cfgsfhr,   r,   r-   extract_fns   s   

r^   modsc                 C   sr   t | }| |\}}t|t| }|dkr,d||f }tjd|  t| g S tdt|t| |S )Nr   z)No '%s' modules to run under section '%s'r"   zRan %s modules with %s failures)MOD_SECTION_TPLrun_sectionlenr%   r&   r'   r9   debug)r_   action_namesectionfull_section_name	which_ranfailurestotal_attemptedr+   r,   r,   r-   run_module_section   s   
rj   c                 C   s"   |  drt|  d d S d S )Nr   )getr   update_configuration)cfgr,   r,   r-   apply_reporting_cfg   s   
rn   cloud-config-urlurlc                 C   s<   t | }|D ]}||v r||| f  S qtd| |f )Nz!No keys (%s) found in string '%s')r
   keyval_str_to_dictKeyError)cmdlinenamesdatakeyr,   r,   r-   parse_cmdline_url   s   
rx   Treturnc              
   C   s"  |du rt  }zt|\}}W n ty   tjdf Y S w |d}|rMtj	| rM|r@d| |f }tj
}|r<tj}||fS d| |f }tj}||fS |dddd	}|sX|r`tj}d
|d< ntj}d|d< d}	d}
zxtjdi |}d}| rd}t|tjrz|t|jt|
d7 }W n	 ty   Y nw ||
sd}n|j|
sd}|r|dkrtjdddddW S n"|dkrtj}ntj
}|d| dt|
 fW S |d||jf fW S ||j }	W n tjy } z|d||f fW  Y d}~S d}~ww t j| |	dd tj
d||| f fS )a  Write data from url referenced in command line to path.

    path: a file to write content to if downloaded.
    network: should network access be assumed.
    cmdline: the cmdline to parse for cloud-config-url.

    This is used in MAAS datasource, in "ephemeral" (read-only root)
    environment where the instance netboots to iscsi ro root.
    and the entity that controls the pxe config has to configure
    the maas datasource.

    An attempt is made on network urls even in local datasource
    for case of network set up in initramfs.

    Return value is a tuple of a logger function (logging.DEBUG)
    and a message indicating what happened.
    Nz!No kernel command line url found.)zfile:///z_file '%s' existed, possibly from local stage download of command line url '%s'. Not re-writing.zafile '%s' existed, possibly from previous boot download of command line url '%s'. Not re-writing.
      T)rq   timeoutretriesstreamr.   sec_betweeng?s   #cloud-config    )
chunk_sizeFrq   z!The kernel command line key `url`z22.3zD Please use `cloud-config-url` kernel command line parameter insteadr0   r1   r2   skip_logrp   zcontents of 'z' did not start with z$url '%s' returned code %s. Ignoring.zretrieving url '%s' failed: %si  )modez*wrote cloud-config data from %s='%s' to %sr,   )r
   get_cmdlinerx   rs   loggingDEBUG
startswithr4   rW   existsINFOWARNr	   read_file_or_urlok
isinstanceUrlResponsenextiter_contentrb   StopIterationcontentsr   r7   strcodeUrlError
write_file)rW   networkrt   cmdline_namerq   path_is_localmlevelkwargsrv   headerrespsniffed_contentis_cloud_cfger,   r,   r-   attempt_cmdline_url   s   



	r   c                 C   s   dt jjt jjf }tj| jdd}tj	|r9t
| }||kr7td | d t|| dS dS tj	| jdrHtd t|| dS )	zPurge the cache if python version changed on us.

    There could be changes not represented in our cache (obj.pkl) after we
    upgrade to a new version of python, so at that point clear the cache
    z%d.%drv   zpython-versionz-Python version change detected. Purging cacheTobj_pklzMWriting python-version file. Cache compatibility status is currently unknown.N)r%   version_infomajorminorr4   rW   joinpaths	get_cpathr   rO   readr9   rc   purge_cacher
   r   get_ipath_curr:   )r   current_python_versionpython_version_pathcached_python_versionr,   r,   r-   $purge_cache_on_python_version_change0  s&   

r   c                 C   s   t | jdr	dS |j S )Ndisable_network_activationF)r
   get_cfg_option_boolrm   local)r   r[   r,   r,   r-   _should_bring_up_interfacesN  s   r   c                    s&  t jt jg}|jrt jg}ttjdt d|j dg |jr"dnd}t	|}t
j||jd}|t| d }d }z |jsQt fdd t|j| \}}n	t|j| \}}W n tyx   d	}tt| t|  tj|f Y nw |jrtd
 t  |jst|j t |j t!| |d t"|j#|  D ]
\}	}t|	| qz|$  W n ty   ttd Y nw |j%}
t&| |jrt j'nt j(}|t j(krd}t)j*+dt,-   n,d}t.|jdd}|rtd d}n|
/d}tj0|rtd| d}|1  t2||}z"|j3|d |t j(kr6|j4j5|kr6td||j4 d g fW S W nF t j6y}   |t j'krLtd nttd |j7su|j8|d td| |t j'krnd g f Y S d dgf Y S td| Y nw t9| |: }td|| ||;  |t j'krt<|ddd  |j8|d |t j'kr|j4j5|krtd!||j4 |j4g fS td"||j4 |=  |>  t<|d#d$d  z|? j@d%|jAtBgtBd&\}}|s|AtC W n ty   ttd' |j4d'gf Y S w |j%/d(}tj0|r*tD|jEd)kr*tFtGHtI|ddd*d+ ntd, t |j tJ|t||jd-}z)|}|}t|j| \}}||ksV||krftKd.|| t|j| \}}W n tyw   ttd/ Y nw t|j |L  tM|j4|jd0 |j4tN|| | fS )1Nz%s.dz91_kernel_cmdline_url.cfg)rW   r   r   r   ds_depsreporterc                    s     tj| fS rT   )rV   r   r   r*   
early_logsr,   r-   <lambda>y  s    zmain_init.<locals>.<lambda>#Failed to setup output redirection!@Logging being reset, this logger may no longer be active shortlyr*   z0Failed to initialize, likely bad things to come!trustr"   checkmanual_cache_cleanFz"manual cache clean set from configmanual_clean_markerz(manual cache clean found from marker: %sexistingz)[%s] Exiting. datasource %s in local modezNo local datasource foundz8No instance datasource found! Likely bad things to come!)bring_upz[%s] Exiting without datasourcezNo instance datasource found.z2[%s] barreling on in force mode without datasourcez5[%s] %s will now be targeting instance id: %s. new=%sr   r   )stageretry_stagez.[%s] Exiting. datasource %s not in local mode.z6[%s] %s is in local mode, will apply init modules now.zinit-netzmodules:configconsume_data)r[   freqzConsuming user data failed!cloud_configr   T)configstrictlog_detailslog_deprecationsz2Skipping user-data validation. No user-data found.r   z#Stdout, stderr changing to (%s, %s)z'Failed to re-adjust output redirection!)
datasourcerm   )Or   DEP_FILESYSTEMDEP_NETWORKr   r   r4   rW   r   r   r@   r   Initr   read_cfgr^   skip_log_setuprS   r
   fixup_outputrm   get_output_cfg	Exceptionlogexcr9   r)   rV   r   r   rc   r   reset_loggingsetup_loggingrn   rC   r>   r;   
initializer   r   DSMODE_LOCALDSMODE_NETWORKr%   r&   r'   r   
debug_infor   r   r   r   r   fetchr   dsmodeDataSourceNotFoundExceptionforceapply_network_config_maybe_persist_instance_data
instancifyis_new_instance_maybe_set_hostnamesetup_datasourceupdatecloudifyrunr   r   r   statst_sizer   yaml	safe_loadload_text_filer   warningactivate_datasourcedi_report_warnrj   )rY   r[   depsr<   w_msgr   outfmterrfmtr+   lvlpath_helperr   r   mcfgmfilebring_up_interfacesiidran_resultscloud_cfg_pathr_   outfmt_origerrfmt_origr,   r   r-   	main_initT  s8  








 

r  c                 C   s   d|vrt d d S |d }|d u rt d d S t|ts't d| d S |d}|d u r7t d d S t|tsDt d| d S | jdd	 }|	t
jr\|tt
jd  }nt d
| | ||v rqt d| || d S tjd||t|d d S )N	di_reportzno di_report found in config.zdi_report was None.z%di_report config not a dictionary: %sdatasource_listz(no 'datasource_list' found in di_report.z(di_report/datasource_list not a list: %s.r|   z1Datasource '%s' came from unexpected module '%s'.z:used datasource '%s' from '%s' was in di_report's list: %sdsid_missing_source)sourcedslist)r9   rc   r   dictr   rk   list
__module__
rpartitionr   r   	DS_PREFIXrb   r   show_warningr   )r   rm   dicfgr
  modnamer,   r,   r-   r   6  sH   






r   c                 C   sT  |j }d| |f }t|}tjg |jd}|t| z|jdd W n  tj	yD   d| }t
t| t| |jsB|g Y S Y nw t| t|t||jd}z|jsat  t
|j| W n tyq   t
td Y nw |jr~td t  |jst|j t|j t||d	 t|j| |d
krtjdddd t |||S )Nz%s:%sr   r   r   zGCan not apply stage %s, no datasource found! Likely bad things to come!r   r   r   r*   r   z`--mode init`24.1Use `cloud-init init` instead.r/   )!r   r@   r   r   r   r   r^   r   r   r   r
   r   r9   r)   r   r   r   r   rS   r   rm   r   rc   r   r   r   rn   rC   r>   r;   r   r7   rj   )rd   r[   rY   r<   r   r   r+   r_   r,   r,   r-   main_modulesh  sZ   


r  c           
      C   st  |j }t| }tjg |jd}|t| z|jdd W n tj	y8   t
td td |js6Y dS Y nw t| t|t||jd}|j}|rRtd| |j}|rbtd| t|}zt  t
|jd  W n ty}   t
td	 Y nw |jrtd
 t  t|j t|j t| |d ||||\}}	|	rt d| dS |st d| dS dS )Nr   r   r   z;Failed to fetch your datasource, likely bad things to come!r.   r   zUsing passed in arguments %szUsing passed in frequency %sr   r   r*   zRan %s but it failed!zDid not run %s, does it exist?r   )!rY   r@   r   r   r   r   r^   r   r   r   r
   r   r9   r)   r   r   r   module_argsrc   	frequencyFREQ_SHORT_NAMESrk   rS   r   rm   r   r   r   r   rn   rC   
run_singler   )
rY   r[   mod_namer   r   r_   mod_argsmod_freqrg   rh   r,   r,   r-   main_single  s`   	

r  c                 C   s  t  }|d}tj|j}tj|d}tj|d}tj|d}tj|d}t }	t	
||f |j\}
}| dkrH|jrEd}nd}n| dkrRd|j }ntd|  |tvrctd	|g i d d d
}dd | | | | di}|dkr||||fD ]}t	| qnz
tt	|}W n	 ty   Y nw ||d vr| |d |< |d }||d< || d r|| d stdt|  tt	 || d< ttdd |	j}| }t || t	j!tj"|||dd zz,|| |}|dv r|\}}|d urt#||d< n|}|| d $dd |D  W n\ tyO } zt%d| t&d|  || d 't#| W Y d }~n7d }~w t(y } z&|j)rwt%d| t&d|  || d 'dt#|j) d W Y d }~nd }~ww W tt	 || d< d |d< | }|*  |+ D ]&}||v rt,t-|| ||  || d |< q|| || d |< qt || nHtt	 || d< d |d< | }|*  |+ D ]&}||v r t,t-|| ||  || d |< q|| || d |< qt || w |dkrWg }|+ D ]}t.|| t/r;|| 0dr;|$|| 0dg  qt |d|d |d i t	j!tj"|||dd t1|| d S )!Nrv   zstatus.jsonzresult.jsonr   r   modules
modules-%szunknown name: %sz'Invalid cloud init mode specified '{0}')errorsrecoverable_errorsstartfinishedv1)r   r   r   r   r    r   r"  r#  z=Unexpected start time found for %s. Was this stage restarted?c                 S   s   t | tjS rT   )r   r   LogExporter)hr,   r,   r-   r   9  s    z status_wrapper.<locals>.<lambda>T)r   )r   r   r   r   c                 S   s   g | ]}t |qS r,   )r   ).0r   r,   r,   r-   
<listcomp>L  s    z"status_wrapper.<locals>.<listcomp>zfailed stage %szfailed run of stage %sz	sys.exit(z) calledr!  r    )r   r   )2r   r   r4   rW   normpathrun_dirr   r   	getLoggerr
   ensure_dirsrB   r   r   
ValueError
STAGE_NAMErG   copydel_filejsonloadsr   r   r9   r   floatrD   r   filterhandlersexport_logsr   
write_jsonsym_linkrelpathr   extend	exceptionr)   rV   
SystemExitr   
clean_logskeysr  setr   r  rk   rb   )rY   r[   r   data_dlink_dstatus_pathstatus_linkresult_pathresult_linkroot_logger_namefunctorr   
nullstatusstatusfr$  handlerpreexisting_recoverable_errorsretr   r   r   new_recoverable_errorsrw   r   r,   r,   r-   status_wrapper  s  

	


 " 


 rP  r   c                 C   sB   | j r| jr| jd}tj|s| j jdd dS dS dS dS )zCWrite instance-data.json file if absent and datasource is restored.instance_dataF)write_cacheN)r   ds_restoredr   get_runpathr4   rW   r   persist_instance_data)r   instance_data_filer,   r,   r-   r     s   r   c              
   C   s~   |   }tj| j|dd\}}}|r=ztd| j|d W dS  tjy< } ztd||t	| W Y d}~dS d}~ww dS )zCall set_hostname if metadata, vendordata or userdata provides it.

    @param stage: String representing current stage in which we are running.
    @param retry_stage: String represented logs upon error setting hostname.
    T)metadata_onlyset_hostnameNzGFailed setting hostname in %s stage. Will retry in %s stage. Error: %s.)
r   r
   get_hostname_fqdnrm   r   handleSetHostnameErrorr9   rc   r   )r   r   r   cloudhostname_fqdn_r   r,   r,   r-   r     s"   r   c                 C   s    t jdttjd  d S )Nr#   )r%   stdoutr'   r   sortedr   FEATURES)rY   r[   r,   r,   r-   main_features  s    rc  c              	   C   s  t   | s	tj} tj| dd}|jddddt	  dd |jd	d
dddd |jdddddt
dd |jdddddd |jdddddd |jd d |jdd d!}|jd"d#d$}|jd%d&dd'dd |jdddd(d)t
dd |jd"tfd* |jd+d,d$}tjd-d.d/d0d1j}|jd2d3d4d5| d6d7d8 |jdddd(d)t
dd |jd+tfd* |jd9d:d$}|jd;d<d4d=d0d> |jd?d4d@dtt dA |jdBddCdd> |jdDdEdFdGdH |jdddd(d)t
dd |jd9tfd* |jdIdJd$}|jdKdLd$}|jdKtfd* |jdMdNd$}	|jdOdPd$}
|jdQdRd$}|jdSdTd$}|jdUdVd$}|jdWdXd$}| rtdYdZ | D d }|dMkrYdd[lm} ||	 n|dOkridd[lm} ||
 n|dQkrdd\lm}m} ||d] |jdQ|fd* nm|dSkrdd^lm}m} || |jdS|fd* nS|dIkrdd_l m}m!} || |jd`|fd* n9|dWkrddal"m}m#} || |jdW|fd* n|dUkrddbl$m}m%} || |jdU|fd* n|&dc |j'| dd}t(|ded |j)st*|S t)|S )fNr   )progz	--versionz-vr   z	%(prog)s z'Show program's version number and exit.)rB   r   helpz--debugz-d
store_truezFDEPRECATED: Show additional pre-action logging (default: %(default)s).F)rB   re  defaultz--filez-frV   rU   zPUse additional yaml configuration files for subcommands: init, modules or singlerb)rB   destre  typez--forcezPDEPRECATED: Force running even if no datasource is found (use at your own risk).r   )rB   re  ri  rg  z--all-stages
all_stageszsRun cloud-init's stages under a single process using a syncronization protocol. This is not intended for CLI usage.)ri  rB   re  rg  r   Subcommands
subcommand)titleri  r   z>DEPRECATED: Initialize cloud-init and perform initial modules.)re  --localz-lz+Start in local mode (default: %(default)s).rZ   z(Use additional yaml configuration files.rJ   r  z=DEPRECATED: Activate modules using a given configuration key.z`init`r  r  Tr   z--modez-mstorez9Module configuration name to use (default: %(default)s). r   )r   r   final)rB   re  rg  choicessinglezDManually run a single module. Useful for testing during development.z--namez-nzModule name to run.)rB   re  requiredz--frequencyzModule frequency for this run.)rB   re  rt  rr  z--reportzEnable reporting.r  *argumentz0Any additional arguments to pass to this module.)nargsmetavarre  queryz;Query standardized instance metadata from the command line.featureszList defined features.analyzez-Devel tool: Analyze cloud-init logs and data.develzRun development tools.zcollect-logsz*Collect and tar all cloud-init debug info.cleanz3Remove logs and artifacts so cloud-init can re-run.rJ  z/Report cloud-init status or wait on completion.schemaz-Validate cloud-config files using jsonschema.c                 s   s    | ]
}| d s|V  qdS )-N)r   )r'  posargr,   r,   r-   	<genexpr>r  s    zmain.<locals>.<genexpr>)
get_parser)r  handle_collect_logs_args)parser)r  handle_clean_args)r  handle_argsrender)r  handle_schema_args)r  handle_status_argsza subcommand is requiredr[   r   )+r   configure_root_loggerr%   argvargparseArgumentParserpopadd_argumentr   rH   FileTypeset_defaultsadd_subparsers
add_parserr  r   r7   messager  r  r  r>  r  rc  r   cloudinit.analyzer  cloudinit.cmd.devel.parsercloudinit.cmd.devel.logsr  cloudinit.cmd.cleanr  cloudinit.cmd.queryr  cloudinit.config.schemar  cloudinit.cmd.statusr  error
parse_argssetattrrk  sub_main)	sysv_argsr  
subparsersparser_init
parser_mod
extra_helpparser_singleparser_queryparser_featuresparser_analyzeparser_develparser_collect_logsparser_cleanparser_statusparser_schemarm  analyze_parserdevel_parserlogs_parserr  clean_parserr  query_parserhandle_query_argsschema_parserr  status_parserr  r[   r,   r,   r-   main  s  














r  c                 C   s  t d tdddd}td |d | jddgd	}d
|_t||_W d   n1 s1w   Y  |d | jdgd	}d|_t||_W d   n1 sTw   Y  |d | jddgd	}d|_t||_W d   n1 sxw   Y  |d | jddgd	}d|_t||_W d   n1 sw   Y  |j	rd}|j
rd|j
 }td| d td dS td td dS )z>Run all stages in a single process using an ordering protocol.z*Running cloud-init in single process mode.r   r   r   rq  zREADY=1r   ro  r  FNTr  z--mode=configz--mode=finalz%a stage of cloud-init exited non-zerozfirst exception received: zSTATUS=Completed with failure, z2. Run 'cloud-init status --long' for more details.z
STOPPING=1r.   zSTATUS=Completed)r9   r:   r   
SocketSync	sd_notifyr  r   r  systemd_exit_codeexperienced_any_errorfirst_exception)r  syncr[   r  r,   r,   r-   rk    sD   








rk  c                 C   s\  | j \}}|dvrt| jrtjntj n| jrt  t  d|ks.d|kr0d| j	kr0t
}d }d}|dkrE| jr@d\}}n0d\}}n+|dkrUd| j	 d| j	 }}n|d	krhd
| j d| j }}| j}n|}d| }d}tj|||d| _| j tjtjd| d||| fd}W d    n1 sw   Y  t  d|krd| j	krt|}|S )N)r   r  r   r  T)r   zsearching for local datasources)zinit-networkz!searching for network datasourcesr  zrunning modules for %srs  z	single/%szrunning single module %szrunning 'cloud-init %s'F)reporting_enabledzcloud-init mode '%s')logfuncr+   
get_uptimefuncr[   )rB   r   setup_basic_loggingrc   r   r   WARNINGr   attach_handlersr   rP  r   rY   reportr   ReportEventStackr   r
   log_timer9   r   flush_eventsrb   )r[   rY   rH  rname	report_onrdescretvalr,   r,   r-   r    sX   


r  __main__TZz:/etc/localtime)r!   rT   )ro   )TN)Nr  r1  r4   r%   r(   r   r   typingr   r   	cloudinitr   r   r   r   r   r	   r
   r   r   r   r   r   cloudinit.cmd.develr   cloudinit.configr   cloudinit.config.modulesr   r  r   r   cloudinit.reportingr   cloudinit.settingsr   r   r   r   rF   r`   r  r.  r+  __name__r9   r)   r8   r>   rC   r@   rc   r   rS   r^   rj   rn   rx   intr   r   r   r  r   r  r  rP  r   r   r   rc  r  rk  r  environr  return_valueexitr,   r,   r,   r-   <module>   s   	


	
m c2AF 
  
;
J

