2021-08-06 02:21:50 +02:00
|
|
|
import logging
|
|
|
|
import subprocess
|
2021-08-06 05:24:06 +02:00
|
|
|
import os
|
2021-09-13 04:19:13 +02:00
|
|
|
from config import config
|
2021-09-29 16:54:26 +02:00
|
|
|
from distro import get_base_distros, RepoInfo
|
2021-08-06 05:24:06 +02:00
|
|
|
|
2021-08-08 13:15:48 +02:00
|
|
|
|
2021-09-13 04:19:13 +02:00
|
|
|
def get_chroot_path(chroot_name, override_basepath: str = None) -> str:
|
2021-09-30 03:50:11 +02:00
|
|
|
base_path = config.get_path('chroots') if not override_basepath else override_basepath
|
2021-09-13 04:19:13 +02:00
|
|
|
return os.path.join(base_path, chroot_name)
|
|
|
|
|
|
|
|
|
2021-09-17 04:30:13 +02:00
|
|
|
def create_chroot(
|
|
|
|
chroot_name,
|
|
|
|
arch='aarch64',
|
|
|
|
packages=['base'],
|
|
|
|
pacman_conf='/app/local/etc/pacman.conf',
|
2021-09-29 16:54:26 +02:00
|
|
|
extra_repos: dict[str, RepoInfo] = {},
|
2021-09-17 04:30:13 +02:00
|
|
|
chroot_base_path: str = None,
|
|
|
|
):
|
|
|
|
base_chroot = f'base_{arch}'
|
2021-09-13 04:19:13 +02:00
|
|
|
chroot_path = get_chroot_path(chroot_name, override_basepath=chroot_base_path)
|
2021-09-29 16:54:26 +02:00
|
|
|
base_distro = get_base_distros()[arch]
|
2021-08-08 18:32:42 +02:00
|
|
|
pacman_conf_target = chroot_path + '/etc/pacman.conf'
|
2021-08-06 05:24:06 +02:00
|
|
|
|
2021-09-17 04:30:13 +02:00
|
|
|
# copy base_chroot instead of creating from scratch every time
|
|
|
|
if not (chroot_base_path or chroot_name == base_chroot):
|
|
|
|
# only install base package in base_chroot
|
|
|
|
base_chroot_path = create_chroot(base_chroot, arch=arch)
|
|
|
|
logging.info(f'Copying {base_chroot} chroot to {chroot_name}')
|
|
|
|
result = subprocess.run([
|
|
|
|
'rsync',
|
|
|
|
'-a',
|
|
|
|
'--delete',
|
|
|
|
'-q',
|
|
|
|
'-W',
|
|
|
|
'-x',
|
|
|
|
f'{base_chroot_path}/',
|
|
|
|
f'{chroot_path}/',
|
|
|
|
])
|
|
|
|
if result.returncode != 0:
|
|
|
|
logging.fatal('Failed to sync chroot copy')
|
|
|
|
exit(1)
|
|
|
|
|
2021-08-08 18:32:42 +02:00
|
|
|
os.makedirs(chroot_path + '/etc', exist_ok=True)
|
2021-08-06 05:24:06 +02:00
|
|
|
|
2021-09-29 16:54:26 +02:00
|
|
|
conf_text = base_distro.get_pacman_conf(extra_repos)
|
|
|
|
with open(pacman_conf_target, 'w') as file:
|
|
|
|
file.write(conf_text)
|
2021-08-06 05:24:06 +02:00
|
|
|
|
2021-09-17 04:30:13 +02:00
|
|
|
result = subprocess.run([
|
|
|
|
'pacstrap',
|
|
|
|
'-C',
|
|
|
|
pacman_conf_target,
|
|
|
|
'-c',
|
|
|
|
'-G',
|
|
|
|
chroot_path,
|
|
|
|
] + packages + [
|
2021-08-08 18:32:42 +02:00
|
|
|
'--needed',
|
|
|
|
'--overwrite=*',
|
|
|
|
'-yyuu',
|
2021-09-17 04:30:13 +02:00
|
|
|
],
|
|
|
|
capture_output=True)
|
2021-08-06 02:21:50 +02:00
|
|
|
if result.returncode != 0:
|
2021-09-29 02:35:53 +02:00
|
|
|
logging.debug(result.stdout.decode())
|
|
|
|
raise Exception(f'Failed to install chroot "{chroot_name}":' + '\n' + result.stderr.decode())
|
2021-09-13 04:19:13 +02:00
|
|
|
return chroot_path
|
|
|
|
|
2021-08-06 02:21:50 +02:00
|
|
|
|
2021-09-29 02:00:59 +02:00
|
|
|
def run_chroot_cmd(
|
|
|
|
script: str,
|
|
|
|
chroot_name,
|
|
|
|
chroot_base_path: str = None,
|
|
|
|
):
|
|
|
|
chroot_path = get_chroot_path(chroot_name, override_basepath=chroot_base_path)
|
|
|
|
result = subprocess.run([
|
|
|
|
'arch-chroot',
|
|
|
|
chroot_path,
|
|
|
|
'/bin/bash',
|
|
|
|
'-c',
|
|
|
|
script,
|
|
|
|
])
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2021-09-13 04:19:13 +02:00
|
|
|
def create_chroot_user(
|
|
|
|
chroot_name,
|
|
|
|
chroot_base_path: str = None,
|
|
|
|
user='kupfer',
|
|
|
|
password='123456',
|
|
|
|
groups=['network', 'video', 'audio', 'optical', 'storage', 'input', 'scanner', 'games', 'lp', 'rfkill', 'wheel'],
|
|
|
|
):
|
2021-09-26 17:17:53 +02:00
|
|
|
install_script = f'''
|
2021-09-29 02:00:59 +02:00
|
|
|
set -e
|
2021-09-26 17:17:53 +02:00
|
|
|
if ! id -u "{user}" >/dev/null 2>&1; then
|
|
|
|
useradd -m {user}
|
|
|
|
fi
|
|
|
|
usermod -a -G {",".join(groups)} {user}
|
|
|
|
chown {user}:{user} /home/{user} -R
|
|
|
|
'''
|
2021-09-29 02:00:59 +02:00
|
|
|
if password:
|
|
|
|
install_script += f'echo "{user}:{password}" | chpasswd'
|
|
|
|
else:
|
|
|
|
install_script += 'passwd'
|
|
|
|
result = run_chroot_cmd(install_script, chroot_name=chroot_name, chroot_base_path=chroot_base_path)
|
2021-08-06 02:21:50 +02:00
|
|
|
if result.returncode != 0:
|
2021-09-29 02:00:59 +02:00
|
|
|
raise Exception('Failed to setup user')
|