linux_hardened: only provide latest LTS and lattest stable version
As proposed in #346018 (not closing the ticket, this affects other variants as well). The packaging for hardened is in a pretty sad state: it was lagging several patch-releases behind and nobody seems to care. The update script aged poorly: the automatic removal was flat-out broken, several type annotations are plain wrong (`list[int] != packaging.Version`). This patch is an attempt to reduce the scope for the maintainer team drastically to provide _some_ maintenance again by only packaging latest LTS and latest stable. Also, remove the top-level attributes for this. I still don't see any compelling reason to give hardly used flavours that special treatment.
This commit is contained in:
@@ -35,14 +35,8 @@ let
|
||||
) args);
|
||||
kernels = pkgs.linuxKernel.vanillaPackages // {
|
||||
inherit (pkgs.linuxKernel.packages)
|
||||
linux_5_4_hardened
|
||||
linux_5_10_hardened
|
||||
linux_5_15_hardened
|
||||
linux_6_1_hardened
|
||||
linux_6_6_hardened
|
||||
linux_6_12_hardened
|
||||
linux_6_13_hardened
|
||||
linux_6_14_hardened
|
||||
linux_6_15_hardened
|
||||
linux_rt_5_4
|
||||
linux_rt_5_10
|
||||
linux_rt_5_15
|
||||
|
||||
@@ -156,10 +156,11 @@ def fetch_patch(*, name: str, release_info: ReleaseInfo) -> Optional[Patch]:
|
||||
)
|
||||
|
||||
|
||||
def parse_version(version_str: str) -> Version:
|
||||
def normalize_kernel_version(version_str: str) -> list[str|int]:
|
||||
# There have been two variants v6.10[..] and 6.10[..], drop the v
|
||||
version_str_without_v = version_str[1:] if not version_str[0].isdigit() else version_str
|
||||
version: Version = []
|
||||
|
||||
version: list[str|int] = []
|
||||
|
||||
for component in re.split(r'\.|\-', version_str_without_v):
|
||||
try:
|
||||
@@ -173,14 +174,14 @@ def version_string(version: Version) -> str:
|
||||
return ".".join(str(component) for component in version)
|
||||
|
||||
|
||||
def major_kernel_version_key(kernel_version: Version) -> str:
|
||||
def major_kernel_version_key(kernel_version: list[int|str]) -> str:
|
||||
return version_string(kernel_version[:-1])
|
||||
|
||||
|
||||
def commit_patches(*, kernel_key: str, message: str) -> None:
|
||||
def commit_patches(*, kernel_key: Version, message: str) -> None:
|
||||
new_patches_path = HARDENED_PATCHES_PATH.with_suffix(".new")
|
||||
with open(new_patches_path, "w") as new_patches_file:
|
||||
json.dump(patches, new_patches_file, indent=4, sort_keys=True)
|
||||
json.dump(patch_json, new_patches_file, indent=4, sort_keys=True)
|
||||
new_patches_file.write("\n")
|
||||
os.rename(new_patches_path, HARDENED_PATCHES_PATH)
|
||||
message = f"linux/hardened/patches/{kernel_key}: {message}"
|
||||
@@ -197,43 +198,32 @@ def commit_patches(*, kernel_key: str, message: str) -> None:
|
||||
|
||||
|
||||
# Load the existing patches.
|
||||
patches: Dict[str, Patch]
|
||||
with open(HARDENED_PATCHES_PATH) as patches_file:
|
||||
patches = json.load(patches_file)
|
||||
patch_json = json.load(patches_file)
|
||||
patch_versions = set([parse_version(k) for k in patch_json.keys()])
|
||||
|
||||
# Get the set of currently packaged kernel versions.
|
||||
kernel_versions = {}
|
||||
with open(NIXPKGS_KERNEL_PATH / "kernels-org.json") as kernel_versions_json:
|
||||
kernel_versions = json.load(kernel_versions_json)
|
||||
for kernel_branch_str in kernel_versions:
|
||||
if kernel_branch_str == "testing": continue
|
||||
kernel_branch = [int(i) for i in kernel_branch_str.split(".")]
|
||||
if kernel_branch < MIN_KERNEL_VERSION: continue
|
||||
kernel_version = [int(i) for i in kernel_versions[kernel_branch_str]["version"].split(".")]
|
||||
kernel_versions[kernel_branch_str] = kernel_version
|
||||
|
||||
# Remove patches for unpackaged kernel versions.
|
||||
for kernel_key in sorted(patches.keys() - kernel_versions.keys()):
|
||||
del patches[kernel_key]
|
||||
commit_patches(kernel_key=kernel_key, message="remove")
|
||||
kernels = {
|
||||
parse_version(version): meta
|
||||
for version, meta in kernel_versions.items()
|
||||
if version != "testing"
|
||||
}
|
||||
|
||||
latest_lts = sorted(ver for ver, meta in kernels.items() if meta.get("lts", False))[-1]
|
||||
keys = sorted(kernels.keys())
|
||||
latest_release = keys[-1]
|
||||
fallback = keys[-2]
|
||||
|
||||
g = Github(os.environ.get("GITHUB_TOKEN"))
|
||||
repo = g.get_repo(HARDENED_GITHUB_REPO)
|
||||
failures = False
|
||||
|
||||
# Match each kernel version with the best patch version.
|
||||
releases = {}
|
||||
i = 0
|
||||
for release in repo.get_releases():
|
||||
# Dirty workaround to make sure that we don't run into issues because
|
||||
# GitHub's API only allows fetching the last 1000 releases.
|
||||
# It's not reliable to exit earlier because not every kernel minor may
|
||||
# have hardened patches, hence the naive search below.
|
||||
i += 1
|
||||
if i > 100:
|
||||
break
|
||||
|
||||
version = parse_version(release.tag_name)
|
||||
all_candidates = set([latest_lts, latest_release, fallback])
|
||||
kernels_to_package = {}
|
||||
for release in repo.get_releases()[:30]:
|
||||
version = normalize_kernel_version(release.tag_name)
|
||||
# needs to look like e.g. 5.6.3-hardened1
|
||||
if len(version) < 4:
|
||||
continue
|
||||
@@ -242,44 +232,51 @@ for release in repo.get_releases():
|
||||
continue
|
||||
|
||||
kernel_version = version[:-1]
|
||||
kernel_key = parse_version(major_kernel_version_key(kernel_version))
|
||||
|
||||
kernel_key = major_kernel_version_key(kernel_version)
|
||||
try:
|
||||
packaged_kernel_version = kernel_versions[kernel_key]
|
||||
except KeyError:
|
||||
if kernel_key not in all_candidates:
|
||||
continue
|
||||
|
||||
release_info = ReleaseInfo(version=version, release=release)
|
||||
|
||||
if kernel_version == packaged_kernel_version:
|
||||
releases[kernel_key] = release_info
|
||||
else:
|
||||
# Fall back to the latest patch for this major kernel version,
|
||||
# skipping patches for kernels newer than the packaged one.
|
||||
if '.'.join(str(x) for x in kernel_version) > '.'.join(str(x) for x in packaged_kernel_version):
|
||||
try:
|
||||
found = kernels_to_package[kernel_key]
|
||||
if found.version > version:
|
||||
continue
|
||||
elif (
|
||||
kernel_key not in releases or releases[kernel_key].version < version
|
||||
):
|
||||
releases[kernel_key] = release_info
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
kernels_to_package[kernel_key] = ReleaseInfo(version=version, release=release)
|
||||
|
||||
if latest_release in kernels_to_package:
|
||||
if fallback != latest_lts:
|
||||
del kernels_to_package[fallback]
|
||||
kernel_versions = set([latest_lts, latest_release])
|
||||
else:
|
||||
kernel_versions = set([latest_lts, fallback])
|
||||
|
||||
# Remove patches for unpackaged kernel versions.
|
||||
removals = False
|
||||
for kernel_key in sorted(patch_versions - kernels_to_package.keys()):
|
||||
del patch_json[str(kernel_key)]
|
||||
removals = True
|
||||
commit_patches(kernel_key=kernel_key, message="remove")
|
||||
|
||||
# Update hardened-patches.json for each release.
|
||||
for kernel_key in sorted(releases.keys()):
|
||||
release_info = releases[kernel_key]
|
||||
for kernel_key in sorted(kernels_to_package.keys()):
|
||||
release_info = kernels_to_package[kernel_key]
|
||||
release = release_info.release
|
||||
version = release_info.version
|
||||
version_str = release.tag_name
|
||||
name = f"linux-hardened-{version_str}"
|
||||
|
||||
old_version: Optional[Version] = None
|
||||
old_version: Optional[list[int|str]] = None
|
||||
old_version_str: Optional[str] = None
|
||||
update: bool
|
||||
try:
|
||||
old_filename = patches[kernel_key]["patch"]["name"]
|
||||
old_filename = patch_json[str(kernel_key)]["patch"]["name"]
|
||||
old_version_str = old_filename.replace("linux-hardened-", "").replace(
|
||||
".patch", ""
|
||||
)
|
||||
old_version = parse_version(old_version_str)
|
||||
old_version = normalize_kernel_version(old_version_str)
|
||||
update = old_version < version
|
||||
except KeyError:
|
||||
update = True
|
||||
@@ -289,21 +286,16 @@ for kernel_key in sorted(releases.keys()):
|
||||
if patch is None:
|
||||
failures = True
|
||||
else:
|
||||
patches[kernel_key] = patch
|
||||
if old_version:
|
||||
if str(kernel_key) in patch_json:
|
||||
message = f"{old_version_str} -> {version_str}"
|
||||
else:
|
||||
message = f"init at {version_str}"
|
||||
patch_json[str(kernel_key)] = patch
|
||||
|
||||
commit_patches(kernel_key=kernel_key, message=message)
|
||||
|
||||
missing_kernel_versions = kernel_versions.keys() - patches.keys()
|
||||
|
||||
if missing_kernel_versions:
|
||||
print(
|
||||
f"warning: no patches for kernel versions "
|
||||
+ ", ".join(missing_kernel_versions),
|
||||
file=sys.stderr,
|
||||
)
|
||||
if removals:
|
||||
print("Hardened kernels were removed. Don't forget to remove their attributes!")
|
||||
|
||||
if failures:
|
||||
sys.exit(1)
|
||||
|
||||
@@ -1413,6 +1413,22 @@ mapAliases {
|
||||
'';
|
||||
linux_latest_hardened = linuxPackages_latest_hardened;
|
||||
|
||||
# Added 2025-08-10
|
||||
linuxPackages_hardened = linuxKernel.packages.linux_hardened;
|
||||
linux_hardened = linuxPackages_hardened.kernel;
|
||||
linuxPackages_5_4_hardened = linuxKernel.packages.linux_5_4_hardened;
|
||||
linux_5_4_hardened = linuxKernel.kernels.linux_5_4_hardened;
|
||||
linuxPackages_5_10_hardened = linuxKernel.packages.linux_5_10_hardened;
|
||||
linux_5_10_hardened = linuxKernel.kernels.linux_5_10_hardened;
|
||||
linuxPackages_5_15_hardened = linuxKernel.packages.linux_5_15_hardened;
|
||||
linux_5_15_hardened = linuxKernel.kernels.linux_5_15_hardened;
|
||||
linuxPackages_6_1_hardened = linuxKernel.packages.linux_6_1_hardened;
|
||||
linux_6_1_hardened = linuxKernel.kernels.linux_6_1_hardened;
|
||||
linuxPackages_6_6_hardened = linuxKernel.packages.linux_6_6_hardened;
|
||||
linux_6_6_hardened = linuxKernel.kernels.linux_6_6_hardened;
|
||||
linuxPackages_6_12_hardened = linuxKernel.packages.linux_6_12_hardened;
|
||||
linux_6_12_hardened = linuxKernel.kernels.linux_6_12_hardened;
|
||||
|
||||
# Added 2023-11-18, modified 2024-01-09
|
||||
linuxPackages_testing_bcachefs = throw "'linuxPackages_testing_bcachefs' has been removed, please use 'linuxPackages_latest', any kernel version at least 6.7, or any other linux kernel with bcachefs support";
|
||||
linux_testing_bcachefs = throw "'linux_testing_bcachefs' has been removed, please use 'linux_latest', any kernel version at least 6.7, or any other linux kernel with bcachefs support";
|
||||
|
||||
@@ -10602,20 +10602,6 @@ with pkgs;
|
||||
linux-rt = linuxPackages-rt.kernel;
|
||||
linux-rt_latest = linuxPackages-rt_latest.kernel;
|
||||
|
||||
# hardened kernels
|
||||
linuxPackages_hardened = linuxKernel.packages.linux_hardened;
|
||||
linux_hardened = linuxPackages_hardened.kernel;
|
||||
linuxPackages_5_10_hardened = linuxKernel.packages.linux_5_10_hardened;
|
||||
linux_5_10_hardened = linuxKernel.kernels.linux_5_10_hardened;
|
||||
linuxPackages_5_15_hardened = linuxKernel.packages.linux_5_15_hardened;
|
||||
linux_5_15_hardened = linuxKernel.kernels.linux_5_15_hardened;
|
||||
linuxPackages_6_1_hardened = linuxKernel.packages.linux_6_1_hardened;
|
||||
linux_6_1_hardened = linuxKernel.kernels.linux_6_1_hardened;
|
||||
linuxPackages_6_6_hardened = linuxKernel.packages.linux_6_6_hardened;
|
||||
linux_6_6_hardened = linuxKernel.kernels.linux_6_6_hardened;
|
||||
linuxPackages_6_12_hardened = linuxKernel.packages.linux_6_12_hardened;
|
||||
linux_6_12_hardened = linuxKernel.kernels.linux_6_12_hardened;
|
||||
|
||||
# GNU Linux-libre kernels
|
||||
linuxPackages-libre = linuxKernel.packages.linux_libre;
|
||||
linux-libre = linuxPackages-libre.kernel;
|
||||
|
||||
@@ -294,14 +294,10 @@ in
|
||||
|
||||
linux_latest_libre = deblobKernel packageAliases.linux_latest.kernel;
|
||||
|
||||
linux_hardened = hardenedKernelFor packageAliases.linux_default.kernel { };
|
||||
|
||||
linux_5_10_hardened = hardenedKernelFor kernels.linux_5_10 { };
|
||||
linux_5_15_hardened = hardenedKernelFor kernels.linux_5_15 { };
|
||||
linux_6_1_hardened = hardenedKernelFor kernels.linux_6_1 { };
|
||||
linux_6_6_hardened = hardenedKernelFor kernels.linux_6_6 { };
|
||||
linux_6_12_hardened = hardenedKernelFor kernels.linux_6_12 { };
|
||||
linux_6_15_hardened = hardenedKernelFor kernels.linux_6_15 { };
|
||||
|
||||
linux_hardened = hardenedKernelFor packageAliases.linux_default.kernel { };
|
||||
}
|
||||
// lib.optionalAttrs config.allowAliases {
|
||||
linux_4_19 = throw "linux 4.19 was removed because it will reach its end of life within 24.11";
|
||||
@@ -311,6 +307,11 @@ in
|
||||
linux_6_13 = throw "linux 6.13 was removed because it has reached its end of life upstream";
|
||||
linux_6_14 = throw "linux 6.14 was removed because it has reached its end of life upstream";
|
||||
|
||||
linux_5_10_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
linux_5_15_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
linux_6_1_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
linux_6_6_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
|
||||
linux_4_19_hardened = throw "linux 4.19 was removed because it will reach its end of life within 24.11";
|
||||
linux_5_4_hardened = throw "linux_5_4_hardened was removed because it was broken";
|
||||
linux_6_9_hardened = throw "linux 6.9 was removed because it has reached its end of life upstream";
|
||||
@@ -776,11 +777,8 @@ in
|
||||
|
||||
linux_hardened = recurseIntoAttrs (packagesFor kernels.linux_hardened);
|
||||
|
||||
linux_5_10_hardened = recurseIntoAttrs (packagesFor kernels.linux_5_10_hardened);
|
||||
linux_5_15_hardened = recurseIntoAttrs (packagesFor kernels.linux_5_15_hardened);
|
||||
linux_6_1_hardened = recurseIntoAttrs (packagesFor kernels.linux_6_1_hardened);
|
||||
linux_6_6_hardened = recurseIntoAttrs (packagesFor kernels.linux_6_6_hardened);
|
||||
linux_6_12_hardened = recurseIntoAttrs (packagesFor kernels.linux_6_12_hardened);
|
||||
linux_6_15_hardened = recurseIntoAttrs (packagesFor kernels.linux_6_15_hardened);
|
||||
|
||||
linux_zen = recurseIntoAttrs (packagesFor kernels.linux_zen);
|
||||
linux_lqx = recurseIntoAttrs (packagesFor kernels.linux_lqx);
|
||||
@@ -794,6 +792,12 @@ in
|
||||
__recurseIntoDerivationForReleaseJobs = true;
|
||||
}
|
||||
// lib.optionalAttrs config.allowAliases {
|
||||
|
||||
linux_5_10_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
linux_5_15_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
linux_6_1_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
linux_6_6_hardened = throw "linux_hardened on nixpkgs only contains latest stable and latest LTS";
|
||||
|
||||
linux_4_19_hardened = throw "linux 4.19 was removed because it will reach its end of life within 24.11";
|
||||
linux_5_4_hardened = throw "linux_5_4_hardened was removed because it was broken";
|
||||
linux_6_9_hardened = throw "linux 6.9 was removed because it has reached its end of life upstream";
|
||||
|
||||
Reference in New Issue
Block a user