diff --git a/README.md b/README.md
index 579d525..9039ac4 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ The following variables will be used throughout this description:
`version` - new kernel's version string
-###
configure`ekernel-configure`
+### `ekernel-configure`
Runs `make menuconfig` if the current config file is missing, or no other kernel is installed
@@ -58,7 +58,7 @@ cd ${new}
make oldconfig || exit
```
-### build`ekernel-build`
+### `ekernel-build`
Build and install modules, using the given number of jobs.
@@ -66,7 +66,7 @@ Build and install modules, using the given number of jobs.
make -j ${jobs} && make modules_install
```
-### install`ekernel-install`
+### `ekernel-install`
Update symlink ``/usr/src/linux`` to the new source directory.
@@ -88,18 +88,7 @@ Rebuild external modules.
emerge @module-rebuild
```
-### commit`ekernel-commit`
-
-Commit the new kernel config with a detailed commit message.
-
-```sh
-git add -f /usr/src/linux/.config
-git commit -S -m "${msg}"
-```
-
-The message will not only contain the version change, but also details about the newly added or removed options.
-
-### clean`ekernel-clean`
+### `ekernel-clean`
Remove unused kernel source directories, modules and boot images.
@@ -113,9 +102,20 @@ rm -rf $(ls -1 ${esp} | sed -e '/${old}/d' -e '/${new}/d' -e '/bootx64/d')
The default is to keep the previous kernel version in case something goes
horribly wrong.
+### `ekernel-commit`
+
+Commit the new kernel config with a detailed commit message.
+
+```sh
+git add -f /usr/src/linux/.config
+git commit -S -m "${msg}"
+```
+
+The message will not only contain the version change, but also details about the newly added or removed options.
+
## Installation
-TODO: add ebuild `app-admin/ekernel`
+You may use the ebuild `app-admin/ekernel` from my [personal repository](https://github.com/phlo/phlo-portage).
## Requirements
diff --git a/ekernel.py b/ekernel.py
index 60e1d0d..d04c7e8 100644
--- a/ekernel.py
+++ b/ekernel.py
@@ -41,15 +41,12 @@ class Kernel:
# kernel source symlink
linux = src / "linux"
- # EFI system partition
- esp = pathlib.Path("/boot/EFI/Gentoo")
-
- # boot image
- bootx64 = esp / "bootx64.efi"
-
# module directory
modules = pathlib.Path("/lib/modules")
+ # EFI system partition
+ esp = pathlib.Path("/boot/EFI/Gentoo")
+
def __init__ (self, src):
"""Construct a Kernel based on a given source path."""
self.src = pathlib.Path(src)
@@ -61,6 +58,7 @@ class Kernel:
raise ValueError(f"illegal source: {src}") from e
self.config = self.src / ".config"
self.bzImage = self.src / "arch/x86_64/boot/bzImage"
+ self.bootx64 = self.esp / "bootx64.efi"
self.efi = self.esp / f"gentoo-{self.version.base_version}.efi"
self.modules = self.modules / f"{self.version.base_version}-gentoo"
@@ -76,8 +74,8 @@ class Kernel:
f"* src = {self.src}\n"
f"* config = {self.config}\n"
f"* bzImage = {self.bzImage}\n"
- f"* efi = {self.efi}\n"
f"* modules = {self.modules}\n"
+ f"* efi = {self.efi}\n"
)
@classmethod
@@ -211,9 +209,9 @@ def configure (argv):
parser.add_argument(
"-s",
metavar="",
- dest="kernel",
- type=Kernel,
- default=Kernel.latest(),
+ dest="src",
+ type=pathlib.Path,
+ default=Kernel.latest().src,
help="kernel source directory (default: latest)"
)
parser.add_argument(
@@ -223,8 +221,9 @@ def configure (argv):
help="be quiet"
)
args = parser.parse_args(argv)
+ kernel = Kernel(args.src)
out.quiet = args.quiet
- newoptions = args.kernel.src / ".newoptions"
+ newoptions = kernel.src / ".newoptions"
# check if current kernel config exists
try:
@@ -233,18 +232,18 @@ def configure (argv):
oldconfig = Kernel.esp / "FILENOTFOUND"
# change to source directory
- os.chdir(args.kernel.src)
+ os.chdir(kernel.src)
# delete config - reconfigure
- if args.delete and args.kernel.config.exists():
- out.einfo(f"deleting {args.kernel.config}")
- args.kernel.config.unlink()
+ if args.delete and kernel.config.exists():
+ out.einfo(f"deleting {kernel.config}")
+ kernel.config.unlink()
# make oldconfig
- if not args.kernel.config.exists() and oldconfig.exists():
+ if not kernel.config.exists() and oldconfig.exists():
# copy oldconfig
out.einfo(f"copying {out.hilite(oldconfig)}")
- shutil.copy(oldconfig, args.kernel.config)
+ shutil.copy(oldconfig, kernel.config)
# store newly added options
out.einfo(f"running {out.hilite('make listnewconfig')}")
make = subprocess.run(["make", "listnewconfig"], capture_output=True)
@@ -313,9 +312,9 @@ def build (argv):
parser.add_argument(
"-s",
metavar="",
- dest="kernel",
- type=Kernel,
- default=Kernel.latest(),
+ dest="src",
+ type=pathlib.Path,
+ default=Kernel.latest().src,
help="kernel source directory (default: latest)"
)
parser.add_argument(
@@ -325,17 +324,18 @@ def build (argv):
help="be quiet"
)
args = parser.parse_args(argv)
+ kernel = Kernel(args.src)
out.quiet = args.quiet
# check if config exists
- if not args.kernel.config.exists():
- raise FileNotFoundError(f"missing config: {args.kernel.config}")
+ if not kernel.config.exists():
+ raise FileNotFoundError(f"missing config: {kernel.config}")
# change directory
- os.chdir(args.kernel.src)
+ os.chdir(kernel.src)
# build and install modules
- out.einfo(f"building {out.hilite(args.kernel.src.name)}")
+ out.einfo(f"building {out.hilite(kernel.src.name)}")
subprocess.run(["make", "-j", str(args.jobs)], check=True)
out.einfo("installing modules")
subprocess.run(["make", "modules_install"], check=True)
@@ -353,6 +353,9 @@ def install (argv):
Command Line Arguments
----------------------
+ ``-e ``
+ EFI bootloader directory (default: ``/boot/EFI/Gentoo``)
+
``-s ``
kernel source directory (default: latest)
@@ -379,12 +382,19 @@ def install (argv):
description="Install a kernel.",
formatter_class=argparse.RawDescriptionHelpFormatter
)
+ parser.add_argument(
+ "-e",
+ metavar="",
+ dest="esp",
+ type=pathlib.Path,
+ help="EFI bootloader directory (default: /boot/EFI/Gentoo)"
+ )
parser.add_argument(
"-s",
metavar="",
- dest="kernel",
- type=Kernel,
- default=Kernel.latest(),
+ dest="src",
+ type=pathlib.Path,
+ default=Kernel.latest().src,
help="kernel source directory (default: latest)"
)
parser.add_argument(
@@ -394,29 +404,31 @@ def install (argv):
help="be quiet"
)
args = parser.parse_args(argv)
+ if args.esp: Kernel.esp = args.esp
+ kernel = Kernel(args.src)
out.quiet = args.quiet
# check if bzImage exists
- if not args.kernel.bzImage.exists():
- raise FileNotFoundError(f"missing bzImage {args.kernel.bzImage}")
+ if not kernel.bzImage.exists():
+ raise FileNotFoundError(f"missing bzImage {kernel.bzImage}")
# update symlink to the new source directory
out.einfo(
"updating symlink "
- f"{out.hilite(args.kernel.linux)} → {out.hilite(args.kernel.src)}"
+ f"{out.hilite(kernel.linux)} → {out.hilite(kernel.src)}"
)
subprocess.run(
- ["eselect", "kernel", "set", args.kernel.src.name],
+ ["eselect", "kernel", "set", kernel.src.name],
check=True
)
# copy boot image
- out.einfo(f"creating boot image {out.hilite(args.kernel.bootx64)}")
- shutil.copy(args.kernel.bzImage, args.kernel.bootx64)
+ out.einfo(f"creating boot image {out.hilite(kernel.bootx64)}")
+ shutil.copy(kernel.bzImage, kernel.bootx64)
# create backup
- out.einfo(f"creating backup image {out.hilite(args.kernel.efi)}")
- shutil.copy(args.kernel.bzImage, args.kernel.efi)
+ out.einfo(f"creating backup image {out.hilite(kernel.efi)}")
+ shutil.copy(kernel.bzImage, kernel.efi)
# rebuild external modules
out.einfo(f"rebuilding external kernel modules")
@@ -437,6 +449,9 @@ def clean (argv):
Command Line Arguments
----------------------
+ ``-e ``
+ EFI bootloader directory (default: ``/boot/EFI/Gentoo``)
+
``-k ``
keep the previous ```` kernels (default: 1)
@@ -452,6 +467,14 @@ def clean (argv):
description="Remove unused kernel leftovers.",
formatter_class=argparse.RawDescriptionHelpFormatter
)
+ parser.add_argument(
+ "-e",
+ metavar="",
+ dest="esp",
+ type=pathlib.Path,
+ default=Kernel.esp,
+ help="EFI bootloader directory (default: /boot/EFI/Gentoo)"
+ )
parser.add_argument(
"-k",
metavar="",
@@ -473,6 +496,7 @@ def clean (argv):
help="be quiet"
)
args = parser.parse_args(argv)
+ if args.esp: Kernel.esp = args.esp
out.quiet = args.quiet
if args.keep < 0:
raise ValueError("invalid int value: must be greater equal zero")
@@ -739,15 +763,20 @@ def update (argv):
metavar="",
dest="jobs",
type=int,
- default=int(jobs),
help=f"number of parallel make jobs (default: {jobs})"
)
+ parser.add_argument(
+ "-e",
+ metavar="",
+ dest="esp",
+ type=pathlib.Path,
+ help="EFI bootloader directory (default: /boot/EFI/Gentoo)"
+ )
parser.add_argument(
"-s",
metavar="",
- dest="kernel",
- type=Kernel,
- default=Kernel.latest(),
+ dest="src",
+ type=pathlib.Path,
help="kernel source directory (default: latest)"
)
parser.add_argument(
@@ -755,7 +784,6 @@ def update (argv):
metavar="",
dest="keep",
type=int,
- default=1,
help="keep the previous bootable kernels (default: 1)"
)
parser.add_argument(
@@ -763,7 +791,6 @@ def update (argv):
metavar="",
dest="msg",
type=str,
- default="",
help="additional information for the commit message"
)
parser.add_argument(
@@ -773,14 +800,15 @@ def update (argv):
help="be quiet"
)
args = parser.parse_args(argv)
- args.jobs = ["-j", str(args.jobs)]
- args.src = ["-s", str(args.kernel.src)]
- args.keep = ["-k", str(args.keep)]
- args.msg = ["-m", args.msg]
+ args.jobs = ["-j", str(args.jobs)] if args.jobs else []
+ args.esp = ["-e", str(args.esp)] if args.esp else []
+ args.src = ["-s", str(args.src)] if args.src else []
+ args.keep = ["-k", str(args.keep)] if args.keep is not None else []
+ args.msg = ["-m", args.msg] if args.msg else []
args.quiet = ["-q"] if args.quiet else []
configure(args.quiet + args.src)
build(args.quiet + args.jobs + args.src)
- install(args.quiet + args.src)
- clean(args.quiet + args.keep)
+ install(args.quiet + args.esp + args.src)
+ clean(args.quiet + args.esp + args.keep)
commit(args.quiet + args.msg)
diff --git a/tests/data/kernel.py b/tests/data/kernel.py
index 622d549..a27c5d6 100644
--- a/tests/data/kernel.py
+++ b/tests/data/kernel.py
@@ -24,13 +24,6 @@ esp = root / "boot/EFI/Gentoo"
# boot image
bootx64 = esp / "bootx64.efi"
-# change Kernel class' root directory
-Kernel.src = src
-Kernel.linux = linux
-Kernel.modules = modules
-Kernel.esp = esp
-Kernel.bootx64 = bootx64
-
# list of installed kernels
kernels = []
sources = [
@@ -80,6 +73,13 @@ def setup ():
for p in root.glob("*"):
shutil.rmtree(p)
+ # change Kernel class' root directory
+ Kernel.src = src
+ Kernel.linux = linux
+ Kernel.modules = modules
+ Kernel.esp = esp
+ Kernel.bootx64 = bootx64
+
# create EFI system partition
esp.mkdir(parents=True)
diff --git a/tests/test_clean.py b/tests/test_clean.py
index d4bceb7..fd12899 100644
--- a/tests/test_clean.py
+++ b/tests/test_clean.py
@@ -93,6 +93,19 @@ class Tests (unittest.TestCase):
self.assertEqual(run("-q", "-k", "10"), 0)
self.check_clean(10)
+ def test_clean_esp (self):
+ esp = data.root / "boot/EFI/linux"
+ esp.mkdir(parents=True)
+ for k in data.kernels:
+ efi = esp / k.efi.name
+ if k.efi.exists():
+ efi.touch()
+ k.efi.unlink()
+ k.efi = efi
+ data.esp.rmdir()
+ self.assertEqual(run("-q", "-e", str(esp)), 0)
+ self.check_clean()
+
@colorless
@capture_stdout
def test_clean_dry_run (self):
diff --git a/tests/test_install.py b/tests/test_install.py
index 2786440..6dea38c 100644
--- a/tests/test_install.py
+++ b/tests/test_install.py
@@ -24,6 +24,8 @@ class Tests (unittest.TestCase):
self.interceptor.start()
# setup test environment
data.setup()
+ self.kernel = Kernel.latest()
+ self.kernel.bzImage.touch()
def tearDown (self):
# stop interceptor
@@ -55,19 +57,25 @@ class Tests (unittest.TestCase):
self.assertTrue(self.kernel.efi.exists())
def test_install (self):
- self.kernel = Kernel.latest()
- self.kernel.bzImage.touch()
self.assertEqual(run("-q"), 0)
self.check_install()
- def test_install_version (self):
+ def test_install_esp (self):
+ esp = data.root / "boot/EFI/linux"
+ esp.mkdir(parents=True)
+ self.kernel.efi = esp / self.kernel.efi.name
+ self.kernel.bootx64 = esp / self.kernel.bootx64.name
+ self.assertEqual(run("-q", "-e", str(esp)), 0)
+ self.check_install()
+
+ def test_install_source (self):
self.kernel = Kernel.current()
self.assertEqual(run("-q", "-s", str(data.current)), 0)
self.check_install()
@capture_stderr
def test_install_missing_bzImage (self):
- self.kernel = Kernel.latest()
+ self.kernel.bzImage.unlink()
with self.assertRaises(SystemExit):
self.assertEqual(run("-s", str(data.latest)), 1)
self.assertRegex(sys.stderr.getvalue(), r"missing.*bzImage")
diff --git a/tests/test_update.py b/tests/test_update.py
index 9c39876..f438549 100644
--- a/tests/test_update.py
+++ b/tests/test_update.py
@@ -81,6 +81,21 @@ class Tests (unittest.TestCase):
self.assertEqual(run("-q", "-j", "8"), 0)
self.check_update()
+ def test_update_esp (self):
+ esp = data.root / "boot/EFI/linux"
+ esp.mkdir(parents=True)
+ for k in data.kernels:
+ efi = esp / k.efi.name
+ if k.efi.exists():
+ efi.touch()
+ k.efi.unlink()
+ k.efi = efi
+ data.esp.rmdir()
+ self.latest.efi = esp / self.latest.efi.name
+ self.latest.bootx64 = esp / self.latest.bootx64.name
+ self.assertEqual(run("-q", "-e", str(esp)), 0)
+ self.check_update()
+
def test_update_source (self):
self.assertEqual(run("-q", "-s", str(data.latest)), 0)
self.check_update()
@@ -90,6 +105,8 @@ class Tests (unittest.TestCase):
self.assertEqual(run("-q", "-k", "0"), 0)
self.check_update()
self.assertFalse(current.src.exists())
+ self.assertFalse(current.modules.exists())
+ self.assertFalse(current.efi.exists())
@capture_stdout
def test_update_message (self):