show duplication
This commit is contained in:
@@ -1,27 +1,12 @@
|
|||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
runCommand,
|
pkgs,
|
||||||
makeInitrdNG,
|
|
||||||
uutils-coreutils-noprefix,
|
|
||||||
bash,
|
|
||||||
util-linux,
|
|
||||||
e2fsprogs,
|
|
||||||
dosfstools,
|
|
||||||
parted,
|
|
||||||
vim-full,
|
|
||||||
findutils,
|
|
||||||
gnugrep,
|
|
||||||
procps,
|
|
||||||
less,
|
|
||||||
writeScript,
|
|
||||||
kmod,
|
|
||||||
linuxPackages_latest,
|
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
# Simple init script
|
# Simple init script
|
||||||
init = writeScript "init" ''
|
init = pkgs.writeScript "init" ''
|
||||||
#!${bash}/bin/bash
|
#!${pkgs.bash}/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Set up PATH first
|
# Set up PATH first
|
||||||
@@ -42,46 +27,74 @@ let
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
# Packages to include (all binaries from each package will be included)
|
# Packages to include (all binaries from each package will be included)
|
||||||
packages = [
|
packages = with pkgs; [
|
||||||
uutils-coreutils-noprefix
|
vim
|
||||||
bash
|
bash
|
||||||
util-linux
|
|
||||||
e2fsprogs
|
|
||||||
dosfstools
|
|
||||||
parted
|
|
||||||
vim-full
|
|
||||||
findutils
|
|
||||||
gnugrep
|
|
||||||
procps
|
|
||||||
less
|
less
|
||||||
kmod
|
kmod
|
||||||
|
parted
|
||||||
|
procps
|
||||||
|
gnugrep
|
||||||
|
findutils
|
||||||
|
e2fsprogs
|
||||||
|
dosfstools
|
||||||
|
btrfs-progs
|
||||||
|
util-linux
|
||||||
|
uutils-coreutils-noprefix
|
||||||
];
|
];
|
||||||
|
|
||||||
# Generate binary entries for makeInitrdNG by auto-discovering all binaries
|
# Generate binary entries for makeInitrdNG by auto-discovering all binaries
|
||||||
binaryEntries =
|
binaryEntries =
|
||||||
let
|
let
|
||||||
allEntries = lib.flatten (
|
# Collect all entries with package info
|
||||||
|
allEntriesWithPkg = lib.flatten (
|
||||||
map (
|
map (
|
||||||
pkg:
|
pkg:
|
||||||
let
|
let
|
||||||
binDir = "${pkg}/bin";
|
binDir = "${pkg}/bin";
|
||||||
# Get all files in the bin directory
|
# Get all files in the bin directory
|
||||||
binFiles = if builtins.pathExists binDir then builtins.attrNames (builtins.readDir binDir) else [ ];
|
binFiles = if builtins.pathExists binDir then builtins.attrNames (builtins.readDir binDir) else [ ];
|
||||||
|
pkgName = pkg.name or (builtins.baseNameOf (builtins.toString pkg));
|
||||||
in
|
in
|
||||||
map (bin: {
|
map (bin: {
|
||||||
source = "${binDir}/${bin}";
|
source = "${binDir}/${bin}";
|
||||||
target = "/bin/${bin}";
|
target = "/bin/${bin}";
|
||||||
|
package = pkgName;
|
||||||
|
binary = bin;
|
||||||
}) binFiles
|
}) binFiles
|
||||||
) packages
|
) packages
|
||||||
);
|
);
|
||||||
# Deduplicate by target path, keeping first occurrence
|
|
||||||
|
# Build map of binary -> list of packages providing it
|
||||||
|
binaryMap = lib.foldl' (
|
||||||
|
acc: entry:
|
||||||
|
let
|
||||||
|
existing = acc.${entry.binary} or [ ];
|
||||||
|
in
|
||||||
|
acc // { ${entry.binary} = existing ++ [ entry.package ]; }
|
||||||
|
) { } allEntriesWithPkg;
|
||||||
|
|
||||||
|
# Deduplicate by target path, keeping first occurrence and warning about duplicates
|
||||||
deduped = lib.foldl' (
|
deduped = lib.foldl' (
|
||||||
acc: entry: if builtins.any (e: e.target == entry.target) acc then acc else acc ++ [ entry ]
|
acc: entry:
|
||||||
) [ ] allEntries;
|
let
|
||||||
|
alreadyExists = builtins.any (e: e.target == entry.target) acc;
|
||||||
|
providers = binaryMap.${entry.binary};
|
||||||
|
hasDuplicates = builtins.length providers > 1;
|
||||||
|
in
|
||||||
|
if alreadyExists then
|
||||||
|
acc
|
||||||
|
else if hasDuplicates then
|
||||||
|
builtins.trace
|
||||||
|
"Warning: binary '${entry.binary}' provided by multiple packages: ${builtins.concatStringsSep ", " providers}. Chose: ${entry.package}"
|
||||||
|
(acc ++ [ entry ])
|
||||||
|
else
|
||||||
|
acc ++ [ entry ]
|
||||||
|
) [ ] allEntriesWithPkg;
|
||||||
in
|
in
|
||||||
deduped;
|
deduped;
|
||||||
|
|
||||||
initrd = makeInitrdNG {
|
initrd = pkgs.makeInitrdNG {
|
||||||
name = "mrescue-initrd";
|
name = "mrescue-initrd";
|
||||||
compressor = "zstd";
|
compressor = "zstd";
|
||||||
compressorArgs = [
|
compressorArgs = [
|
||||||
@@ -91,14 +104,12 @@ let
|
|||||||
];
|
];
|
||||||
|
|
||||||
contents = [
|
contents = [
|
||||||
# Init script
|
|
||||||
{
|
{
|
||||||
source = init;
|
source = init;
|
||||||
target = "/init";
|
target = "/init";
|
||||||
}
|
}
|
||||||
# Kernel modules (not ELF binaries, must be added manually)
|
|
||||||
{
|
{
|
||||||
source = "${linuxPackages_latest.kernel.modules}/lib/modules";
|
source = "${pkgs.linuxPackages_latest.kernel.modules}/lib/modules";
|
||||||
target = "/lib/modules";
|
target = "/lib/modules";
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -107,9 +118,9 @@ let
|
|||||||
|
|
||||||
in
|
in
|
||||||
# Package both kernel and initrd together
|
# Package both kernel and initrd together
|
||||||
runCommand "mrescue" { } ''
|
pkgs.runCommand "mrescue" { } ''
|
||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
ln -s ${linuxPackages_latest.kernel}/bzImage $out/bzImage
|
ln -s ${pkgs.linuxPackages_latest.kernel}/bzImage $out/bzImage
|
||||||
ln -s ${initrd}/initrd $out/initrd
|
ln -s ${initrd}/initrd $out/initrd
|
||||||
ln -s ${initrd}/initrd $out/initrd.zst
|
ln -s ${initrd}/initrd $out/initrd.zst
|
||||||
''
|
''
|
||||||
|
|||||||
Reference in New Issue
Block a user