File: dumpdir

package info (click to toggle)
composefs 1.0.8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,040 kB
  • sloc: ansic: 9,004; sh: 416; python: 225; makefile: 5
file content (90 lines) | stat: -rwxr-xr-x 2,765 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/python3

import os
import sys
import shlex
import hashlib
import stat
import argparse

def log_error(error):
    print("Readdir error: " + error)

def should_convert_whiteout(stbuf):
    return args.whiteout and stat.S_ISCHR(stbuf.st_mode) and stbuf.st_rdev == os.makedev(0,0)

def has_whiteout_child(path):
    for f in os.listdir(path):
        s = os.lstat(os.path.join(path, f))
        if should_convert_whiteout(s):
            return True
    return False

def dumpfile(file, root):
    rel = os.path.relpath(file, root)
    s = os.lstat(file)

    st_mode = s.st_mode

    content = None
    xattrs = {}
    if should_convert_whiteout(s):
        content = b''
        st_mode = (st_mode & ~stat.S_IFMT(st_mode)) | stat.S_IFREG
        xattrs["trusted.overlay.overlay.whiteout"] = b''
        xattrs["user.overlay.whiteout"] = b''

    if stat.S_ISDIR(st_mode) and has_whiteout_child(file):
        xattrs["trusted.overlay.overlay.whiteouts"] = b''
        xattrs["user.overlay.whiteouts"] = b''
        xattrs["trusted.overlay.overlay.opaque"] = b'x'
        xattrs["user.overlay.opaque"] = b'x'

    nlink = s.st_nlink;
    if args.no_nlink or (args.no_root_nlink and file == root):
        nlink = 1
    print(f"{shlex.quote(rel)} {oct(st_mode)} {nlink} {s.st_uid}:{s.st_gid} {s.st_rdev} {s.st_mtime_ns}",end="")
    if stat.S_ISREG(st_mode):
        if content == None:
            content = open(file,'rb').read()
        digest = hashlib.sha256(content).hexdigest()
        print(f" {s.st_size} sha256:{digest}",end="")
    elif stat.S_ISLNK(st_mode):
        link = os.readlink(file)
        print(f" ->{shlex.quote(link)}",end="")

    for attr in sorted(os.listxattr(file, follow_symlinks=False)):
        v = os.getxattr(file, attr, follow_symlinks=False)
        xattrs[attr] = v

    for attr in sorted(xattrs.keys()):
        v = xattrs[attr]
        if args.userxattr and not attr.startswith("user."):
            continue
        if args.noescaped and attr.startswith("trusted.overlay.overlay."):
            continue

        print(f" {attr}={v}", end="")

    print()



def dumpdir(root):
    dumpfile(root, root)
    for parent, dirs, files in os.walk(root, topdown=True, onerror=log_error):
        dirs.sort()
        for file in sorted(dirs + files):
            dumpfile(os.path.join(parent, file), root)

argParser = argparse.ArgumentParser()
argParser.add_argument("--no-nlink", action='store_true')
argParser.add_argument("--no-root-nlink", action='store_true')
argParser.add_argument("--userxattr", action='store_true')
argParser.add_argument("--whiteout", action='store_true')
argParser.add_argument("--noescaped", action='store_true')
argParser.add_argument('path')

args = argParser.parse_args()

dumpdir(args.path)