o nnh@sddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddlmZmZmZmZmZmZddlmZddlmZddlmZddlmZdd lmZmZdd l m!Z!dd l"m#Z#dd l$m%Z%dd l&m'Z'ddl(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4ddl5m6Z6m7Z7ddl8m9Z9m:Z:ddl;mZ>e<Z?dde j@ADZBdgZCGdddeDZEddZFddZGGdddZHd d!ZIdS)") annotationsN) constants) AnsibleErrorAnsibleParserErrorAnsibleUndefinedVariableAnsibleConnectionFailureAnsibleActionFailAnsibleActionSkip) TaskResult)get_action_args_with_defaults)boolean) binary_type)to_text to_native)write_to_file_descriptor) Conditional)Task)get_plugin_class) become_loadercliconf_loaderconnection_loaderhttpapi_loadernetconf_loaderterminal_loader)Templar)AnsibleCollectionConfig)listify_lookup_plugin_terms)to_unsafe_textwrap_var)namespace_facts clean_facts)Display) combine_varscCs g|] }d|vrd|vr|qS)become_pass).0xr%r%I/usr/local/lib/python3.10/dist-packages/ansible/executor/task_executor.py 's r) TaskExecutorc@s eZdZdS)TaskTimeoutErrorN)__name__ __module__ __qualname__r%r%r%r(r+,sr+cCstN)r+)signumframer%r%r( task_timeout0sr2cst|ts|Si}|D];}|dkrq t|dtr)t|d||d<q t|dtr@fdd|dD||d<q |d||d<q |S)z Remove args with a value equal to the ``omit_token`` recursively to align with now having suboptions in the argument_spec rcsg|]}t|qSr%) remove_omit)r&v omit_tokenr%r(r)Dszremove_omit..) isinstancedictitemsr4list) task_argsr7new_argsir%r6r(r44s    r4c@seZdZdZddZddZddZdd Zd d Zdd dZ dddZ ddZ ddZ ddZ ddZddZddZddZd S) r*z This is the main worker class for the executor pipeline, which handles loading an action plugin to actually dispatch the task to a given host. This class roughly corresponds to the old Runner() class. c CsP||_||_||_||_||_||_||_d|_||_| |_ d|_ |j dSr/) _host_task _job_vars _play_context _new_stdin_loader_shared_loader_obj _connection_final_q_variable_manager_loop_eval_errorsquash) selfhosttaskjob_vars play_context new_stdinloadershared_loader_objfinal_qvariable_managerr%r%r(__init__TszTaskExecutor.__init__c sltd|jjzzWz|}Wnty*}z d}||_WYd}~nd}~ww|durt|dkr||}t |d}d|d<|D]}d|vrY|drY| dsYd|d<|drmd|vsid|vrm|dsmd|d<d |vr|d r| d }| d sd|d <d |d <||j_ n |jj r|s||j_ d |vr|d r| d}| d sd|d <||j_ n |jj r|s||j_ dD]-}||vr||r||vrg||<t||ts||g||<||||||<||=qqF| d dsd|d <|drd|d <nt dddgd}ntd|}tdd|vrd|d<d"fdd td|}td|WWz|jWStyHYStyc}ztdt|WYd}~Sd}~wwty}zBt dtt|dd|jjdWYd}~Wz|jWStyYSty}ztdt|WYd}~Sd}~wwd}~wty}zJt dtdt|ddttd |jjd!WYd}~Wz|jWStyYSty}ztdt|WYd}~Sd}~wwd}~wwz|jWwtyYwty5}ztdt|WYd}~wd}~ww)#a The main executor entrypoint, where we determine if the specified task requires looping and either runs the task with self._run_loop() or self._execute(). After that, the returned results are parsed and returned as a dict. zin run() - task %sNr)resultsTskippedchangedFfailed_ansible_ignore_errorszOne or more items failedmsg unreachable_ansible_ignore_unreachable)warnings deprecationszAll items completedzAll items skippedzNo items in the list)rXrWskipped_reasonrVzcalling self._execute()z_execute() donesurrogate_or_strictc st|tr t||dSt|trA|D],}z |||d||<Wqty>|dkr;td||dd||<nYqw|St|trWt|D] \}}||d||<qJ|S)Nerrorsdiffz{We were unable to decode all characters in the module return data. Replaced some in an effort to return as much as possiblesurrogate_then_replace) r8r rr9 UnicodeErrordisplaywarningr; enumerate)resrckidxitem _clean_resr%r(ros$      z$TaskExecutor.run.._clean_reszdumping result to jsonzdone dumping result, returningzerror closing connection: %s simplerepr) nonstring)rYr[_ansible_no_logz.Unexpected failure during module execution: %s)rYr[ exceptionstdoutrr)ra)rgdebugr@_uuid_get_loop_itemsrrIlen _run_loopr9getpop ignore_errorsignore_unreachabler8r;_executerFcloseAttributeError ExceptionrrrrBno_logr traceback format_exc) rKr:e item_resultsrjrm item_ignoreitem_ignore_unreachablearrayr%rnr(runcs                    *zTaskExecutor.runcCs,|j|jd<|j|jdvr|jd|jt|j|jd}d}|jjr||jj|jj vrtt |jjdk}t |jj ||dd}|jj j |jj|j|d}dD] }||jjvr^nqTt|d |d t|j||jd d }|Std |jj|jj dur||jj }t|tstd||S)z Loads a lookup plugin to handle the with_* portion of a task (if specified), and returns the items result. ansible_search_pathrQ variablesN first_foundF)termstemplarfail_on_undefined convert_bare)rQr)templatevarfile_subdirsT)rrwantlistzSUnexpected failure in finding the lookup named '%s' in the available lookup pluginszInvalid data passed to 'loop', it requires a list, got this instead: %s. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup.)r@get_search_pathrArD get_basedirappendr loop_withrE lookup_loaderboolrloopr{actionsetattrrrrrr8r;)rKrr:fail loop_termsmylookupsubdirr%r%r(rxs6    zTaskExecutor._get_loop_itemsc CsP|j}t|j|d}|jjj|d|jjj}|jjj}|jjj}|jjj }|jjj }|jjj p5d|d} ||vrDt d|j|fd} d} d} t|} g}t|D]\}}||d<|||<|rk||d <|||<|r|d ||d k|d | k| | || |d d |d <|r||d d<z ||d |d d<Wn tyYnw|d d kr||d |d d<||_|r| rt|nd} z|jjddd}|jj|_|j}Wnty}z|tdt|dWYd}~qTd}~ww||j|_}||j|_}|j|d}|jjr|||jj<|j} ||j|_}||j|_}| p-|j} |||<||d<|rA|||<||d <|rJ|d |d <d|d<| d|d<| d|d<z | | |d<Wnt!y}z|"ddt|dWYd}~nd}~wwt#|j$j%|jj&|| d}|'s|(r|j)*d|n+|+r|j)*d|nt,|jddr|j)*d ||jj-t.j/vr|j)*d!|||||=|j0r|j0j1|j0j2j1d"}|j0j3r|j0j3j1|d#<|4D]\}}t.j56||D]}||vr||jvr||=qqqT| |j_| d$|j_7| d%|j_-|S)&z Runs the task with the loop items specified and collates the result into an array named 'results' which is inserted into the final result along with the item for which the loop ran. rrz{{z}}z%s: The loop variable '%s' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable collisions and unexpected behavior.FNansible_loop_varansible_index_varr3r)indexindex0firstlastlengthrevindex revindex0 ansible_loopallitemsnextitemprevitemT)exclude_parent exclude_tasksrYr[)r_ansible_item_resultr}rZr~r]_ansible_item_labelz)Failed to template loop_control.label: %s task_fieldsv2_runner_item_on_failedv2_runner_item_on_skippedrdv2_on_file_diffv2_runner_item_on_ok) connectionshellr#run_oncer)8rArrDr@ loop_control post_validateloop_var index_varpauseextendedextended_allitemslabelrgrhryri IndexErroravailable_variablestimesleepcopy_parentrBrrr9rrregister dump_attrsrr{rrupdater r?namerw is_failedis_unreachablerG send_callback is_skippedgetattrrC_ACTION_INVENTORY_TASKSrF _load_name_shellr#r:configget_plugin_varsr)rKr: task_varsrrr loop_pauserrrran_oncerr items_lenrV item_indexrmtmp_tasktmp_play_contextrrjtr clear_plugins plugin_type plugin_namerr%r%r(rzs                        zTaskExecutor._run_loopcCs4|j||j|\}}|r||j_||dSdS)zThis method is responsible for effectively pre-validating Task.delegate_to and will happen before Task.post_validate is executed N)rHget_delegated_vars_and_hostnamer@ delegate_tor)rKrrdelegated_varsdelegated_host_namer%r%r(_calculate_delegate_tos z#TaskExecutor._calculate_delegate_toNc sn |durj}tj|d|d}|}z$jjj|d_jjdjj s7j j j_ j |Wnt yR}z|}WYd}~nd}~wwjj}zj|\}}|srtdtddd||d WSWnt y}zjdurtt|jd}~wwjdurj|durd}jjrt|trd}nt|trt|d d} t| trd}|r||_jjtjvrjj} | d d} | stdd d S!| } t| | dSjjtj"vrjj} t| dSz jjdWnt y t#y"tdd|tt$%dYSwdjjvrTjj d} t| trLtj&r@t'd| (jj| j_nt d| djj}i}jjrl|)di)jji} n|} | _| )ddur!| d}njj*}j+rtj+ddrj+,|grjj j+jj kr-| |_+n jj+_.| j+/| }|j+ _jjjdj+_d| vrd| vrtj+ddrt0j1| d<j2d\_3}|dur|j4}njj5}t6|jjjj7jj8j9j:dj_|)d}|dur+t;jj|j_d}jj|t=djj<7}n jj>rG|d7}jj?}|dkrRd}td d}t@d|dD]}td!zzjjAr}tBBtBjCtD}tBEjjAj3jFd"}WntGtHfy}z"|jIWYd}~WjjArtBEdtBBtBjC|}j3JSd}~wtKy}z'tdt|d#WYd}~WjjArtBEdtBBtBjC|}j3JSd}~wtLy$}z/d$jjjjAf}td|d WYd}~WjjArtBEdtBBtBjC|}j3JSd}~wwWjjAr7tBEdtBBtBjC|}j3JnjjArNtBEdtBBtBjC|}j3Jwtd%tM|pb|)d&d|d&<jjtjNvrrtO|}jjPr}|jjP<jjQdkr҈jjRdkr|)d's|)d(sΈjS|d)}|)d(rjTUd*tVj jWjjX|jYd+njTUd,tVj jWjjX|jYd+||d&<fd-d.}fd/d0}d1|vr=jjtjZvr=jjtjNvrjjrjj[rd2vrd2(|d1n-|d1d2<n&(|d1ntO|d1}t\)d1it]|d1<tj&r=(t^|d(|vrWd3|vrS|d3d4vrSd|d(<nd|d(<|dkr`||d5<d6|vrid|d6<jjtjNvrutO|}jjPr|jjP<d'|vrd6}z ||d(}||Wnt y}zd|d(<t||d7|<WYd}~nd}~ww|dkr t_jd8}jj>p|d( g|_`|arnG||kr d|d9<||d:<td;||fjTUdjji|d2<|D] }| )||d2|<qd?D]}||d2vr|| vr| )||d2|<qtd@|S)Az The primary workhorse of the executor system, this runs the task on the specified host (which may be the delegated_to host) and handles the retry/until and block rescue/always execution Nr)rMrrrz,when evaluation is False, skipping this taskFTzConditional result was False)rXrW skip_reasonfalse_conditionrrorig_exc _raw_paramsz,No include file was specified to the includer)include include_args)r)rXrYrrrt_variable_paramszUsing a variable for a task's 'args' is unsafe in some situations (see https://docs.ansible.com/ansible/devel/reference_appendices/faq.html#argsplat-unsafe)z invalid or malformed argument: ''ansible_delegated_varsansible_connection connectedansible_python_interpreteransible_network_os_remote_is_local) action_groupsomitr3rzstarting attempt loopzrunning the handlerr)r\r[zRThe %s action failed to execute in the expected time frame (%d) and was terminatedzhandler run completerrrWrY)resultrrv2_runner_on_async_failedrv2_runner_on_async_okcsFjjdurjjr!tjd}jj|_||d<dSdSdS)NrQrX)r@ changed_whenrrDwhenevaluate_conditional)rcondrKr vars_copyr%r(_evaluate_changed_when_results   z._evaluate_changed_when_resultcsFjjrtjd}jj|_|}||d<|d<|Sd}|S)Nrfailed_when_resultrYF)r@ failed_whenrrDrr)rr r r r%r(_evaluate_failed_when_results   z;TaskExecutor._execute.._evaluate_failed_when_result ansible_facts_ansible_delegated_varsrc)r0attemptsrXz%s_when_resultr_ansible_retryretrieszRetrying task, attempt %d of %dv2_runner_retry_ansible_notifyansible_delegated_host) ansible_host ansible_port ansible_userrz'attempt loop complete, returning result)frArrDrrrBset_task_and_variable_overrider@r remote_addrr?address update_varsrr evaluate_conditional_with_resultrgrvr9rIr5rrr8rrrrrr_ACTION_INCLUDE_TASKSargsr|r_ACTION_INCLUDE_ROLErrrINJECT_FACTS_AS_VARSrhrr{rrF matches_name_get_connection_set_become_plugin_set_connection_optionssys executable'_get_action_handler_with_module_context_handler resolved_fqcnresolved_actionr module_defaultsr_play_action_groupsr4rmaxuntildelayrangetimeoutsignalSIGALRMr2alarmrrr rcleanuprr+r_ACTION_WITH_CLEAN_FACTSrr async_valpoll_poll_async_resultrGrr rrwr _ACTION_DEBUGdelegate_factsr"rr rrrrr_get_action_handlernotify) rKrcontext_validation_errortempvarsrrconditional_resultrraiseitrr include_filevariable_paramscvarscurrent_connection plugin_varsmodule_contextmodule_defaults_fqcnr7rr5rattemptold_sigr[r rafcondnamer rk requireshedr%r r(rs                         $                       &                        zTaskExecutor._executec Cs@|dur|j}|d}|durtdddSttdd|i|jj|jjd}|jj jd ||j |j |j ||jd }|jj }|d krt|jjz"|j|d }t|d d dksgd|vrc|ddsgd|vriWn`WnBty} z6tdt| tdttz|j Wn tyYnw||jj8}|d krWYd} ~ nd} ~ ww||jj8}|jdt|jj |j!||"d|d ksAt|d d dkr|drtdd|jj |dStdd|dSt|dd|jj|jjd} |jj jd | |j |j |j ||jd } | j|d | j#dd|j#dd|S)z< Polls for the specified JID to be complete Nansible_job_idTz(No job id was returned by the async taskr async_statusjid)rr# check_mode environmentzansible.legacy.async_status)rMrrOrQrrRrrfinishedr3rY_ansible_parsedFrWz-Exception during async poll, retrying... (%s)zAsync poll exception was: %sv2_runner_on_async_pollrz;async task did not complete within the requested time - %ss)rYr[ async_resultz'async task produced unparseable resultsr;)rVmode)rUrWrX)force)$rAr{r9rloadr@rWrXrE action_loaderrFrBrDr=rrr>rintrrgvvvvrrvrrresetrrGrr r?rrwrr;) rKrrr async_jid async_task async_handler time_leftr\r cleanup_taskcleanup_handlerr%r%r(r?@s         )    zTaskExecutor._poll_async_resultcCst|}|s td||S)NzInvalid become method specified, could not find matching plugin: '%s'. Use `ansible-doc -t become -l` to list available plugins.)rr{r)rKrr#r%r%r( _get_becomes zTaskExecutor._get_becomecCsj||j_|jj}|jjj||j|j|jjtt d\}}|s&t d|| ||||j ||S)z Reads the connection property for the host, and returns the correct connection object from the list of connection plugins ) task_uuidansible_playbook_pidz(the connection plugin '%s' was not found)rBrrErget_with_contextrCr@rwrosgetppidrr(set_attributes_from_plugin)rKrJrrK conn_typerplugin_load_contextr%r%r(r's    zTaskExecutor._get_connectioncCs|ddurt||d}n|jj}|r/|dr'|||d}n ||jj}nd}z||Wn tyAYnw|rdt |jddr[t |dds[t d|j |j f|j |j dSdS)Nansible_becomeansible_become_method require_ttyFhas_ttyz`The '%s' connection does not provide a TTY which is required for the selected become plugin: %s.)r{r rr@r#rj become_methodset_become_pluginrrrrrrB)rKrJrrr# become_pluginr%r%r(r(s,   zTaskExecutor._set_become_pluginc Csz t|jd|}Wntyt|j|}Ynw|dkr d}tj||j}i}|D]}||vr;|||||<q,|j||d|S)Nz_%s ssh_type_connr task_keys var_options) rrFrrrrrr set_options) rKrrrr|plugin option_varsoptionsrkr%r%r(_set_plugin_optionss z TaskExecutor._set_plugin_optionsc Cstg}tjd|jj}|||j}|jj |d<|jj r%|jj |d<|d=|j ||}|jj ||d|| d||||jjdur|jjrR|jj|d<|| d|||d D]}zt|j||jj|Wq_tyxYq_w|jjj|j_t|jd d}|r|d d krt|d } || | |||t|jdd} | dur|| d||||S)Nrr7passwordrr{r become_passr#) become_user become_flags become_exer _sub_plugintypeexternalobjrz)rrrrFrextendr@rrBr7r_resolve_option_variablesr~rr#rr get_optionKeyErrorpromptrr{r) rKrrvarnamesrr|r}optionsubrsub_connr%r%r(r)s<       z$TaskExecutor._set_connection_optionscCs||dS)zX Returns the correct action plugin to handle the requestion task action r)r,)rKrr%r%r(rBIsz TaskExecutor._get_action_handlerc Cs|jjd\}}}|dd}|rd||}n|}|jj}|jjj|jj|d}|j r1|j s3d}|dur;|j } n7|jj j |jj|drK|jj} n't |tjv|jj j ||dfrn|} tjdj| |jjd|jjd nd } d}t|jjoytj|jjfr|jj j| d d } t| d d r|jd|j_tjd|jjd tjd|jj|jjd |j} t|j| |jj } tjd| |jjd t!|jd| n|"i|d|_|jj j| |j|j|j|j#||j|d} | st$d| | |fS)zo Returns the correct action plugin to handle the requestion task action and the module context ._rz{0}.{1})collection_listNz1Using network group action {handler} for {action})handlerrrLzansible.legacy.normalT) class_only_requires_connectionpersistent_command_timeoutzattempting to start connectionzusing connection plugin %szlocal domain socket path is %s _socket_pathlocal)rMrrOrQrrRrzthe handler '%s' was not found)%r@r rpartitionsplitformat collectionsrE module_loaderfind_plugin_with_contextresolved action_pluginr` has_pluginallrNETWORK_GROUP_MODULESrgrbrBranyrFsupports_persistenceUSE_PERSISTENT_CONNECTIONSforce_persistencer{rrr7 transport get_optionsstart_connectionrwrr'rDr)rKrmodule_collection separator module_name module_prefixnetwork_actionrmodule handler_name handler_classr socket_pathrr%r%r(r,Os`       z4TaskExecutor._get_action_handler_with_module_contextr/)r,r-r.__doc__rUrrxrzrrr?rjr'r(rr)rBr,r%r%r%r(r*Ks(o0  o$; c Cstjp tjtjdg}|tj dd tj |D]}tj |d}tj |r6td|nqtdtj}|ttttj tjttttdg}tjro|dd tjtj }t!"\} } t#j$||g|t%t&t%|| t#j't#j'|d } t(| t)*| } t)*| } | d t)j+@| d <z$t),| t)j-| t.| |t.| |/| 0\}}Wt),| t)j-| n t),| t)j-| wt(| | j1dkrt23t%|d d }n z t23t%|d d }Wnt2j4j5y dt%|d d i}Ynwd|vrR|dD];\}}|dkr(tj|ddq|dvr9t6t|||j7dqt8t|rHt6t||qtj||j7dqd|vrwtjdkrq| drqd|d}tj|tj9dt|d|dS)z* Starts the persistent connection rPATHrszansible-connectionz$Found ansible-connection at path {0}ziUnable to find location of 'ansible-connection'. Please set or check the value of ANSIBLE_CONNECTION_PATH)ANSIBLE_BECOME_PLUGINSANSIBLE_CLICONF_PLUGINSANSIBLE_COLLECTIONS_PATHANSIBLE_CONNECTION_PLUGINSANSIBLE_HTTPAPI_PLUGINSANSIBLE_NETCONF_PLUGINSANSIBLE_TERMINAL_PLUGINSz-%sr5)stdinrustderrenvrrerberrormessageslogT)log_only)rvr5vvvvvrbvvvvvvvvvvvrrtzThe full traceback is: )colorr):rANSIBLE_CONNECTION_PATHrnpathdirnamer*argvrenvironr{rpathsepjoinisfilergrbrrrrr print_pathsrrrcollection_pathsrrrr verbosityrr+ptyopenpty subprocessPopenrroPIPErtermios tcgetattrICANON tcsetattrTCSANOWr serialize communicate returncodejsonloadsdecoderJSONDecodeErrorrrhasattr COLOR_ERROR)rOrrkcandidate_pathsrrrrpythonmasterslavepoldnewrurrlevelmessager[r%r%r(rs|         $           r)J __future__rrnrrrr8rr*rransiblerransible.errorsrrrrrr ansible.executor.task_resultr ansible.executor.module_commonr )ansible.module_utils.parsing.convert_boolr ansible.module_utils.sixr +ansible.module_utils.common.text.convertersrransible.module_utils.connectionransible.playbook.conditionalransible.playbook.taskransible.pluginsransible.plugins.loaderrrrrrransible.templateransible.utils.collection_loaderransible.utils.listifyransible.utils.unsafe_proxyrransible.vars.cleanrr ansible.utils.displayr!ansible.utils.varsr"rgMAGIC_VARIABLE_MAPPINGr: RETURN_VARS__all__ BaseExceptionr+r2r4r*rr%r%r%r(sZ                  U