2021-08-05 20:26:48 +02:00
|
|
|
import atexit
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import click
|
2021-08-08 18:32:42 +02:00
|
|
|
from logger import logging, setup_logging, verbose_option
|
2021-08-08 18:18:36 +02:00
|
|
|
from chroot import create_chroot, create_chroot_user
|
2021-08-05 20:26:48 +02:00
|
|
|
|
|
|
|
devices = {
|
|
|
|
'oneplus-enchilada': ['sdm845-oneplus-enchilada'],
|
|
|
|
'xiaomi-beryllium-ebbg': ['sdm845-xiaomi-beryllium-ebbg'],
|
|
|
|
'xiaomi-beryllium-tianma': ['sdm845-xiaomi-beryllium-tianma'],
|
|
|
|
}
|
|
|
|
|
|
|
|
flavours = {
|
|
|
|
'barebone': [],
|
|
|
|
'phosh': [],
|
|
|
|
'plasma-mobile': [],
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def get_device_and_flavour() -> tuple[str, str]:
|
|
|
|
if not os.path.exists('.device'):
|
2021-08-08 18:32:42 +02:00
|
|
|
logging.fatal(f'Please set the device using \'kupferbootstrap image device ...\'')
|
2021-08-05 20:26:48 +02:00
|
|
|
exit(1)
|
|
|
|
if not os.path.exists('.flavour'):
|
2021-08-08 18:32:42 +02:00
|
|
|
logging.fatal(f'Please set the flavour using \'kupferbootstrap image flavour ...\'')
|
2021-08-05 20:26:48 +02:00
|
|
|
exit(1)
|
|
|
|
|
|
|
|
with open('.device', 'r') as file:
|
|
|
|
device = file.read()
|
|
|
|
with open('.flavour', 'r') as file:
|
|
|
|
flavour = file.read()
|
|
|
|
|
|
|
|
return (device, flavour)
|
|
|
|
|
|
|
|
|
|
|
|
def get_image_name(device, flavour):
|
|
|
|
return f'{device}-{flavour}-rootfs.img'
|
|
|
|
|
|
|
|
|
|
|
|
def mount_rootfs_image(path):
|
|
|
|
rootfs_mount = '/mnt/kupfer/rootfs'
|
|
|
|
if not os.path.exists(rootfs_mount):
|
|
|
|
os.makedirs(rootfs_mount)
|
|
|
|
|
|
|
|
def umount():
|
2021-08-08 18:32:42 +02:00
|
|
|
subprocess.run(
|
|
|
|
[
|
|
|
|
'umount',
|
|
|
|
'-lc',
|
|
|
|
rootfs_mount,
|
|
|
|
],
|
|
|
|
stderr=subprocess.DEVNULL,
|
|
|
|
)
|
|
|
|
|
2021-08-05 20:26:48 +02:00
|
|
|
atexit.register(umount)
|
|
|
|
|
2021-08-08 18:32:42 +02:00
|
|
|
result = subprocess.run([
|
|
|
|
'mount',
|
|
|
|
'-o',
|
|
|
|
'loop',
|
|
|
|
path,
|
|
|
|
rootfs_mount,
|
|
|
|
])
|
2021-08-05 20:26:48 +02:00
|
|
|
if result.returncode != 0:
|
|
|
|
logging.fatal(f'Failed to loop mount {path} to {rootfs_mount}')
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
return rootfs_mount
|
|
|
|
|
|
|
|
|
|
|
|
@click.group(name='image')
|
|
|
|
def cmd_image():
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
@click.command(name='device')
|
|
|
|
@verbose_option
|
|
|
|
@click.argument('device')
|
|
|
|
def cmd_device(verbose, device):
|
|
|
|
setup_logging(verbose)
|
|
|
|
|
|
|
|
for key in devices.keys():
|
|
|
|
if '-'.join(key.split('-')[1:]) == device:
|
|
|
|
device = key
|
|
|
|
break
|
|
|
|
|
|
|
|
if device not in devices:
|
2021-08-08 18:32:42 +02:00
|
|
|
logging.fatal(f'Unknown device {device}. Pick one from:\n{", ".join(devices.keys())}')
|
2021-08-05 20:26:48 +02:00
|
|
|
exit(1)
|
|
|
|
|
|
|
|
logging.info(f'Setting device to {device}')
|
|
|
|
|
|
|
|
with open('.device', 'w') as file:
|
|
|
|
file.write(device)
|
|
|
|
|
|
|
|
|
|
|
|
@click.command(name='flavour')
|
|
|
|
@verbose_option
|
|
|
|
@click.argument('flavour')
|
|
|
|
def cmd_flavour(verbose, flavour):
|
|
|
|
setup_logging(verbose)
|
|
|
|
|
|
|
|
if flavour not in flavours:
|
2021-08-08 18:32:42 +02:00
|
|
|
logging.fatal(f'Unknown flavour {flavour}. Pick one from:\n{", ".join(flavours.keys())}')
|
2021-08-05 20:26:48 +02:00
|
|
|
exit(1)
|
|
|
|
|
|
|
|
logging.info(f'Setting flavour to {flavour}')
|
|
|
|
|
|
|
|
with open('.flavour', 'w') as file:
|
|
|
|
file.write(flavour)
|
|
|
|
|
|
|
|
|
|
|
|
@click.command(name='build')
|
|
|
|
@verbose_option
|
|
|
|
def cmd_build(verbose):
|
|
|
|
setup_logging(verbose)
|
|
|
|
|
|
|
|
device, flavour = get_device_and_flavour()
|
|
|
|
image_name = get_image_name(device, flavour)
|
|
|
|
|
|
|
|
if not os.path.exists(image_name):
|
2021-08-08 18:32:42 +02:00
|
|
|
result = subprocess.run([
|
|
|
|
'fallocate',
|
|
|
|
'-l',
|
|
|
|
'4G',
|
|
|
|
image_name,
|
|
|
|
])
|
2021-08-05 20:26:48 +02:00
|
|
|
if result.returncode != 0:
|
|
|
|
logging.fatal(f'Failed to allocate {image_name}')
|
|
|
|
exit(1)
|
|
|
|
|
2021-08-08 18:32:42 +02:00
|
|
|
result = subprocess.run([
|
|
|
|
'mkfs.ext4',
|
|
|
|
'-L',
|
|
|
|
'kupfer',
|
|
|
|
image_name,
|
|
|
|
])
|
2021-08-05 20:26:48 +02:00
|
|
|
if result.returncode != 0:
|
|
|
|
logging.fatal(f'Failed to create ext4 filesystem on {image_name}')
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
rootfs_mount = mount_rootfs_image(image_name)
|
|
|
|
|
2021-08-14 11:55:54 +02:00
|
|
|
extra_repos = {
|
|
|
|
'main': {
|
|
|
|
'Server': 'https://gitlab.com/kupfer/packages/prebuilts/-/raw/main/$repo',
|
|
|
|
},
|
|
|
|
'device': {
|
|
|
|
'Server': 'https://gitlab.com/kupfer/packages/prebuilts/-/raw/main/$repo',
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if os.path.exists('/prebuilts'):
|
|
|
|
extra_repos = {
|
2021-08-08 18:32:42 +02:00
|
|
|
'main': {
|
2021-08-14 11:55:54 +02:00
|
|
|
'Server': 'file:///prebuilts/$repo',
|
2021-08-08 18:32:42 +02:00
|
|
|
},
|
|
|
|
'device': {
|
2021-08-14 11:55:54 +02:00
|
|
|
'Server': 'file:///prebuilts/$repo',
|
2021-08-08 18:32:42 +02:00
|
|
|
},
|
2021-08-14 11:55:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
create_chroot(
|
|
|
|
rootfs_mount,
|
|
|
|
packages=(['base', 'base-kupfer'] + devices[device] + flavours[flavour]),
|
|
|
|
pacman_conf='/app/local/etc/pacman.conf',
|
|
|
|
extra_repos=extra_repos,
|
2021-08-08 18:32:42 +02:00
|
|
|
)
|
2021-08-08 18:18:36 +02:00
|
|
|
create_chroot_user(rootfs_mount)
|
2021-08-05 20:26:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
This doesn't work, because the mount isn't passed through to the real host
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
@click.command(name='inspect')
|
|
|
|
@verbose_option
|
|
|
|
def cmd_inspect(verbose):
|
|
|
|
setup_logging(verbose)
|
|
|
|
|
|
|
|
device, flavour = get_device_and_flavour()
|
|
|
|
image_name = get_image_name(device, flavour)
|
|
|
|
|
|
|
|
rootfs_mount = mount_rootfs_image(image_name)
|
|
|
|
|
|
|
|
logging.info(f'Inspect the rootfs image at {rootfs_mount}')
|
|
|
|
|
|
|
|
signal.pause()
|
|
|
|
"""
|
|
|
|
|
|
|
|
cmd_image.add_command(cmd_device)
|
|
|
|
cmd_image.add_command(cmd_flavour)
|
|
|
|
cmd_image.add_command(cmd_build)
|
|
|
|
# cmd_image.add_command(cmd_inspect)
|