virtual-appliance/scripts/build-kernel

133 lines
3.5 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python3
"""Build the latest kernel but only if need be"""
import os
import shutil
import subprocess
2018-10-27 20:15:59 +02:00
EMERGE = os.environ["EMERGE"].split()
USEPKG = os.environ["USEPKG"].split()
def get_latest_available_kernel():
2018-10-27 20:15:59 +02:00
kernel = os.environ["KERNEL"]
package_name = "sys-kernel/{}".format(kernel)
popen = subprocess.Popen(
2018-10-27 20:15:59 +02:00
["portageq", "best_visible", "/", package_name], stdout=subprocess.PIPE
)
cpv = popen.stdout.read().decode().strip()
2018-10-27 20:15:59 +02:00
return cpv.rpartition("-")[2]
def get_current_kernel():
"""what kernel does /boot/vmlinuz point to"""
2018-10-27 20:15:59 +02:00
vmlinuz = "/boot/vmlinuz"
if not os.path.islink(vmlinuz):
return None
filename = os.path.basename(os.path.realpath(vmlinuz))
2018-10-27 20:15:59 +02:00
assert filename.startswith("vmlinuz")
part_after_vmlinuz = filename[8:]
# may have "-gentoo" or whatever in the name
2018-10-27 20:15:59 +02:00
version = part_after_vmlinuz.rpartition("-")[0]
return version
def install_kernel_package_deps():
2018-10-27 20:15:59 +02:00
kernel = os.environ["KERNEL"]
package_name = "sys-kernel/{}".format(kernel)
cmd = EMERGE + USEPKG + ["--onlydeps", "--oneshot", "--noreplace", package_name]
subprocess.check_call(cmd)
def copy_kernel_config():
2018-10-27 20:15:59 +02:00
filename = "/root/kernel.config"
2018-10-27 20:15:59 +02:00
shutil.copy(filename, "/usr/src/linux/.config")
def build_kernel():
2018-10-27 20:15:59 +02:00
makeopts = os.environ.get("MAKEOPTS", "")
2018-10-27 20:15:59 +02:00
subprocess.check_call(
["make", "-C", "/usr/src/linux", "MAKEOPTS=" + makeopts, "oldconfig"]
)
subprocess.check_call(["make", "-C", "/usr/src/linux", "MAKEOPTS=" + makeopts])
def remove_old_kernels():
2018-10-27 20:15:59 +02:00
kernel_files = ["vmlinuz-", "System.map-", "config-"]
2018-10-27 20:15:59 +02:00
for filename in os.listdir("/boot"):
for kernel_file in kernel_files:
if filename.startswith(kernel_file):
2018-10-27 20:15:59 +02:00
path = os.path.join("/boot", filename)
os.unlink(path)
2018-10-27 20:15:59 +02:00
if os.path.exists("/boot/vmlinuz"):
os.unlink("/boot/vmlinuz")
##shutil.rmtree("/lib/modules", ignore_errors=True)
def install_kernel():
2018-10-27 20:15:59 +02:00
makeopts = os.environ.get("MAKEOPTS", "")
modules_install = False
for line in open("/usr/src/linux/.config"):
if "CONFIG_MODULES=y" in line:
modules_install = True
break
if modules_install:
subprocess.check_call([
'make', '-C', '/usr/src/linux', 'MAKEOPTS=' + makeopts, 'install',
'modules_install'
])
else:
subprocess.check_call([
'make', '-C', '/usr/src/linux', 'MAKEOPTS=' + makeopts, 'install'
])
# create the symlink. /sbin/installkernel claims this is not used on
# "modern" distributions and doesn't create it (unless it already
# exists). I still do this however.
for filename in os.listdir("/boot"):
if filename.startswith("vmlinuz-"):
if os.path.lexists("/boot/vmlinuz"):
os.unlink("/boot/vmlinuz")
os.symlink(filename, "/boot/vmlinuz")
break
def uninstall_kernel_package_deps():
2018-10-27 20:15:59 +02:00
subprocess.check_call(EMERGE + USEPKG + ["--depclean", "--with-bdeps=n"])
def backup_kernel_config():
2018-10-27 20:15:59 +02:00
shutil.copy("/usr/src/linux/.config", "/root/kernel.config")
def main():
latest_kernel = get_latest_available_kernel()
current_kernel = get_current_kernel()
if current_kernel == latest_kernel:
return
install_kernel_package_deps()
##copy_kernel_config()
build_kernel()
remove_old_kernels()
install_kernel()
backup_kernel_config()
uninstall_kernel_package_deps()
main()