diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2022-02-18 11:59:40 +0100 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2022-02-18 11:59:40 +0100 |
commit | a0b0cd24e8341c3d71eb4990b27979b90962bf32 (patch) | |
tree | 09b9a50b5066d55e5b3a9efc55e584cc5de673ab /hosts/vidhar/borg/copy.py | |
parent | 42620945a92775ecab4f47280083ec8e0169317d (diff) | |
download | nixos-a0b0cd24e8341c3d71eb4990b27979b90962bf32.tar nixos-a0b0cd24e8341c3d71eb4990b27979b90962bf32.tar.gz nixos-a0b0cd24e8341c3d71eb4990b27979b90962bf32.tar.bz2 nixos-a0b0cd24e8341c3d71eb4990b27979b90962bf32.tar.xz nixos-a0b0cd24e8341c3d71eb4990b27979b90962bf32.zip |
vidhar: ...
Diffstat (limited to 'hosts/vidhar/borg/copy.py')
-rwxr-xr-x | hosts/vidhar/borg/copy.py | 61 |
1 files 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 = { | |||
45 | 45 | ||
46 | borg_pwd = getpwnam('borg') | 46 | borg_pwd = getpwnam('borg') |
47 | 47 | ||
48 | def as_borg(caps=set(), newns=True): | 48 | def as_borg(caps=set(), withns=lambda: pass): |
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 | 52 | ||
53 | if newns: | 53 | unshare.unshare(unshare.CLONE_NEWNS) |
54 | unshare.unshare(unshare.CLONE_NEWNS) | 54 | subprocess.run(['mount', '--make-rprivate', '/'], check=True) |
55 | subprocess.run(['mount', '--make-rprivate', '/'], check=True) | 55 | withns() |
56 | if os.environ.get('CREDENTIALS_DIRECTORY'): | 56 | if os.environ.get('CREDENTIALS_DIRECTORY'): |
57 | creds_path = pathlib.Path(os.environ['CREDENTIALS_DIRECTORY']).relative_to('/') | 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) | 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) |
@@ -114,34 +114,33 @@ def copy_archive(src_repo_path, dst_repo_path, entry): | |||
114 | dir = pathlib.Path('/borg') | 114 | dir = pathlib.Path('/borg') |
115 | 115 | ||
116 | def preexec_fn(): | 116 | def preexec_fn(): |
117 | # print('unshare/chroot', file=stderr) | 117 | def withns(): |
118 | unshare.unshare(unshare.CLONE_NEWNS) | 118 | chroot = pathlib.Path(tmpdir) / 'chroot' |
119 | subprocess.run(['mount', '--make-rprivate', '/'], check=True) | 119 | upper = pathlib.Path(tmpdir) / 'upper' |
120 | chroot = pathlib.Path(tmpdir) / 'chroot' | 120 | work = pathlib.Path(tmpdir) / 'work' |
121 | upper = pathlib.Path(tmpdir) / 'upper' | 121 | for path in [chroot,upper,work]: |
122 | work = pathlib.Path(tmpdir) / 'work' | 122 | path.mkdir() |
123 | for path in [chroot,upper,work]: | 123 | subprocess.run(['mount', '-t', 'overlay', 'overlay', '-o', f'lowerdir=/,upperdir={upper},workdir={work}', chroot], check=True) |
124 | path.mkdir() | 124 | bindMounts = ['nix', 'run', 'proc', 'dev', 'sys', pathlib.Path(os.path.expanduser('~')).relative_to('/')] |
125 | subprocess.run(['mount', '-t', 'overlay', 'overlay', '-o', f'lowerdir=/,upperdir={upper},workdir={work}', chroot], check=True) | 125 | if os.environ.get('BORG_BASE_DIR'): |
126 | 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('/')) |
127 | if os.environ.get('BORG_BASE_DIR'): | 127 | if not ":" in src_repo_path: |
128 | bindMounts.append(pathlib.Path(os.environ['BORG_BASE_DIR']).relative_to('/')) | 128 | bindMounts.append(pathlib.Path(src_repo_path).relative_to('/')) |
129 | if not ":" in src_repo_path: | 129 | if 'SSH_AUTH_SOCK' in os.environ: |
130 | bindMounts.append(pathlib.Path(src_repo_path).relative_to('/')) | 130 | bindMounts.append(pathlib.Path(os.environ['SSH_AUTH_SOCK']).parent.relative_to('/')) |
131 | if 'SSH_AUTH_SOCK' in os.environ: | 131 | for bindMount in bindMounts: |
132 | bindMounts.append(pathlib.Path(os.environ['SSH_AUTH_SOCK']).parent.relative_to('/')) | 132 | (chroot / bindMount).mkdir(parents=True,exist_ok=True) |
133 | for bindMount in bindMounts: | 133 | # print(*['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], file=stderr) |
134 | (chroot / bindMount).mkdir(parents=True,exist_ok=True) | 134 | subprocess.run(['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], check=True) |
135 | # print(*['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], file=stderr) | 135 | os.chroot(chroot) |
136 | subprocess.run(['mount', '--bind', pathlib.Path('/') / bindMount, chroot / bindMount], check=True) | 136 | os.chdir('/') |
137 | os.chroot(chroot) | 137 | dir.mkdir(parents=True,exist_ok=True,mode=750) |
138 | os.chdir('/') | 138 | os.chown(dir, borg_pwd.pw_uid, borg_pwd.pw_gid) |
139 | dir.mkdir(parents=True,exist_ok=True,mode=750) | 139 | as_borg(withns=withns, caps={Cap.DAC_READ_SEARCH}) |
140 | os.chown(dir, borg_pwd.pw_uid, borg_pwd.pw_gid) | 140 | |
141 | as_borg(newns=False, caps={Cap.DAC_READ_SEARCH}) | 141 | total_size = None |
142 | total_files = None | ||
142 | with Halo(text=f'Determine size', **halo_args) as sp: | 143 | with Halo(text=f'Determine size', **halo_args) as sp: |
143 | total_size = None | ||
144 | total_files = None | ||
145 | 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: | 144 | 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: |
146 | stats = json.load(proc.stdout)['archives'][0]['stats'] | 145 | stats = json.load(proc.stdout)['archives'][0]['stats'] |
147 | total_size = stats['original_size'] | 146 | total_size = stats['original_size'] |