77 lines
2.0 KiB
Ruby
77 lines
2.0 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
require 'date'
|
|
|
|
SNAPSHOTS_TO_RETAIN = 7
|
|
SNAPSHOT_FORMAT = "daily-%Y-%m-%d"
|
|
|
|
input = ARGV
|
|
|
|
def usage
|
|
puts "Usage: "
|
|
puts " #{$PROGRAM_NAME} <pool>"
|
|
|
|
exit -1
|
|
end
|
|
|
|
def run_command(*cmd)
|
|
pipe = IO.popen(cmd)
|
|
stdout = pipe.read
|
|
puts stdout
|
|
pipe.close
|
|
|
|
return stdout, $?.success?
|
|
end
|
|
|
|
class Array
|
|
def drop_tail(n)
|
|
slice(0...(length - n))
|
|
end
|
|
end
|
|
|
|
class Dataset
|
|
def initialize(name)
|
|
_, dataset_exists = run_command("zfs", "list", "-H", name)
|
|
raise "No such pool: #{name}" unless dataset_exists
|
|
|
|
@name = name
|
|
end
|
|
|
|
def has_snapshot(name)
|
|
_, snapshot_exists = run_command("zfs", "list", "-H", "#{@name}@#{name}")
|
|
return snapshot_exists
|
|
end
|
|
|
|
def create_snapshot_today
|
|
current_snapshot_name = Date.today.strftime(SNAPSHOT_FORMAT)
|
|
raise "Snapshot already created: #{@name}@#{current_snapshot_name}" if has_snapshot(current_snapshot_name)
|
|
|
|
_, made_snapshot = run_command("zfs", "snapshot", "#{@name}@#{current_snapshot_name}")
|
|
raise "Could not create new snapshot #{@name}@#{current_snapshot_name}" unless made_snapshot
|
|
end
|
|
|
|
def get_all_snapshots
|
|
all_snapshots, could_list_all_snapshot = run_command("zfs", "list", "-t", "snapshot", "-H", @name)
|
|
raise "Could not list snapshots for #{@name}" unless could_list_all_snapshot
|
|
|
|
return all_snapshots.lines.map { |line| line.split("\t").first }.map { |snapshot_name| snapshot_name.split("@").last }
|
|
end
|
|
|
|
def clean_up_old_snapshots
|
|
snapshots_to_delete = get_all_snapshots.drop_tail(SNAPSHOTS_TO_RETAIN)
|
|
p snapshots_to_delete
|
|
|
|
return if snapshots_to_delete.length == 0
|
|
|
|
output, could_delete_old_snapshots = run_command("zfs", "destroy", "#{@name}@#{snapshots_to_delete.first}%#{snapshots_to_delete.last}")
|
|
raise "Could not delete old snapshots for #{@name}" unless could_delete_old_snapshots
|
|
end
|
|
end
|
|
|
|
usage unless input.length == 1
|
|
usage if input[0] == "-h" or input[0] == "--help"
|
|
|
|
dataset = Dataset.new input[0]
|
|
dataset.create_snapshot_today
|
|
dataset.clean_up_old_snapshots
|