public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Michał Górny" <mgorny@gentoo.org>
To: gentoo-dev@lists.gentoo.org
Cc: "Michał Górny" <mgorny@gentoo.org>
Subject: [gentoo-dev] [PATCH v2 1/4] kernel-install.eclass: Install logic for dist-kernels
Date: Sun,  5 Jan 2020 07:27:38 +0100	[thread overview]
Message-ID: <20200105062741.82357-1-mgorny@gentoo.org> (raw)

Introduce a new eclass that contains common logic needed to test
and install distribution kernels.  This is the eclass common both
to kernels built from source and installed from binary packages.

Signed-off-by: Michał Górny <mgorny@gentoo.org>
---
 eclass/kernel-install.eclass | 309 +++++++++++++++++++++++++++++++++++
 1 file changed, 309 insertions(+)
 create mode 100644 eclass/kernel-install.eclass

diff --git a/eclass/kernel-install.eclass b/eclass/kernel-install.eclass
new file mode 100644
index 000000000000..f64e01976a7b
--- /dev/null
+++ b/eclass/kernel-install.eclass
@@ -0,0 +1,309 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: kernel-install.eclass
+# @MAINTAINER:
+# Distribution Kernel Project <dist-kernel@gentoo.org>
+# @AUTHOR:
+# Michał Górny <mgorny@gentoo.org>
+# @SUPPORTED_EAPIS: 7
+# @BLURB: Installation mechanics for Distribution Kernels
+# @DESCRIPTION:
+# This eclass provides the logic needed to test and install different
+# kinds of Distribution Kernel packages, including both kernels built
+# from source and distributed as binaries.  The eclass relies on the
+# ebuild installing a subset of built kernel tree into
+# /usr/src/linux-${PV} containing the kernel image in its standard
+# location and System.map.
+#
+# The eclass exports src_test, pkg_postinst and pkg_postrm.
+# Additionally, the inherited mount-boot eclass exports pkg_pretend.
+# It also stubs out pkg_preinst and pkg_prerm defined by mount-boot.
+
+if [[ ! ${_KERNEL_INSTALL_ECLASS} ]]; then
+
+case "${EAPI:-0}" in
+	0|1|2|3|4|5|6)
+		die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
+		;;
+	7)
+		;;
+	*)
+		die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
+		;;
+esac
+
+inherit mount-boot
+
+TCL_VER=10.1
+SRC_URI+="
+	test? (
+		amd64? (
+			https://dev.gentoo.org/~mgorny/dist/tinycorelinux-${TCL_VER}-amd64.qcow2
+		)
+		x86? (
+				https://dev.gentoo.org/~mgorny/dist/tinycorelinux-${TCL_VER}-x86.qcow2
+		)
+	)"
+
+SLOT="${PV}"
+IUSE="+initramfs test"
+RESTRICT+=" !test? ( test ) test? ( userpriv )"
+
+# install-DEPEND actually
+# note: we need installkernel with initramfs support!
+RDEPEND="
+	|| (
+		sys-kernel/installkernel-gentoo
+		sys-kernel/installkernel-systemd-boot
+	)
+	initramfs? ( >=sys-kernel/dracut-049-r3 )"
+BDEPEND="
+	test? (
+		dev-tcltk/expect
+		sys-kernel/dracut
+		amd64? ( app-emulation/qemu[qemu_softmmu_targets_x86_64] )
+		x86? ( app-emulation/qemu[qemu_softmmu_targets_i386] )
+	)"
+
+# @FUNCTION: kernel-install_build_initramfs
+# @USAGE: <output> <version>
+# @DESCRIPTION:
+# Build an initramfs for the kernel.  <output> specifies the absolute
+# path where initramfs will be created, while <version> specifies
+# the kernel version, used to find modules.
+kernel-install_build_initramfs() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	[[ ${#} -eq 2 ]] || die "${FUNCNAME}: invalid arguments"
+	local output=${1}
+	local version=${2}
+
+	ebegin "Building initramfs via dracut"
+	dracut --force "${output}" "${version}"
+	eend ${?} || die "Building initramfs failed"
+}
+
+# @FUNCTION: kernel-install_get_image_path
+# @DESCRIPTION:
+# Get relative kernel image path specific to the current ${ARCH}.
+kernel-install_get_image_path() {
+	case ${ARCH} in
+		amd64|x86)
+			echo arch/x86/boot/bzImage
+			;;
+		*)
+			die "${FUNCNAME}: unsupported ARCH=${ARCH}"
+			;;
+	esac
+}
+
+# @FUNCTION: kernel-install_install_kernel
+# @USAGE: <version> <image> <system.map>
+# @DESCRIPTION:
+# Install kernel using installkernel tool.  <version> specifies
+# the kernel version, <image> full path to the image, <system.map>
+# full path to System.map.
+kernel-install_install_kernel() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	[[ ${#} -eq 3 ]] || die "${FUNCNAME}: invalid arguments"
+	local version=${1}
+	local image=${2}
+	local map=${3}
+
+	ebegin "Installing the kernel via installkernel"
+	# note: .config is taken relatively to System.map;
+	# initrd relatively to bzImage
+	installkernel "${version}" "${image}" "${map}"
+	eend ${?} || die "Installing the kernel failed"
+}
+
+# @FUNCTION: kernel-install_update_symlink
+# @USAGE: <target> <version>
+# @DESCRIPTION:
+# Update the kernel source symlink at <target> (full path) with a link
+# to <target>-<version> if it's either missing or pointing out to
+# an older version of this package.
+kernel-install_update_symlink() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	[[ ${#} -eq 2 ]] || die "${FUNCNAME}: invalid arguments"
+	local target=${1}
+	local version=${2}
+
+	if [[ ! -e ${target} ]]; then
+		ebegin "Creating ${target} symlink"
+		ln -f -n -s "${target##*/}-${version}" "${target}"
+		eend ${?}
+	else
+		local symlink_target=$(readlink "${target}")
+		local symlink_ver=${symlink_target#${target##*/}-}
+		if [[ ${symlink_target} == ${target##*/}-* && \
+				-z ${symlink_ver//[0-9.]/} ]]
+		then
+			local symlink_pkg=${CATEGORY}/${PN}-${symlink_ver}
+			# if the current target is either being replaced, or still
+			# installed (probably depclean candidate), update the symlink
+			if has "${symlink_ver}" ${REPLACING_VERSIONS} ||
+					has_version -r "~${symlink_pkg}"
+			then
+				ebegin "Updating ${target} symlink"
+				ln -f -n -s "${target##*/}-${version}" "${target}"
+				eend ${?}
+			fi
+		fi
+	fi
+}
+
+# @FUNCTION: kernel-install_get_qemu_arch
+# @DESCRIPTION:
+# Get appropriate qemu suffix for the current ${ARCH}.
+kernel-install_get_qemu_arch() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	case ${ARCH} in
+		amd64)
+			echo x86_64
+			;;
+		x86)
+			echo i386
+			;;
+		*)
+			die "${FUNCNAME}: unsupported ARCH=${ARCH}"
+			;;
+	esac
+}
+
+# @FUNCTION: kernel-install_test
+# @USAGE: <version> <image> <modules>
+# @DESCRIPTION:
+# Test that the kernel can successfully boot a minimal system image
+# in qemu.  <version> is the kernel version, <image> path to the image,
+# <modules> path to module tree.
+kernel-install_src_test() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	[[ ${#} -eq 3 ]] || die "${FUNCNAME}: invalid arguments"
+	local version=${1}
+	local image=${2}
+	local modules=${3}
+
+	local qemu_arch=$(kernel-install_get_qemu_arch)
+
+	dracut \
+		--conf /dev/null \
+		--confdir /dev/null \
+		--no-hostonly \
+		--kmoddir "${modules}" \
+		"${T}/initrd" "${version}" || die
+	# get a read-write copy of the disk image
+	cp "${DISTDIR}/tinycorelinux-${TCL_VER}-${ARCH}.qcow2" \
+		"${T}/fs.qcow2" || die
+
+	cd "${T}" || die
+	cat > run.sh <<-EOF || die
+		#!/bin/sh
+		exec qemu-system-${qemu_arch} \
+			-m 256M \
+			-display none \
+			-no-reboot \
+			-kernel '${image}' \
+			-initrd '${T}/initrd' \
+			-serial mon:stdio \
+			-hda '${T}/fs.qcow2' \
+			-append 'root=/dev/sda console=ttyS0,115200n8'
+	EOF
+	chmod +x run.sh || die
+	# TODO: initramfs does not let core finish starting on some systems,
+	# figure out how to make it better at that
+	expect - <<-EOF || die "Booting kernel failed"
+		set timeout 900
+		spawn ./run.sh
+		expect {
+			"Kernel panic" {
+				send_error "\n* Kernel panic"
+				exit 1
+			}
+			"Entering emergency mode" {
+				send_error "\n* Initramfs failed to start the system"
+				exit 1
+			}
+			"Core 10.1" {
+				send_error "\n* Booted successfully"
+				exit 0
+			}
+			timeout {
+				send_error "\n* Kernel boot timed out"
+				exit 2
+			}
+		}
+	EOF
+}
+
+# @FUNCTION: kernel-install_src_test
+# @DESCRIPTION:
+# Boilerplate function to remind people to call the tests.
+kernel-install_src_test() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	die "Please redefine src_test() and call kernel-install_test()."
+}
+
+# @FUNCTION: kernel-install_pkg_preinst
+# @DESCRIPTION:
+# Stub out mount-boot.eclass.
+kernel-install_pkg_preinst() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# (no-op)
+}
+
+# @FUNCTION: kernel-install_pkg_postinst
+# @DESCRIPTION:
+# Build an initramfs for the kernel, install it and update
+# the /usr/src/linux symlink.
+kernel-install_pkg_postinst() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	if [[ -z ${ROOT} ]]; then
+		mount-boot_pkg_preinst
+
+		if use initramfs; then
+			# putting it alongside kernel image as 'initrd' makes
+			# kernel-install happier
+			kernel-install_build_initramfs \
+				"${EROOT}/usr/src/linux-${PV}/initrd" "${PV}"
+		fi
+
+		kernel-install_install_kernel "${PV}" \
+			"${EROOT}/usr/src/linux-${PV}/$(kernel-install_get_image_path)" \
+			"${EROOT}/usr/src/linux-${PV}/System.map"
+	fi
+
+	kernel-install_update_symlink "${EROOT}/usr/src/linux" "${PV}"
+}
+
+# @FUNCTION: kernel-install_pkg_prerm
+# @DESCRIPTION:
+# Stub out mount-boot.eclass.
+kernel-install_pkg_prerm() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# (no-op)
+}
+
+# @FUNCTION: kernel-install_pkg_postrm
+# @DESCRIPTION:
+# No-op at the moment.  Will be used to remove obsolete kernels
+# in the future.
+kernel-install_pkg_postrm() {
+	debug-print-function ${FUNCNAME} "${@}"
+
+	# (no-op at the moment)
+}
+
+_KERNEL_INSTALL_ECLASS=1
+fi
+
+EXPORT_FUNCTIONS src_test pkg_preinst pkg_postinst pkg_prerm pkg_postrm
-- 
2.24.1



             reply	other threads:[~2020-01-05  6:28 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-05  6:27 Michał Górny [this message]
2020-01-05  6:27 ` [gentoo-dev] [PATCH v2 2/4] kernel-build.eclass: Build logic for dist-kernels Michał Górny
2020-01-06 17:43   ` Mike Gilbert
2020-01-06 17:54     ` Michał Górny
2020-01-06 18:07       ` Mike Gilbert
2020-01-06 18:13         ` Michał Górny
2020-01-05  6:27 ` [gentoo-dev] [PATCH v2 3/4] sys-kernel/vanilla-kernel: Migrate to kernel-build.eclass Michał Górny
2020-01-05  6:27 ` [gentoo-dev] [PATCH v2 4/4] sys-kernel/vanilla-kernel-bin: Migrate to kernel-install.eclass Michał Górny
2020-01-05  7:30 ` [gentoo-dev] [PATCH v2 1/4] kernel-install.eclass: Install logic for dist-kernels Robin H. Johnson
2020-01-07  6:11   ` Michał Górny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200105062741.82357-1-mgorny@gentoo.org \
    --to=mgorny@gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox