summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2022-02-18 12:03:02 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2022-02-18 12:03:02 +0100
commita3e887a43aba76997aab033a42358f400e2ef9af (patch)
tree6d8e74e06a925550e92685a096aba2fe4af0328b
parenta0b0cd24e8341c3d71eb4990b27979b90962bf32 (diff)
downloadnixos-a3e887a43aba76997aab033a42358f400e2ef9af.tar
nixos-a3e887a43aba76997aab033a42358f400e2ef9af.tar.gz
nixos-a3e887a43aba76997aab033a42358f400e2ef9af.tar.bz2
nixos-a3e887a43aba76997aab033a42358f400e2ef9af.tar.xz
nixos-a3e887a43aba76997aab033a42358f400e2ef9af.zip
vidhar: ...
-rwxr-xr-xhosts/vidhar/borg/copy.py68
1 files changed, 37 insertions, 31 deletions
diff --git a/hosts/vidhar/borg/copy.py b/hosts/vidhar/borg/copy.py
index df77e4bb..d4edb09d 100755
--- a/hosts/vidhar/borg/copy.py
+++ b/hosts/vidhar/borg/copy.py
@@ -45,17 +45,10 @@ halo_args = {
45 45
46borg_pwd = getpwnam('borg') 46borg_pwd = getpwnam('borg')
47 47
48def as_borg(caps=set(), withns=lambda: pass): 48def as_borg(caps=set()):
49 if caps: 49 if caps:
50 for capset in [cap_permitted, cap_inheritable, cap_effective, cap_ambient]: 50 for capset in [cap_permitted, cap_inheritable, cap_effective, cap_ambient]:
51 capset.add(*caps) 51 capset.add(*caps)
52
53 unshare.unshare(unshare.CLONE_NEWNS)
54 subprocess.run(['mount', '--make-rprivate', '/'], check=True)
55 withns()
56 if os.environ.get('CREDENTIALS_DIRECTORY'):
57 creds_path = pathlib.Path(os.environ['CREDENTIALS_DIRECTORY']).relative_to('/')
58 subprocess.run(['bindfs', '-r', f'--force-user={borg_pwd.pw_uid}', f'--force-group={borg_pwd.pw_gid}', pathlib.Path('/') / creds_path, chroot / creds_path], check=True)
59 52
60 os.setgid(borg_pwd.pw_gid) 53 os.setgid(borg_pwd.pw_gid)
61 os.setuid(borg_pwd.pw_uid) 54 os.setuid(borg_pwd.pw_uid)
@@ -114,29 +107,32 @@ def copy_archive(src_repo_path, dst_repo_path, entry):
114 dir = pathlib.Path('/borg') 107 dir = pathlib.Path('/borg')
115 108
116 def preexec_fn(): 109 def preexec_fn():
117 def withns(): 110 unshare.unshare(unshare.CLONE_NEWNS)
118 chroot = pathlib.Path(tmpdir) / 'chroot' 111 subprocess.run(['mount', '--make-rprivate', '/'], check=True)
119 upper = pathlib.Path(tmpdir) / 'upper' 112 chroot = pathlib.Path(tmpdir) / 'chroot'
120 work = pathlib.Path(tmpdir) / 'work' 113 upper = pathlib.Path(tmpdir) / 'upper'
121 for path in [chroot,upper,work]: 114 work = pathlib.Path(tmpdir) / 'work'
122 path.mkdir() 115 for path in [chroot,upper,work]:
123 subprocess.run(['mount', '-t', 'overlay', 'overlay', '-o', f'lowerdir=/,upperdir={upper},workdir={work}', chroot], check=True) 116 path.mkdir()
124 bindMounts = ['nix', 'run', 'proc', 'dev', 'sys', pathlib.Path(os.path.expanduser('~')).relative_to('/')] 117 subprocess.run(['mount', '-t', 'overlay', 'overlay', '-o', f'lowerdir=/,upperdir={upper},workdir={work}', chroot], check=True)
125 if os.environ.get('BORG_BASE_DIR'): 118 bindMounts = ['nix', 'run', 'proc', 'dev', 'sys', pathlib.Path(os.path.expanduser('~')).relative_to('/')]
126 bindMounts.append(pathlib.Path(os.environ['BORG_BASE_DIR']).relative_to('/')) 119 if os.environ.get('BORG_BASE_DIR'):
127 if not ":" in src_repo_path: 120 bindMounts.append(pathlib.Path(os.environ['BORG_BASE_DIR']).relative_to('/'))
128 bindMounts.append(pathlib.Path(src_repo_path).relative_to('/')) 121 if not ":" in src_repo_path:
129 if 'SSH_AUTH_SOCK' in os.environ: 122 bindMounts.append(pathlib.Path(src_repo_path).relative_to('/'))
130 bindMounts.append(pathlib.Path(os.environ['SSH_AUTH_SOCK']).parent.relative_to('/')) 123 if 'SSH_AUTH_SOCK' in os.environ:
131 for bindMount in bindMounts: 124 bindMounts.append(pathlib.Path(os.environ['SSH_AUTH_SOCK']).parent.relative_to('/'))
132 (chroot / bindMount).mkdir(parents=True,exist_ok=True) 125 if 'CREDENTIALS_DIRECTORY' in os.environ:
133 # print(*['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], file=stderr) 126 bindMounts.append(pathlib.Path(os.environ['CREDENTIALS_DIRECTORY']).parent.relative_to('/'))
134 subprocess.run(['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], check=True) 127 for bindMount in bindMounts:
135 os.chroot(chroot) 128 (chroot / bindMount).mkdir(parents=True,exist_ok=True)
136 os.chdir('/') 129 # print(*['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], file=stderr)
137 dir.mkdir(parents=True,exist_ok=True,mode=750) 130 subprocess.run(['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], check=True)
138 os.chown(dir, borg_pwd.pw_uid, borg_pwd.pw_gid) 131 os.chroot(chroot)
139 as_borg(withns=withns, caps={Cap.DAC_READ_SEARCH}) 132 os.chdir('/')
133 dir.mkdir(parents=True,exist_ok=True,mode=750)
134 os.chown(dir, borg_pwd.pw_uid, borg_pwd.pw_gid)
135 as_borg(caps={Cap.DAC_READ_SEARCH})
140 136
141 total_size = None 137 total_size = None
142 total_files = None 138 total_files = None
@@ -245,6 +241,16 @@ def sigterm(signum, frame):
245 241
246def main(): 242def main():
247 signal.signal(signal.SIGTERM, sigterm) 243 signal.signal(signal.SIGTERM, sigterm)
244
245 if 'CREDENTIALS_DIRECTORY' in os.environ:
246 for root, dirs, files in os.walk(os.environ['CREDENTIALS_DIRECTORY']):
247 def do_chown(path):
248 os.chown(pathlib.Path(root) / pathlib.Path(path), borg_pwd.pw_uid, borg_pwd.pw_gid)
249
250 for dir in dirs:
251 do_chown(dir)
252 for file in files:
253 do_chown(file)
248 254
249 if "::" in args.source: 255 if "::" in args.source:
250 (src_repo_path, _, src_archive) = args.source.partition("::") 256 (src_repo_path, _, src_archive) = args.source.partition("::")