a 'Dg <@sRddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z ddlm Z ddl mZddlmZmZmZddlmZeeZGdddeZGd d d ejd ZGd d d eZGdddeZGdddeZGdddeZeeeeeefZ eZ!e!"dee!"dee!"dee!"dedS)N)datetimetimezone)Event)Union) performance url_helperutil) DictRegistryc@s eZdZdS)ReportExceptionN)__name__ __module__ __qualname__rr@/usr/lib/python3.9/site-packages/cloudinit/reporting/handlers.pyr sr c@s&eZdZdZejddZddZdS)ReportingHandlerzBase class for report handlers. Implement :meth:`~publish_event` for controlling what the handler does with an event. cCsdS)zPublish an event.Nrselfeventrrr publish_event"szReportingHandler.publish_eventcCsdS)z0Ensure ReportingHandler has published all eventsNrrrrrflush&szReportingHandler.flushN)r r r __doc__abcabstractmethodrrrrrrrs r) metaclasscs*eZdZdZdfdd ZddZZS) LogHandlerzBPublishes events to the cloud-init log at the ``DEBUG`` log level.DEBUGcs`tt|t|trn<|}ztt|}Wn$tyTt d|tj }Yn0||_ dS)Nzinvalid level '%s', using WARN) superr__init__ isinstanceintgetattrloggingupper ExceptionLOGwarningZWARNlevel)rr'Z input_level __class__rrr-s    zLogHandler.__init__cCs2tddd|j|jg}||j|dS)N. cloudinitZ reporting)r" getLoggerjoin event_typenamelogr' as_string)rrloggerrrrr:szLogHandler.publish_event)r)r r r rrr __classcell__rrr(rr*s rc@seZdZdZddZdS) PrintHandlerzPrint the event as a string.cCst|dSN)printr1rrrrrDszPrintHandler.publish_eventN)r r r rrrrrrr4Asr4cs6eZdZd fdd ZddZddZdd ZZS) WebHookHandlerNc stt|t||||gr:tj||||d}|j|_ntj|_||_||_||_ t |_ t |_t|_tj|jd|_d|j_|jdS)N) consumer_key token_key token_secretconsumer_secrettargetT)rr7ranyrZOauthUrlHelperreadurlendpointtimeoutretriesrZfetch_ssl_details ssl_detailsrflush_requestedqueueQueue threadingThreadprocess_requestsZevent_processordaemonstart) rr@r8r9r:r;rArBZ oauth_helperr(rrrIs&    zWebHookHandler.__init__c Csd}|jrD|dkrDtd|js@|j|jq d}|jjdd}zz2|j |d|d|d|d|dd d d}Wn>t y}z&td |d||d7}WYd}~n d}~00W|jq|j0qdS) NrzNMultiple consecutive failures in WebHookHandler. Cancelling all queued events.TblockF)datarArBrCZ log_req_respz0Failed posting event: %s. This was caused by: %s) rDis_setr%r&rEemptyZ get_nowait task_donegetr?r$)rZconsecutive_failedargserrrrIjs8    zWebHookHandler.process_requestscCs@|}td|j||j|jt||j|j |j fdS)NzQueuing POST to %s, data: %s) Zas_dictr%debugr@rEputjsondumpsrArBrC)rrZ event_datarrrrszWebHookHandler.publish_eventcCs,|jtd|j|jdS)Nz(WebHookHandler flushing remaining events)rDsetr%rYrEr-clearrrrrrs   zWebHookHandler.flush)NNNNNN)r r r rrIrrr3rrr(rr7Hs!&r7cseZdZdZdZdZdZeeZdZdZ dZ dZ d Z d Z d Ze d ffd d ZeddZddZddZddZddZddZddZddZeed dd d!Zd"d#Zd$d%Zd&d'Zd(d)ZZS)*HyperVKvpReportingHandlera, Reports events to a Hyper-V host using Key-Value-Pair exchange protocol and can be used to obtain high level diagnostic information from the host. To use this facility, the KVP user-space daemon (hv_kvp_daemon) has to be running. It reads the kvp_file when the host requests the guest to enumerate the KVP's. This reporter collates all events for a module (origin|name) in a single json string in the dictionary. For more information, see https://technet.microsoft.com/en-us/library/dn798287.aspx#Linux%20guests iiiZ CLOUD_INITmsgresultZmsg_i),:z/var/lib/hyperv/.kvp_pool_1FNcsrtt|||_t|j||_t|_| |_ d |j |j |_ tj|jd|_d|j_|jdS)Nz{0}|{1}r<T)rr_r_kvp_file_path_truncate_guest_pool_file _event_typesrErFq_get_incarnation_noZincarnation_noformat EVENT_PREFIXevent_key_prefixrGrH_publish_event_routineZpublish_threadrJrK)rZ kvp_file_pathZ event_typesr(rrrs   z"HyperVKvpReportingHandler.__init__c Cs|jr dSttt}z~z>tj||kr\t|dWdn1sR0YWn4t t fy}zt d|WYd}~n d}~00Wd|_nd|_0dS)a Truncate the pool file if it has not been truncated since boot. This should be done exactly once for the file indicated by KVP_POOL_FILE_GUEST constant above. This method takes a filename so that we can use an arbitrary file during unit testing. Since KVP is a best-effort telemetry channel we only attempt to truncate the file once and only if the file has not been modified since boot. Additional truncation can lead to loss of existing KVPs. Nwz$failed to truncate kvp pool file, %sT) _already_truncated_pool_filetimefloatruptimeospathgetmtimeopenOSErrorIOErrorr%r&)clsZkvp_fileZ boot_timerXrrrres  "$z3HyperVKvpReportingHandler._truncate_guest_pool_filecCsDt}zttt|WSty>td|YdS0dS)z use the time passed as the incarnation number. the incarnation number is the number which are used to distinguish the old data stored in kvp and the new data. z"uptime '%s' not in correct format.rN)rrqr rorp ValueErrorr%r&)rZ uptime_strrrrrhs   z-HyperVKvpReportingHandler._get_incarnation_noccst|jdn}t|tj||||j}t||jkr^| |}|V||j}q2t|tj Wdn1s0YdS)z-iterate the kvp file from the current offset.rbN) rurdfcntlflockLOCK_EXseekreadHV_KVP_RECORD_SIZElen_decode_kvp_itemLOCK_UN)roffsetf record_dataZkvp_itemrrr _iterate_kvpss   z'HyperVKvpReportingHandler._iterate_kvpscCsd|j|j|jtS)z the event key format is: CLOUD_INIT|||| [|subevent_index] z{0}|{1}|{2}|{3})rirkr.r/uuidZuuid4rrrr _event_key sz$HyperVKvpReportingHandler._event_keycCs*td|j|jf|d|d}|S)Nz%ds%dsutf-8)structpackHV_KVP_EXCHANGE_MAX_KEY_SIZEHV_KVP_EXCHANGE_MAX_VALUE_SIZEencoderkeyvaluerRrrr_encode_kvp_items z*HyperVKvpReportingHandler._encode_kvp_itemcCsdt|}||jkr$td||j|d|jdd}||j|jdd}||dS)Nz$record_data len not correct {0} {1}.rr)rr)rrr rirdecodestrip)rrZrecord_data_lenkvrrrr!s,  z*HyperVKvpReportingHandler._decode_kvp_itemc Cstd|jtt|jdH}t|tj|D]}||q4|t|tj Wdn1sn0YWdn1s0YdS)Nz Appending ab) rZTimedrdrur{r|r}writerr)rrrrRrrr_append_kvp_item8s z*HyperVKvpReportingHandler._append_kvp_itemc Cs||j=t|}|dt|d}d}g}d|jd}|||j<d||j<tj||jd}|jt|d} ||dj|j|d| d } d ||} | | | | |d7}|| d}t|dkrsH    `