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 […]

Author:

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.

Add Your Comment

Powered by sweet Captcha


− six = 0