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