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
25 from __future__ import division, print_function, unicode_literals
30 import ConfigParser as configparser
34 from cumulus import retention
36 _BACKUP_PREFIX = "backup:"
37 _TIME_UNITS = {"s": 1, "m": 60, "h": 3600, "D": 86400, "W": 7 * 86400,
38 "M": 30 * 86400, "Y": 365 * 86400}
39 _INTERVAL_RE = r"(\d+)([smhDWMY])"
41 def _build_retention_engine(spec):
42 """Parse a retention specification and return a RetentionEngine object."""
43 policy = retention.RetentionEngine()
44 class_re = re.compile(r"^(\w+):((%s)+)$" % _INTERVAL_RE)
45 interval_re = re.compile(r"^%s(.*)$" % _INTERVAL_RE)
46 for s in spec.split():
49 print("Invalid retain spec:", s)
51 period = datetime.timedelta()
52 classname = m.group(1)
53 intervalspec = m.group(2)
55 m = interval_re.match(intervalspec)
56 seconds = int(m.group(1)) * _TIME_UNITS[m.group(2)]
57 period = period + datetime.timedelta(seconds=seconds)
58 intervalspec = m.group(3)
59 policy.add_policy(classname, period)
63 class CumulusConfig(object):
64 def __init__(self, filename):
65 """Parse a Cumulus backup configuration from the specified file."""
66 self._config = configparser.RawConfigParser()
67 self._config.readfp(open(filename))
69 def get_global(self, key):
70 return self._config.get("global", key)
72 def backup_schemes(self):
73 """Returns a list of backup schemes."""
74 return [s[len(_BACKUP_PREFIX):] for s in self._config.sections()
75 if s.startswith(_BACKUP_PREFIX)]
77 def get_retention_for_scheme(self, scheme):
78 spec = self._config.get(_BACKUP_PREFIX + scheme, "retain")
79 return _build_retention_engine(spec)