2016-07-24 17:08:27 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
"""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()
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_latest_available_kernel():
|
2018-10-27 20:15:59 +02:00
|
|
|
kernel = os.environ["KERNEL"]
|
|
|
|
package_name = "sys-kernel/{}".format(kernel)
|
2016-07-24 17:08:27 +02:00
|
|
|
popen = subprocess.Popen(
|
2018-10-27 20:15:59 +02:00
|
|
|
["portageq", "best_visible", "/", package_name], stdout=subprocess.PIPE
|
2016-07-24 17:08:27 +02:00
|
|
|
)
|
|
|
|
cpv = popen.stdout.read().decode().strip()
|
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
return cpv.rpartition("-")[2]
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_current_kernel():
|
|
|
|
"""what kernel does /boot/vmlinuz point to"""
|
2018-10-27 20:15:59 +02:00
|
|
|
vmlinuz = "/boot/vmlinuz"
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
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")
|
2016-07-24 17:08:27 +02:00
|
|
|
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]
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
return version
|
|
|
|
|
|
|
|
|
|
|
|
def install_kernel_package():
|
2018-10-27 20:15:59 +02:00
|
|
|
kernel = os.environ["KERNEL"]
|
|
|
|
package_name = "sys-kernel/{}".format(kernel)
|
|
|
|
cmd = EMERGE + USEPKG + ["--oneshot", "--noreplace", package_name]
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
subprocess.check_call(cmd)
|
|
|
|
|
|
|
|
|
|
|
|
def copy_kernel_config():
|
2018-10-27 20:15:59 +02:00
|
|
|
filename = "/root/kernel.config"
|
2016-07-24 17:08:27 +02:00
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
shutil.copy(filename, "/usr/src/linux/.config")
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
def build_kernel():
|
2018-10-27 20:15:59 +02:00
|
|
|
makeopts = os.environ.get("MAKEOPTS", "")
|
2016-07-24 17:08:27 +02:00
|
|
|
|
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])
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
def remove_old_kernels():
|
2018-10-27 20:15:59 +02:00
|
|
|
kernel_files = ["vmlinuz-", "System.map-", "config-"]
|
2016-07-24 17:08:27 +02:00
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
for filename in os.listdir("/boot"):
|
2016-07-24 17:08:27 +02:00
|
|
|
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)
|
2016-07-24 17:08:27 +02:00
|
|
|
os.unlink(path)
|
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
if os.path.exists("/boot/vmlinuz"):
|
|
|
|
os.unlink("/boot/vmlinuz")
|
2016-07-24 17:08:27 +02:00
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
shutil.rmtree("/lib/modules", ignore_errors=True)
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
def install_kernel():
|
2018-10-27 20:15:59 +02:00
|
|
|
makeopts = os.environ.get("MAKEOPTS", "")
|
2016-07-24 17:08:27 +02:00
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
subprocess.check_call(
|
2018-12-02 03:08:02 +01:00
|
|
|
[
|
|
|
|
"make",
|
|
|
|
"-C",
|
|
|
|
"/usr/src/linux",
|
|
|
|
"MAKEOPTS=" + makeopts,
|
|
|
|
"install",
|
|
|
|
"modules_install",
|
|
|
|
]
|
2018-10-27 20:15:59 +02:00
|
|
|
)
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
# 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.
|
2018-12-02 03:08:02 +01:00
|
|
|
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")
|
2016-07-24 17:08:27 +02:00
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
def uninstall_kernel_package():
|
2018-10-27 20:15:59 +02:00
|
|
|
subprocess.check_call(["make", "-C", "/usr/src/linux", "distclean"])
|
2016-07-24 17:08:27 +02:00
|
|
|
|
2018-10-27 20:15:59 +02:00
|
|
|
subprocess.check_call(EMERGE + USEPKG + ["--depclean", "--with-bdeps=n"])
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
|
2016-08-07 14:46:45 +02:00
|
|
|
def backup_kernel_config():
|
2018-10-27 20:15:59 +02:00
|
|
|
shutil.copy("/usr/src/linux/.config", "/root/kernel.config")
|
2016-08-07 14:46:45 +02:00
|
|
|
|
|
|
|
|
2016-07-24 17:08:27 +02:00
|
|
|
def main():
|
|
|
|
latest_kernel = get_latest_available_kernel()
|
|
|
|
current_kernel = get_current_kernel()
|
|
|
|
|
|
|
|
if current_kernel == latest_kernel:
|
|
|
|
return
|
|
|
|
|
|
|
|
install_kernel_package()
|
|
|
|
copy_kernel_config()
|
|
|
|
build_kernel()
|
|
|
|
remove_old_kernels()
|
|
|
|
install_kernel()
|
2016-08-07 14:46:45 +02:00
|
|
|
backup_kernel_config()
|
2016-07-24 17:08:27 +02:00
|
|
|
|
|
|
|
uninstall_kernel_package()
|
|
|
|
|
|
|
|
|
|
|
|
main()
|