]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
feat: Add download-redis script matching the upload-redis (#1111)
authorAnders Björklund <anders.f.bjorklund@gmail.com>
Mon, 18 Jul 2022 16:47:28 +0000 (18:47 +0200)
committerGitHub <noreply@github.com>
Mon, 18 Jul 2022 16:47:28 +0000 (18:47 +0200)
misc/download-redis [new file with mode: 0755]

diff --git a/misc/download-redis b/misc/download-redis
new file mode 100755 (executable)
index 0000000..021c701
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+
+# This script downloads the contents of the cache from a Redis secondary storage
+
+import redis
+import os
+
+import progress.bar
+import progress.spinner
+import humanize
+
+config = os.getenv("REDIS_CONF", "localhost")
+if ":" in config:
+    host, port = config.rsplit(":", 1)
+    sock = None
+elif config.startswith("/"):
+    host, port, sock = None, None, config
+else:
+    host, port, sock = config, 6379, None
+username = os.getenv("REDIS_USERNAME")
+password = os.getenv("REDIS_PASSWORD")
+context = redis.Redis(host=host, port=port, unix_socket_path=sock, password=password)
+pipe = context.pipeline(transaction=False)
+
+ccache = os.getenv("CCACHE_DIR", os.path.expanduser("~/.cache/ccache"))
+try:
+    count = context.info()["db0"]["keys"]
+except:
+    count = None  # only for showing progress
+files = result = manifest = objects = 0
+size = 0
+columns = os.get_terminal_size()[0]
+width = min(columns - 24, 100)
+bar = progress.bar.Bar(
+    "Downloading...", max=count, fill="=", suffix="%(percent).1f%%", width=width
+)
+if not count:
+    bar = progress.spinner.Spinner("Downloading... ")
+keys = context.scan_iter()
+# Note: doesn't work with the SSDB SCAN command
+#       syntax: keys key_start, key_end, limit
+for key in keys:
+    if not key.startswith(b"ccache:"):
+        bar.next()
+        continue
+    base = key.decode().replace("ccache:", "")
+    pipe.get(key)
+    val = pipe.execute()[-1]
+    if val is None:
+        continue
+    if val[0:2] == b"\xcc\xac":  # magic
+        objects = objects + 1
+        if val[2] == 0 and val[3] == 0:
+            ext = "R"
+            result = result + 1
+        elif val[2] == 0 and val[3] == 1:
+            ext = "M"
+            manifest = manifest + 1
+        else:
+            bar.next()
+            continue
+        filename = os.path.join(ccache, base[0], base[1], base[2:] + ext)
+        if not os.path.exists(filename):
+            dirname = os.path.join(ccache, base[0], base[1])
+            os.makedirs(dirname, mode=0o755, exist_ok=True)
+            with open(filename, "wb") as out:
+                out.write(val)
+    files = files + 1
+    size = size + len(val)
+    bar.next()
+bar.finish()
+print(
+    "%d files, %d result (%d manifest) = %d objects (%s)"
+    % (files, result, manifest, objects, humanize.naturalsize(size, binary=True))
+)