diff --git a/crane-build.nix b/crane-build.nix index 4c05d7ec..84b16b21 100644 --- a/crane-build.nix +++ b/crane-build.nix @@ -30,7 +30,10 @@ let args = { inherit version; - src = ./.; + src = lib.fileset.toSource { + root = ./.; + fileset = lib.fileset.fileFilter ({ hasExt, ... }: !hasExt "nix") ./.; + }; strictDeps = true; env = { @@ -71,19 +74,31 @@ let // { inherit cargoArtifacts; + outputs = [ + "out" + "dkms" + ]; + + makeFlags = args.makeFlags ++ [ + "DKMSDIR=${placeholder "dkms"}" + ]; + enableParallelBuilding = true; buildPhaseCargoCommand = '' make ''${enableParallelBuilding:+-j''${NIX_BUILD_CORES}} $makeFlags ''; doNotPostBuildInstallCargoBinaries = true; + enableParallelInstalling = true; installPhaseCommand = '' - make ''${enableParallelBuilding:+-j''${NIX_BUILD_CORES}} $makeFlags install + make ''${enableParallelInstalling:+-j''${NIX_BUILD_CORES}} $makeFlags install install_dkms ''; doInstallCheck = true; nativeInstallCheckInputs = [ versionCheckHook ]; versionCheckProgramArg = "version"; + passthru.kernelModule = import ./module-build.nix package; + meta = { description = "Userspace tools for bcachefs"; license = lib.licenses.gpl2Only; diff --git a/flake.nix b/flake.nix index 8b38ba19..84d3ac31 100644 --- a/flake.nix +++ b/flake.nix @@ -42,6 +42,12 @@ }: let systems = nixpkgs.lib.filter (s: nixpkgs.lib.hasSuffix "-linux" s) nixpkgs.lib.systems.flakeExposed; + + cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); + rustfmtToml = builtins.fromTOML (builtins.readFile ./rustfmt.toml); + + rev = self.shortRev or self.dirtyShortRev or (nixpkgs.lib.substring 0 8 self.lastModifiedDate); + version = "${cargoToml.package.version}+${rev}"; in flake-parts.lib.mkFlake { inherit inputs; } { imports = [ inputs.treefmt-nix.flakeModule ]; @@ -55,6 +61,8 @@ inherit systems; + flake.overlays.default = import ./overlay.nix { inherit inputs version; }; + perSystem = { self', @@ -68,12 +76,6 @@ inherit system; overlays = [ (import rust-overlay) ]; }; - - cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); - rustfmtToml = builtins.fromTOML (builtins.readFile ./rustfmt.toml); - - rev = self.shortRev or self.dirtyShortRev or (lib.substring 0 8 self.lastModifiedDate); - version = "${cargoToml.package.version}+${rev}"; in { packages = @@ -84,18 +86,17 @@ localSystem = system; pkgs' = import nixpkgs { inherit crossSystem localSystem; - overlays = [ (import rust-overlay) ]; + overlays = [ + (import rust-overlay) + self.overlays.default + ]; }; + withCrossName = set: lib.mapAttrs' (name: value: lib.nameValuePair "${name}-${crossSystem}" value) set; - - craneBuild = pkgs'.callPackage ./crane-build.nix { inherit crane version; }; - crossPackages = { - "bcachefs-tools" = craneBuild.package; - "bcachefs-tools-fuse" = craneBuild.packageFuse; - }; in - (withCrossName crossPackages) // lib.optionalAttrs (crossSystem == localSystem) crossPackages; + (withCrossName pkgs'.bcachefsPackages) + // lib.optionalAttrs (crossSystem == localSystem) pkgs'.bcachefsPackages; packages = lib.mergeAttrsList (map packagesForSystem systems); in packages @@ -109,6 +110,8 @@ bcachefs-tools-aarch64-linux bcachefs-tools-fuse bcachefs-tools-fuse-i686-linux + bcachefs-module-linux-latest + bcachefs-module-linux-testing ; inherit (pkgs.callPackage ./crane-build.nix { inherit crane version; }) # cargo-clippy @@ -127,6 +130,8 @@ pname = "${prev.pname}-msrv"; } ); + + nixos-test = pkgs.nixosTest (import ./nixos-test.nix self'); }; devShells.default = pkgs.mkShell { diff --git a/module-build.nix b/module-build.nix new file mode 100644 index 00000000..5d3410d4 --- /dev/null +++ b/module-build.nix @@ -0,0 +1,67 @@ +/* + Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +bcachefs-tools: +{ + lib, + stdenv, + kernelModuleMakeFlags, + kernel, +}: + +stdenv.mkDerivation { + pname = "bcachefs"; + version = "${kernel.version}-${bcachefs-tools.version}"; + + __structuredAttrs = true; + + src = bcachefs-tools.dkms; + + nativeBuildInputs = kernel.moduleBuildDependencies; + + enableParallelBuilding = true; + + makeFlags = kernelModuleMakeFlags ++ [ + "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + "INSTALL_MOD_PATH=${placeholder "out"}" + ]; + + installPhase = '' + runHook preInstall + make -C ${kernel.dev}/lib/modules/${kernel.modDirVersion}/build M=$(pwd) modules_install "''${makeFlags[@]}" "''${installFlags[@]}" + runHook postInstall + ''; + + passthru = { + inherit (bcachefs-tools.passthru) tests; + }; + + meta = { + description = "out-of-tree bcachefs kernel module"; + + inherit (bcachefs-tools.meta) + license + maintainers + ; + }; +} diff --git a/nixos-test.nix b/nixos-test.nix new file mode 100644 index 00000000..015c46a5 --- /dev/null +++ b/nixos-test.nix @@ -0,0 +1,34 @@ +self': { + name = "bcachefs-nixos"; + + nodes.machine = + { config, ... }: + { + assertions = [ + { + assertion = + config.boot.bcachefs.modulePackage or null == self'.packages.bcachefs-module-linux-latest; + message = "Local bcachefs module isn't being used; update nixpkgs?"; + } + ]; + + virtualisation.emptyDiskImages = [ + { + size = 4096; + driveConfig.deviceExtraOpts.serial = "test-disk"; + } + ]; + + boot.supportedFilesystems.bcachefs = true; + boot.bcachefs.package = self'.packages.bcachefs-tools; + }; + + testScript = '' + machine.succeed( + "modinfo bcachefs | grep updates/src/fs/bcachefs > /dev/null", + "mkfs.bcachefs /dev/disk/by-id/virtio-test-disk", + "mkdir /mnt", + "mount /dev/disk/by-id/virtio-test-disk /mnt", + ) + ''; +} diff --git a/overlay.nix b/overlay.nix new file mode 100644 index 00000000..9d9ddd44 --- /dev/null +++ b/overlay.nix @@ -0,0 +1,20 @@ +{ inputs, version }: +final: prev: +let + craneBuild = prev.callPackage ./crane-build.nix { + inherit version; + inherit (inputs) crane; + }; +in +{ + bcachefsPackages = { + "bcachefs-tools" = craneBuild.package; + "bcachefs-tools-fuse" = craneBuild.packageFuse; + "bcachefs-module-linux-latest" = + final.linuxPackages_latest.callPackage craneBuild.package.kernelModule + { }; + "bcachefs-module-linux-testing" = + final.linuxPackages_testing.callPackage craneBuild.package.kernelModule + { }; + }; +}