def backupFile(backupRoot, previousBackup, file_, altRoot, writer): """ Backup a file to according to the files state. If it's new or modified, it's copied otherwise a hard link is created pointing to the file found in the previous backup. """ previousFileName = previousBackup + fn.removeAltRoot(altRoot, file_) backupFileName = backupRoot + fn.removeAltRoot(altRoot, file_) if isFileModifiedOrNew(previousFileName, file_): writer("Copying: {0}".format(file_)) fn.copy(file_, backupFileName) else: writer("Linking: {0}".format(file_)) os.link(previousFileName, backupFileName)
def test_removeAltRoot_withAlt(self): testFile = "/mnt/foo/bar" newRoot = fn.removeAltRoot("/mnt", testFile) self.assertEqual( newRoot, "/foo/bar", "Invalid alt root returned: {0}".format(newRoot))
def test_removeAltRoot_noAlt(self): testFile = "/mnt/foo/bar" newRoot = fn.removeAltRoot("/", testFile) self.assertEqual( newRoot, testFile, "Original root was modified: {0}".format(newRoot))
def backupDirectory(backupRoot, previousBackup, directory, settings, writer): """ Primary function to perform a system backup. """ if directory in settings.ignoredDirectories: writer("Ignore: {0}".format(directory)) return altRootDir = fn.removeAltRoot(settings.root, directory) destination = backupRoot + altRootDir createDestination(directory, destination) for item in (join(directory, f) for f in os.listdir(directory)): if os.path.islink(item): backupLink(backupRoot, item, settings.root) elif os.path.isdir(item): backupDirectory(backupRoot, previousBackup, item, settings, writer) elif os.path.isfile(item): if skipFile(item, settings.ignoredFiles, settings.maxFileSize): writer("Ignore: {0}".format(item)) else: backupFile( backupRoot, previousBackup, item, settings.root, writer) os.utime( destination, (os.path.getatime(directory), os.path.getmtime(directory)))
def backupLink(backupRoot, symbolicLink, altRoot): """ Backup a symbolic link. """ realValue = os.readlink(symbolicLink) newLinkDest = backupRoot + fn.removeAltRoot(altRoot, symbolicLink) os.symlink(realValue, newLinkDest)
def listFiles(args, settings): """ Main function for the list option. """ wordArgs = fn.parseWordArgs(args) home = fn.getBackupHome(settings.backupLocation, settings.hostName) backups = fn.getBackupsForArgs(wordArgs, fn.getBackups(home)) backupWd = fn.removeAltRoot(settings.root, os.getcwd()) for id_ in backups.keys(): items = fn.expandGlob(home, backups[id_], backupWd, wordArgs["glob"]) for item in items: _outputItemInfo(id_, fn.getInfo(item))
def remove(args, settings): """ Main function for the remove option. """ wordArgs = fn.parseWordArgs(args) _validateArgs(wordArgs) home = fn.getBackupHome(settings.backupLocation, settings.hostName) backups = fn.getBackupsForArgs(wordArgs, fn.getBackups(home)) backupWd = fn.removeAltRoot(settings.root, os.getcwd()) for id_ in backups.keys(): items = fn.expandGlob(home, backups[id_], backupWd, wordArgs["glob"]) for item in items: _delete(item)
def restore(args, settings): """ Main function for the restore option. """ wordArgs = fn.parseWordArgs(args) _validateArgs(wordArgs) home = fn.getBackupHome(settings.backupLocation, settings.hostName) fn.insureBackupHomeExists(home) backup = fn.getBackupOrLatest(wordArgs, home) cwd = os.getcwd() backupWd = fn.removeAltRoot(settings.root, cwd) items = fn.expandGlob(home, backup, backupWd, wordArgs["glob"]) _validateItems(items, wordArgs) for item in items: _restoreItem(item, cwd, wordArgs["as"])
def diff(args, settings): """ Main function for the diff option. """ wordArgs = fn.parseWordArgs(args) _validateArgs(wordArgs) home = fn.getBackupHome(settings.backupLocation, settings.hostName) fn.insureBackupHomeExists(home) backup = fn.getBackupOrLatest(wordArgs, home) cwd = os.getcwd() backupWd = fn.removeAltRoot(settings.root, cwd) items = fn.expandGlob(home, backup, backupWd, wordArgs["glob"]) _validateItems(items) localFile = _getLines(join(cwd, wordArgs["glob"])) backupFile = _getLines(items[0]) diff = _getDiff() sys.stdout.writelines(diff(backupFile, localFile))
def changes(args, settings): """ Main function for the changes option. """ wordArgs = fn.parseWordArgs(args) _validateArgs(wordArgs) home = fn.getBackupHome(settings.backupLocation, settings.hostName) fn.insureBackupHomeExists(home) backup = fn.getBackupOrLatest(wordArgs, home) cwd = os.getcwd() backupWd = fn.removeAltRoot(settings.root, cwd) backedUpFiles = fn.expandGlob(home, backup, backupWd, "*") backupDir = join(home, backup) + backupWd allFiles = set(os.listdir(cwd)).union(map(basename, backedUpFiles)) for item in allFiles: status = _getStatus(join(cwd, item), join(backupDir, item)) if status: _outputItem(item, status)