U
    Ӈg4                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZmZm	Z	m
Z
 d dlmZ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mZ d d
lmZ eeZdZddgZ ddiZ!G dd de	Z"dd Z#dd Z$e"e%e&dddZ'G dd dZ(dS )    N)	signature)
ModuleType)DictList
NamedTupleOptional)configimporter	lifecycleperformance
type_utilsutil)ALL_DISTROS)ConfigMerger)ReportEventStack)FREQUENCIES)InitZcc_Zcc_migratorZcc_rightscale_userdataZcc_ubuntu_advantageZcc_ubuntu_proc                   @   s2   e Zd ZU eed< eed< eed< ee ed< dS )ModuleDetailsmodulename	frequencyrun_argsN)__name__
__module____qualname__r   __annotations__strr    r   r   :/usr/lib/python3/dist-packages/cloudinit/config/modules.pyr   2   s   
r   c                 C   sX   |  dd}| dr.|dt|d  }| }|s>d S |tsTdt|f }|S )N-_z.pyr      z%s%s)replacelowerendswithlenstrip
startswith
MOD_PREFIX)r   Z
canon_namer   r   r   form_module_name9   s    
r)   c                 C   s   t | drd| jksd| jkr4td|  d| d| jd tkrdtd|  d| d| jd  dt | d	rtd|  d| d
d S )Nmetar   distroszModule 'z' with name 'z4' MUST have a 'meta' attribute of type 'MetaSchema'.z' has an invalid frequency .ZschemazX' has a JSON 'schema' attribute defined. Please define schema in cloud-init-schema,json.)hasattrr*   
ValueErrorr   )modr   r   r   r   validate_moduleE   s"    
r0   )module_detailscfgreturnc                 C   s2   t | jjdi }|sdS || s.dS dS )NZactivate_by_schema_keysTF)	frozensetr   r*   getintersectionkeys)r1   r2   Zactivate_by_schema_keys_keysr   r   r   
_is_active[   s    r8   c                   @   sx   e Zd ZdedddZeejdddZe	e
 ddd	Ze	e dd
dZe	e dddZdddZdd ZdS )ModulesN)initc                 C   s2   || _ || _d | _|d kr(tdddd}|| _d S )Nzmodule-reporterzmodule-descF)r   descriptionZreporting_enabled)r:   	cfg_files_cached_cfgr   reporter)selfr:   r<   r>   r   r   r   __init__g   s    zModules.__init__)r3   c                 C   s<   | j d kr0t| jj| jj| j| jjd}|j| _ t| j S )N)paths
datasourceZadditional_fnsZbase_cfg)	r=   r   r:   rA   rB   r<   r2   copydeepcopy)r?   Zmergerr   r   r   r2   t   s    
zModules.cfgc                 C   s`  g }|| j kr|S | j |}|s&|S |D ].}|s6q*t|trT|d| i q*t|tri }t|dkr~|d  |d< t|dkr|d  |d< t|dkr|dd |d< |r|| q*t|trDi }d	}d
|kr|d
  |d< d}d|kr|d  |d< d|kr,|d p&g |d< |rZ|rZ|| q*t	d|t
|f q*|S )aU  Read the modules from the config file given the specified name.

        Returns a list of module definitions. E.g.,
        [
            {
                "mod": "bootcmd",
                "freq": "always",
                "args": "some_arg",
            }
        ]

        Note that in the default case, only "mod" will be set.
        r/      r      freqr!   NargsFr   Tr   z3Failed to read '%s' item in config, unknown type %s)r2   r5   
isinstancer   appendr&   listr%   dict	TypeErrorr   obj_name)r?   r   Zmodule_listZcfg_modsitemcontentsZvalidr   r   r   _read_modules   sV    


 


zModules._read_modulesc              	   C   s.  g }|D ]}|d }| d}| dp,g }t|}|s<q|rf|tkrftjd| d| dd d}|tkrtjd	| d
t|  ddd t| }t|dt	t
gdg\}}	|s|tkrtd|dd  qtd||	 qt|d }
t|
| |dkr|
jd }|t|
|||d q|S )zConvert list of returned from _read_modules() into new format.

        Invalid modules and arguments are ignored.
        Also ensures that the module has the required meta fields.
        r/   rG   rH   zConfig specified module z has an unknown frequency z22.1Z
deprecatedZdeprecated_versionNzModule has been renamed from z to z/. Update any references in /etc/cloud/cloud.cfgz24.1 handlez\Module `%s` has been removed from cloud-init. It may be removed from `/etc/cloud/cloud.cfg`.r!   z,Could not find module named %s (searched %s)r   r   )r   r   r   r   )r5   r)   r   r
   	deprecateRENAMED_MODULESr	   find_moduler   rN   r   REMOVED_MODULESLOGinfoZwarningimport_moduler0   r*   rJ   r   )r?   raw_modsmostly_modsZraw_modZraw_namerG   r   mod_nameZmod_locsZlooked_locsr/   r   r   r   _fixup_modules   sd    

	  



zModules._fixup_modules)r]   c                 C   sh  | j  }g }g }|D ]F\}}}}ztd||| || d| }	d|	|f }
t|	|
| jd}|| j||d}| t|j	}|j
}t|dkrtjddd	 |d
ti tjddd}|j|	|j	||d\}}W 5 Q R X |r|	 d|jdd|_n
d|	 |_W 5 Q R X W q tk
r\ } z"ttd|| |||f W 5 d }~X Y qX q||fS )Nz(Running module %s (%s) with frequency %szconfig-zrunning %s with frequency %s)r   r;   parent)r   r2   ZcloudrH      z%Config modules with a `log` parameterz23.2rR   logrS   skip)Zlog_mode)rG   z ran successfully and took z.3fz secondsz%s previously ranzRunning module %s (%s) failed)r:   ZcloudifyrY   debugrJ   r   r>   r2   r   rT   Z
parametersr%   r
   rU   updater   ZTimedrunZdeltamessage	Exceptionr   Zlogexc)r?   r]   ZccZfailuresZ	which_ranr/   r   rG   rH   run_nameZdescZmyrepZ	func_argsZfunc_signatureZfunc_paramsZtimerZranZ_rer   r   r   _run_modules   s`    
   

  
   "zModules._run_modulesc                 C   s&   |||d}|g}|  |}| |S )N)r/   rH   rG   )r_   rk   )r?   r^   rH   rG   Z	mod_to_ber\   r]   r   r   r   
run_single7  s    
zModules.run_singlec                 C   s  |  |}| |}| jjj}g }g }| jdg }g }g }	|D ]}
|
\}}}}|dkrZq@|jd }t|
| js||	| q@|r|t
gkr||kr||kr|	| q@|	| |		||||g q@|rtdd| |rtdd|| |r
tdd| | |	S )	zRuns all modules in the given section.

        section_name - One of the modules lists as defined in
          /etc/cloud/cloud.cfg. One of:
         - cloud_init_modules
         - cloud_config_modules
         - cloud_final_modules
        Zunverified_modulesNr+   z?Skipping modules '%s' because no applicable config is provided.,zSkipping modules '%s' because they are not verified on distro '%s'.  To run anyway, add them to 'unverified_modules' in config.z running unverified_modules: '%s'z, )rQ   r_   r:   Zdistror   r2   r5   r*   r8   rJ   r   rY   rZ   joinrk   )r?   Zsection_namer\   r]   Zdistro_nameZskippedZforcedZ
overriddenZinapplicable_modsZactive_modsr1   r/   r   Z_freqZ_argsZworked_distrosr   r   r   run_sectionC  sJ    	






zModules.run_section)NN)NN)r   r   r   r   r@   propertyr   ZConfigr2   r   r   rQ   r   r_   rk   rl   ro   r   r   r   r   r9   f   s   ;C7
r9   ))rC   Zlogginginspectr   typesr   typingr   r   r   r   Z	cloudinitr   r	   r
   r   r   r   Zcloudinit.distrosr   Zcloudinit.helpersr   Zcloudinit.reporting.eventsr   Zcloudinit.settingsr   Zcloudinit.stagesr   Z	getLoggerr   rY   r(   rX   rV   r   r)   r0   rL   boolr8   r9   r   r   r   r   <module>	   s.    
 