feat: nixpkgs-ify and unflake-ify system-manager

This commit is contained in:
Sofie 2024-10-29 11:25:16 +01:00
parent 5c477c1a31
commit f64a24f727
No known key found for this signature in database
GPG key ID: C9E9DE9EDCD42BC1
10 changed files with 208 additions and 507 deletions

3
.gitignore vendored
View file

@ -5,7 +5,6 @@
# These are backup files generated by rustfmt # These are backup files generated by rustfmt
**/*.rs.bk **/*.rs.bk
result /result*
.pre-commit-config.yaml
.direnv .direnv
**/.nixos-test-history **/.nixos-test-history

17
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,17 @@
default_install_hook_types: [pre-commit]
repos:
- repo: local
hooks:
- id: treefmt
name: treefmt
entry: treefmt --fail-on-change
language: system
pass_filenames: false
stages: [pre-commit]
- id: cargo-clippy
name: cargo-clippy
entry: cargo-clippy --workspace -- -D warnings
language: system
files: \.rs$
pass_filenames: false
stages: [pre-commit]

9
.treefmt.toml Normal file
View file

@ -0,0 +1,9 @@
# One CLI to format the code tree - https://git.numtide.com/numtide/treefmt
[formatter.nixfmt]
command = "nixfmt"
includes = ["*.nix"]
[formatter.rustfmt]
command = "rustfmt"
includes = ["*.rs"]

View file

@ -1,4 +1,8 @@
(import (fetchTarball { {
url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz"; nixpkgs ? <nixpkgs>,
sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; pkgs ? import nixpkgs { },
}) { src = ./.; }).defaultNix }:
{
lib = import ./nix/lib.nix { inherit nixpkgs; };
}
// import ./packages.nix { inherit pkgs; }

213
flake.lock generated
View file

@ -1,115 +1,5 @@
{ {
"nodes": { "nodes": {
"crane": {
"locked": {
"lastModified": 1729273024,
"narHash": "sha256-Mb5SemVsootkn4Q2IiY0rr9vrXdCCpQ9HnZeD/J3uXs=",
"owner": "ipetkov",
"repo": "crane",
"rev": "fa8b7445ddadc37850ed222718ca86622be01967",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"devshell": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1728330715,
"narHash": "sha256-xRJ2nPOXb//u1jaBnDP56M7v5ldavjbtR6lfGqSvcKg=",
"owner": "numtide",
"repo": "devshell",
"rev": "dd6b80932022cea34a019e2bb32f6fa9e494dfef",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "devshell",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": {
"inputs": {
"nixpkgs": [
"pre-commit-hooks",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709087332,
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
"owner": "hercules-ci",
"repo": "gitignore.nix",
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "gitignore.nix",
"type": "github"
}
},
"nix-vm-test": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1729365388,
"narHash": "sha256-PRBcv8IWfXlw7DLuljqyPVAqtcj3/7RtmsKCou8dhAg=",
"owner": "numtide",
"repo": "nix-vm-test",
"rev": "62092e89a2a69fa63fb4f560f48e2f874d3393bb",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-vm-test",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1729256560, "lastModified": 1729256560,
@ -126,110 +16,9 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-stable": {
"locked": {
"lastModified": 1720386169,
"narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "194846768975b7ad2c4988bdb82572c00222c0d7",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit-hooks": {
"inputs": {
"flake-compat": "flake-compat",
"gitignore": "gitignore",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1729104314,
"narHash": "sha256-pZRZsq5oCdJt3upZIU4aslS9XwFJ+/nVtALHIciX/BI=",
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"rev": "3c3e88f0f544d6bb54329832616af7eb971b6be6",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "pre-commit-hooks.nix",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"crane": "crane", "nixpkgs": "nixpkgs"
"devshell": "devshell",
"flake-utils": "flake-utils",
"nix-vm-test": "nix-vm-test",
"nixpkgs": "nixpkgs",
"pre-commit-hooks": "pre-commit-hooks",
"rust-overlay": "rust-overlay",
"treefmt-nix": "treefmt-nix"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1729477859,
"narHash": "sha256-r0VyeJxy4O4CgTB/PNtfQft9fPfN1VuGvnZiCxDArvg=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "ada8266712449c4c0e6ee6fcbc442b3c217c79e1",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1729242555,
"narHash": "sha256-6jWSWxv2crIXmYSEb3LEVsFkCkyVHNllk61X4uhqfCs=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "d986489c1c757f6921a48c1439f19bfb9b8ecab5",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
} }
} }
}, },

322
flake.nix
View file

@ -1,284 +1,78 @@
{ {
inputs = { description = "Manage system config using nix on any distro";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
devshell = {
url = "github:numtide/devshell";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
pre-commit-hooks = {
url = "github:cachix/pre-commit-hooks.nix";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
crane.url = "github:ipetkov/crane"; inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nix-vm-test = {
url = "github:numtide/nix-vm-test";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = outputs =
{ self, nixpkgs }:
let
systems = [
"aarch64-linux"
"x86_64-linux"
];
eachSystem =
f:
nixpkgs.lib.genAttrs systems (
system:
f {
inherit system;
pkgs = nixpkgs.legacyPackages.${system};
}
);
in
{ {
self, lib = import ./nix/lib.nix { inherit nixpkgs; };
nixpkgs,
flake-utils, packages = eachSystem (
rust-overlay, { pkgs, system }:
crane, import ./packages.nix { inherit pkgs; }
devshell, // {
treefmt-nix, default = self.packages.${system}.system-manager;
pre-commit-hooks, }
... );
}@inputs:
{
lib = import ./nix/lib.nix {
inherit nixpkgs self;
nixos = "${nixpkgs}/nixos";
};
# Only useful for quick tests # Only useful for quick tests
systemConfigs.default = self.lib.makeSystemConfig { systemConfigs.default = self.lib.makeSystemConfig {
modules = [ ./examples/example.nix ]; modules = [ ./examples/example.nix ];
}; };
formatter = eachSystem ({ pkgs, ... }: pkgs.treefmt);
devShells = eachSystem (
{ pkgs, ... }:
{
default = import ./shell.nix { inherit pkgs; };
} }
// (flake-utils.lib.eachSystem );
[
flake-utils.lib.system.x86_64-linux checks = (
flake-utils.lib.system.aarch64-linux nixpkgs.lib.recursiveUpdate
] (eachSystem (
( { system, ... }:
system: {
system-manager = self.packages.${system}.system-manager;
}
))
{
x86_64-linux =
let let
pkgs = import nixpkgs { system = "x86_64-linux";
nix-vm-test-src = builtins.fetchTarball {
url = "https://github.com/numtide/nix-vm-test/archive/7901cec00670681b3e405565cb7bffe6a9368240.tar.gz";
sha256 = "0m82a40r3j7qinp3y6mh36da89dkwvpalz6a4znx9rqp6kh3885x";
};
nix-vm-test = import "${nix-vm-test-src}/lib.nix" {
inherit nixpkgs;
inherit system; inherit system;
overlays = [
(import rust-overlay)
devshell.overlays.default
];
};
# TODO Pin the version for release
rust = pkgs.rust-bin.stable.latest;
craneLib = (crane.mkLib pkgs).overrideToolchain rust.default;
# Common derivation arguments used for all builds
commonArgs =
{ dbus, pkg-config }:
{
src = craneLib.cleanCargoSource ./.;
buildInputs = [
dbus
];
nativeBuildInputs = [
pkg-config
];
# https://github.com/ipetkov/crane/issues/385
doNotLinkInheritedArtifacts = true;
};
# Build only the cargo dependencies
cargoArtifacts =
{ dbus, pkg-config }:
craneLib.buildDepsOnly (
(commonArgs { inherit dbus pkg-config; })
// {
pname = "system-manager";
}
);
system-manager-unwrapped =
{
dbus,
pkg-config,
}:
craneLib.buildPackage (
(commonArgs { inherit dbus pkg-config; })
// {
pname = "system-manager";
cargoArtifacts = cargoArtifacts { inherit dbus pkg-config; };
}
);
system-manager =
{
dbus,
makeBinaryWrapper,
nix,
pkg-config,
runCommand,
}:
let
unwrapped = system-manager-unwrapped { inherit dbus pkg-config; };
in
runCommand "system-manager"
{
nativeBuildInputs = [ makeBinaryWrapper ];
}
''
makeWrapper \
${unwrapped}/bin/system-manager \
$out/bin/system-manager \
--prefix PATH : ${nixpkgs.lib.makeBinPath [ nix ]}
'';
system-manager-clippy =
{
dbus,
pkg-config,
}:
craneLib.cargoClippy (
(commonArgs { inherit dbus pkg-config; })
// {
cargoArtifacts = cargoArtifacts { inherit dbus pkg-config; };
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
}
);
system-manager-test =
{
dbus,
pkg-config,
}:
craneLib.cargoTest (
(commonArgs { inherit dbus pkg-config; })
// {
cargoArtifacts = cargoArtifacts { inherit dbus pkg-config; };
}
);
# treefmt-nix configuration
treefmt.config = {
projectRootFile = "flake.nix";
programs = {
nixfmt.enable = true;
rustfmt = {
enable = true;
package = rust.rustfmt;
};
};
}; };
in in
{ (import ./test/nix/modules {
packages = {
# The unwrapped version takes nix from the PATH, it will fail if nix
# cannot be found.
# The wrapped version has a reference to the nix store path, so nix is
# part of its runtime closure.
system-manager-unwrapped = pkgs.callPackage system-manager-unwrapped { };
system-manager = pkgs.callPackage system-manager { };
system-manager-clippy = pkgs.callPackage system-manager-clippy { };
system-manager-test = pkgs.callPackage system-manager-test { };
default = self.packages.${system}.system-manager;
};
devShells.default =
let
llvm = pkgs.llvmPackages_latest;
in
pkgs.devshell.mkShell {
packages = with pkgs; [
llvm.clang
pkg-config
(rust.default.override {
extensions = [ "rust-src" ];
})
(treefmt-nix.lib.mkWrapper pkgs treefmt.config)
];
env = [
{
name = "PKG_CONFIG_PATH";
value = pkgs.lib.makeSearchPath "lib/pkgconfig" [
pkgs.dbus.dev
pkgs.systemdMinimal.dev
];
}
{
name = "LIBCLANG_PATH";
value = "${llvm.libclang}/lib";
}
{
# for rust-analyzer
name = "RUST_SRC_PATH";
value = "${rust.rust-src}";
}
{
name = "RUST_BACKTRACE";
value = "1";
}
{
name = "RUSTFLAGS";
value =
let
getLib = pkg: "${pkgs.lib.getLib pkg}/lib";
in
pkgs.lib.concatStringsSep " " [
"-L${getLib pkgs.systemdMinimal} -lsystemd"
];
}
{
name = "DEVSHELL_NO_MOTD";
value = "1";
}
];
devshell.startup.pre-commit.text =
(pre-commit-hooks.lib.${system}.run {
src = ./.;
hooks = {
check-format = {
enable = true;
entry = "treefmt --fail-on-change";
};
cargo-clippy = {
enable = true;
description = "Lint Rust code.";
entry = "cargo-clippy --workspace -- -D warnings";
files = "\\.rs$";
pass_filenames = false;
};
};
}).shellHook;
};
checks =
let
# The Aarch64 VM tests seem to hang on garnix, we disable them for now
enableVmTests = system != flake-utils.lib.system.aarch64-linux;
in
{
inherit (self.packages.${system})
# Build the crate as part of `nix flake check` for convenience
system-manager
system-manager-clippy
system-manager-test
;
}
// pkgs.lib.optionalAttrs enableVmTests (
import ./test/nix/modules {
inherit system; inherit system;
inherit (pkgs) lib; inherit (nixpkgs) lib;
inherit (inputs) nix-vm-test; inherit nix-vm-test;
system-manager = self; system-manager = self;
});
} }
); );
} };
)
);
} }

View file

@ -1,12 +1,9 @@
{ {
nixpkgs, # The nixpkgs flake nixpkgs ? <nixpkgs>,
self, # The system-manager flake lib ? import "${nixpkgs}/lib",
nixos, # The path to the nixos dir from nixpkgs nixos ? "${nixpkgs}/nixos",
}: }:
let rec {
inherit (nixpkgs) lib;
in
{
# Function that can be used when defining inline modules to get better location # Function that can be used when defining inline modules to get better location
# reporting in module-system errors. # reporting in module-system errors.
# Usage example: # Usage example:
@ -34,14 +31,18 @@ in
... ...
}: }:
{ {
_file = "${self.lib.printAttrPos (builtins.unsafeGetAttrPos "a" { a = null; })}: inline module"; _file = "${printAttrPos (builtins.unsafeGetAttrPos "a" { a = null; })}: inline module";
_module.args = { _module.args = {
pkgs = nixpkgs.legacyPackages.${config.nixpkgs.hostPlatform}; pkgs = import nixpkgs { system = config.nixpkgs.hostPlatform; };
utils = import "${nixos}/lib/utils.nix" { utils = import "${nixos}/lib/utils.nix" {
inherit lib config pkgs; inherit lib config pkgs;
}; };
# Pass the wrapped system-manager binary down # Pass the wrapped system-manager binary down
inherit (self.packages.${config.nixpkgs.hostPlatform}) system-manager; # TODO: Use nixpkgs version by default.
inherit
(import ../packages.nix { pkgs = import nixpkgs { system = config.nixpkgs.hostPlatform; }; })
system-manager
;
}; };
}; };
@ -58,7 +59,7 @@ in
# Get the system as it was defined in the modules. # Get the system as it was defined in the modules.
system = config.nixpkgs.hostPlatform; system = config.nixpkgs.hostPlatform;
pkgs = nixpkgs.legacyPackages.${system}; pkgs = import nixpkgs { inherit system; };
returnIfNoAssertions = returnIfNoAssertions =
drv: drv:
@ -123,19 +124,19 @@ in
activateProfileSnippet = activateProfileSnippet =
{ node, profile }: { node, profile }:
self.lib.mkTestPreamble { mkTestPreamble {
inherit node profile; inherit node profile;
action = "activate"; action = "activate";
}; };
deactivateProfileSnippet = deactivateProfileSnippet =
{ node, profile }: { node, profile }:
self.lib.mkTestPreamble { mkTestPreamble {
inherit node profile; inherit node profile;
action = "deactivate"; action = "deactivate";
}; };
prepopulateProfileSnippet = prepopulateProfileSnippet =
{ node, profile }: { node, profile }:
self.lib.mkTestPreamble { mkTestPreamble {
inherit node profile; inherit node profile;
action = "prepopulate"; action = "prepopulate";
}; };

53
packages.nix Normal file
View file

@ -0,0 +1,53 @@
{
pkgs ? import <nixpkgs> { },
lib ? pkgs.lib,
}:
let
# This project's `.gitignore` implemented for cleanSource.
filterGitignore =
orig_path: type:
let
baseName = baseNameOf (toString orig_path);
in
!(baseName == "target" && type == "directory")
|| lib.hasSuffix ".rs.bk" baseName
|| baseName == ".nixos-test-history"
|| (baseName == ".direnv" && type == "directory");
cleanSourceWithGitignore =
src:
lib.cleanSourceWith {
src = lib.cleanSource src;
filter = filterGitignore;
};
cargoManifest = (pkgs.lib.importTOML ./Cargo.toml).package;
in
{
system-manager = pkgs.callPackage (
{
rustPlatform,
dbus,
pkg-config,
makeWrapper,
nix,
}:
rustPlatform.buildRustPackage {
pname = "system-manager";
version = cargoManifest.version;
src = cleanSourceWithGitignore ./.;
cargoLock.lockFile = ./Cargo.lock;
buildInputs = [ dbus ];
nativeBuildInputs = [
pkg-config
makeWrapper
];
checkType = "debug"; # might not be required?
# TODO: Is prefixing nix here the correct approach?
postFixup = ''
wrapProgram $out/bin/system-manager \
--prefix PATH : ${lib.makeBinPath [ nix ]}
'';
}
) { };
}

View file

@ -1,7 +1,42 @@
{
pkgs ? import <nixpkgs> { },
}:
let let
compat = builtins.fetchTarball { llvm = pkgs.llvmPackages_latest;
url = "https://github.com/edolstra/flake-compat/archive/b4a34015c698c7793d592d66adbab377907a2be8.tar.gz";
sha256 = "sha256:1qc703yg0babixi6wshn5wm2kgl5y1drcswgszh4xxzbrwkk9sv7";
};
in in
(import compat { src = ./.; }).shellNix.default pkgs.mkShellNoCC {
shellHook = ''
${pkgs.pre-commit}/bin/pre-commit install --install-hooks --overwrite
export PKG_CONFIG_PATH="${
pkgs.lib.makeSearchPath "lib/pkgconfig" [
pkgs.dbus.dev
pkgs.systemdMinimal.dev
]
}"
export LIBCLANG_PATH="${llvm.libclang}/lib"
# for rust-analyzer
export RUST_SRC_PATH="${pkgs.rustPlatform.rustLibSrc}"
export RUST_BACKTRACE=1
export RUSTFLAGS="${
pkgs.lib.concatStringsSep " " [
"-L${pkgs.lib.getLib pkgs.systemdMinimal}/lib"
"-lsystemd"
]
}"
'';
buildInputs = with pkgs; [
dbus
];
nativeBuildInputs = with pkgs; [
llvm.clang
pkg-config
rustc
cargo
# Formatting
pre-commit
treefmt
nixfmt-rfc-style
rustfmt
clippy
];
}

View file

@ -15,7 +15,7 @@ let
projectTest ? test: test.sandboxed, projectTest ? test: test.sandboxed,
}: }:
let let
ubuntu = nix-vm-test.lib.${system}.ubuntu; ubuntu = nix-vm-test.ubuntu;
in in
lib.listToAttrs ( lib.listToAttrs (
lib.flip map (lib.attrNames ubuntu.images) ( lib.flip map (lib.attrNames ubuntu.images) (