debug put-obj: id must be given on commandline, fixes #7290

this is an incompatible change:

before:
borg debug put-obj path1 path2 ...
(and borg computed all IDs automatically) (*)

after:
borg debug put-obj id path
(id must be given)

(*) the code just using sha256(data) was outdated and incorrect anyway.

also: debug get-obj: improve error handling
This commit is contained in:
Thomas Waldmann 2023-03-04 18:09:44 +01:00
parent 8027c7b284
commit 9a39b53828
No known key found for this signature in database
GPG key ID: 243ACFA951F78E01
2 changed files with 37 additions and 31 deletions

View file

@ -1,7 +1,6 @@
import argparse
from binascii import unhexlify, hexlify
import functools
import hashlib
import json
import textwrap
@ -241,28 +240,36 @@ class DebugMixIn:
hex_id = args.id
try:
id = unhexlify(hex_id)
except ValueError:
print("object id %s is invalid." % hex_id)
else:
try:
data = repository.get(id)
except Repository.ObjectNotFound:
print("object %s not found." % hex_id)
else:
with open(args.path, "wb") as f:
f.write(data)
print("object %s fetched." % hex_id)
if len(id) != 32: # 256bit
raise ValueError("id must be 256bits or 64 hex digits")
except ValueError as err:
print("object id %s is invalid [%s]." % (hex_id, str(err)))
return EXIT_ERROR
try:
data = repository.get(id)
except Repository.ObjectNotFound:
print("object %s not found." % hex_id)
return EXIT_ERROR
with open(args.path, "wb") as f:
f.write(data)
print("object %s fetched." % hex_id)
return EXIT_SUCCESS
@with_repository(manifest=False, exclusive=True)
def do_debug_put_obj(self, args, repository):
"""put file(s) contents into the repository"""
for path in args.paths:
with open(path, "rb") as f:
data = f.read()
h = hashlib.sha256(data) # XXX hardcoded
repository.put(h.digest(), data)
print("object %s put." % h.hexdigest())
"""put file contents into the repository"""
with open(args.path, "rb") as f:
data = f.read()
hex_id = args.id
try:
id = unhexlify(hex_id)
if len(id) != 32: # 256bit
raise ValueError("id must be 256bits or 64 hex digits")
except ValueError as err:
print("object id %s is invalid [%s]." % (hex_id, str(err)))
return EXIT_ERROR
repository.put(id, data)
print("object %s put." % hex_id)
repository.commit(compact=False)
return EXIT_SUCCESS
@ -503,7 +510,7 @@ class DebugMixIn:
debug_put_obj_epilog = process_epilog(
"""
This command puts objects into the repository.
This command puts an object into the repository.
"""
)
subparser = debug_parsers.add_parser(
@ -516,9 +523,8 @@ class DebugMixIn:
help="put object to repository (debug)",
)
subparser.set_defaults(func=self.do_debug_put_obj)
subparser.add_argument(
"paths", metavar="PATH", nargs="+", type=str, help="file(s) to read and create object(s) from"
)
subparser.add_argument("id", metavar="ID", type=str, help="hex object ID to put into the repo")
subparser.add_argument("path", metavar="PATH", type=str, help="file to read and create object from")
debug_delete_obj_epilog = process_epilog(
"""

View file

@ -2,7 +2,6 @@ import json
import os
import pstats
import unittest
from hashlib import sha256
from ...constants import * # NOQA
from .. import changedir
@ -47,18 +46,19 @@ class ArchiverTestCase(ArchiverTestCaseBase):
def test_debug_put_get_delete_obj(self):
self.cmd(f"--repo={self.repository_location}", "rcreate", RK_ENCRYPTION)
data = b"some data"
hexkey = sha256(data).hexdigest()
self.create_regular_file("file", contents=data)
output = self.cmd(f"--repo={self.repository_location}", "debug", "put-obj", "input/file")
assert hexkey in output
output = self.cmd(f"--repo={self.repository_location}", "debug", "get-obj", hexkey, "output/file")
assert hexkey in output
# TODO: to compute the correct hexkey, we need: borg debug id-hash file
id_hash = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" # 256bit = 64 hex digits
output = self.cmd(f"--repo={self.repository_location}", "debug", "put-obj", id_hash, "input/file")
assert id_hash in output
output = self.cmd(f"--repo={self.repository_location}", "debug", "get-obj", id_hash, "output/file")
assert id_hash in output
with open("output/file", "rb") as f:
data_read = f.read()
assert data == data_read
output = self.cmd(f"--repo={self.repository_location}", "debug", "delete-obj", hexkey)
output = self.cmd(f"--repo={self.repository_location}", "debug", "delete-obj", id_hash)
assert "deleted" in output
output = self.cmd(f"--repo={self.repository_location}", "debug", "delete-obj", hexkey)
output = self.cmd(f"--repo={self.repository_location}", "debug", "delete-obj", id_hash)
assert "not found" in output
output = self.cmd(f"--repo={self.repository_location}", "debug", "delete-obj", "invalid")
assert "is invalid" in output