Browse Source

Use actual file blocks rather than apparent size; doc updates

master
Jim Paris 11 months ago
parent
commit
0f56415493
4 changed files with 27 additions and 16 deletions
  1. +1
    -1
      Makefile
  2. +16
    -11
      backup.py
  3. +6
    -4
      config.yaml
  4. +4
    -0
      initial-setup.sh

+ 1
- 1
Makefile View File

@@ -19,7 +19,7 @@ ctrl: test-backup
.PHONY: test-backup
test-backup: .venv
.venv/bin/mypy backup.py
./backup.py -n >/dev/null
./backup.py -n

.PHONY: test-setup
test-setup:


+ 16
- 11
backup.py View File

@@ -18,7 +18,7 @@ import wcmatch.glob # type: ignore
import humanfriendly # type: ignore

class Config:
root: str
root: bytes
max_file_size: typing.Optional[int]
one_file_system: bool
exclude: list[bytes]
@@ -91,9 +91,8 @@ class Config:
return yaml.dump(d, default_flow_style=False)

class Backup:
def __init__(self, config: Config, dry_run: bool, out: typing.BinaryIO):
def __init__(self, config: Config, dry_run: bool):
self.config = config
self.outfile = out
self.dry_run = dry_run

# All logged messages, with severity
@@ -111,7 +110,8 @@ class Backup:
sys.stderr.write(f"\033[1;{c}m{letter}:\033[22m {msg}\033[0m\n")
self.logs.append((letter, msg))

def run(self):
def run(self, outfile: typing.BinaryIO):
self.outfile = outfile
self.scan(self.config.root)

def scan(self, path: bytes, parent_st: os.stat_result=None):
@@ -140,16 +140,16 @@ class Backup:
# Config file says to exclude
exclude_reason = ('I', f"skipping, excluded by config file")

elif (stat.S_ISDIR(st().st_mode)
and self.config.one_file_system
elif (self.config.one_file_system
and parent_st is not None
and stat.S_ISDIR(st().st_mode)
and st().st_dev != parent_st.st_dev):
# Crosses a mount point
exclude_reason = ('I', "skipping, on different filesystem")

elif (stat.S_ISREG(st().st_mode)
and self.config.max_file_size
and st().st_size > self.config.max_file_size):
elif (self.config.max_file_size
and stat.S_ISREG(st().st_mode)
and (st().st_blocks * 512) > self.config.max_file_size):
# Too big
def format_size(n):
return humanfriendly.format_size(
@@ -199,8 +199,13 @@ def main(argv: list[str]):

args = parser.parse_args()
config = Config(args.config)
backup = Backup(config, args.dry_run, sys.stdout.buffer)
backup.run()

backup = Backup(config, args.dry_run)
if args.dry_run:
with open(os.devnull, "wb") as out:
backup.run(out)
else:
backup.run(sys.stdout.buffer)

if __name__ == "__main__":
import sys


+ 6
- 4
config.yaml View File

@@ -1,18 +1,20 @@
root: "/tmp"
root: "/"
one-file-system: true

# Files larger than this are excluded. If a large file isn't
# explicitly mentioned in "excludes" below, it also generates a
# warning.
# warning. Note that this counts used blocks, so files with large
# holes will still be considered small (since they'll compress easily)
max-file-size: 500MiB

# Files/dirs to exclude from backup.
# Paths should be absolute, or start with **/
exclude: |
/var/tmp
/tmp
/var/cache/apt/archives
**/Steam/steamapps
**/Steam/ubuntu*
/tmp/bigfile
/tmp/out.ps

# Files that are always included, even if they would have been
# excluded due to file size or the "exclude" list.


+ 4
- 0
initial-setup.sh View File

@@ -324,6 +324,10 @@ notice " Notes: (paste the following key)"
sed -ne '/BORG/,/^$/{/./p}' "${BORG_DIR}/key.txt"
notice ""
notice ""
notice "Then, test the backup file list with"
notice " sudo ${BORG_DIR}/backup.py --dry-run"
notice "and make any necessary adjustments to:"
notice " ${BORG_DIR}/config.yaml"

echo



Loading…
Cancel
Save