From a0b0cd24e8341c3d71eb4990b27979b90962bf32 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 18 Feb 2022 11:59:40 +0100 Subject: vidhar: ... --- hosts/vidhar/borg/copy.py | 61 +++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/hosts/vidhar/borg/copy.py b/hosts/vidhar/borg/copy.py index 168fa967..df77e4bb 100755 --- a/hosts/vidhar/borg/copy.py +++ b/hosts/vidhar/borg/copy.py @@ -45,14 +45,14 @@ halo_args = { borg_pwd = getpwnam('borg') -def as_borg(caps=set(), newns=True): +def as_borg(caps=set(), withns=lambda: pass): if caps: for capset in [cap_permitted, cap_inheritable, cap_effective, cap_ambient]: capset.add(*caps) - if newns: - unshare.unshare(unshare.CLONE_NEWNS) - subprocess.run(['mount', '--make-rprivate', '/'], check=True) + 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) @@ -114,34 +114,33 @@ def copy_archive(src_repo_path, dst_repo_path, entry): dir = pathlib.Path('/borg') def preexec_fn(): - # print('unshare/chroot', file=stderr) - 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('/')) - 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(newns=False, caps={Cap.DAC_READ_SEARCH}) + 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}) + + total_size = None + total_files = None with Halo(text=f'Determine size', **halo_args) as sp: - total_size = None - total_files = None with subprocess.Popen(['borg', 'info', '--info', '--json', '--lock-wait=600', f'{src_repo_path}::{entry["name"]}'], stdout=subprocess.PIPE, text=True, preexec_fn=lambda: as_borg()) as proc: stats = json.load(proc.stdout)['archives'][0]['stats'] total_size = stats['original_size'] -- cgit v1.2.3