Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidePrincipi committed Nov 12, 2024
1 parent 739ac4b commit 40766e0
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 0 deletions.
68 changes: 68 additions & 0 deletions imageroot/actions/seek-snapshot-contents/50seek_snapshot_contents
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python3

#
# Copyright (C) 2024 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-3.0-or-later
#

import json
import sys
import os
import subprocess
import agent
import hashlib

request = json.load(sys.stdin)

limit_reached = False
counter_limit = request.get("limit", 1000)
cache_seed = '-'.join(request['destination'], request['snapshot'], request['share'])
plocate_cache = hashlib.md5(cache_seed.encode(), usedforsecurity=False).hexdigest()

podman_exec = ["podman", "exec", "samba-dc"]
pcheck = agent.run_helper(*(podman_exec + ["net", "conf", "showshare", request["share"]]))
if pcheck.returncode != 0:
agent.set_status('validation-failed')
json.dump([{'field':'share', 'parameter':'share','value': request['share'], 'error':'share_not_found'}], fp=sys.stdout)
sys.exit(2)

cache_exits = False
if not cache_exists:
# Extract the .plocate files from the snapshot and store them under a
# temporary cache directory:
podman_args = ["--workdir=/srv"] + agent.agent.get_state_volume_args()
restic_args = [
"restore",
f"{request["snapshot"]}:volumes/data/backup",
"--include=*.plocate",
f"--target=/srv/volumes/data/plocate/{plocate_cache}"
]
agent.run_restic(agent.redis_connect(), request["destination"], request["repopath"], podman_args, restic_args).check_returnvalue()
# TODO: remove stale cache dirs (age > 8hours?)

# Search share paths matching the query:
plocate_cmd = ['podman', 'exec', 'samba-dc', 'plocate', '-d', f"/var/lib/samba/plocate/{plocate_cache}/{request['share']}.plocate", request.get('query', "")]
if request.get("basename"):
plocate_cmd += ["-b"] # restrict search to file basename
with subprocess.Popen(plocate_cmd, stdout=subprocess.PIPE, stderr=sys.stderr, text=True) as vproc:
contents = []
counter = 0
while True:
line = vproc.stdout.readline()
if not line:
break
contents.append(line.rstrip())
counter += 1
if counter >= counter_limit:
limit_reached = True
break
if vproc.returncode != 0:
print(agent.SD_ERR + f"Plocate command failed with exit code {vproc.returncode}.", file=sys.stderr)
sys.exit(1)

contents.sort()
json.dump({
"request": request,
"contents": contents,
"limit_reached": limit_reached,
}, fp=sys.stdout)
46 changes: 46 additions & 0 deletions imageroot/actions/seek-snapshot-contents/validate-input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "seek-snapshot-contents input",
"$id": "http://schema.nethserver.org/mail/seek-snapshot-contents-input.json",
"description": "Extract the list of IMAP folders from a backup snapshot",
"examples": [

],
"type": "object",
"required": [
"destination",
"repopath",
"snapshot",
"share"
],
"properties": {
"destination": {
"type": "string",
"description": "The UUID of the backup destination where the Restic repository resides."
},
"repopath": {
"type": "string",
"description": "Restic repository path, under the backup destination"
},
"snapshot": {
"type": "string",
"description": "Restic snapshot ID to restore"
},
"share": {
"type": "string",
"description": "Seek the paths of this Samba share"
},
"query": {
"type": "string",
"description": "Seek matching paths"
},
"basename": {
"type":"boolean",
"description": "If true, match the path basename part"
},
"limit": {
"type": "integer",
"description": "Limit the number of returned contents"
}
}
}
47 changes: 47 additions & 0 deletions imageroot/actions/seek-snapshot-contents/validate-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "seek-snapshot-content output",
"$id": "http://schema.nethserver.org/mail/seek-snapshot-content-output.json",
"description": "Extract the list of IMAP folders from a backup snapshot",
"examples": [
{
"request": {
"destination": "14030a59-a4e6-54cc-b8ea-cd5f97fe44c8",
"repopath": "mail/4372a5d5-0886-45d3-82e7-68d913716a4c",
"snapshot": "latest",
"share": "myshare",
"query": "*.php",
"basename": true,
"limit": 1000
},
"contents": [
"dir1/file001.php",
"dir1/file002.php",
"Project/NethServer/Main.php"
],
"limit_reached": false
}
],
"type": "object",
"required": [
"contents",
"limit_reached"
],
"properties": {
"contents": {
"type": "array",
"description": "List of absolute share content paths",
"items": {
"type": "string"
}
},
"limit_reached": {
"type":"boolean",
"description": "If true, the query matches more contents than the returned items"
},
"request": {
"type": "object",
"title": "Original request object"
}
}
}

0 comments on commit 40766e0

Please sign in to comment.