53720becf1
Keep the native APK indexes alongside the expanded package metadata so image builds do not fetch mutable repository state. Generate pins atomically and retry transient generation failures.
109 lines
3.4 KiB
Nix
109 lines
3.4 KiB
Nix
{
|
|
description = "Pinned OpenWrt package feed hashes";
|
|
|
|
inputs = {
|
|
nixpkgs.url = "nixpkgs/nixos-unstable";
|
|
openwrt-imagebuilder.url = "github:astro/nix-openwrt-imagebuilder";
|
|
openwrt-imagebuilder.inputs.nixpkgs.follows = "nixpkgs";
|
|
};
|
|
|
|
outputs = { self, nixpkgs, openwrt-imagebuilder }:
|
|
let
|
|
system = "x86_64-linux";
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
|
|
# What `update` regenerates. Each entry becomes a `cache/<release>` tree holding the
|
|
# ImageBuilder hash and the expanded package feeds for that target's architecture.
|
|
pins = [
|
|
{ release = "snapshot"; target = "realtek/rtl930x"; }
|
|
{ release = "25.12.5"; target = "realtek/rtl930x"; }
|
|
];
|
|
|
|
vendorIndexes = pkgs.writeShellApplication {
|
|
name = "vendor-openwrt-indexes";
|
|
runtimeInputs = [ pkgs.curl pkgs.python3 ];
|
|
text = ''
|
|
exec python3 ${./vendor-indexes.py} "$@"
|
|
'';
|
|
};
|
|
|
|
update = pkgs.writeShellApplication {
|
|
name = "update-openwrt-feeds";
|
|
runtimeInputs = [ pkgs.coreutils openwrt-imagebuilder.packages.${system}.release2nix vendorIndexes ];
|
|
text = ''
|
|
release_filter="''${1:-}"
|
|
root="''${2:-$PWD}"
|
|
if [ ! -e "$root/flake.nix" ]; then
|
|
echo "update-openwrt-feeds: $root is not the repository root" >&2
|
|
exit 1
|
|
fi
|
|
cd "$root"
|
|
|
|
generated=$(mktemp -d)
|
|
trap 'rm -rf "$generated"' EXIT
|
|
|
|
generate_release() {
|
|
local release="$1"
|
|
local target="$2"
|
|
local destination="$generated/$release"
|
|
|
|
for attempt in 1 2 3; do
|
|
rm -rf "$destination"
|
|
if release2nix -o "$destination" "$release" "$target" \
|
|
&& vendor-openwrt-indexes "$destination"; then
|
|
return
|
|
fi
|
|
if [ "$attempt" -lt 3 ]; then
|
|
echo "Failed to generate $release; retrying ($attempt/3)" >&2
|
|
sleep 10
|
|
fi
|
|
done
|
|
echo "Failed to generate a consistent $release cache" >&2
|
|
return 1
|
|
}
|
|
|
|
matched=false
|
|
${builtins.concatStringsSep "\n" (map
|
|
({ release, target }: ''
|
|
if [ -z "$release_filter" ] || [ "$release_filter" = '${release}' ]; then
|
|
matched=true
|
|
generate_release '${release}' '${target}'
|
|
fi
|
|
'')
|
|
pins)}
|
|
|
|
${builtins.concatStringsSep "\n" (map
|
|
({ release, ... }: ''
|
|
if [ -d "$generated/${release}" ]; then
|
|
rm -rf 'cache/${release}'
|
|
mv "$generated/${release}" 'cache/${release}'
|
|
fi
|
|
'')
|
|
pins)}
|
|
|
|
if [ "$matched" != true ]; then
|
|
echo "Unknown release: $release_filter" >&2
|
|
exit 1
|
|
fi
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
# Paths to pass as `nix-openwrt-imagebuilder`'s `cachePath`. A flake's source is copied to
|
|
# the store, so these resolve to importable store paths in a consumer.
|
|
cachePaths = builtins.listToAttrs (map
|
|
({ release, ... }: {
|
|
name = release;
|
|
value = ./cache + "/${release}";
|
|
})
|
|
pins);
|
|
|
|
packages.${system}.update = update;
|
|
apps.${system} =
|
|
let
|
|
app = { type = "app"; program = "${update}/bin/update-openwrt-feeds"; };
|
|
in
|
|
{ update = app; default = app; };
|
|
};
|
|
}
|