Add CachyOS-patched ZFS module

This commit is contained in:
Lan Tian 2025-12-08 21:41:55 -08:00
parent 96b4b59a9b
commit 3319bf8462
No known key found for this signature in database
GPG Key ID: 04E66B6B25A0862B
8 changed files with 439 additions and 11 deletions

View File

@ -58,10 +58,15 @@ jobs:
sudo systemctl restart nix-daemon
- name: Build nix packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
export TMPDIR=/nix/tmpdir
nix flake update
chmod +x zfs-cachyos/update.py
zfs-cachyos/update.py
- env:
API_TOKEN_GITHUB: ${{ secrets.AUTOMERGE_TOKEN }}
run: |

178
.gitignore vendored
View File

@ -9,3 +9,181 @@ trace.txt*
update-git-commits.txt
*.cmp
*.fetchlog
# Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=python
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python

View File

@ -1,6 +1,6 @@
# Nix packages for CachyOS Kernel
This repo contains Linux kernels with both [CachyOS patches](https://github.com/CachyOS/kernel-patches) and [CachyOS tunings](https://github.com/CachyOS/linux-cachyos).
This repo contains Linux kernels with both [CachyOS patches](https://github.com/CachyOS/kernel-patches) and [CachyOS tunings](https://github.com/CachyOS/linux-cachyos), as well as [CachyOS-patched ZFS module](https://github.com/CachyOS/zfs).
## Which kernel versions are provided?
@ -29,7 +29,7 @@ For each linux kernel entry under `packages`, we have a corresponding `linuxPack
- `linux-cachyos-latest` -> `inputs.nix-cachyos-kernel.legacyPackages.x86_64-linux.linuxPackages-cachyos-latest`
- `linux-cachyos-lts-lto` -> `inputs.nix-cachyos-kernel.legacyPackages.x86_64-linux.linuxPackages-cachyos-lts-lto`
## How to use
## How to use kernels
Add this repo to the inputs section of your `flake.nix`:
@ -64,3 +64,59 @@ Then specify `pkgs.cachyosKernels.linuxPackages-cachyos-latest` (or other varian
};
}
```
## How to use ZFS modules
> Note: CachyOS-patched ZFS module may fail to compile from time to time. Most compilation failures are caused by incompatibilities between kernel and ZFS. Please check [ZFS upstream issues](https://github.com/openzfs/zfs/issues) for any compatibility reports, and try switching between `zfs_2_3`, `zfs_unstable` and `zfs_cachyos`.
To use ZFS module with `linuxPackages-cachyos-*` provided by this flake, point `boot.zfs.package` to `config.boot.kernelPackages.zfs_cachyos`.
```nix
{
nixosConfigurations.example = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
(
{ pkgs, ... }:
{
nixpkgs.overlays = [ self.overlay ];
boot.kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest;
# ZFS config
boot.supportedFilesystems.zfs = true;
boot.zfs.package = config.boot.kernelPackages.zfs_cachyos;
# ... your other configs
}
)
];
};
}
```
If you want to construct your own `linuxPackages` attrset with `linuxKernel.packagesFor (path to your kernel)`, you can directly reference the `zfs-cachyos` attribute in this flake's `packages` / `legayPackages` output, or the `cachyosKernels` overlay:
```nix
{
nixosConfigurations.example = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
(
{ pkgs, ... }:
{
nixpkgs.overlays = [ self.overlay ];
boot.kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest;
# ZFS config
boot.supportedFilesystems.zfs = true;
boot.zfs.package = pkgs.cachyosKernels.zfs-cachyos.override {
kernel = config.boot.kernelPackages.kernel;
};
# ... your other configs
}
)
];
};
}
```

View File

@ -23,6 +23,8 @@
let
loadPackages =
pkgs:
let
kernels =
lib.removeAttrs
(pkgs.callPackage ./kernel-cachyos {
inherit inputs;
@ -32,6 +34,14 @@
"overrideDerivation"
];
in
kernels
// {
zfs-cachyos = pkgs.callPackage ./zfs-cachyos {
inherit inputs;
kernel = kernels.linux-cachyos-latest;
};
};
in
rec {
systems = [
"x86_64-linux"
@ -57,17 +67,23 @@
cachyosKernels = loadPackages prev;
};
# Example configurations for testing CachyOS kernel
nixosConfigurations = lib.genAttrs systems (
system:
inputs.nixpkgs.lib.nixosSystem {
inherit system;
modules = [
(
{ pkgs, ... }:
{ pkgs, config, ... }:
{
nixpkgs.overlays = [ self.overlay ];
boot.kernelPackages = pkgs.cachyosKernels.linuxPackages-cachyos-latest;
# ZFS test
boot.supportedFilesystems.zfs = true;
boot.zfs.package = config.boot.kernelPackages.zfs_cachyos;
networking.hostId = "12345678";
# Minimal config to make test configuration build
boot.loader.grub.devices = [ "/dev/vda" ];
fileSystems."/" = {

View File

@ -77,10 +77,21 @@ let
description = "Linux CachyOS Kernel" + lib.optionalString lto " with Clang+ThinLTO";
};
};
zfsPackage = callPackage ../zfs-cachyos {
inherit inputs;
kernel = kernelPackage;
};
in
[
(lib.nameValuePair "linux-cachyos-${pnameSuffix}" kernelPackage)
(lib.nameValuePair "linuxPackages-cachyos-${pnameSuffix}" (
kernelModuleLLVMOverride (linuxKernel.packagesFor kernelPackage)
kernelModuleLLVMOverride (
(linuxKernel.packagesFor kernelPackage).extend (
final: prev: {
zfs_cachyos = zfsPackage;
}
)
)
))
]

35
zfs-cachyos/default.nix Normal file
View File

@ -0,0 +1,35 @@
{
inputs,
callPackage,
kernel ? null,
lib,
fetchFromGitHub,
}:
let
versionJson = lib.importJSON ./version.json;
zfsGeneric = callPackage "${inputs.nixpkgs.outPath}/pkgs/os-specific/linux/zfs/generic.nix" {
inherit kernel;
};
in
# https://github.com/chaotic-cx/nyx/blob/aacb796ccd42be1555196c20013b9b674b71df75/pkgs/linux-cachyos/packages-for.nix#L99
(zfsGeneric {
kernelModuleAttribute = "zfs_cachyos";
kernelMinSupportedMajorMinor = "1.0";
kernelMaxSupportedMajorMinor = "99.99";
enableUnsupportedExperimentalKernel = true;
version = builtins.elemAt (lib.splitString "-" versionJson.zfs_branch) 1;
tests = { };
maintainers = with lib.maintainers; [
pedrohlc
];
hash = "";
extraPatches = [ ];
}).overrideAttrs
(prevAttrs: {
src = fetchFromGitHub {
owner = "cachyos";
repo = "zfs";
inherit (versionJson) rev hash;
};
postPatch = builtins.replaceStrings [ "grep --quiet '^Linux-M" ] [ "# " ] prevAttrs.postPatch;
})

112
zfs-cachyos/update.py Executable file
View File

@ -0,0 +1,112 @@
#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p python3 -p python3Packages.requests -p nix-prefetch-git
import json
import os
import re
import subprocess
import sys
from pathlib import Path
from typing import Dict, Any, Optional
import requests
def get_latest_zfs_cachyos_branch() -> Optional[str]:
api_url = "https://api.github.com/repos/CachyOS/zfs/branches"
all_branches = []
page = 1
per_page = 100 # Maximum allowed
# Setup headers for GitHub API authentication if token is available
headers = {}
github_token = os.environ.get("GITHUB_TOKEN")
if github_token:
headers["Authorization"] = f"token {github_token}"
while True:
params = {"per_page": per_page, "page": page}
response = requests.get(api_url, params=params, headers=headers, timeout=30)
response.raise_for_status()
branches = response.json()
if not branches:
break
all_branches.extend(branches)
page += 1
# If we got less than per_page results, we're on the last page
if len(branches) < per_page:
break
cachyos_branches = []
branch_pattern = re.compile(r"^zfs-\d+\.\d+\.\d+-cachyos$")
for branch in all_branches:
branch_name = branch.get("name", "")
if branch_pattern.match(branch_name):
cachyos_branches.append(branch_name)
if not cachyos_branches:
print("No branch found matching zfs-x.y.z-cachyos or x.y.z-cachyos pattern")
return None
cachyos_branches.sort(reverse=True)
latest_branch = cachyos_branches[0]
print(f"Found latest branch: {latest_branch}")
return latest_branch
def run_nix_prefetch_git(branch: str) -> Optional[Dict[str, Any]]:
cmd = ["nix-prefetch-git", "https://github.com/CachyOS/zfs.git", "--branch-name", branch]
print(f"Running command: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
if result.returncode != 0:
print(f"nix-prefetch-git command failed with return code: {result.returncode}")
print(f"Error output: {result.stderr}")
return None
output = result.stdout.strip()
if not output:
print("nix-prefetch-git output is empty")
return None
parsed_output = json.loads(output)
return parsed_output
def save_version_info(branch: str, prefetch_data: Dict[str, Any], output_file: Path):
with open(output_file, "w", encoding="utf-8") as f:
json.dump({"zfs_branch": branch, **prefetch_data}, f, indent=2)
print(f"Version info saved to: {output_file}")
def main() -> int:
print("Starting ZFS CachyOS version update...")
latest_branch = get_latest_zfs_cachyos_branch()
if not latest_branch:
print("Failed to get latest branch, exiting")
return 1
prefetch_data = run_nix_prefetch_git(latest_branch)
if not prefetch_data:
print("nix-prefetch-git execution failed, exiting")
return 1
script_dir = Path(__file__).parent
output_file = script_dir / "version.json"
save_version_info(latest_branch, prefetch_data, output_file)
print("ZFS CachyOS version info update completed!")
return 0
if __name__ == "__main__":
sys.exit(main())

15
zfs-cachyos/version.json Normal file
View File

@ -0,0 +1,15 @@
{
"zfs_branch": "zfs-2.3.6-cachyos",
"url": "https://github.com/CachyOS/zfs.git",
"rev": "4ddaf45ba468c6953a4fcdbfe79795f74fa6e489",
"date": "2025-03-13T10:35:31-04:00",
"path": "/nix/store/clbq55q8pca9im5jsr28g472x0l0y50w-zfs",
"sha256": "07gh7x7lwq013ni4jb6vxavhf348g8zl3db65sz408lsp2bpx0v5",
"hash": "sha256-ZYN+l7iaIkC+Lma1QT96iAwHt+rbLEmiHQFgTk8/8B0=",
"fetchLFS": false,
"fetchSubmodules": false,
"deepClone": false,
"fetchTags": false,
"leaveDotGit": false,
"rootDir": ""
}