Fix typo in documentation of 'whenjobs --test' option.
[whenjobs.git] / tools / whenjobs.pod
1 =encoding utf8
2
3 =head1 NAME
4
5 whenjobs - A powerful but simple cron replacement
6
7 =head1 SYNOPSIS
8
9 Editing the jobs script:
10
11  whenjobs -e | --edit
12  whenjobs -l | --list
13
14 Get and set variables:
15
16  whenjobs --get variable
17  whenjobs --set variable=value [variable=value ...]
18  whenjobs --variables
19
20 Start and stop the per-user daemon:
21
22  whenjobs --daemon-start
23  whenjobs --daemon-stop
24  whenjobs --daemon-status
25  whenjobs --daemon-restart
26
27 Examine running jobs:
28
29  whenjobs --jobs
30  whenjobs --cancel serial
31  whenjobs --start "name"
32  whenjobs --tail serial
33
34 =head1 DESCRIPTION
35
36 Whenjobs is a powerful but simple replacement for cron.  It lets you
37 run jobs periodically like cron, but it also lets you trigger jobs to
38 run when user-defined variables are set or change value.
39
40 Periodic jobs are written like this:
41
42  every 10 minutes :
43  <<
44    # Get the current load average.
45    load=`awk '{print $1}' /proc/loadavg`
46    whenjobs --set --type float load=$load
47  >>
48
49 When-statements let you create jobs that run based on variables set
50 elsewhere:
51
52  when load >= 6 :
53  <<
54    mail -s "ALERT: high load average: $load" $LOGNAME < /dev/null
55  >>
56
57 (When statements are "edge-triggered", meaning that this job will only
58 run when the load goes from under 6 to E<ge> 6).
59
60 Like L<crontab(5)>, whenjobs are controlled by a jobs file which can
61 be edited from the command line:
62
63  $ whenjobs -e
64
65 Whenjobs uses a daemon called L<whenjobsd(8)>.  Unlike crond, this
66 daemon runs as the same user.  Each user who wants to use whenjobs
67 starts their own daemon:
68
69  $ whenjobs --daemon-start
70
71 You can also have the daemon start as you when the machine boots by
72 adding the following line to a boot file such as C</etc/rc.local>.
73 Replace C<username> with your username:
74
75  su username -c /usr/sbin/whenjobsd
76
77 Variables are the key to expressing dependencies between whenjobs.
78 Variables are stored (per-user) in the daemon.  You can use the
79 command line tool to examine and set variables:
80
81  $ whenjobs --variables
82  load=0.9
83  $ whenjobs --set cat=sushi
84  $ whenjobs --get cat
85  sushi
86
87 The act of setting a variable (using I<--set>) can trigger jobs to run.
88
89 =head1 OPTIONS
90
91 =over 4
92
93 =item B<--cancel> serial
94
95 Cancel the job with the given serial number.
96
97 Use I<--jobs> to list running jobs along with their serial numbers.
98 The serial number is also available in the job script (as
99 C<$JOBSERIAL>) and in the log file.
100
101 =item B<--daemon-start>
102
103 =item B<--daemon-stop>
104
105 Start and stop the per-user daemon.
106
107 =item B<--daemon-status>
108
109 Prints the status of the daemon: C<up> or C<down>.
110
111 =item B<--daemon-restart>
112
113 Restart the daemon.  (If it is not running, then this command
114 starts it).
115
116 =item B<-e>
117
118 =item B<--edit>
119
120 Edit the jobs script.  If you make changes to the jobs script, then it
121 is automatically uploaded to the daemon.
122
123 The C<$EDITOR> environment variable is used for editing.  If not set,
124 C<vi> is used.
125
126 =item B<--get> variable
127
128 Print the value of a variable.
129
130 =item B<--job-names>
131
132 List the names of all loaded jobs (whether they are running or not).
133 Use I<--jobs> to list running jobs.
134
135 =item B<--jobs>
136
137 List all running jobs.
138
139 Note that it is possible for the same job to be running more than once
140 (for example, a periodic job that takes longer than the period to run).
141
142 =item B<-l>
143
144 =item B<--list>
145
146 List the jobs script.
147
148 =item B<--lib> directory
149
150 Set the library directory which needs to contain the auxiliary files
151 C<pa_when.cmo> and C<whenlib.cma>.  Normally you do not need to
152 specify this.  However if you are running whenjobs without installing
153 it, then you need to point this to the C<lib/> directory from the
154 source, eg:
155
156  whenjobs --lib $builddir/lib -e
157
158 =item B<--set> variable=value [variable=value ...]
159
160 =item B<--type> bool|int|float|string|unit
161
162 I<--set> sets the variable named C<variable> to the new C<value>.  The
163 variable is created if it does not already exist.  Note that setting a
164 variable can cause jobs to run immediately.
165
166 To unset a variable, set it to the empty string like this:
167
168  whenjobs --set var=
169
170 By default variables are strings.  You can also set the type of a
171 variable when setting it by adding the optional I<--type> parameter.
172 The I<--type> parameter should come I<before> the variable
173 declaration, like this:
174
175  whenjobs --set --type int free_space=10000
176
177 See the discussion of variable types in the L</REFERENCE> section
178 below.
179
180 You can set multiple variables.  When setting multiple variables in a
181 single command, the values are all changed in a single atomic
182 operation.
183
184  whenjobs --set cat=sushi food=fish
185
186 When using I<--type> and multiple variables, the type changes the
187 remaining command line parameters until the next I<--type>, eg:
188
189  whenjobs --set cat=sushi --type float weight=3.5 --type string food=fish
190
191 (C<cat> and C<food> are strings, and C<weight> is a float).
192
193 =item B<--start> "job name"
194
195 Start the job immediately and unconditionally.
196
197 This runs the job even if its normal preconditions are not met.  This
198 may cause unexpected results, so use with caution.
199
200 =item B<--tail> serial
201
202 Tail the output of the running job identified by its serial number.
203 Use the I<--jobs> flag to get a list of running jobs.
204
205 =item B<--test> variable=value [variable=value ...]
206
207 This works the same way as the I<--set> option, but the difference is
208 that the variables are not set.  Instead, it lists out the jobs that
209 I<would> run, I<if> the variables were updated to these new values.
210
211 The variables are not actually updated, and the jobs are not actually
212 run.
213
214 The output is a list of job names that would run.
215
216 =item B<--upload>
217
218 Compile the jobs script and upload it to the daemon, without editing.
219 Note that the I<--edit> option does this automatically.  Furthermore,
220 when the daemon is started it checks for a jobs script and loads it if
221 found.
222
223 =item B<--variables>
224
225 Display all the variables and their values, in the format C<name=value>.
226
227 =item B<-V>
228
229 =item B<--version>
230
231 Display the name and version of the program and exit.
232
233 =item B<-help>
234
235 =item B<--help>
236
237 Display brief usage and exit.
238
239 =back
240
241 =head1 REFERENCE
242
243 A whenjobs file consists of a series of one or more "every" or "when"
244 statements.
245
246 Comments in the file can be written using C<(* ... *)>.  Comments
247 may be nested.
248
249 Shell script fragments are written using C<E<lt>E<lt> ... E<gt>E<gt>>.
250 Within shell script fragments, use C<#> for comments (as in ordinary
251 shell scripts).  Because C<E<gt>E<gt>> has a special meaning, it
252 cannot be used in the shell script (ie. for redirection).  You have to
253 write C<E<gt>\E<gt>> instead which is replaced with C<E<gt>E<gt>> when
254 the shell script is parsed.
255
256 =head2 EVERY STATEMENTS (PERIODIC JOBS)
257
258 An every statement has the form:
259
260  every <period> :
261  <<
262    # shell script
263  >>
264
265 where C<E<lt>periodE<gt>> is a I<period expression>, which may take
266 one of the forms below.  Don't forget the colon character between the
267 period expression and the shell script.
268
269 An every statement is a job which runs periodically.
270
271 =head3 PERIOD EXPRESSIONS
272
273 =over 4
274
275 =item B<every second>
276
277 The job runs every second.
278
279 =item B<every minute>
280
281 The job runs every minute.
282
283 =item B<every hour>
284
285 The job runs every hour.
286
287 =item B<every day>
288
289 The job runs every day, at midnight UTC.
290
291 =item B<every week>
292
293 The job runs every week, on a Thursday at midnight UTC.
294
295 =item B<every month>
296
297 The job runs every month, on the first of the month at midnight UTC.
298
299 =item B<every year>
300
301 The job runs every year, on the first day of the year at midnight UTC.
302
303 =item B<every decade>
304
305 =item B<every century>
306
307 =item B<every millenium>
308
309 The job runs every 10, 100 or 1000 years.
310
311 =item B<every I<N> seconds>
312
313 The job runs every I<N> seconds (I<N> is any number E<ge> 1).
314
315 =item B<every I<N> minutes>
316
317 The job runs every I<N> minutes.
318
319 =item B<every I<N> hours>
320
321 The job runs every I<N> hours.
322
323 =item B<every I<N> days>
324
325 The job runs every I<N> days.
326
327 =item B<every I<N> weeks>
328
329 The job runs every I<N> weeks.
330
331 =item B<every I<N> months>
332
333 The job runs every I<N> months.
334
335 =item B<every I<N> years>
336
337 =item B<every I<N> decades>
338
339 =item B<every I<N> centuries>
340
341 =item B<every I<N> millenia>
342
343 The job runs every I<N>, I<10*N>, I<100*N> or I<1000*N> years.
344
345 =back
346
347 =head2 WHEN STATEMENTS (DEPENDENT JOBS)
348
349 A when statement has the form:
350
351  when <expr> :
352  <<
353    # shell script
354  >>
355
356 where C<E<lt>exprE<gt>> is a I<when expression>, described below.
357 Don't forget the colon character between the period expression and the
358 shell script.
359
360 A when statement is a job which runs when the conditions described in
361 its when-expression become true.
362
363 When jobs are I<edge triggered>.  This means that they run when the
364 condition changes from false to true (or in the case where the
365 expression has not been evaluated before, when it evaluates initially
366 to true).
367
368 =head3 WHEN EXPRESSIONS
369
370 When expressions are fully recursive expressions constructed from the
371 following elements:
372
373 =over 4
374
375 =item I<expr> B<&&> I<expr>
376
377 =item I<expr> B<||> I<expr>
378
379 The boolean "and" or "or" of the two sub-expressions.
380
381 =item I<expr> B<E<lt>> I<expr>
382
383 =item I<expr> B<E<lt>=> I<expr>
384
385 =item I<expr> B<==> I<expr>
386
387 =item I<expr> B<E<gt>=> I<expr>
388
389 =item I<expr> B<E<gt>> I<expr>
390
391 The two sub-expressions are evaluated and the usual comparison
392 operator is performed.
393
394 If the sub-expressions are numeric, then numeric comparison is done.
395 If either sub-expression is non-numeric, then both expressions are
396 converted (if necessary) to strings and string comparison is done.
397
398 =item B<!> I<expr>
399
400 Boolean negative of I<expr>.
401
402 =item I<expr> B<+> I<expr>
403
404 For numeric sub-expressions, this performs addition.
405
406 If both sub-expressions are strings, this performs string
407 concatenation.
408
409 Other types give an error.
410
411 =item I<expr> B<-> I<expr>
412
413 =item I<expr> B<*> I<expr>
414
415 =item I<expr> B</> I<expr>
416
417 =item I<expr> B<mod> I<expr>
418
419 Both sub-expressions are evaluated, and if both are numeric, then the
420 result is subtraction, multiplication, division or modulo.
421
422 Other types give an error.  Note that I<mod> really is an infix
423 operator.
424
425 =item B<len> I<expr>
426
427 If I<expr> is a string, this returns the length of the string.
428
429 =item I<variable>
430
431 The value of the named variable.
432
433 Previously undefined variables are automatically initialized to the
434 empty string.
435
436 =item B<prev> I<variable>
437
438 The I<previous> value of the named variable.  This means, the value
439 that it had last time this when-job ran.
440
441 If the when-job has not run yet, then this returns C<"">.
442
443 Job state is preserved across file reloads, but I<only> for jobs that
444 are explicitly named.  If you find that jobs using C<prev>, C<changes>
445 etc are running unnecessarily when the jobs file is edited or
446 uploaded, try giving the jobs an explicit name.
447
448 =item B<changes> I<variable>
449
450 If the named variable has changed since this job last ran, then this
451 evaluates to true, else false.
452
453 This is the same as writing C<prev variable == variable>.
454
455 =item B<increases> I<variable>
456
457 If the named variable has changed and increased since this job last
458 ran, then this evaluates to true, else false.
459
460 This is the same as writing C<prev variable E<lt> variable>.
461
462 =item B<decreases> I<variable>
463
464 If the named variable has changed and decreased since this job last
465 ran, then this evaluates to true, else false.
466
467 This is the same as writing C<prev variable E<gt> variable>.
468
469 B<Note:> There is a subtle gotcha with the I<decreases> operator: The
470 first time the expression is evaluated, the job has (by definition)
471 not yet run.  Therefore C<prev variable> evaluates to C<""> (see
472 definition of I<prev> above).  Since it is always true that
473
474  "" < anything
475
476 the I<decreases> operator evaluates to false, and since this usually
477 means the job does not run, the operator always evaluates to false.
478
479 To fix this, ensure that the variable is initialized (see
480 L</SETTING THE INITIAL VALUE OF VARIABLES> below).
481
482 =item B<reloaded ()>
483
484 This evaluates to true the first time the expression is evaluated
485 after the jobs file has been reloaded or the daemon restarted.
486 Thereafter it evaluates to false.
487
488 Don't use this to initialize variables: it won't do what you mean.
489
490 =item B<false>
491
492 =item B<true>
493
494 Constants that evaluate to boolean false or true respectively.
495
496 =item I<"any string">
497
498 Any string.
499
500 In a boolean context, the empty string evaluates to false, and
501 non-empty strings evaluate to true.
502
503 =item I<N>
504
505 Any integer.  (Arbitrarily large integers are supported.)
506
507 In a boolean context, 0 evaluates to false, and non-zero evaluates to
508 true.
509
510 =item I<N.>
511
512 =item I<.N>
513
514 =item I<N.N>
515
516 =item I<N.NeN>
517
518 Any floating point number.
519
520 In a boolean context, 0 evaluates to false, and non-zero evaluates to
521 true.
522
523 =back
524
525 =head2 SHELL SCRIPTS
526
527 The code between C<E<lt>E<lt> ... E<gt>E<gt>> is a shell script.  It
528 is executed using C<$SHELL>, or if that environment variable is not
529 set then C</bin/sh>.
530
531 =head3 SHELL SCRIPT VARIABLES
532
533 Every variable that has been set (using the whenjobs I<--set> option)
534 is exported to the script, so you can simply get the value of any
535 variable by writing C<$name>.
536
537 In addition, there are some special variables available:
538
539 =over 4
540
541 =item C<$JOBNAME>
542
543 The name of the job.  If the job has been named explicitly, then that
544 name is available through this variable, else it will be some implicit
545 name like C<job$1>.
546
547 =item C<$JOBSERIAL>
548
549 The serial number of the job.  This is simply a variable that
550 increments each time a job is run, and is unique to that run of the
551 job.
552
553 =back
554
555 Other environment variables such as C<$HOME>, C<$LOGNAME> etc are
556 available as normal.
557
558 =head3 SHELL SCRIPT TEMPORARY CURRENT DIRECTORY
559
560 The shell script runs with its current directory set to a temporary
561 directory.  The temporary directory is removed when the shell script
562 exits.  Therefore you can write temporary files here without worrying
563 about cleaning them up.
564
565 If you want to store permanent state, then you have to save it to a
566 well-known directory, eg. C<$HOME>, C</var> etc.
567
568 =head3 SHELL SCRIPT USER
569
570 The shell script runs as the ordinary user.  It has no special
571 privileges.
572
573 =head2 JOB NAMES
574
575 Jobs are given implicit names (C<job$1>, C<job$2> etc.).  You can also
576 name jobs explicitly by preceeding the "every" or "when" statement
577 with C<job "name">:
578
579  job "poll source"
580  every 10 seconds :
581  <<
582    # ...
583  >>
584
585 The job name is passed to the shell script in the C<$JOBNAME>
586 environment variable.
587
588 =head2 OCAML EXPRESSIONS
589
590 As well as simple "every" and "when" expressions, advanced users may
591 want to use arbitrary OCaml expressions, functions, etc in the jobs
592 script.  These are useful for factoring common code or strings, for
593 setting the initial values of variables, or for defining pre and post
594 functions.
595
596 A simple example of an OCaml expression is:
597
598  let prefix = "daily_"
599  
600  job (prefix ^ "virus_scan")
601  every day :
602  <<
603    # ...
604  >>
605  
606  job (prefix ^ "disk_check")
607  every day :
608  <<
609    # ...
610  >>
611
612 which creates two jobs called C<"daily_virus_scan"> and
613 C<"daily_disk_check"> (C<^> is the OCaml string concatenation
614 operator).
615
616 OCaml expressions have access to a library of functions called
617 B<Whentools> which is described below.  It lets you set variables,
618 create jobs algorithmically, etc.
619
620 The OCaml expressions run once, when the jobs file is being loaded or
621 reloaded.
622
623 =head3 SETTING THE INITIAL VALUE OF VARIABLES
624
625 Variables are created when they are referenced, and until set they
626 have the value empty string (just like the shell).  Across file
627 reloads, the previous values of variables are preserved.
628
629 To initialize a variable to a known value when the jobs file is
630 loaded, call one of the C<Whentools.set_variable*> functions as in
631 this example:
632
633  let () =
634    Whentools.set_variable "name" "Richard";
635    Whentools.set_variable_int "counter" 0
636
637 =head3 PRE FUNCTIONS
638
639 Before a job runs, you can arrange that a C<pre> function is called.
640 This function may decide not to run the job (by returning C<false>).
641
642 One use for this is to prevent a particular job from running if there
643 is already an instance of the same job running:
644
645  job "only one"
646  pre (Whentools.one ())
647  every 10 seconds :
648  <<
649    # Takes longer than 10 seconds to run, but 'Whentools.one ()'
650    # will ensure only one is ever running.
651    sleep 11
652  >>
653
654 When using pre functions, jobs must be given an explicit name, ie.
655 you must use the C<job> statement.
656
657 A number of pre functions are available in the library; see below.
658
659 You can also write your own post functions (in OCaml).  The function
660 is passed one argument which is a C<Whentools.preinfo> struct, defined
661 below.  It should return a boolean: C<true> if the job should run, and
662 C<false> if the job should not run.
663
664 Note that a fresh serial number (see L</JOBSERIAL>) is assigned to
665 each run, whether or not the job actually runs because of
666 preconditions.
667
668 =head3 POST FUNCTIONS
669
670 After a job runs, you can control what happens to its output by
671 writing a C<post> function.  To write a post function you have to
672 name the job (ie. have an explicit C<job> statement).  Put C<post ...>
673 after the job name like this:
674
675  job "poll source"
676  post (Whentools.mailto "you@example.com")
677  every 10 seconds :
678  <<
679    # ...
680  >>
681
682 A number of post functions are available in the library; see below.
683
684 You can also write your own post functions (in OCaml).  The
685 function is passed one argument which is a C<Whentools.result> struct,
686 defined below.
687
688 =head3 WHENTOOLS LIBRARY
689
690 =head4 Functions
691
692 =over 4
693
694 =item B<Whentools.mailto> [I<~only_on_failure:true>]
695 [I<~from:from_address>] I<email_address> I<result>
696
697 This built-in post function sends the result of the script by email to
698 the given email address.
699
700 If the optional C<~only_on_failure:true> flag is set, then it is only
701 sent out if the script failed.
702
703 If the optional C<~from> flag is set, then the from address is set
704 accordingly.  This is sometimes needed when sending mail.
705
706 Note the C<result> parameter is passed implicitly by the daemon.  You
707 do not need to add it.
708
709 Here are some examples of using the mailto function:
710
711  job "ex.1"
712  post (Whentools.mailto "you@example.com")
713  every 10 seconds :
714  <<
715    # do something
716  >>
717
718  job "ex.2"
719  post (Whentools.mailto ~only_on_failure:true
720                         "you@example.com")
721  every 10 seconds :
722  <<
723    # do something
724  >>
725
726  let from = "me@example.com"
727  let to_addr = "you@example.com"
728  
729  job "ex.3"
730  post (Whentools.mailto ~from to_addr)
731  every 10 seconds :
732  <<
733    # do something
734  >>
735
736 =item B<Whentools.max> I<n>
737
738 This built-in pre function ensures that a maximum of I<n> instances of
739 the job are running.
740
741 It checks the list of running jobs, and if I<n> or more instances are
742 already running, then it returns C<false>, which ensures that the new
743 job is not started.
744
745 =item B<Whentools.one> I<()>
746
747 This built-in pre function ensures that only one instance of the job
748 is running.  It is the same as calling:
749
750  Whentools.max 1
751
752 =item B<Whentools.set_variable> I<name> I<string>
753
754 Set variable I<name> to the string.
755
756 =item B<Whentools.set_variable_bool> I<name> I<b>
757
758 Set variable I<name> to the boolean value I<b>.
759
760 =item B<Whentools.set_variable_int> I<name> I<i>
761
762 Set variable I<name> to the integer value I<i>.
763
764 =item B<Whentools.set_variable_string> I<name> I<s>
765
766 Set variable I<name> to the string value <s>.  This is
767 the same as I<Whentools.set_variable>.
768
769 =item B<Whentools.set_variable_float> I<name> I<f>
770
771 Set variable I<name> to the floating point value I<f>.
772
773 =back
774
775 =head4 Structures
776
777 =over 4
778
779 =item B<Whentools.preinfo>
780
781 This structure is passed to pre functions.  It has the following
782 fields:
783
784  type preinfo = {
785    pi_job_name : string;           # Job name.
786    pi_serial : Big_int.big_int;    # Job serial number.
787    pi_variables : (string * variable) list; # Variables set in job.
788    pi_running : preinfo_running_job list;   # List of running jobs.
789  }
790  and preinfo_running_job = {
791    pirun_job_name : string;        # Running job name.
792    pirun_serial : Big_int.big_int; # Running job serial number.
793    pirun_start_time : float;       # Running job start time.
794    pirun_pid : int;                # Running job process ID.
795  }
796
797 =item B<Whentools.result>
798
799 This structure is passed to post functions.  It has the following
800 fields:
801
802  type result = {
803    res_job_name : string;  # job name
804    res_serial : big_int;   # job serial (same as $JOBSERIAL)
805    res_code : int;         # return code from the shell script
806    res_tmpdir : string;    # temporary directory script ran in
807    res_output : string;    # filename of stdout/stderr output
808    res_start_time : float; # when the job started
809  }
810
811 =back
812
813 =head1 FILES
814
815
816
817 =head1 ENVIRONMENT VARIABLES
818
819
820
821 =head1 SEE ALSO
822
823 L<whenjobsd(8)>
824
825 =head1 AUTHOR
826
827 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
828
829 =head1 COPYRIGHT
830
831 Copyright (C) 2012 Red Hat Inc.
832
833 This program is free software; you can redistribute it and/or modify
834 it under the terms of the GNU General Public License as published by
835 the Free Software Foundation; either version 2 of the License, or
836 (at your option) any later version.
837
838 This program is distributed in the hope that it will be useful,
839 but WITHOUT ANY WARRANTY; without even the implied warranty of
840 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
841 GNU General Public License for more details.
842
843 You should have received a copy of the GNU General Public License
844 along with this program; if not, write to the Free Software
845 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.