1 # Cumulus: Efficient Filesystem Backup to the Cloud
2 # Copyright (C) 2012 The Cumulus Developers
3 # See the AUTHORS file for a list of contributors.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 """Parsing of Cumulus backup configuration files.
21 See the Cumulus documentation for a description of the configuration file
29 from cumulus import retention
31 _BACKUP_PREFIX = "backup:"
32 _TIME_UNITS = {"s": 1, "m": 60, "h": 3600, "D": 86400, "W": 7 * 86400,
33 "M": 30 * 86400, "Y": 365 * 86400}
34 _INTERVAL_RE = r"(\d+)([smhDWMY])"
36 def _build_retention_engine(spec):
37 """Parse a retention specification and return a RetentionEngine object."""
38 policy = retention.RetentionEngine()
39 class_re = re.compile(r"^(\w+):((%s)+)$" % _INTERVAL_RE)
40 interval_re = re.compile(r"^%s(.*)$" % _INTERVAL_RE)
41 for s in spec.split():
44 print "Invalid retain spec:", s
46 period = datetime.timedelta()
47 classname = m.group(1)
48 intervalspec = m.group(2)
50 m = interval_re.match(intervalspec)
51 seconds = int(m.group(1)) * _TIME_UNITS[m.group(2)]
52 period = period + datetime.timedelta(seconds=seconds)
53 intervalspec = m.group(3)
54 policy.add_policy(classname, period)
58 class CumulusConfig(object):
59 def __init__(self, filename):
60 """Parse a Cumulus backup configuration from the specified file."""
61 self._config = ConfigParser.RawConfigParser()
62 self._config.readfp(open(filename))
64 def get_global(self, key):
65 return self._config.get("global", key)
67 def backup_schemes(self):
68 """Returns a list of backup schemes."""
69 return [s[len(_BACKUP_PREFIX):] for s in self._config.sections()
70 if s.startswith(_BACKUP_PREFIX)]
72 def get_retention_for_scheme(self, scheme):
73 spec = self._config.get(_BACKUP_PREFIX + scheme, "retain")
74 return _build_retention_engine(spec)