
    f>/                        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dddd	d
dddddZ
dj                  e
j                         D  cg c]'  \  } }dj                  | j                  dd      |      ) c}}       ZdZdZdZedddfZd Zd Zd Zd Zd Zd Zd Zd Zd  Zd! Z G d" d#      Zd$ Zd% Z d& Z!	 	 	 	 d*d'Z"d( Z#d) Z$yc c}} w )+    N)subputil)uses_systemddeltadescriptionelapsed
event_typeindentlevelnameoriginresult	timestamp
total_time)z%dz%Dz%Ez%ez%Iz%lz%nz%oz%rz%tz%T z{0}: {1}%z%%
successfulfailure	containerc                     t         j                         D ]9  \  }}|| v s|dv r| j                  |d|z        } %| j                  |d|z        } ;  | j                  di |S )N)r   r   r   z
{%s:08.5f}z{%s} )
format_keyitemsreplaceformat)msgeventijs       8/usr/lib/python3/dist-packages/cloudinit/analyze/show.pyformat_recordr"   :   sm      " 11855kk!\A%56kk!VaZ01 3::    c                 *    | r| j                  d      S y )Nr   getr   s    r!   
event_namer(   E   s    yy  r#   c                 *    | r| j                  d      S y )Nr	   r%   r'   s    r!   r	   r	   K   s    yy&&r#   c                 B    | rt        |       j                  d      d   S y )N/r   )r(   splitr'   s    r!   event_parentr-   Q   s#    % &&s+A..r#   c                 6    t        | j                  d            S Nr   )floatr&   r'   s    r!   event_timestampr1   W   s    ;'((r#   c                 R    t         j                   j                  t        |             S N)datetimeutcfromtimestampr1   r'   s    r!   event_datetimer6   [   s    --oe.DEEr#   c                 (    || z
  j                         S r3   )total_seconds)t1t2s     r!   delta_secondsr;   _   s    G""$$r#   c                 >    t        t        |       t        |            S r3   )r;   r6   )startfinishs     r!   event_durationr?   c   s    .v0FGGr#   c           	          |j                         }|j                  t        ||      t        | t	        |            ddt        |      j                  d      dz
  z  z   dz   d       |S )N|r   r+      z`->)r   r   r
   )copyupdater?   r;   r6   r(   count)
start_timer=   r>   records       r!   event_recordrH   g   se    [[]F
MM#E62$Z1FGC:e#4#:#:3#?!#CDDuL	
 Mr#   c                     d| z  S )NzTotal Time: %3.5f seconds
r   )r   s    r!   total_time_recordrJ   t   s    (:55r#   c                   $    e Zd ZdZddZd Zd Zy)SystemctlReaderzQ
    Class for dealing with all systemctl subp calls in a consistent manner.
    Nc                     d | _         t        j                  d      dg| _        |r| j                  j	                  |       | j                  j                  d|g       | j                         | _        y )N	systemctlshowz-p)epochr   whichargsappendextendr   )selfproperty	parameters      r!   __init__zSystemctlReader.__init__}   sY    
ZZ,f5	IIY'		$)* yy{r#   c                     	 t        j                   | j                  d      \  }}|r|S || _        y# t        $ r}|cY d}~S d}~ww xY w)z
        Make a subp call based on set args and handle errors by setting
        failure code

        :return: whether the subp call failed or not
        TcaptureN)r   rR   rP   	Exception)rU   valueerrsystemctl_fails       r!   r   zSystemctlReader.subp   sG    	"499d;JE3
DJ 	"!!	"s   '2 2 	AAAAc                     | j                   r$t        dj                  | j                               | j                  j	                  d      d   }t        |      dz  S )z{
        If subp call succeeded, return the timestamp from subp as a float.

        :return: timestamp as a float
        zBSubprocess call to systemctl has failed, returning error code ({})=rB   i@B )r   RuntimeErrorr   rP   r,   r0   )rU   r   s     r!   parse_epoch_as_floatz$SystemctlReader.parse_epoch_as_float   sV     <<,,2F4<<,@  JJ$$S)!,	Y'))r#   r3   )__name__
__module____qualname____doc__rX   r   rc   r   r#   r!   rL   rL   x   s    	#" *r#   rL   c                      t               r
t               S t        j                         s'dt        j                         d   j                         v r
t               S t        S )a)  
    Determine which init system a particular linux distro is using.
    Each init system (systemd, etc) has a different way of
    providing timestamps.

    :return: timestamps of kernelboot, kernelendboot, and cloud-initstart
    or TIMESTAMP_UNKNOWN if the timestamps cannot be retrieved.
    gentoosystem)r   gather_timestamps_using_systemdr   
is_FreeBSDsystem_infolowergather_timestamps_using_dmesgTIMESTAMP_UNKNOWNr   r#   r!   dist_check_timestamprq      sM     ~.00 H(8(8(:8(D(J(J(LL,.. r#   c                     	 t        j                   dgd      \  } }| d   j                         }|D ]  }|j                  d      j                  d      dk7  s'|j                  d      j	                         }|d   j                  d	      }t        |      }t        t        j                               t        t        j                               z
  }||z   }t        |||fc S  	 t        S # t        $ r Y t        S w xY w)
a  
    Gather timestamps that corresponds to kernel begin initialization,
    kernel finish initialization using dmesg as opposed to systemctl

    :return: the two timestamps plus a dummy timestamp to keep consistency
    with gather_timestamps_using_systemd
    dmesgTrZ   r   zUTF-8userr   rB   ])r   
splitlinesdecodefindr,   stripr0   timer   uptimeSUCCESS_CODEr\   rp   )	data_split_entriesr   splitupstrippeduser_space_timestampkernel_start
kernel_ends	            r!   ro   ro      s    ))WIt4aQ**, 	JAxx %%f-3((7+113"1:++C0 (-X$$TYY[1E$++-4HH),@@
 $\:zII	J"   s   AC+ B	C+ #C+ +	C<;C<c                     t        t        j                               t        t        j                               z
  } 	 t	        d      j                         }t	        dd      j                         }| }t        }t        j                         rct        t        j                               t        t        j                               z
  }	 t        j                  d      }|j                  } t        }||z   }||z   }|| ||fS # t        $ r }t        dj                  |            |d}~ww xY w# t         $ r}	t#        |	       t$        cY d}	~	S d}	~	ww xY w)z
    Gather timestamps that corresponds to kernel begin initialization,
    kernel finish initialization. and cloud-init systemd unit activation

    :return: the three timestamps
    UserspaceTimestampMonotonicInactiveExitTimestampMonotoniczcloud-init-localz/proc/1/cmdlinezBCould not determine container boot time from /proc/1/cmdline. ({})N)r0   rz   r   r{   rL   rc   r|   is_container	monotonicosstatst_atimeOSErrorrb   r   CONTAINER_CODEr\   printrp   )
r   delta_k_end
delta_ci_s	base_timestatus	file_statr^   r   cloudinit_sysdes
             r!   rk   rk      s8    %dkkm(<<L"!%)



  	 %,.@



  	 !	 diik*U4>>3C-DDIGG$56	(11 $F,
"Z/ <^;;  "66<fSk   ! 	a  !sB   B
D+ !C? )D+ ?	D(D##D((D+ +	E4E
E
Ec                    t        | d       }g }d}d}i }	g }
g }t        t        |            D ]}  }| |   }	 | |dz      }t	        |      dk(  r|rE|j                  d      dk(  r1|j                  t        |             |
j                  |       g }d}d}|t        |      }||	t        |      <   t        |      t        |      k(  r6t	        |      d	k(  s|j                  t        |t        |||                   |j                  d
|j                  d      z         |j                  |       |j                         }t        |      t        |      k(  rAt        |||      }|j                  t        d|      dz          ||j                  d      z  }m|j                  |        |j                  t        |             |
j                  |       |
S # t        $ r d}Y w xY w)a2  
    Take in raw events and create parent-child dependencies between events
    in order to order events in chronological order.

    :param events: JSONs from dump that represents events taken from logs
    :param blame_sort: whether to sort by timestamp or by time taken.
    :param print_format: formatting to represent event, time stamp,
    and time taken by the event in one line
    :param dump_files: whether to dump files into JSONs
    :param log_datafiles: whether or not to log events generated

    :return: boot records ordered chronologically
    c                     | d   S r/   r   )xs    r!   <lambda>z"generate_records.<locals>.<lambda>%  s
    ; r#   )keyNg        rB   r=   r   z
init-localr>   zStarting stage: %szFinished stage: (%n) %d seconds
r   )sortedrangelen
IndexErrorr	   r&   rS   rJ   r6   r-   r(   r"   rH   pop)events
blame_sortprint_format
dump_fileslog_datafilessorted_eventsrecordsrF   r   stage_start_timeboot_recordsunprocessedr   r   next_evtprev_evtrG   s                    r!   generate_recordsr     s   * 6'?@MGJJLK3}%& ,-q		a!e}H e'599V,<0<=##G,!
 
!+E2
8B e!45 % Jx$88h'83NN%((UHE 3eii6GGH""5)"(H% Jx$88%j(EB!"CVL fjj11
 ""8,Y,-\ NN$Z01 Y  	H	s   GG,+G,c                     t        | |      S )a<  
    A passthrough method that makes it easier to call generate_records()

    :param events: JSONs from dump that represents events taken from logs
    :param print_format: formatting to represent event, time stamp,
    and time taken by the event in one line

    :return: boot records ordered chronologically
    )r   )r   )r   r   s     r!   show_eventsr   `  s     F>>r#   c                    | j                         }|j                         sAt        j                  j	                  d| j
                  z         t        j                  d       	 t        j                  |      |fS # t        $ r d|fcY S w xY w)z
    Takes in a log file, read it, and convert to json.

    :param infile: The Log file to be read

    :return: json version of logfile, raw file
    zEmpty file %s
rB   N)
readry   sysstderrwriter   exitjsonloads
ValueError)infiler}   s     r!   load_events_infiler   m  sq     ;;=D::<

*V[[89zz$%% Tzs   #A: :B
	B
)Fz(%n) %d seconds in %I%DFF)%r4   r   r   r   rz   	cloudinitr   r   cloudinit.distrosr   r   joinr   r   r   formatting_helpr|   	FAIL_CODEr   rp   r"   r(   r	   r-   r1   r6   r;   r?   rH   rJ   rL   rq   ro   rk   r   r   r   )kvs   00r!   <module>r      s     	 
    *, 










 ((<F<L<L<NODAqZqyyd+Q/O 	B+ )F%H
62* 2*j,>+<` *M`
?w	 Ps   ,C
