From a3e887a43aba76997aab033a42358f400e2ef9af Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 18 Feb 2022 12:03:02 +0100 Subject: vidhar: ... --- hosts/vidhar/borg/copy.py | 68 ++++++++++++++++++++++++++--------------------- 1 file 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 = { borg_pwd = getpwnam('borg') -def as_borg(caps=set(), withns=lambda: pass): +def as_borg(caps=set()): if caps: for capset in [cap_permitted, cap_inheritable, cap_effective, cap_ambient]: capset.add(*caps) - - unshare.unshare(unshare.CLONE_NEWNS) - subprocess.run(['mount', '--make-rprivate', '/'], check=True) - withns() - if os.environ.get('CREDENTIALS_DIRECTORY'): - creds_path = pathlib.Path(os.environ['CREDENTIALS_DIRECTORY']).relative_to('/') - 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) os.setgid(borg_pwd.pw_gid) os.setuid(borg_pwd.pw_uid) @@ -114,29 +107,32 @@ def copy_archive(src_repo_path, dst_repo_path, entry): dir = pathlib.Path('/borg') def preexec_fn(): - def withns(): - chroot = pathlib.Path(tmpdir) / 'chroot' - upper = pathlib.Path(tmpdir) / 'upper' - work = pathlib.Path(tmpdir) / 'work' - for path in [chroot,upper,work]: - path.mkdir() - subprocess.run(['mount', '-t', 'overlay', 'overlay', '-o', f'lowerdir=/,upperdir={upper},workdir={work}', chroot], check=True) - bindMounts = ['nix', 'run', 'proc', 'dev', 'sys', pathlib.Path(os.path.expanduser('~')).relative_to('/')] - if os.environ.get('BORG_BASE_DIR'): - bindMounts.append(pathlib.Path(os.environ['BORG_BASE_DIR']).relative_to('/')) - if not ":" in src_repo_path: - bindMounts.append(pathlib.Path(src_repo_path).relative_to('/')) - if 'SSH_AUTH_SOCK' in os.environ: - bindMounts.append(pathlib.Path(os.environ['SSH_AUTH_SOCK']).parent.relative_to('/')) - for bindMount in bindMounts: - (chroot / bindMount).mkdir(parents=True,exist_ok=True) - # print(*['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], file=stderr) - subprocess.run(['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], check=True) - os.chroot(chroot) - os.chdir('/') - dir.mkdir(parents=True,exist_ok=True,mode=750) - os.chown(dir, borg_pwd.pw_uid, borg_pwd.pw_gid) - as_borg(withns=withns, caps={Cap.DAC_READ_SEARCH}) + unshare.unshare(unshare.CLONE_NEWNS) + subprocess.run(['mount', '--make-rprivate', '/'], check=True) + chroot = pathlib.Path(tmpdir) / 'chroot' + upper = pathlib.Path(tmpdir) / 'upper' + work = pathlib.Path(tmpdir) / 'work' + for path in [chroot,upper,work]: + path.mkdir() + subprocess.run(['mount', '-t', 'overlay', 'overlay', '-o', f'lowerdir=/,upperdir={upper},workdir={work}', chroot], check=True) + bindMounts = ['nix', 'run', 'proc', 'dev', 'sys', pathlib.Path(os.path.expanduser('~')).relative_to('/')] + if os.environ.get('BORG_BASE_DIR'): + bindMounts.append(pathlib.Path(os.environ['BORG_BASE_DIR']).relative_to('/')) + if not ":" in src_repo_path: + bindMounts.append(pathlib.Path(src_repo_path).relative_to('/')) + if 'SSH_AUTH_SOCK' in os.environ: + bindMounts.append(pathlib.Path(os.environ['SSH_AUTH_SOCK']).parent.relative_to('/')) + if 'CREDENTIALS_DIRECTORY' in os.environ: + bindMounts.append(pathlib.Path(os.environ['CREDENTIALS_DIRECTORY']).parent.relative_to('/')) + for bindMount in bindMounts: + (chroot / bindMount).mkdir(parents=True,exist_ok=True) + # print(*['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], file=stderr) + subprocess.run(['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], check=True) + os.chroot(chroot) + os.chdir('/') + dir.mkdir(parents=True,exist_ok=True,mode=750) + os.chown(dir, borg_pwd.pw_uid, borg_pwd.pw_gid) + as_borg(caps={Cap.DAC_READ_SEARCH}) total_size = None total_files = None @@ -245,6 +241,16 @@ def sigterm(signum, frame): def main(): signal.signal(signal.SIGTERM, sigterm) + + if 'CREDENTIALS_DIRECTORY' in os.environ: + for root, dirs, files in os.walk(os.environ['CREDENTIALS_DIRECTORY']): + def do_chown(path): + os.chown(pathlib.Path(root) / pathlib.Path(path), borg_pwd.pw_uid, borg_pwd.pw_gid) + + for dir in dirs: + do_chown(dir) + for file in files: + do_chown(file) if "::" in args.source: (src_repo_path, _, src_archive) = args.source.partition("::") -- cgit v1.2.3