
    }f
+                         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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)'    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
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    6   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&   A   s    yy  r!   c                 *    | r| j                  d      S y )Nr	   r#   r%   s    r   r	   r	   G   s    yy&&r!   c                 B    | rt        |       j                  d      d   S y )N/r   )r&   splitr%   s    r   event_parentr+   M   s#    % &&s+A..r!   c                 6    t        | j                  d            S Nr   )floatr$   r%   s    r   event_timestampr/   S   s    ;'((r!   c                 R    t         j                   j                  t        |             S N)datetimeutcfromtimestampr/   r%   s    r   event_datetimer4   W   s    --oe.DEEr!   c                 (    || z
  j                         S r1   )total_seconds)t1t2s     r   delta_secondsr9   [   s    G""$$r!   c                 >    t        t        |       t        |            S r1   )r9   r4   )startfinishs     r   event_durationr=   _   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)      z`->)r   r   r
   )copyupdater=   r9   r4   r&   count)
start_timer;   r<   records       r   event_recordrG   c   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_recordrI   p   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__y   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   rQ   rO   	Exception)rT   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 ({})=rA   i@B )r   RuntimeErrorr   rO   r*   r.   )rT   r   s     r   parse_epoch_as_floatz$SystemctlReader.parse_epoch_as_float   sV     <<,,2F4<<,@  JJ$$S)!,	Y'))r!   r1   )__name__
__module____qualname____doc__rW   r   rb   r   r!   r   rK   rK   t   s    	#" *r!   rK   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_timestamprp      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
    dmesgTrY   r   zUTF-8userr   rA   ])r   
splitlinesdecodefindr*   stripr.   timer   uptimeSUCCESS_CODEr[   ro   )	data_split_entriesr   splitupstrippeduser_space_timestampkernel_start
kernel_ends	            r   rn   rn      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                         rt        }||z   }||z   }|| ||fS # 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-localN)r.   ry   r   rz   rK   rb   r{   is_containerCONTAINER_CODEr[   printro   )r   delta_k_end
delta_ci_s	base_timestatusr   cloudinit_sysdes           r   rj   rj      s     %dkkm(<<L!%)

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



  	 !	 #F,
"Z/ <^;;  ! 	a  !s   AB" "	C+C;CC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)as  
    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 print_format: formatting to represent event, time stamp,
    and time taken by the event in one line

    :return: boot records ordered chronologically
    c                     | d   S r-   r   )xs    r   <lambda>z"generate_records.<locals>.<lambda>  s
    ; r!   )keyNg        rA   r;   r   z
init-localr<   zStarting stage: %szFinished stage: (%n) %d seconds
r   )sortedrangelen
IndexErrorr	   r$   rR   rI   r4   r+   r&   r    rG   pop)eventsprint_formatsorted_eventsrecordsrE   r   stage_start_timeboot_recordsunprocessedr   r   next_evtprev_evtrF   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   I  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
rA   N)
readrx   sysstderrwriter   exitjsonloads
ValueError)infiler|   s     r   load_events_infiler   V  sq     ;;=D::<

*V[[89zz$%% Tzs   #A: :B
	B
)z(%n) %d seconds in %I%D)r2   r   r   ry   	cloudinitr   r   cloudinit.distrosr   r   r{   	FAIL_CODEr   ro   r    r&   r	   r+   r/   r4   r9   r=   rG   rI   rK   rp   rn   rj   r   r   r   r   r!   r   <module>r      s      
    *, 










 	B+ )F%H
62* 2*j,><F +GT
?r!   