³ò
kóýIc           @   sO  d  d k  Z  d  d k Z d  d k Z d  d k Z d  d k Z d  d k Z d  d k l Z l Z l	 Z	 e i
 d i d ƒ d Z e i ƒ  Z d d Z d Z d	 Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e d j oD e d e  i ƒ Z e d j o e	 d d e d ƒ n e e ƒ n d S(   iÿÿÿÿN(   t   hide_envt   startt   sayt   HOSTNAMEt   .i    i€Q i   i
   t   skyd_c         C   sh  d } t  d d g ƒ } t i t |  | ƒ } | d d j o t | d d | d d ƒ n | i d	 ƒ } |  oíd
 t | d <t | d <t i	 d ƒ | d <d } x8 | i
 ƒ  D]* } | i d ƒ d j o | d 7} q± q± Wd
 | d | d <| i d ƒ o t | d ƒ } n d } d
 | | d <| i d ƒ o | d i d ƒ } n t g } | | d <| i d ƒ oN t i i | d ƒ a t i i t ƒ p! t | d d t d ƒ d a qÇn d a t d j o< t i d a t t ƒ | d <t | d d | d d ƒ n | | d	 <t i t | ƒ } | d d j o t | d d | d d ƒ qƒn$ t | d ƒ } | d i d ƒ } t  ƒ  } x t t | ƒ ƒ D]k }	 d | |	 j o | | | |	 <qŸ| |	 i d ƒ }
 |
 d | |	 <t t |
 d ƒ | ƒ | | |	 <qŸWt  ƒ  a xJ | D]B } g  t | <x/ t | | ƒ D] }
 t | i t i ƒ  ƒ q?WqWd S(    sY  
#+
# NAME:
#	skyd_load
# PURPOSE:
#	Read conf file and set up the dictionary needed for
#	tracking the skyd_orbit processes launched on all grunts.
# SIDE EFFECTS:
#	Several entries in the conf file are updated/added.
#	'pid' is set with pid of skyd_wait
#	'boss' is set to hostname of machine that controls skyd_wait
#	'time' is set to time at which skyd_wait was started
#
#	If 'max_load' (# processes per grunt) is not set then
#	'max_load' is set to 2.
#	IF 'grunts' (list of machines that run skyd_orbit) is not
#	set then 'grunts' is set to 'boss' (i.e. the daemon will
#	run htm_orbit locally only).
#	If 'reportdir' (dir for report files) is not set then it
#	is set to $TUB.
# PROCEDURE:
#	The global variable new_runs is set up as a dictionary
#	with one entry for each grunt listed in the conf file.
#	The entry for each grunt is a list of max_proc elements.
#	Each element is a dictionary with entries describing
#	the process. Each process is characterized by:
#		'status': 'dead','start' or 'runs'
#		'wmark'	: '' or 'watermark'
#		'result': '', 'runs','done','kill'
#	Processes are initialized here as 'dead' with a
#	blank watermark. The watermark is a filename of type
#	<reportdir>/skyd_<random> with <random> a unique set
#	of characters (created by tempfile.mkstemp).
# MODIFICATION HISTORY:
#	DEC-2005, Paul  Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	t	   skyd_loadt   numberi    t   messaget    t   Et   cfs   
terminatedt   confs   %dt   pidt   bosss   %Y_%j_%H%M%St   timet   group_i   t	   cur_groupt   max_loadi   t   gruntst   ,t	   reportdirt   It   #s   does not existt   TUBs   is report directoryt   :N(   R   i    (   s   messageR	   (   t   dictt	   skyd_funct   skyd_read_conft   cffileR   t   popR   R   R   t   strftimet   keyst   findt   has_keyt   intt   splitt   ost   patht
   expandvarsR   t   isdirt   environR    t   skyd_write_conft   ranget   lent   mint   new_runst   appendt   skyd_empty_run(   t   claimt   csayt   statusR   R   t   keyR   R   t   grunts_loadt   it   runt   grunt(    (    s   skyd_wait.pyR      sp    )
 	

#	 %	 
 c          C   s¾  d }  t  |  d d d ƒ t } t ƒ  a x3 t i ƒ  D]% } g  t | <t | i t | ƒ q5 Wt i ƒ  } x^ | D]V } t i t | ƒ } x: | d j o, g  t | | | d +t i t | ƒ } q Wqq Wx6 | D]. } t t | ƒ d j o t i	 | ƒ qÒ qÒ Wt i ƒ  } xr t | ƒ d j o^ | i ƒ  d } | i
 | ƒ d j o | | t | <n t | i | | ƒ | i	 | ƒ qWt t ƒ t i ƒ  } x t i ƒ  D]s } | i
 | ƒ d j oW t t t | ƒ t t | ƒ g ƒ } t | d | !t | d | +g  t | d | +q¨q¨Wt i ƒ  } x6 | D]. } t t | ƒ d j o t i	 | ƒ q2q2Wt o t  |  d d d	 ƒ t a n t i ƒ  } d } x | D] } t | | ƒ } q¡Wd
 S(   sL  
#+
# NAME:
#	skyd_reload
# PURPOSE:
#	Rereads the conf file and resets the dictionary needed for
#	tracking the skyd_orbit processes.
# CALLING SEQUENCE:
#	skyd_reload
# PROCEDURE:
#	skyd_reload is called when a SIGHUP signal is received.
#
#	skyd_reload merges the current list of processes in new_runs
#	with the list of unfinished processes in old_runs.
#	Then htm_load is called to set up a fresh new_runs list.
#
#	The old_runs array will only contain processes that are
#	marked as 'start' or 'runs'.
# MODIFICATION HISTORY:
#	DEC-2005, Paul  Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	t   skyd_reloadR   t   reloads   
configuration file
iÿÿÿÿi   i    t
   terminators   cleared
N(   R   t   old_runsR   R.   R    t   extendR   t   skyd_not_runningR,   R   t   countR   t   FalseR-   R;   t
   skyd_start(   R2   t
   saved_runsR8   R   R7   t   nR?   (    (    s   skyd_wait.pyR9   “   s`    	 
  	
 & 
 c      	   C   sŽ  d } t  } | i ƒ  } xo| D]R} xçt t | | ƒ ƒ D]Ï} | | | d } | | | d } | d j o2 | d j o! t | d | d | | f ƒ qq< | d j o¦ | d j o! t | d | d	 | | f ƒ n t i i | ƒ d
 }	 d }
 |  i |	 d |
 ƒ d j } | o Pn d }
 |  i |	 d |
 ƒ d j } | o Pqq< | d j o¦ | d j o! t | d | d	 | | f ƒ n t i i | ƒ d
 }	 d }
 |  i |	 d |
 ƒ d j } | o Pn d }
 |  i |	 d |
 ƒ d j } | o Pqq< q< W| o[ t	 h  | d |
 d <| | | d d <| d <| d <| d <|
 d <ƒ } Pq q Wt	 h  d d <ƒ } | S(   s®  
#+
# NAME:
#	skyd_find_run
# PURPOSE:
#	Match a file on a list of files to a process on a specfied list
# CALLING SEQUENCE:
#	rtn = skyd_find_run( reports, lst_runs )
# INPUTS:
#	reports		string array
#				list of files in reportdir
#				skyd_orbit runs will send SIGUSR1 signals back
#				to skyd_wait signalling that a 'report' file was
#				put in reportdir reporting about their status.
#				These report files should be in the 'reports' array.
#	lst_runs	dictionary
#				old_runs or new_runs list of skyd_orbit processes
# OUTPUTS:
#	rtn		dictionary
#				if a matching report is found
#				then the entries are
#				'report'  	name of report from 'reports'
#				'grunt' 	name of grunt running process
#				'run'		number of run on grunt
#				'status'	either 'start' or 'runs'
#				'result'	'runs' if 'status'='start'
#						either 'done' or 'kill' if
#						'status'='runs'
#				if no matching report is found
#				then only one entry is present:
#				'report'	set to null string
# PROCEDURE:
#	An attemps is made to match one of the processes in
#	lst_runs to one of the reports.
#	If a process is marked 'start' then the matching
#	report file has name <report>_runs or <report>_kill.
#	If a process is marked 'runs' then the matching
#	report file has name <report>_done or <report>_kill
#	If a process is marked 'dead' then no report
#	is expected for that process.
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	t   skyd_find_runt   reportR3   t   deadR	   R
   s,   run %d is %s, but has a watermark
terminatedR   s-   run %d is %s, but has no watermark
terminatedi   t   runst   _i    t   killt   donet   wmarkR8   R7   t   result(
   R@   R    R+   R,   R   R%   R&   R$   R?   R   (   t   reportst   lst_runsR2   t	   run_foundt
   all_gruntsR8   R7   RE   R3   t   nameRL   t   rtn(    (    s   skyd_wait.pyRD     s\    -  %!	!				c          C   s
  t  i t ƒ }  g  } xl |  D]d } t i | ƒ d j o t d d d d | ƒ q n | i t ƒ d j o q n | i | ƒ q Wt	 | t
 ƒ }  |  d d j o# t i |  d ƒ d |  d <|  Sn t	 | t ƒ }  |  d d j o t i |  d ƒ d	 |  d <n |  S(
   sb  
#+
# NAME:
#	skyd_find
# PURPOSE:
#	Match a file in reportdir against a process in the old_runs
#	or new_runs dictionary.
# CALLING SEQUENCE:
#	rtn = skyd_find()
# OUTPUTS:
#	rtn	dictionary	dictionary returned from skyd_find_run
#				with one extra item if a matching report
#				was found:
#				'list' is set to 'old_runs' or 'new_runs'
#				reflecting the process list
# CALLS:
#	skyd_find_run
# PROCEDURE:
#	The content of reportdir is picked up. This will include all
#	report files, and possible some other stuff too.
#	First the old_runs is checked for a matching report file.
#	If unsucessfull, the new_runs list is tried.
#	It is essential that the old_runs list is tried first.
#	Ideally this list is empty already. If not we want to clean
#	it out before processing new_runs.
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	i    t	   skyd_findR   RE   s   avoiding collision with %sR	   R<   t   listR.   (   R%   t   listdirR   t   reports_claimedR?   R   R!   t   report_prefixR/   RD   R<   R.   (   RR   RM   RE   (    (    s   skyd_wait.pyRS   ‡  s(      
c      
   C   s6  d } t  o t | d d d ƒ | Sn d } d } |  t j o
 t } n t } | } xt t t |  ƒ ƒ D]ë } t |  | d | j oÌ t i	 d d	 d
 t
 t ƒ i } | t |  | d <t i i | ƒ d t t
 ƒ t |  | d <| t |  | d <t i d ƒ t |  | d <| | j o
 d
 }	 n |	 d 7}	 |	 | | | f 7}	 | d 7} qn qn WH| | j o t | d |  d | ƒ n­ t | d |  | d | | ƒ |  t j o d |  d |	 d }	 n d }
 x] |
 d j  oO y t i |	 ƒ Wn6 |	 GHt t d d d ƒ |
 d 7}
 t i d ƒ qÕXPqÕW| S(   sÎ  
#+
# NAME:
#	skyd_start
# PURPOSE:
#	Start indexing runs for specified grunts until the
#	maximum number of processes are running.
# CALLING SEQUENCE:
#	new_count = skyd_start(grunt,count)
# INPUTS:
#	grunt		string		name of computer on SMEI subnet
#	count		integer		number of mintutes to delay start
#					of next skyd_orbit run
# OUTPUTS:
#	new_count	integer		input count, plus number of
#					new processes started here
# PROCEDURE:
#	All processes marked as 'dead' in new_runs[grunt]
#	are selected to be launched again.
#	skyd_orbit is set up to be submitted to the at batch
#	queue on grunt with a delay of count minutes.
#	For each process launched count is incremented by one.
#	The final count value is returned.
#
#	skyd_start is typically run in a loop like this.
#
#	count = 0
#	for grunt in grunts:
#		count = skyd_start(grunt, count)
#
#	As a result skyd_orbit are launched across all grunts
#	at intervals of roughly 1 minutes. This should reduce the
#	risk of multiple skyd_orbit runs access the conf file or
#	the user catalogue at the same time (skyd_orbit actually
#	provides some defense against this, but better safe than sorry).
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	RA   R   R;   s   is set; no new runs startedRF   R   R3   s   w+biÿÿÿÿR	   RE   i   RK   s   %Y_%j_%H%M%SR   s   ; s   no new process s    %d process(es)s
   echo "ssh s    \"s   \"" | at nowi    i   t   Wt   faileds#   system commmand; try again in a seci
   (   R;   R   R   t	   local_cmdt
   remote_cmdR+   R,   R.   t   tempfilet   NamedTemporaryFileRW   R   RQ   R%   R&   R$   R   R   t   popent   cSayt   sleep(   R8   R?   R2   R3   RL   t   one_cmdt
   count_saveR7   RE   t   cmdRC   (    (    s   skyd_wait.pyRA   Ã  sP    *
 ,


c         C   s   t  ƒ  d S(   ss   
#+
# NAME:
#	skyd_sighup
# PURPOSE
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	N(   R9   (   t   signumt   frame(    (    s   skyd_wait.pyt   skyd_sighup=  s    
c         C   s4   d } t  | d d d ƒ t ƒ  t i t t ƒ d S(   sr   
#+
# NAME:
#	skyd_alarm
# PURPOSE
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	t
   skyd_alarmRX   s   <time>s*   got alarm signal, no activity for too longN(   R   R9   R   t   skyd_kill_runsR<   R   (   Rd   Re   R2   (    (    s   skyd_wait.pyRg   K  s
    
c         C   s#   d } t  a t | d d d ƒ d S(   sr   
#+
# NAME:
#	skyd_ctrlc
# PURPOSE
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	t
   skyd_ctrlcRX   s   ctrl-cs"   terminator set; coasting to finishN(   t   TrueR;   R   (   Rd   Re   R2   (    (    s   skyd_wait.pyRi   b  s    
	c         C   s  d } d } xm | t  j  o@ t ƒ  } | d } | d j o Pn t i d ƒ | d 7} q Wt | d d d d	 t  ƒ d
 S| d } | d } | d } | d }	 | d }
 t | d ƒ i ƒ  } y t i | ƒ t	 i | ƒ Wn t | d d d | ƒ n X|	 d j oa t
 | ƒ d j o' t | d d d t | ƒ ƒ d } qpt | i d ƒ d i ƒ  d ƒ } n t | d d d t | ƒ ƒ t | d | d | | |	 |
 f d | ƒ | d d j o¼ |	 d j oC d t | | d <| t | | d <t i d ƒ t | | d <qd|	 d j oH t i ƒ  t | | <|
 d  j o
 t a n t d 7a t | d ƒ } qdt | d! d" d# ƒ nà |	 d j oC d t | | d <| t | | d <t i d ƒ t | | d <n |	 d j oo g  t | | | d +t
 t | ƒ d j o t i | ƒ n |
 d  j o t | d | d$ ƒ qdt d 7a n t | d! d" d# ƒ t o© t i t ƒ t i t ƒ } | d j o= t i t d t ƒ t i t d t ƒ t | d% d" d& ƒ n | d j o t | d d' d( | ƒ qt | d d' d) | ƒ n d
 S(*   s  
#+
# NAME:
#	skyd_go
# PURPOSE:
# PROCEDURE:
#	Called when a SIGUSR1 signal is received from an skyd_orbit run.
#	These are send after a 'report' file has been put in reportdir.
#	Try to match one of the files in reportdir to one of processes
#	in the old_runs or new_runs dictionary using the watermark.
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#-
	t   skyd_goi    RE   R	   i   RX   s   <time>s   received SIGUSR1 signal,s&    but no report found within %d secondsNRK   R8   R7   R3   RL   t   rs!   ignoring os.remove() error for %sR   R   s   empty report file, %siÿÿÿÿs   
s   

%s
s   run %d (%s): %s -> %ss   
%sRT   R.   RG   R   s   %Y_%j_%H%M%SR   RI   R
   t   stops   rats 2
terminateds)   ignoring temination signal from old gruntt   Ss!   all processes finished
terminatedR;   s'   is set; %d process has not finished yets*   is set; %d processes have not finished yet(   t   report_delayRS   R   R`   R   t   opent   readR%   t   removeRV   R,   R    R#   R$   R.   R   R   R0   Rj   R;   t   ncountRA   R<   R   t   skyd_count_runst   skyd_show_runsR   (   Rd   Re   R2   RC   RR   RE   RK   R8   R7   R3   RL   R   t   gpidR?   (    (    s   skyd_wait.pyRk   z  s€    		





	
'+

c         C   s	  t  i i t  i i t i d ƒ d ƒ d } t | d | d ƒ t  i ƒ  a |  a	 d a
 t  i i t	 ƒ p t | d d t	 d ƒ n d t  i d	 d
 d d t t t	 f d } d | d a d | d a t t ƒ t ƒ  a xj t  i t ƒ D]Y } | i t ƒ d j o= t  i i t | ƒ } t | d d | d ƒ t  i | ƒ qó qó Wt d' d( g ƒ } t i t	 t | ƒ } | d d j o' t | d d t	 | d d ƒ d Sn | i d ƒ } x9| i ƒ  D]+} | i d ƒ d j o qËn | | } | i d ƒ p qËn t  | d ƒ p qËn | d } t  i i! | ƒ } t  i i | ƒ p qËn t i" t | | ƒ } | d d j o qËn | i d ƒ }	 t  | d ƒ }
 t  | d ƒ } d } xì |	 D]ä } t# | ƒ d j o qÆn | i$ ƒ  o qÆn | i d ƒ d j o qÆn | i d  ƒ } | d! j o qÆn | i ƒ  } t  | d ƒ |
 j  o qÆn t  | d ƒ | j o qÆn | d 7} | d | !d" |	 |	 i% | ƒ <qÆW| d j o; |	 | d <t i& | | ƒ } t | d d | d# | ƒ qËqËWt' i' t' i( t) ƒ t' i' t' i* t+ ƒ t' i' t' i, t- ƒ t' i' t' i. t/ ƒ g  a0 t a1 d } x# t2 i ƒ  D] } t3 | | ƒ } qeWx„ t o| t i4 t d t ƒ t i4 t2 d t ƒ t | d d$ d% t t
 t5 i5 ƒ  t6 d& f ƒ t' i7 t8 ƒ t' i9 ƒ  t' i7 d ƒ qWd S()   s“  
#+
# NAME:
#	skyd_wait
# PURPOSE:
#	Main routine for SMEI indexing daemon. This is the program
#	set up by skyd.py as a daemon
# CALLING SEQUENCE:
#	skyd_wait(conf_file)
# INPUTS:
#	conf_file	string		name of configuration file
# RESTRICTIONS:
#	Outstanding issues:
#
#	Sometimes the daemon crashes when trying to remove a report file,
#	because the report file doesn't exist anymore. Presumably the same
#	report file is picked up before the filesystem is updated after
#	a remove during processing of the previous signal.
#	It should be possible to make sure that the same report file is
#	processed only once.
#
#	I'm not sure what happens if the two report files (_runs and
#	_done (or _terminate) are present at the same time. This could
#	happen when processing many signals in a short time.
# PROCEDURE:
#	There are a number of requirements for this whole scheme to work.
#
#	0. all software must be accessible from all machines.
#		Currently everything is located in the SMEI software tree on the SMEI
#		server (which is NFS exported to all machines on the subnet)
#	1. sshd must be running on all machines (boss launches remote skyd_orbits
#		by issuing a command over ssh; grunts send back signals to boss lauching
#		the kill command over ssh).
#	2. all grunts must have an account with the same username as the account
#		on boss (running skyd_wait). Moreover, the accounts must allow access
#		in both directions using SSH keys (i.e. no passwords needed).
#		(see href=ssh_to=.py to set this up)
#		Currently an account with user name skyd exists on all machines on the
#		the subnet.
#	3. the batch utility 'at' must be installed on all grunts
#		(skyd_orbit is launched as a batchjob using 'at')
#	4  the configuration file and user catalogue must be located
#		where all machines can access it (e.g. in a directory on a shared
#		NFS volume), and all machines should have read & write permission,
#		and should be able to switch read-protection on/off.
#	5. reportdir, the directory were skyd_orbit puts the report files, also must
#		be accessible by all machines.
#	6. when 'at' finishes a job it sends an email to the local account (currently
#		the account skyd). Email forwarding is set up on all machines sending
#		all these email to the machine running the daemon. The easiest way to
#		do this is to create a soft link in the home directory of the skyd
#		account pointing to a .forward file located somewhere where all
#		machines have read access.
#
#	Most configuration file entries are optional with reasonable defaults
#	if absent. The configuration file has the structure
#
#	<name_1>=<value_1>
#	<name_2>=<value_2>
#	..
#	<name_n>=<value_n>
#	group_0:
#	<_name_1>=<value0_1>
#	..
#	<_name_m>=<value0_m>
#	group_1:
#	<_name_1>=<value0_1>
#	..
#	<_name_m>=<value0_m>
#	..
#	..
#	group_k:
#	<_name_1>=<value0_1>
#	..
#	<_name_2>=<value0_2>
#
#	The first block are 'global entries'. The following entries are separate
#	groups with instruction to run a specific group of orbits. skyd_orbit
#	calls by picking an orbit from group one, then group two, and so on,
#	cycling through all groups.
#
#	Global entries:
#
#	reportdir=reportdir	directory where report files from skyd_orbit
#				runs are put. Default: $TUB
#	max_load=max_load	max number of concurrent processes run on
#				each grund. Default: 2
#	grunts=grunt1,grunt2	comma separated list of machines on which
#				to run skyd_orbit. Default: boss
#
#	The following main entries are set when htm_wait is started.
#
#	boss=boss		machine controlling skyd_wait
#	pid=pid			process id of skyd_wait
#	time=2005_354_162151	time at which skyd_wait started
#	cur_group=0		first group for which orbit is selected
#				(this field incremented in skyd_orbit)
#
#	Group entries:
#
#	Many of these correspond to keyword needed for the indexing program
#	smeidb_htm
#
#	_camera=camera		camera id (1,2,3); default: 1
#	_mode=mode		mode id (0,1,2); default: -1 (this effectively
#				select the main science mode for each camera
#				(mode 2 for cam 1 and 2; mode 1 for cam 3)
#	_min_orbit=min_orbit	minimum orbit to run; zero means no restriction
#				on minimum orbit; default: 0
#	_max_orbit=max_orbit	maximum orbit to run; zero means no restriction
#				on maximum orbit; default: 1
#	_source=source		source for SMEI frames; default: SMEIDC?
#	_destination=destination
#				destination directory for sky maps
#	_level=level		indexing level
#	_keepglare=0/1		0: subtract glare; 1; keep glare; default: 0
#	_catalogue=catalogue	user catalogue
#	_checkversion=0/1	0: don't check version number; 1: update only
#				if smeidb_skyd version is higher than version
#				in existing skymap
#	_overwrite=0/1		0: don't overwrite existing skymaps
#				1: overwrite existing skymaps
#
#	The user catalogue is an ascii file with one line for each orbit in the
#	following format:
#
#   orbnr  orbnr+1 YYYY_DOY_hhmmss status
#
#	orbnr			orbit number to be processed
#	orbnr+1			orbit number, plus one
#	YYYY_doy_hhmmss	start time of orbit orbnr
#	status			status of orbit; can be 'make','skip','busy','done'
#
#	The catalogue can be constructed from a list of available skymaps
#	using the IDL procedure href=skyd_cat=.
# MODIFICATION HISTORY:
#	DEC-2005, Paul Hick (UCSD/CASS)
#	NOV-2006, Paul Hick (UCSD/CASS)
#		The script sometimes crashed while executing the os.remove(report)
#		command claiming the file didn't exist even though the file
#		was just read succesfully, and the remove actually worked correctly.
#		Bracketed os.remove(report) command with try block to avoid crash.
#		Also added the reports_claimed dictionary to store the names of
#		report files that have been identified by skyd_find_run. The name
#		is deleted from the dictionary only if the os.remove() succeeds.
#	JAN-2007, Paul Hick (UCSD/CASS)
#		Moved initialization of global reports_claimed in front of the loop
#		starting the initial indexing runs.
#	MAR-2008, Paul Hick (UCSD/CASS)
#		Fixed bug in processing of -overwrite keyword.
#		Now if -overwrite is set for one or more groups then the
#		orbit catalogue for the range of orbits specified is updated
#		by changing the status for all "done" orbits to "make".
#		This way, skyd_orbit only needs to look at status "make"
#		if -overwrite is set. Without this change skyd_orbit will
#		keep processing the same "done" orbit over and over again.
#	NOV-2008, Paul Hick (UCSD/CASS; pphick@ucsd.edu)
#		The call to skyd_orbit is now prefixed with ". $HOME/.bashrc".
#		This did not use to be necessary. It is needed now for FC9;
#		not sure why.
#-
	i    i   R   s
   is now up
R
   R   s   does not exist
terminateds!   . $HOME/.bashrc; LD_LIBRARY_PATH=t   LD_LIBRARY_PATHs   ; s   export LD_LIBRARY_PATH; s)   skyd_orbit.py -pid=%d -boss=%s -cffile=%ss    -report=%ss   echo "s"   " | at now+%d minutes 2> /dev/nulls   echo \\\"export HOSTNAME; s%   \\\" | at now+%d minutes 2> /dev/nullRX   s   ... cleanupR   R   R	   s   
terminatedNR   R   t	   overwritet	   cataloguet   contentst	   min_orbitt	   max_orbitRJ   iÿÿÿÿs   make 0s   done -> make: %d orbitst   waits   

... pid %d (%d;%.2f hr) ...i  (   s   numberi    (   s   messageR	   (:   R%   R&   t   splitextR$   t   syst   argvR   t   getpidR   R   Rs   t   isfileR)   R   RZ   R[   R   Rj   R   R<   RU   R   R!   RW   t   joinRr   R   R   R@   R   R    R"   R#   R'   t
   skyd_claimR,   t   isspacet   indext   skyd_releaset   signalt   SIGUSR1Rk   t   SIGALRMRg   t   SIGINTRi   t   SIGHUPRf   RV   R;   R.   RA   Ru   R   t   stimet   alarmt
   long_pauset   pause(   t	   conf_fileR2   R&   RQ   R3   R   R4   t   groupRy   t   orbitsR{   R|   t   mt   orbitRC   t   tmpR?   R8   (    (    s   skyd_wait.pyt	   skyd_wait  s¨    £-	.
	  

 
"
# 	
.
t   __main__s   -cffile=R	   R—   R
   s4   specify config file with -cffile=<cffile>
terminated(   R   R%   Rˆ   R   R\   R   t   tinyR    R   R   R)   R$   R   R   R   Ro   RW   R   R9   RD   RS   RA   Rf   Rg   Ri   Rk   R—   t   __name__R€   R‘   (    (    (    s   skyd_wait.pys   <module>   s8   
	}	~	v	<	z				–	ÿ C