added ESP command line option
This commit is contained in:
parent
126e35a91e
commit
0e9d9f4727
32
README.md
32
README.md
@ -27,7 +27,7 @@ The following variables will be used throughout this description:
|
||||
|
||||
`version` - new kernel's version string
|
||||
|
||||
### <p>configure<span style="float:right">`ekernel-configure`</span></p>
|
||||
### `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
|
||||
```
|
||||
|
||||
### <p>build<span style="float:right">`ekernel-build`</span></p>
|
||||
### `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
|
||||
```
|
||||
|
||||
### <p>install<span style="float:right">`ekernel-install`</span></p>
|
||||
### `ekernel-install`
|
||||
|
||||
Update symlink ``/usr/src/linux`` to the new source directory.
|
||||
|
||||
@ -88,18 +88,7 @@ Rebuild external modules.
|
||||
emerge @module-rebuild
|
||||
```
|
||||
|
||||
### <p>commit<span style="float:right">`ekernel-commit`</span></p>
|
||||
|
||||
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.
|
||||
|
||||
### <p>clean<span style="float:right">`ekernel-clean`</span></p>
|
||||
### `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
|
||||
|
||||
|
122
ekernel.py
122
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="<src>",
|
||||
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="<src>",
|
||||
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 <esp>``
|
||||
EFI bootloader directory (default: ``/boot/EFI/Gentoo``)
|
||||
|
||||
``-s <src>``
|
||||
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="<esp>",
|
||||
dest="esp",
|
||||
type=pathlib.Path,
|
||||
help="EFI bootloader directory (default: /boot/EFI/Gentoo)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
metavar="<src>",
|
||||
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 <esp>``
|
||||
EFI bootloader directory (default: ``/boot/EFI/Gentoo``)
|
||||
|
||||
``-k <num>``
|
||||
keep the previous ``<num>`` kernels (default: 1)
|
||||
|
||||
@ -452,6 +467,14 @@ def clean (argv):
|
||||
description="Remove unused kernel leftovers.",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
metavar="<esp>",
|
||||
dest="esp",
|
||||
type=pathlib.Path,
|
||||
default=Kernel.esp,
|
||||
help="EFI bootloader directory (default: /boot/EFI/Gentoo)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-k",
|
||||
metavar="<keep>",
|
||||
@ -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="<jobs>",
|
||||
dest="jobs",
|
||||
type=int,
|
||||
default=int(jobs),
|
||||
help=f"number of parallel make jobs (default: {jobs})"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
metavar="<esp>",
|
||||
dest="esp",
|
||||
type=pathlib.Path,
|
||||
help="EFI bootloader directory (default: /boot/EFI/Gentoo)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
metavar="<src>",
|
||||
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="<keep>",
|
||||
dest="keep",
|
||||
type=int,
|
||||
default=1,
|
||||
help="keep the previous <num> bootable kernels (default: 1)"
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -763,7 +791,6 @@ def update (argv):
|
||||
metavar="<msg>",
|
||||
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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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")
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user