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