modernize, switch to dracut

Signed-off-by: Martin Matous <m@matous.dev>
This commit is contained in:
Martin Matous 2023-09-24 02:38:51 +02:00
parent 5f17d90c7b
commit acd336e659
Signed by: mmatous
GPG key ID: 8BED4CD352953224
2 changed files with 22 additions and 79 deletions

View file

@ -1,43 +1,19 @@
#!/usr/bin/env python
import argparse
import magic
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Any, Dict, List, Tuple
BOOT_FILES = {
'config': Path('config-gentoo'),
'initramfs': Path('initramfs-gentoo.img'),
'kernel': Path('vmlinuz-gentoo'),
'system_map': Path('System.map-gentoo'),
}
SRC_DIR = Path('/usr/src')
BOOT_DIR = Path('/boot')
def backup_kernel(boot_dir: Path, files: Dict[str, Path]) -> None:
for f in files.values():
src = boot_dir/f
dst = boot_dir/(f.name + '.old')
print(f'Backing-up {src} to {dst}')
shutil.copy2(src, dst)
def rollback_impl(boot_dir: Path, files: Dict[str, Path]) -> None:
for f in files.values():
src = boot_dir/(f.name + '.old')
dst = boot_dir/f
print(f'Restoring {src} to {dst}')
shutil.copy2(src, dst)
def update_config(old_dir: Path, new_dir: Path, make_cmd: List[str]) -> None:
def update_config(old_dir: Path, new_dir: Path, make_cmd: list[str]) -> None:
if old_dir == new_dir:
return
old_config = old_dir/'.config'
@ -55,7 +31,7 @@ def update_config(old_dir: Path, new_dir: Path, make_cmd: List[str]) -> None:
print(f'Setting symlink to {new_dir}')
subprocess.run(['eselect', 'kernel', 'set', new_dir.name])
print(f'Migrating config options')
print('Migrating config options')
migrate = make_cmd + ['-C', new_dir.as_posix(), 'oldconfig']
subprocess.run(migrate)
menuconfig = make_cmd + ['-C', new_dir.as_posix(), 'menuconfig']
@ -70,33 +46,26 @@ def update_config(old_dir: Path, new_dir: Path, make_cmd: List[str]) -> None:
print("unrecognized option {}", response)
def compile_kernel(new_dir: Path, make_cmd: List[str]) -> None:
def compile_kernel(new_dir: Path, make_cmd: list[str]) -> None:
cc = make_cmd + ['-C', new_dir.as_posix()]
subprocess.run(cc)
def install_kernel(kernel_dir: Path, boot_dir: Path, boot_files: Dict[str, Path], make_cmd: List[str]) -> None:
make_files = {
'config': Path('.config'),
'system_map': Path('System.map'),
'kernel': Path('arch/x86/boot/bzImage')
}
config = (kernel_dir/make_files['config']).as_posix()
# subprocess.run(make_cmd.extend(['-C', kernel_dir, 'install'])) # this would create unwanted entries
common_keys = make_files.keys() & boot_files.keys()
for key in common_keys:
src = kernel_dir/make_files[key]
dst = boot_dir/boot_files[key]
print(f'Installing {src} to {dst}')
shutil.copy2(src, dst)
def install_kernel(kernel_dir: Path, make_cmd: list[str], kver: str) -> None:
install_modules = make_cmd + ['-C', kernel_dir.as_posix(), 'modules_install']
subprocess.run(install_modules)
genkernel = ['genkernel', f'--kernel-config={config}', '--microcode', 'initramfs']
subprocess.run(genkernel)
kver = kver[6:]
# assumes proper dracut config in /etc
dracut = ['dracut', f'--kver={kver}', '--force', '--no-machineid']
res = subprocess.run(dracut)
print(res)
return
# todo: sign uki
uki_dir = res.split('')
sign_uki = ['sbctl', 'bundle', '--save', '']
subprocess.run(sign_uki)
def linux_folder(src_dir: Path, version: str) -> Path:
revision = ''
@ -107,54 +76,31 @@ def linux_folder(src_dir: Path, version: str) -> Path:
return (src_dir / (f'linux-{version}-gentoo{revision}'))
def module_check(boot_dir: Path, boot_files: Dict[str, Path]) -> Tuple[bool, Path]:
kernel_name = boot_files['kernel'].name + '.old'
old_kernel: Path = boot_dir/kernel_name
magic_list = magic.from_file(old_kernel).split()
version = Path(magic_list[magic_list.index('version') + 1])
modules = Path('/lib/modules')/version
if not modules.exists():
return (False, version)
return (True, version)
def rollback_kernel(boot_dir: Path, boot_files: Dict[str, Path], _args: Any) -> None:
check = module_check(boot_dir, boot_files)
if not check[0]:
err = f'Module directory not found for {check[1]}.\nRefusing to proceed.'
raise RuntimeError(err)
rollback_impl(boot_dir, boot_files)
def update_kernel(boot_dir: Path, boot_files: Dict[str, Path], args: Any) -> None:
def update_kernel(boot_dir: Path, args: argparse.Namespace) -> None:
old_dir = linux_folder(SRC_DIR, args.old_version)
new_dir = linux_folder(SRC_DIR, args.new_version)
new_version = new_dir.name
make_cmd = ['make', f'-j{len(os.sched_getaffinity(0))}']
clang_env = ['CC=clang', 'LD=ld.lld', 'LLVM=1', 'LLVM_IAS=1']
# https://docs.kernel.org/kbuild/llvm.html
if args.llvm:
make_cmd.extend(clang_env)
make_cmd.extend(['LLVM=1'])
none_selected = not (args.backup or args.config or args.compile or args.install or args.rollback)
if none_selected:
backup_kernel(BOOT_DIR, BOOT_FILES)
update_config(old_dir, new_dir, make_cmd)
compile_kernel(new_dir, make_cmd)
install_kernel(new_dir, BOOT_DIR, BOOT_FILES, make_cmd)
if args.backup:
backup_kernel(BOOT_DIR, BOOT_FILES)
install_kernel(new_dir, make_cmd, new_version)
if args.config:
update_config(old_dir, new_dir, make_cmd)
if args.compile:
compile_kernel(new_dir, make_cmd)
if args.install:
install_kernel(new_dir, BOOT_DIR, BOOT_FILES, make_cmd)
install_kernel(new_dir, make_cmd, new_version)
def main() -> None:
parser = argparse.ArgumentParser(description='Convenience for manual kernel updates')
subparsers = parser.add_subparsers()
rollback = subparsers.add_parser('rollback')
rollback.set_defaults(func=rollback_kernel)
update = subparsers.add_parser('update',
usage=f'{sys.argv[0]} update 5.15.12 5.16.3',
)
@ -181,7 +127,7 @@ def main() -> None:
update.set_defaults(func=update_kernel)
args = parser.parse_args()
args.func(BOOT_DIR, BOOT_FILES, args)
args.func(BOOT_DIR, args)
if __name__ == "__main__":