コード例 #1
0
ファイル: archiver.py プロジェクト: joolswills/borg
 def do_rename(self, args):
     """Rename an existing archive"""
     repository = self.open_repository(args.archive, exclusive=True)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest)
     archive = Archive(repository, key, manifest, args.archive.archive, cache=cache)
     archive.rename(args.name)
     manifest.write()
     repository.commit()
     cache.commit()
     return self.exit_code
コード例 #2
0
    def do_prune(self, args):
        """Prune repository archives according to specified rules"""
        repository = self.open_repository(args.repository, exclusive=True)
        manifest, key = Manifest.load(repository)
        cache = Cache(repository, key, manifest)
        archives = list(
            sorted(Archive.list_archives(repository, key, manifest, cache),
                   key=attrgetter('ts'),
                   reverse=True))
        if args.hourly + args.daily + args.weekly + args.monthly + args.yearly == 0 and args.within is None:
            self.print_error(
                'At least one of the "within", "hourly", "daily", "weekly", "monthly" or "yearly" '
                'settings must be specified')
            return 1
        if args.prefix:
            archives = [
                archive for archive in archives
                if archive.name.startswith(args.prefix)
            ]
        keep = []
        if args.within:
            keep += prune_within(archives, args.within)
        if args.hourly:
            keep += prune_split(archives, '%Y-%m-%d %H', args.hourly, keep)
        if args.daily:
            keep += prune_split(archives, '%Y-%m-%d', args.daily, keep)
        if args.weekly:
            keep += prune_split(archives, '%G-%V', args.weekly, keep)
        if args.monthly:
            keep += prune_split(archives, '%Y-%m', args.monthly, keep)
        if args.yearly:
            keep += prune_split(archives, '%Y', args.yearly, keep)

        keep.sort(key=attrgetter('ts'), reverse=True)
        to_delete = [a for a in archives if a not in keep]
        stats = Statistics()
        for archive in keep:
            self.print_verbose('Keeping archive: %s' % format_archive(archive))
        for archive in to_delete:
            if args.dry_run:
                self.print_verbose('Would prune:     %s' %
                                   format_archive(archive))
            else:
                self.print_verbose('Pruning archive: %s' %
                                   format_archive(archive))
                archive.delete(stats)
        if to_delete and not args.dry_run:
            manifest.write()
            repository.commit()
            cache.commit()
        if args.stats:
            stats.print_('Deleted data:', cache)
        return self.exit_code
コード例 #3
0
 def do_delete(self, args):
     """Delete an existing archive"""
     repository = self.open_repository(args.archive, exclusive=True)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest)
     archive = Archive(repository, key, manifest, args.archive.archive, cache=cache)
     stats = Statistics()
     archive.delete(stats)
     manifest.write()
     repository.commit()
     cache.commit()
     if args.stats:
         stats.print_('Deleted data:', cache)
     return self.exit_code
コード例 #4
0
ファイル: archiver.py プロジェクト: iceqapprentice/attic
    def do_prune(self, args):
        """Prune repository archives according to specified rules
        """
        repository = self.open_repository(args.repository)
        manifest, key = Manifest.load(repository)
        cache = Cache(repository, key, manifest)
        archives = list(sorted(Archive.list_archives(repository, key, manifest, cache),
                               key=attrgetter('ts'), reverse=True))
        if args.hourly + args.daily + args.weekly + args.monthly + args.yearly == 0 and args.within is None:
            self.print_error('At least one of the "within", "hourly", "daily", "weekly", "monthly" or "yearly" '
                             'settings must be specified')
            return 1
        if args.prefix:
            archives = [archive for archive in archives if archive.name.startswith(args.prefix)]
        keep = []
        if args.within:
            keep += prune_within(archives, args.within)
        if args.hourly:
            keep += prune_split(archives, '%Y-%m-%d %H', args.hourly, keep)
        if args.daily:
            keep += prune_split(archives, '%Y-%m-%d', args.daily, keep)
        if args.weekly:
            keep += prune_split(archives, '%G-%V', args.weekly, keep)
        if args.monthly:
            keep += prune_split(archives, '%Y-%m', args.monthly, keep)
        if args.yearly:
            keep += prune_split(archives, '%Y', args.yearly, keep)

        keep.sort(key=attrgetter('ts'), reverse=True)
        to_delete = [a for a in archives if a not in keep]
        stats = Statistics()
        for archive in keep:
            self.print_verbose('Keeping archive: %s' % format_archive(archive))
        for archive in to_delete:
            if args.dry_run:
                self.print_verbose('Would prune:     %s' % format_archive(archive))
            else:
                self.print_verbose('Pruning archive: %s' % format_archive(archive))
                archive.delete(stats)
        if to_delete and not args.dry_run:
            manifest.write()
            repository.commit()
            cache.commit()
        if args.stats:
            stats.print_('Deleted data:', cache)
        return self.exit_code
コード例 #5
0
 def do_delete(self, args):
     """Delete an existing archive"""
     repository = self.open_repository(args.archive, exclusive=True)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest)
     archive = Archive(repository,
                       key,
                       manifest,
                       args.archive.archive,
                       cache=cache)
     stats = Statistics()
     archive.delete(stats)
     manifest.write()
     repository.commit()
     cache.commit()
     if args.stats:
         stats.print_('Deleted data:', cache)
     return self.exit_code
コード例 #6
0
ファイル: archiver.py プロジェクト: AaronWebster/attic
 def do_create(self, args):
     """Create new archive"""
     t0 = datetime.now()
     repository = self.open_repository(args.archive, exclusive=True)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest)
     archive = Archive(repository,
                       key,
                       manifest,
                       args.archive.archive,
                       cache=cache,
                       create=True,
                       checkpoint_interval=args.checkpoint_interval,
                       numeric_owner=args.numeric_owner)
     # Add Attic cache dir to inode_skip list
     skip_inodes = set()
     try:
         st = os.stat(get_cache_dir())
         skip_inodes.add((st.st_ino, st.st_dev))
     except IOError:
         pass
     # Add local repository dir to inode_skip list
     if not args.archive.host:
         try:
             st = os.stat(args.archive.path)
             skip_inodes.add((st.st_ino, st.st_dev))
         except IOError:
             pass
     for path in args.paths:
         path = os.path.normpath(path)
         if args.dontcross:
             try:
                 restrict_dev = os.lstat(path).st_dev
             except OSError as e:
                 self.print_error('%s: %s', path, e)
                 continue
         else:
             restrict_dev = None
         excludes = adjust_exclude_patterns(path, args.excludes)
         self._process(archive, cache, excludes, args.exclude_caches,
                       skip_inodes, path, restrict_dev)
     archive.save()
     if args.stats:
         t = datetime.now()
         diff = t - t0
         print('-' * 78)
         print('Archive name: %s' % args.archive.archive)
         print('Archive fingerprint: %s' %
               hexlify(archive.id).decode('ascii'))
         print('Start time: %s' % t0.strftime('%c'))
         print('End time: %s' % t.strftime('%c'))
         print('Duration: %s' % format_timedelta(diff))
         print('Number of files: %d' % archive.stats.nfiles)
         archive.stats.print_('This archive:', cache)
         print('-' * 78)
     return self.exit_code
コード例 #7
0
 def do_init(self, args):
     """Initialize an empty repository"""
     print('Initializing repository at "%s"' % args.repository.orig)
     repository = self.open_repository(args.repository,
                                       create=True,
                                       exclusive=True)
     key = key_creator(repository, args)
     manifest = Manifest(key, repository)
     manifest.key = key
     manifest.write()
     repository.commit()
     Cache(repository, key, manifest, warn_if_unencrypted=False)
     return self.exit_code
コード例 #8
0
ファイル: archiver.py プロジェクト: Ernest0x/attic
 def do_delete(self, args):
     """Delete archive
     """
     repository = self.open_repository(args.archive)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest)
     archive = Archive(repository,
                       key,
                       manifest,
                       args.archive.archive,
                       cache=cache)
     archive.delete(cache)
     return self.exit_code
コード例 #9
0
ファイル: archiver.py プロジェクト: joolswills/borg
 def do_delete(self, args):
     """Delete an existing repository or archive"""
     repository = self.open_repository(args.target, exclusive=True)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest, do_files=args.cache_files)
     if args.target.archive:
         archive = Archive(repository, key, manifest, args.target.archive, cache=cache)
         stats = Statistics()
         archive.delete(stats)
         manifest.write()
         repository.commit()
         cache.commit()
         if args.stats:
             stats.print_('Deleted data:', cache)
     else:
         print("You requested to completely DELETE the repository *including* all archives it contains:")
         for archive in sorted(Archive.list_archives(repository, key, manifest), key=attrgetter('ts')):
             print(format_archive(archive))
         print("""Type "YES" if you understand this and want to continue.\n""")
         if input('Do you want to continue? ') == 'YES':
             repository.destroy()
             cache.destroy()
             print("Repository and corresponding cache were deleted.")
     return self.exit_code
コード例 #10
0
ファイル: archiver.py プロジェクト: Ernest0x/attic
    def do_prune(self, args):
        """Prune repository archives according to specified rules
        """
        repository = self.open_repository(args.repository)
        manifest, key = Manifest.load(repository)
        cache = Cache(repository, key, manifest)
        archives = list(
            sorted(Archive.list_archives(repository, key, manifest, cache),
                   key=attrgetter('ts'),
                   reverse=True))
        if args.hourly + args.daily + args.weekly + args.monthly + args.yearly == 0:
            self.print_error(
                'At least one of the "hourly", "daily", "weekly", "monthly" or "yearly" '
                'settings must be specified')
            return 1
        if args.prefix:
            archives = [
                archive for archive in archives
                if archive.name.startswith(args.prefix)
            ]
        keep = []
        if args.hourly:
            keep += prune_split(archives, '%Y-%m-%d %H', args.hourly)
        if args.daily:
            keep += prune_split(archives, '%Y-%m-%d', args.daily, keep)
        if args.weekly:
            keep += prune_split(archives, '%G-%V', args.weekly, keep)
        if args.monthly:
            keep += prune_split(archives, '%Y-%m', args.monthly, keep)
        if args.yearly:
            keep += prune_split(archives, '%Y', args.yearly, keep)

        keep.sort(key=attrgetter('ts'), reverse=True)
        to_delete = [a for a in archives if a not in keep]

        for archive in keep:
            self.print_verbose('Keeping archive "%s"' % archive.name)
        for archive in to_delete:
            self.print_verbose('Pruning archive "%s"', archive.name)
            archive.delete(cache)
        return self.exit_code
コード例 #11
0
 def do_info(self, args):
     """Show archive details such as disk space used"""
     repository = self.open_repository(args.archive)
     manifest, key = Manifest.load(repository)
     cache = Cache(repository, key, manifest)
     archive = Archive(repository,
                       key,
                       manifest,
                       args.archive.archive,
                       cache=cache)
     stats = archive.calc_stats(cache)
     print('Name:', archive.name)
     print('Fingerprint: %s' % hexlify(archive.id).decode('ascii'))
     print('Hostname:', archive.metadata[b'hostname'])
     print('Username:'******'username'])
     print('Time: %s' % to_localtime(archive.ts).strftime('%c'))
     print('Command line:',
           remove_surrogates(' '.join(archive.metadata[b'cmdline'])))
     print('Number of files: %d' % stats.nfiles)
     stats.print_('This archive:', cache)
     return self.exit_code