I needed something like zfs-auto-snapshot written by Tim Foster but portable so it works on all systems that support ZFS. I reviewed a few scripts on github and was unhappy with what was out there so I decided to write my own.

With zbackup.rb you can define what to snapshot and how many rotation days you want to go back.

So say you want a month of snapshots:


/usr/bin/zbackup.rb iraidz/zWork 30

Simple, no? 😉

[code lang=”ruby”]
#!/usr/bin/env ruby

# Create snapshots for a 7 day rotation.
# ./zbackup.rb iraidz/zWork 7
#
# Add to crontab
# crontab -e
# 0 2 * * * /usr/bin/zbackup.rb iraidz/zWork 7

pool = ARGV[0]
days_back = ARGV[1].to_i

if pool.nil? or pool.empty?
puts “\nDefine the pool you want to snapshot:”
puts “\tex: zbackup.rb iraidz/zWork 7\n\n”
exit 0
end

if days_back.nil? or days_back < 1 puts "\nDefine how many days for your rotation:" puts "\tex: zbackup.rb iraidz/zWork 7\n\n" exit 0 end # response from zfs list curr_snaps = `zfs list -t snapshot -o name` # days back limit variable date_back = Time.now - (86400*days_back) curr_snaps.split(/\n/).each do |pline| if m = pline.match(/#{pool}\@([0-9]+)\-([0-9]+)\-([0-9]+)/) if date_back >= Time.local(m[1],m[2],m[3])
`zfs destroy #{pline}`
end
end
end

# take snapshot for this run if needed.
month = Time.now.month
day = Time.now.day
year = Time.now.year
if curr_snaps !~ /#{pool}\@#{year}\-#{month}\-#{day}/
`zfs snapshot -r #{pool}@#{year}-#{month}-#{day}`
end
[/code]