class Config:
"""Encapsules the configuration for the backup program."""
- class ReadException(Exception):
+ class ReadError(RuntimeError):
"""An exception raised when reading configurations."""
- pass
+ def __init__(self, value):
+ self.value = value
+ self.message = value
class FileSet:
"""A fileset has a name and a list of directories."""
def __str__(self):
return "[name: " + self.name + ", dirs: " + str(self.dirs) + "]"
- formats = ["tar.gz", "tar.bz2", "tar.xz" ]
+ formats = ["tar", "tar.gz", "tar.bz2", "tar.xz" ]
# Filename where checksum of config is saved
checksumfn = "checksum"
"""Read configuration from file"""
if not os.path.isfile(filename):
- raise Config.ReadException("No file '" + filename + "'.")
+ raise Config.ReadError("Cannot read config file '" + filename + "'.")
config = configparser.RawConfigParser()
config.read(filename)
for reqsec in ["destination"]:
if not config.has_section(reqsec):
- raise Config.ReadException("Section '" + reqsec + "' is missing.")
+ raise Config.ReadError("Section '" + reqsec + "' is missing.")
self.directory = config.get("destination", "directory")
+ if not os.path.isdir(self.directory):
+ raise Config.ReadError("Directory '{0}' does not exist.".format(self.directory))
self.format = config.get("destination", "format")
if not self.format in Config.formats:
- raise Config.ReadException("Invalid 'format' given.")
+ raise Config.ReadError("Invalid 'format' given.")
if config.has_section("history"):
if opt.startswith("keep"):
epoch = opt[4:]
if not epoch in RealEpoch.keys():
- raise Config.ReadException("Invalid option 'keep" + epoch + "'.")
- self.epochkeeps[epoch] = int(config.getint("history", opt))
+ raise Config.ReadError("Invalid option 'keep" + epoch + "'.")
+ try:
+ self.epochkeeps[epoch] = int(config.getint("history", opt))
+ except ValueError:
+ raise Config.ReadError("Invalid integer given for '" + opt + "'.")
elif opt.startswith("mode"):
epoch = opt[4:]
if not epoch in RealEpoch.keys():
- raise Config.ReadException("Invalid option 'mode" + epoch + "'.")
+ raise Config.ReadError("Invalid option 'mode" + epoch + "'.")
self.epochmodes[epoch] = config.get("history", opt)
if not self.epochmodes[epoch] in Mode:
- raise Config.ReadException("Invalid mode given.")
+ raise Config.ReadError("Invalid mode given.")
else:
- raise Config.ReadException("Invalid option '" + opt + "'.")
+ raise Config.ReadError("Invalid option '" + opt + "'.")
if config.has_section("input"):
for opt in config.options("input"):
if opt.startswith("exclude"):
self.exclpatterns += [ config.get("input", opt) ]
else:
- raise Config.ReadException("Invalid option '" + opt + "'.")
+ raise Config.ReadError("Invalid option '" + opt + "'.")
for sec in config.sections():
if sec in ["destination", "history", "input"]:
for opt in config.options(sec):
if not opt.startswith("dir"):
- raise Config.ReadException("Unknown option '" + opt + "'.")
+ raise Config.ReadError("Unknown option '" + opt + "'.")
else:
dirs += [config.get(sec, opt)]
self.sets += [Config.FileSet(name, dirs)]
else:
- raise Config.ReadException("Unknown section '" + sec + "'.")
+ raise Config.ReadError("Unknown section '" + sec + "'.")
# Compute checksum of config file
m = hashlib.sha1()
taropts += ["--exclude", pat]
tarargs = [tarpath] + taropts + ["-f", fsfn] + fileset.dirs
- print("tarargs: ", tarargs)
- tarp = subprocess.Popen( tarargs, \
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
- while tarp.poll():
- l = tarp.stdout.readline()
- if len(l) > 0:
- print(l.decode(), end="")
- l = tarp.stderr.readline()
- if len(l) > 0:
- print(l.decode(), end="")
-
- for l in tarp.stdout.readlines():
- print(l.decode(), end="")
-
- for l in tarp.stderr.readlines():
- print(l.decode(), end="")
+ #print("tarargs: ", tarargs)
+ tarp = subprocess.Popen( tarargs )
rett = tarp.wait()
if rett != 0:
print(tarpath + " returned with exit status " + str(rett) + ":")
- print( tarp.stderr.read().decode() )
def backup(self, epoch=None, mode=None):
print(" prune prune outdated/old backups")
print("")
print("Options:")
- print(" -C <configfile> use given configuration file")
+ print(" -h, --help print this usage text")
+ print(" -c, --conf <configfile> use given configuration file")
print(" default: /etc/shbackup.conf")
- print(" -m, --mode <mode> override mode: full, diff, or incr")
print(" -e, --epoch <epoch> force to create backup for given epoch:")
print(" year, month, week, day, hour, sporadic")
- print(" -h, --help print this usage text")
+ print(" -m, --mode <mode> override mode: full, diff, or incr")
if __name__ == "__main__":
printUsage()
exit(0)
- elif opt in ["-C", "--config"]:
+ elif opt in ["-c", "--conf"]:
i += 1
conffn = sys.argv[i]
if cmd == "prune":
man.prune()
- except Config.ReadException as e:
- print("Error reading config file: ", end="")
- for a in e.args:
- print(a, end=" ")
- print()
+ except (Config.ReadError, configparser.DuplicateOptionError) as e:
+ print("Error reading config file: " + e.message)