Skip to content

Instantly share code, notes, and snippets.

@rossomax
Created October 15, 2011 21:47
Show Gist options
  • Select an option

  • Save rossomax/1290201 to your computer and use it in GitHub Desktop.

Select an option

Save rossomax/1290201 to your computer and use it in GitHub Desktop.
shaving zfs snapshots
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ZFS スナップショットをルールに従ってdestroyします
# Copyright 2011 Takeshi Matsubara ([email protected])
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
import subprocess
import time
import getopt
def usage(code = 1, errmsg = 'Error'):
print >>sys.stderr, """
%s
Usage: %s [-vq] filesystem | xargs -n 1 -p zfs destroy
Options:
-v Verbose Output (to stderr)
-q Supress Output (to stdout)
""" % (errmsg, sys.argv[0])
sys.exit(code)
try:
(opts, args) = getopt.getopt(sys.argv[1:], 'vq')
except getopt.GetoptError, err:
usage(2, str(err))
opts0 = dict(opts)
opt_v = True if '-v' in opts0 else False
opt_q = True if '-q' in opts0 else False
if len(args) == 0:
usage(2, 'No filesystem specified')
cmd = 'zfs list -t snapshot -o name,creation -s creation -r'.split()
cmd.append(args[0])
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = p.communicate()[0]
if p.returncode <> 0:
print >>sys.stderr, 'zfs command exits with error %d' % p.returncode
sys.exit(p.returncode)
skip = 1
today = time.time() / 86400
last = 0
# 1週間前まではなにもdestroyしない
period1 = today - 7
# 1ヶ月前までは、1日に1個のsnapshotを残す
period2 = today - 30
# 3ヶ月前までは、1週に1個のsnapshotを残す
period3 = today - 90
# 1年前までは、1月に1個のsnapshotを残す
period4 = today - 365
# それ以前のsnapshotは全部destroyする
for line in output.splitlines():
if skip > 0: skip -= 1; continue;
(name, creation) = line.split(None, 1)
d = time.mktime(time.strptime(creation, '%a %b %d %H:%M %Y')) / 86400
dst = False
if d < period4:
dst = True
elif d < period3 and last + 30 >= d:
dst = True
elif d < period2 and last + 7 >= d:
dst = True
elif d < period1 and last >= d:
dst = True
if dst == False:
last = d
if dst and not opt_q:
print "%s" % name
if opt_v:
msg = 'destroy' if dst else 'keep '
print >>sys.stderr, '%s, %s %s' % (msg, name, creation)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment