2022-02-17 21:49:24 +01:00
|
|
|
import atexit
|
|
|
|
import os
|
|
|
|
|
2022-09-27 05:55:50 +02:00
|
|
|
from typing import ClassVar, Optional
|
2022-08-16 02:14:56 +02:00
|
|
|
|
2022-10-08 04:04:27 +02:00
|
|
|
from config.state import config
|
2022-02-17 21:49:24 +01:00
|
|
|
from constants import Arch, BASE_PACKAGES
|
2022-09-01 03:57:54 +02:00
|
|
|
from distro.repo import RepoInfo
|
2022-03-03 16:54:43 +01:00
|
|
|
from distro.distro import get_kupfer_local, get_kupfer_https
|
2022-08-16 17:52:05 +02:00
|
|
|
from exec.file import get_temp_dir, makedir, root_makedir
|
2022-02-17 21:49:24 +01:00
|
|
|
from utils import check_findmnt
|
|
|
|
|
|
|
|
from .base import BaseChroot
|
|
|
|
from .build import BuildChroot
|
2022-02-18 06:32:04 +01:00
|
|
|
from .abstract import get_chroot
|
2022-02-17 21:49:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
class DeviceChroot(BuildChroot):
|
|
|
|
|
2022-09-27 05:55:50 +02:00
|
|
|
_copy_base: ClassVar[bool] = False
|
2022-02-17 21:49:24 +01:00
|
|
|
|
|
|
|
def create_rootfs(self, reset, pacman_conf_target, active_previously):
|
|
|
|
clss = BuildChroot if self.copy_base else BaseChroot
|
|
|
|
|
2022-08-16 02:14:56 +02:00
|
|
|
makedir(config.get_path('chroots'))
|
|
|
|
root_makedir(self.get_path())
|
|
|
|
if not self.copy_base:
|
2022-08-16 17:52:05 +02:00
|
|
|
pacman_conf_target = os.path.join(get_temp_dir(register_cleanup=True), f'pacman-{self.name}.conf')
|
2022-08-16 02:14:56 +02:00
|
|
|
self.write_pacman_conf(in_chroot=False, absolute_path=pacman_conf_target)
|
|
|
|
|
2022-02-17 21:49:24 +01:00
|
|
|
clss.create_rootfs(self, reset, pacman_conf_target, active_previously)
|
|
|
|
|
2022-11-09 15:22:06 +01:00
|
|
|
def mount_rootfs(self, source_path: str, fs_type: Optional[str] = None, options: list[str] = [], allow_overlay: bool = False):
|
2022-02-17 21:49:24 +01:00
|
|
|
if self.active:
|
|
|
|
raise Exception(f'{self.name}: Chroot is marked as active, not mounting a rootfs over it.')
|
|
|
|
if not os.path.exists(source_path):
|
|
|
|
raise Exception('Source does not exist')
|
|
|
|
if not allow_overlay:
|
|
|
|
really_active = []
|
|
|
|
for mnt in self.active_mounts:
|
|
|
|
if check_findmnt(self.get_path(mnt)):
|
|
|
|
really_active.append(mnt)
|
|
|
|
if really_active:
|
|
|
|
raise Exception(f'{self.name}: Chroot has submounts active: {really_active}')
|
|
|
|
if os.path.ismount(self.path):
|
|
|
|
raise Exception(f'{self.name}: There is already something mounted at {self.path}, not mounting over it.')
|
|
|
|
if os.path.exists(os.path.join(self.path, 'usr/bin')):
|
|
|
|
raise Exception(f'{self.name}: {self.path}/usr/bin exists, not mounting over existing rootfs.')
|
2022-08-16 02:14:19 +02:00
|
|
|
makedir(self.path)
|
2022-02-17 21:49:24 +01:00
|
|
|
atexit.register(self.deactivate)
|
|
|
|
self.mount(source_path, '/', fs_type=fs_type, options=options)
|
|
|
|
|
|
|
|
|
2022-02-18 06:32:04 +01:00
|
|
|
def get_device_chroot(
|
|
|
|
device: str,
|
|
|
|
flavour: str,
|
|
|
|
arch: Arch,
|
|
|
|
packages: list[str] = BASE_PACKAGES,
|
2022-03-03 16:54:43 +01:00
|
|
|
use_local_repos: bool = True,
|
2022-09-01 03:57:54 +02:00
|
|
|
extra_repos: Optional[dict[str, RepoInfo]] = None,
|
2022-02-18 06:32:04 +01:00
|
|
|
**kwargs,
|
|
|
|
) -> DeviceChroot:
|
2022-02-17 21:49:24 +01:00
|
|
|
name = f'rootfs_{device}-{flavour}'
|
2022-09-01 03:57:54 +02:00
|
|
|
repos: dict[str, RepoInfo] = get_kupfer_local(arch).repos if use_local_repos else get_kupfer_https(arch).repos # type: ignore
|
|
|
|
|
2022-03-03 16:54:43 +01:00
|
|
|
repos.update(extra_repos or {})
|
|
|
|
|
2022-09-27 05:55:50 +02:00
|
|
|
args = dict(arch=arch, base_packages=packages, extra_repos=repos)
|
2022-09-27 04:55:17 +02:00
|
|
|
chroot = get_chroot(name, **kwargs, extra_repos=repos, chroot_class=DeviceChroot, chroot_args=args)
|
2022-03-03 16:54:43 +01:00
|
|
|
assert isinstance(chroot, DeviceChroot)
|
2022-02-18 06:32:04 +01:00
|
|
|
return chroot
|