Advertisement
trevellyan

backup pruning script inspired by Time Machine

Mar 12th, 2016
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.47 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. import datetime
  4. import glob
  5. import logging
  6. import os
  7. import shutil
  8. import sys
  9.  
  10. def datefrompath(path):
  11.     name = os.path.basename(path)
  12.     year = int(name[0:4])
  13.     month = int(name[4:6])
  14.     day = int(name[6:8])
  15.     hour = int(name[9:11])
  16.     minute = int(name[11:13])
  17.     second = int(name[13:15])
  18.     return datetime.datetime(year, month, day, hour, minute, second)
  19.  
  20. def keep(folder):
  21.     logging.info('keep %s', folder)
  22.  
  23. def pruneerror(function, path, excinfo):
  24.     logging.error('unable to prune %s', path)
  25.  
  26. def prune(folder):
  27.     logging.info('prune %s', folder)
  28.     shutil.rmtree(folder, False, pruneerror)
  29.  
  30. # keep oldest backup per interval from now through period back in time
  31. def prunefolders(folders, now, interval, period):
  32.     then = now - period;
  33.     maybeprune = []
  34.  
  35.     while now > then:
  36.         now -= interval
  37.  
  38.         while folders:
  39.             folder = folders.pop()
  40.             folderdate = datefrompath(folder)
  41.  
  42.             if folderdate > now:
  43.                 maybeprune.append(folder)
  44.             else:
  45.                 folders.append(folder)
  46.                 break;
  47.  
  48.         if maybeprune:
  49.             keep(maybeprune.pop())
  50.             while maybeprune:
  51.                 prune(maybeprune.pop())
  52.  
  53.  
  54. repository = os.path.abspath(sys.argv[1])
  55.  
  56. logging.basicConfig(
  57.     filename = os.path.join(repository, 'prune.log'),
  58.     format = '%(asctime)s:%(levelname)s: %(message)s',
  59.     level = logging.INFO
  60.     )
  61.  
  62. logging.info('pruning %s', repository)
  63.  
  64. folders = glob.glob(os.path.join(repository, '20*'))
  65. folders.sort()
  66.  
  67. oneday = datetime.timedelta(days = 1)
  68. oneweek = datetime.timedelta(weeks = 1)
  69. onemonth = datetime.timedelta(weeks = 4)
  70. oneyear = datetime.timedelta(weeks = 52)
  71.  
  72. now = datetime.datetime.now()
  73. then = now - oneday
  74.  
  75. # keep all backups for last 24 hours
  76. logging.info('hourly')
  77. while folders:
  78.     folder = folders.pop()
  79.     folderdate = datefrompath(folder)
  80.  
  81.     if folderdate > then:
  82.         keep(folder)
  83.     else:
  84.         folders.append(folder)
  85.         break
  86.  
  87. midnight = datetime.datetime(now.year, now.month, now.day)
  88.  
  89. # keep oldest backup daily for one month
  90. logging.info('daily')
  91. prunefolders(folders, midnight, oneday, onemonth)
  92.  
  93. # keep oldest backup weekly for one year
  94. logging.info('weekly')
  95. prunefolders(folders, midnight, oneweek, oneyear)
  96.  
  97. # discard all backups older than one year
  98. logging.info('yearly')
  99. while folders:
  100.     prune(folders.pop())
  101.  
  102. logging.shutdown()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement