Today I noticed that it might be useful to backup some folders on one of my VMs from time to time. At first I thought about creating a new cron job, but then I noticed that Cfengine 3 is running on that VM. So – why not letting Cfengine 3 do all the work? Writing [...]
Today I noticed that it might be useful to backup some folders on one of my VMs from time to time. At first I thought about creating a new cron job, but then I noticed that Cfengine 3 is running on that VM. So – why not letting Cfengine 3 do all the work?
Writing the Cfengine 3 code for performing simple backups
body common control {
version => "1.0";
inputs => { "cfengine_stdlib.cf" };
bundlesequence => { "simple_backup" };
}
body contain cd(dir) {
chdir => "${dir}";
useshell => "true";
}
bundle agent simple_backup {
vars:
"backup_dir" string => "/var/backups";
"folder_list" string => "/root /etc /usr/local/bin";
"date" string => execresult ("/bin/date +\"%k-%M_%m-%d-%y\"", "noshell");
files:
"$(backup_dir)/."
create => "true";
commands:
"/bin/tar czvf automated_cfengine_backup-$(date).tar.gz $(folder_list)"
contain => cd($(backup_dir));
}
That’s already it! Now save the snippet as “xenuser_org-019-performing_simple_backups.cf” and apply it:
/var/cfengine/bin/cf-promises -f xenuser_org-019-performing_simple_backups.cf /var/cfengine/bin/cf-agent -f xenuser_org-019-performing_simple_backups.cf
Great! Let’s have a look at our backup folder:
mintbox backups # ls -lah --color /var/backups total 219M drwxr-xr-x 4 root root 4,0K 2013-02-17 22:16 . drwxr-xr-x 14 root root 4,0K 2013-02-17 20:50 .. -rw-r--r-- 1 root root 36K 2012-10-09 23:08 apt.extended_states.0 -rw-r--r-- 1 root root 3,1K 2012-10-01 23:08 apt.extended_states.1.gz -rw-r--r-- 1 root root 3,1K 2012-09-22 23:08 apt.extended_states.2.gz -rw-r--r-- 1 root root 3,1K 2012-08-07 19:20 apt.extended_states.3.gz -rw-r--r-- 1 root root 3,0K 2012-06-20 22:59 apt.extended_states.4.gz -rw-r--r-- 1 root root 3,0K 2012-06-10 19:59 apt.extended_states.5.gz -rw-r--r-- 1 root root 42 2012-06-03 15:06 apt.extended_states.6.gz -rw-r--r-- 1 root root 2,8M 2012-05-09 22:36 aptitude.pkgstates.0 -rw-r--r-- 1 root root 288K 2011-11-24 20:12 aptitude.pkgstates.1.gz -rw------- 1 root root 32M 2013-02-17 21:21 automated_cfengine_backup-21-20_02-17-13.tar.gz
Yay! Cfengine 3 just created a simple backup!
Analyzing the Cfengine 3 code snippet
Well, the first part of the code snippet doesn’t contain any surprises. At first we define the “body common control” which contains a few information about the Cfengine 3 policy file. Afterwards we create another body, but this time a “contain(ment) body” which provides a sandbox for running commands as a non-privileged user inside an isolated directory tree. The “body contain cd(dir)” is needed to define and run a change dir command which can be used later:
body common control {
version => "1.0";
inputs => { "cfengine_stdlib.cf" };
bundlesequence => { "simple_backup" };
}
body contain cd(dir) {
chdir => "${dir}";
useshell => "true";
}
The next section is very simple as it contains only a promise of the type vars. We define a place for storing our backups, a list of folders to be archived and we let Cfengine 3 define a variable which contains the current date:
bundle agent simple_backup {
vars:
"backup_dir" string => "/var/backups";
"folder_list" string => "/root /etc /usr/local/bin";
"date" string => execresult ("/bin/date +\"%k-%M_%m-%d-%y\"", "noshell");
Now here comes the interesting part. The promise of the type “files” ensures that our directory containing the backups exists. The promise of the type “commands” then runs the command “/bin/tar czvf” which creates a .tar.gz file. “$(folder list) contains the directories to be backed up:
files:
"$(backup_dir)/."
create => "true";
commands:
"/bin/tar czvf automated_cfengine_backup-$(date).tar.gz $(folder_list)"
contain => cd($(backup_dir));
}
Summary
As you can see, it is very easy to create a backup mechanism within Cfengine 3. However, my sample above lacks a few details:
- The backups are created each time Cfengine 3 runs.
- The backups are stored locally.
It is up to you if you let Cfengine 3 e.g. store the .tar.gz files on a NFS share or let them be transported to another server directly (rsync, scp..).
As usual, you can download today’s Cfengine 3 code snippet here.

Comments on this entry (no comments)
Did you like this post? You can share your opinion with us! Simply click here.