JXRVASgr

2021-09-13 14:26

			import atexit
from matrix import get_config
import shutil
import tempfile
from download import download_url
import logging
import subprocess
import os


class Repository:
    name = ""
    options = {}

    def __init__(self, name: str, options: dict[str, str]) -> None:
        self.name = name
        self.options = options

    def __repr__(self) -> str:
        backlash = '\\'
        return f"""
[{self.name}]
{f'{backlash}n'.join(list(map(lambda k: f'{k} = {self.options[k]}',self.options.keys)))}
"""


class PacmanConf:
    options = {}
    repositories = []

    def __init__(self, options: dict[str, str], repositories: list[Repository]) -> None:
        self.options = options
        self.repositories = repositories

    def __repr__(self) -> str:
        backlash = '\\'
        return f"""
// AUTO GENERATED
[options]
{f'{backlash}n'.join(list(map(lambda k: f'{k} = {self.options[k]}',self.options)))}

{(f'{backlash}n'*2).join(list(map(lambda r: repr(r),self.repositories)))}
"""


def create_chroot(
    chroot_path,
    arch,
    pacman_conf: PacmanConf,
    packages=['base'],
):
    arch_config = get_config(arch)

    tmp_dir = tempfile.mkdtemp()

    def delete_tmp_dir():
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)

    atexit.register(delete_tmp_dir)

    download_url(arch_config.rootfs_url, '')

    pacman_conf_target = chroot_path + '/etc/pacman.conf'

    os.makedirs(chroot_path + '/etc', exist_ok=True)
    with open(pacman_conf_target, 'w') as file:
        file.write(repr(pacman_conf))

    run_chroot_command(chroot_path, f'pacman -Syu {" ".join(packages)}')


def run_chroot_command(chroot_path, command):
    mounts = {
        '/proc': ['-t', 'proc', 'proc'],
        '/sys': ['-t', 'sysfs', 'sys'],
        '/tmp': ['-t', 'tmpfs', 'none'],
        '/dev': ['-o', 'bin', '/dev'],
    }

    def umount():
        for node in mounts.keys():
            path = os.path.join(chroot_path, node)
            if os.path.exists(path):
                result = subprocess.run(['mountpoint', path])
                if result.returncode == 0:
                    result = subprocess.run(['umount', path])
                    if result.returncode != 0:
                        logging.fatal(f'Failed to umount {node}')
                        exit(1)

    atexit.register(umount)

    for node in mounts.keys():
        result = subprocess.run(['mount'] + mounts[node] + [os.path.join(chroot_path, node)])
        if result.returncode != 0:
            logging.fatal(f'Failed to mount {node}')
            exit(1)

    result = subprocess.run([
        'unshare',
        '--fork',
        '--pid',
        'chroot',
        chroot_path,
        command,
    ], env=os.environ.copy() | {'SHELL': '/bin/bash'})

    umount()


def create_chroot_user(chroot_path):
    user = 'kupfer'
    password = '123456'
    groups = ['network', 'video', 'audio', 'optical', 'storage', 'input', 'scanner', 'games', 'lp', 'rfkill', 'wheel']
    install_script = '\n'.join([
        f'if ! id -u "{user}" >/dev/null 2>&1; then',
        f'  useradd -m {user}',
        f'fi',
        f'usermod -a -G {",".join(groups)} {user}',
        f'echo "{user}:{password}" | chpasswd',
        f'chown {user}:{user} /home/{user} -R',
    ])
    result = subprocess.run([
        'arch-chroot',
        chroot_path,
        '/bin/bash',
        '-c',
        install_script,
    ])
    if result.returncode != 0:
        logging.fatal('Failed to setup user')
        exit(1)