HowTo -- PHP script: Automatic ZFS snapshot creation and deletion

I've made a PHP script which may be run as a cron job.
I relaize there are snapshot management utilities out there, but I really wanted to put together something which did exactly what I wanted, the way I wanted it, without too much hassle.

It takes snapshots recursively. (# zfs snapshot -r poolname@snapshotname)

Its purpose is the following:
  • Create ZFS snapshots and keep track of them
  • Automatically delete said snapshots after a given expirity period

The default configuration is meant to be run daily, and store the daily snapshots (mon-sat) for 7 days, weekly snapshots (sun) for 30 days, and monthly snapshots (1st every month) for 400 days.

Parameters:
  1. Time to keep the snapshot. Intriger representing seconds from current time, or the word "auto" (see source for how "auto" works)
  2. Name of pool to make snapshots for

Feel free to use the script.

Here's the script itself:
PHP:
<?php
//Script originally created by Savagedlight :)
//Example use of script:  /path/to/script auto ZFSPoolName
//Parse arguments.
//Expirity argument is $argv[1]. Either "auto" or a intriger value representing seconds from current time.
//ZFS Pool Name


$repisory_file="/usr/local/etc/snapshots.index"; //File for storage of snapshot expirity information.
$chmod="0700"; //Make sure only the user running this script is able to write to it. (chmod 0700)

$snapshotname="GMT-".gmdate("Y.m.d-H.i.s");	//Set the snapshots name.	
												//This would produce '@GMT-2010.01.22-14.56.03' at 2:56:03 pm, 22nd January, 2010. 

//How long to keep the snapshot we are about to take?
switch ($argv[1]) {
	case "auto":
		//Generate expire time based on when we are at. This should be configured manually!
		if (date("d")=="01") $expires=time()+(3600*24*400);		//Monthly snapshot. Keep it for 400 days.
		elseif (date("w")==0) $expires=time()+(3600*24*30);		//Weekly snapshot. Keep it for 30 days.
		else $expires=time()+time()+(3600*24*7);						//Daily snapshot. Keep it for 7 days.
	break;
	default:
		if (!$argv[1] || $argv[1]<3600) $expires=time()+(3600*24*7); //Default is to keep for one week.
		else $expires=time()+$argv[1];
	break;
}

/* NO EDITING NESSECARY BELOW THIS LINE */
if (!$argv[2]) die("Wops! You forgot to specify a pool! Example usage: path/to/script auto ZFSPoolName\n");

//Load the snapshot structure.
$snapshots=@unserialize(@file_get_contents($repisory_file));
//Go through the snapshot structure and find snapshots that should expire.
if (count($snapshots)>=1 && is_array($snapshots)) {
        foreach ($snapshots as $snapshot=>$info) {
                if (strstr($snapshot,"GMT-")) {
                        if ($info["expire"]<=time()) {
                                exec("/sbin/zfs destroy -r ".escapeshellarg($argv[2]."@".$snapshot));
                                unset($snapshots[$snapshot]);
                        }
                }
        }
}

exec("/sbin/zfs snapshot -r ".escapeshellarg($argv[2]."@".$snapshotname));

$snapshots[$snapshotname]=array(
"expire"=>$expires,
"created"=>time());

file_put_contents($repisory_file, serialize($snapshots));
exec("/bin/chmod 0700 ".escapeshellarg($repisory_file)); //Make sure the file is safe from world.
?>


Obligatory disclaimer: Snapshots are not a replacement for proper offline/offsite backups, but a mere tool of convenience.
 
Savagedlight said:
Obligatory disclaimer: Snapshots are not a replacement for backups, but a mere tool of convenience.

Although snapshots don't ensure data integrity, they do come in handy when you accidentally delete files, so perhaps they can be regarded as a type of backup.
 
Even though it's a form of backup, I'd still say it doesn't replace proper offsite backups. Changed the wording slightly.
 
Back
Top