Menu

Tree [520459] master /
 History

HTTPS access


File Date Author Commit
 tests 2024-05-01 vincent.delft vincent.delft [e29d8d] add rootID check
 INSTALL 2018-07-05 vincent.delft vincent.delft [64ecf5] Add a regression testing script. Contains 20 te...
 Makefile 2024-05-01 vincent.delft vincent.delft [699858] improve Makefile
 README.md 2024-05-01 vincent.delft vincent.delft [520459] remove nmctl which is no more used
 vdcron 2024-05-01 vincent.delft vincent.delft [c5584d] Silently manage comments: line starting by #
 vdcron.8 2018-07-21 vincent.delft vincent.delft [c1244d] adapt vdcron for my Linux friends ;-)
 vdcron.conf.8 2024-05-01 vincent.delft vincent.delft [47422c] remove nmctl which is no more used
 vdcron_root.conf 2018-05-11 vincent.delft vincent.delft [56a658] add a sample of vdcron.conf for root account

Read Me

Auteur : Vincent vincent.delft@gmail.com
licence : BSD
version : 0.6
Description : Execute scheduled commands without assuming that the machine runs permanently
Dependencies : Is is based on the BSD's date command.
Config file : ~/.vdcron/vdcron.conf or /etc/vdcron.conf
Log file : ~/.vdcron/vdcron.log or /var/log/vdcron.log

Introduction:

vdcron is first of all a cron. The main reasons I've created this one are the following:
- Having a very lite cron routine, in generic code like shell
- Be able to run it with root account, but also with any other account
- Designed to run on non-permanent machine like laptops and desktops. In other words, be able to run commands scheduled in a moment where the machine what not running.
- Be able to re-run commands having failed, until they are successful.
- We keep a trace of all execution, and the output of it, in the associated log files.
- No dependencies on other tools than what we can find in a standard OpenBSD install

Like many cron, you can use it to run commands at a specific moment: day, hour, minute. But you can also use it to run a command every Monday, or every 10 days, every odd days, every hour, every 5 hour, each Monday at 10AM, every months, every 2 months, … Nothing different than usual cron.

What makes vdcron special? :
- vdcron is not planned to run permanently as a daemon, but an external program will trigger Vdcron. It can be you normal cron, it can be your .profile script, it can be your .login script. In my case vdcron is triggered by the resume process of apmd. Thus each time I open the lid of my laptop, vdcron is triggered and execute commands that he must run.
- Since vdcron is not a daemon, the config file and the schedule are a little bit different from what we are used to use in cron programs.

vdcron has been developped on OpenBSD, but I've tested it on Debian and DragonFlyBSD 5.2.2

Optional parameters

vdcron accept the following optional parameters:

Options are:
-h : this help
-d : debug
-s <value>: force an initial sleep different than the default: 10 seconds
-f <file> : use a specific input file</file></value>

Configuration

Vdcron relies on 1 config file. This config file is /etc/vdcron.conf if you run it with a root account, or it will be ~/.vdcron/vdcron.conf for each other users.

The basic concept of the conf file is that, like in a queue, each line represent a command that we have to trigger if the schedule timing is compliant with the current date and time. For example, if you ask vdcron to run a command on Monday, vdcron will not run it until we are a Monday. Once successfully executed the command will be removed from the file. This is why I’m talking about the queuing principle. This aspect is not what we are used to have in “normal” cron systems.
If I take a specific case, you can ask vdcron to run a command at Noon on May 1st. In such case, vdcron will execute it if we are between 12:00:00 and 12:00:59. Before it’s too soon, after it’s too late.
Since vdcron is foresee to run on non-permanent machines, such concept, with a very strict timing, (with hour and minute) is not the usual case for vdcron. We prefer situations where we specify the day. We expect to have the command executed on that day, and we are less demanding for the timing.

The command part can be a command with his parameters, but is can also be a list of commands (split by “;”) or a command that you want to launch in background (add “&” at the end). In the last case, the return code of the command will not be used, vdcron will estimate that the job is successful. Thus, background commands will never be restarted if they fails.

The config file must respect some conventions:

/date/ /command and parameters/ the 2 elements must be separated by one space

/date/ can be :
A date with the form [+]YYYYmmdd[/d] or [+]HHMM[/d] or [+]YYYYmmddHHMM[/d]
In case you put the "+" sign in front this means that the command will run even we are after this specific date
In case you append with a "/" and digit(s), the command will be re-scheduled automatically for later.
The digits represent the number of time unit you want to add to the current moment.
This unit is always the last one used by the timing associated. Thus for a schedule with HHMM and YYYYmmddHHMM, the digits you have specified will add minutes.
For YYYYmmdd, you will add days.
A locale's full weekday name with optionally re-schedule digits. For example: Monday/7.
As explained above, in this case, the rescheduling unit for will be in days.
A locale's full month name with optionally re-schedule digits. For example: April/1.
As explained above, in this case, the rescheduling unit will be in months
Always. With this keyword your command will always been executed when you trigger vdcron

/command/ can be preceded with "-q ". In such case there will be no logging at all. Without this parameter the results of the command (and some other info) are stored in the log file: ~/.vdcron/vdcron.log for standard users and /var/log/vdcron.log for root.
If the exit code is not zero "0", the line will not be removed from the config file. In other words, vdcron will retry until successful execution. This is useful for script requiring network connections, which you could not always have (surely with laptops).
As consequence is you always finalize your command by the command “false”, the command will always remain in the vdcron.conf file. This is like with the “Always” keyword.

You can also define some environment variable by respecting the following structure:
/var/=/value/

“var” should be alpha characters. “value” can be alpha, numeric or alphanumeric.
Such settings is exactly like you do in your usual shell scripts. Please do not put spaces before or after the sign “=” or before the “var”.

All lines, in the config file, which do not respect those formats will be treated as a comment. By looking at the log files, you can identified them easily.

Thus, since, commands been successfully executed will be removed from the config file, adding some comments or keeping a copy of your line preceded by a “#” character will allow you to easily remember it.

Config file examples

20180429 echo "Last weekend of April"

As explained, the 1st word is the schedule requirement, all the rest is your command.
In this case, we ask to execute on 2018, April the 29th the command that will echo the funny text “Last weekend of April”. All of this will be present in the log file.

+20180429/1 sh /etc/daily

In this case we ask vdcron to execute on 2018 April 29th, or after, the /etc/daily script. Moreover, if the return code of “/etc/daily” is zero (successful), we ask vdcron to reschedule it 1 day after.
If the command “/etc/daily” return a non-zero return code, the line will remain in the config file untouched.

+20180429/1 sh /etc/daily; true

With this line in the config file, we enforce the fact that command will run once, and only once, per day because the return code will always be zero. As said, above, if the scheduled date is in the past (in case the machine was down more than 1 day), the command will be triggered anyhow.

Sunday sh /etc/weekly_once
+20180429/7 sh /etc/weekly
Sunday/7 sh /etc/weekly

Those are 3 “weekly” command. Except that the 1st one will run only once; the 2 others will be rescheduled.
The 2 others will run every 7 days. Since Sunday + 7 days is also Sunday, vdcron will add a “_” at the beginning of the word. If we are Sunday, this sign allow vdcron differentiate a task to execute from a task to no more execute. Vdcron will remove this special character when needed. You don’t have to remove it your self.
The difference between the last 2 entries, is that the 2nd one will be executed even if we trigger vdcron after the specified date. With the 3rd line, if you never trigger vdcron on Sunday, you will have to wait next Sunday for an execution.

Always echo "heartbeat"
+20180429/1 echo “heartbeat”;false

The “Always” keyword informs vdcron to run the command every time vdcron is started.
The 2nd line has the same effect. Indeed, each time the command will return a non zero return code, so vdcron will keep the command on the config file and will trigger it at each run.

April sh /etc/monthly_once
+20180401/31 /etc/monthly
April/1 /etc/monthly

Those are 3 methods to run a monthly command. The 1st line will be execute only once, because not rescheduled. The 2 others will be rescheduled just after correct execution of the command. If you are not sure and want to avoid that such monthly script will be triggered each time vdcron run, you can add “; true” at the end of each line.
On the 2nd line vdcron will re-schedule the command 31 days after 1st of April 2018. So, this will be rescheduled for 2nd of May. Then, 2nd of June 2018, then 3rd of July, … On the opposite, the 3rd line will always be reschedule for the next month, without any specification for the day.
Like for week day’s name, vdcron will add a “_” sign at the beginning to mark script already successfully executed.

a Real config file

I remind that in my implementation, I trigger vdcron via /etc/apm/resume (at each lid open)

My personal config file for root is the following:

$ doas more /etc/vdcron.conf                                                 
+20180509/1 sh /etc/daily &
Sunday/7 sh /etc/weekly &
Always su - vi -c "/usr/local/bin/vdcron -s3 "

With this config, I run my /etc/daily once per day in background. I run the weekly script every Sunday. If I do not open my machine on a Sunday, I accept to run it on next week. I always run my Network Manager script (details here ). And I always trigger vdcron for my own user: vi.

In my vi’s home directory, I have the following vdcron.conf file

$  more ~/.vdcron/vdcron.conf                                                 
+20180509/1 openboxmenuCreate &
+20180511/7 sh ~/bin/sync_working_files.sh

In my case, I run once per day a python script I’ve made to recreate my openbox’s menus.
On a weekly basis (ideally on Friday), I sync my local files to my NAS. If I’m not connected to my NAS vdcron will keep it in the config file. Moreover, in this case, I accept to run it after the Friday or later (because sign “+”)

How to trigger vdcron ?

As said, to my eyes, the ideal is to trigger the execution of vdcron at each lid's open of my laptop.
To do that, on my openbsd machine, I’ve added the following file in /etc/apm:

cat /etc/apm/resume
#!/bin/sh
/usr/local/bin/vdcron

And I’ve activated apm:

rcctl enable apmd

rcctl start apmd

Maybe you will prefer to trigger vdcron at each reboot. In such case, just add the vdcron in your /etc/rc.local or in your normal cron with the keyword “@reboot”.
For specific cases, you could imagine to trigger vdcron from your .login script of from your .profile script.
Why not putting triggering vdcron from your cron every hour ?

It’s really up to you to decide when, how often, … you want to trigger vdcron. The ideal solution will depend on what you want to execute with vdcron.