Ejemplo n.º 1
0
def collectFileInfo(filename, tardis, crypt):
    """
    Collect information about a file in all the backupsets
    Note that we sometimes need to reduce the pathlength.  It's done here, on a directory
    by directory basis.
    """
    lookup = crypt.encryptPath(filename) if crypt else filename

    fInfos = {}
    lInfo = {}
    if filename == '/':
        fInfos = makeFakeRootInfo()
    elif args.reduce:
        for bset in backupSets:
            temp = lookup
            temp = Util.reducePath(tardis, bset['backupset'], temp, args.reduce)     # No crypt, as we've already run that to get to lookup

            if lInfo and lInfo['firstset'] <= bset['backupset'] <= lInfo['lastset']:
                fInfos[bset['backupset']] = lInfo
            else:
                lInfo = tardis.getFileInfoByPath(temp, bset['backupset'])
                fInfos[bset['backupset']] = lInfo
    else:
        fSet = backupSets[0]['backupset']
        lSet = backupSets[-1]['backupset']
        for (bset, info) in tardis.getFileInfoByPathForRange(lookup, fSet, lSet):
            logger.debug("Bset: %s, info: %s", bset, info)
            fInfos[bset] = info

    return fInfos
Ejemplo n.º 2
0
def collectFileInfo(filename, tardis, crypt):
    """
    Collect information about a file in all the backupsets
    Note that we sometimes need to reduce the pathlength.  It's done here, on a directory
    by directory basis.
    """
    lookup = crypt.encryptPath(filename) if crypt else filename

    fInfos = {}
    lInfo = {}
    if filename == '/':
        fInfos = makeFakeRootInfo()
    elif args.reduce:
        for bset in backupSets:
            temp = lookup
            temp = Util.reducePath(tardis, bset['backupset'], temp, args.reduce)     # No crypt, as we've already run that to get to lookup

            if lInfo and lInfo['firstset'] <= bset['backupset'] <= lInfo['lastset']:
                fInfos[bset['backupset']] = lInfo
            else:
                lInfo = tardis.getFileInfoByPath(temp, bset['backupset'])
                fInfos[bset['backupset']] = lInfo
    else:
        fSet = backupSets[0]['backupset']
        lSet = backupSets[-1]['backupset']
        for (bset, info) in tardis.getFileInfoByPathForRange(lookup, fSet, lSet):
            fInfos[bset] = info

    return fInfos
Ejemplo n.º 3
0
def findLastPath(path, reduce):
    logger.debug("findLastPath: %s", path)
    # Search all the sets in backwards order
    bsets = list(tardis.listBackupSets())
    for bset in reversed(bsets):
        logger.debug("Checking for path %s in %s (%d)", path, bset['name'], bset['backupset'])
        tmp = Util.reducePath(tardis, bset['backupset'], os.path.abspath(path), reduce, crypt)
        tmp2 = tmp
        if args.crypt and crypt:
            tmp2 = crypt.encryptPath(tmp)
        info = tardis.getFileInfoByPath(tmp2, bset['backupset'])
        if info:
            logger.debug("Found %s in backupset %s: %s", path, bset['name'], tmp)
            return bset['backupset'], tmp, bset['name']
    return (None, None, None)
Ejemplo n.º 4
0
def getFileInfo(path, bset, tardis, crypt, reducePath):
    p = Util.reducePath(tardis, bset, path, reducePath, crypt)
    e = crypt.encryptPath(p) if crypt else p
    info = tardis.getFileInfoByPath(e, bset)
    return info, p
Ejemplo n.º 5
0
def getFileInfo(path, bset, tardis, crypt, reducePath):
    p = Util.reducePath(tardis, bset, path, reducePath, crypt)
    e = crypt.encryptPath(p) if crypt else p
    info = tardis.getFileInfoByPath(e, bset)
    return info, p
Ejemplo n.º 6
0
def main():
    global logger, crypt, tardis, args, owMode
    args = parseArgs()
    logger = Util.setupLogging(args.verbose, stream=sys.stderr)

    try:
        password = Util.getPassword(args.password, args.passwordfile, args.passwordprog, prompt="Password for %s: " % (args.client))
        args.password = None
        (tardis, cache, crypt) = Util.setupDataConnection(args.database, args.client, password, args.keys, args.dbname, args.dbdir)

        r = Regenerator.Regenerator(cache, tardis, crypt=crypt)
    except TardisDB.AuthenticationException as e:
        logger.error("Authentication failed.  Bad password")
        #if args.exceptions:
            #logger.exception(e)
        sys.exit(1)
    except Exception as e:
        logger.error("Regeneration failed: %s", e)
        sys.exit(1)

    try:
        bset = False

        if args.date:
            cal = parsedatetime.Calendar()
            (then, success) = cal.parse(args.date)
            if success:
                timestamp = time.mktime(then)
                logger.info("Using time: %s", time.asctime(then))
                bsetInfo = tardis.getBackupSetInfoForTime(timestamp)
                if bsetInfo and bsetInfo['backupset'] != 1:
                    bset = bsetInfo['backupset']
                    logger.debug("Using backupset: %s %d", bsetInfo['name'], bsetInfo['backupset'])
                else:
                    logger.critical("No backupset at date: %s (%s)", args.date, time.asctime(then))
                    sys.exit(1)
            else:
                logger.critical("Could not parse date string: %s", args.date)
                sys.exit(1)
        elif args.backup:
            #bsetInfo = tardis.getBackupSetInfo(args.backup)
            bsetInfo = Util.getBackupSet(tardis, args.backup)
            if bsetInfo:
                bset = bsetInfo['backupset']
            else:
                logger.critical("No backupset at for name: %s", args.backup)
                sys.exit(1)

        outputdir = None
        output    = sys.stdout.buffer
        outname   = None
        linkDB    = None

        owMode    = overwriteNames[args.overwrite]

        if args.output:
            if len(args.files) > 1:
                outputdir = mkOutputDir(args.output)
            elif os.path.isdir(args.output):
                outputdir = args.output
            else:
                outname = args.output
        logger.debug("Outputdir: %s  Outname: %s", outputdir, outname)

        if args.hardlinks:
            linkDB = {}

        #if args.cksum and (args.settime or args.setperm):
            #logger.warning("Unable to set time or permissions on files specified by checksum.")

        permChecker = setupPermissionChecks()

        retcode = 0
        hasher = None

        # do the work here
        if args.cksum:
            for i in args.files:
                try:
                    if args.auth:
                        hasher = Util.getHash(crypt)
                    ckname = i
                    if args.recovername:
                        ckname = recoverName(i)
                    f = r.recoverChecksum(i, args.auth)
                    if f:
                        logger.info("Recovering checksum %s", ckname)
                    # Generate an output name
                        if outname:
                            # Note, this should ONLY be true if only one file
                            output = open(outname,  "wb")
                        elif outputdir:
                            outname = os.path.join(outputdir, ckname)
                            if os.path.exists(outname) and owMode == OW_NEVER:
                                logger.warning("File %s exists.  Skipping", outname)
                                continue
                            logger.debug("Writing output to %s", outname)
                            output = open(outname,  "wb")
                        elif outname:
                            # Note, this should ONLY be true if only one file
                            if os.path.exists(outname) and owMode == OW_NEVER:
                                logger.warning("File %s exists.  Skipping", outname)
                                continue
                            output = file(outname,  "wb")
                        try:
                            x = f.read(64 * 1024)
                            while x:
                                output.write(x)
                                if hasher:
                                    hasher.update(x)
                                x = f.read(64 * 1024)
                        except Exception as e:
                            logger.error("Unable to read file: {}: {}".format(i, repr(e)))
                            raise
                        finally:
                            f.close()
                            if output is not sys.stdout.buffer:
                                output.close()
                        if args.auth:
                            logger.debug("Checking authentication")
                            outname = doAuthenticate(outname, i, hasher.hexdigest())

                except TardisDB.AuthenticationException as e:
                    logger.error("Authentication failed.  Bad password")
                    #if args.exceptions:
                        #logger.exception(e)
                    sys.exit(1)
                except Exception as e:
                    logger.error("Could not recover: %s: %s", i, e)
                    if args.exceptions:
                        logger.exception(e)
                    retcode += 1

        else: # Not checksum, but acutal pathnames
            for i in args.files:
                try:
                    i = os.path.abspath(i)
                    logger.info("Processing %s", Util.shortPath(i))
                    path = None
                    f = None
                    if args.last:
                        (bset, path, name) = findLastPath(i, args.reduce)
                        if bset is None:
                            logger.error("Unable to find a latest version of %s", i)
                            raise Exception("Unable to find a latest version of " + i)
                        logger.info("Found %s in backup set %s", i, name)
                    elif args.reduce:
                        path = Util.reducePath(tardis, bset, i, args.reduce, crypt)
                        logger.debug("Reduced path %s to %s", path, i)
                        if not path:
                            logger.error("Unable to find a compute path for %s", i)
                            raise Exception("Unable to compute path for " + i)
                    else:
                        path = i

                    if args.crypt and crypt:
                        actualPath = crypt.encryptPath(path)
                    else:
                        actualPath = path
                    logger.debug("Actual path is %s -- %s", actualPath, bset)
                    info = tardis.getFileInfoByPath(actualPath, bset)
                    if info:
                        retcode += recoverObject(r, info, bset, outputdir, path, linkDB, name=outname, authenticate=args.auth)
                    else:
                        logger.error("Could not recover info for %s (File not found)", i)
                        retcode += 1
                except TardisDB.AuthenticationException as e:
                    logger.error("Authentication failed.  Bad password")
                    #if args.exceptions:
                        #logger.exception(e)
                    sys.exit(1)
                except Exception as e:
                    logger.error("Could not recover: %s: %s", i, e)
                    if args.exceptions:
                        logger.exception(e)
    except KeyboardInterrupt:
        logger.error("Recovery interupted")
    except TardisDB.AuthenticationException as e:
        logger.error("Authentication failed.  Bad password")
        if args.exceptions:
            logger.exception(e)
    except Exception as e:
        logger.error("Regeneration failed: %s", e)
        if args.exceptions:
            logger.exception(e)

    if errors:
        logger.warning("%d files could not be recovered.")

    return retcode