nix-openwrt-imagebuilder
nix-openwrt-imagebuilder copied to clipboard
How to install custom packages?
Is it possible to add custom packages (as documented by OpenWrt here)?
I played around with this for a while, and wasn't able to figure out a way to accomplish this without patching astro/nix-openwrt-imagebuilder. Basically, the only thing passed to make image PACKAGES=... is the packages parameter to the builder, and it appears to be assumed that those packages are the ones available on https://downloads.openwrt.org/.
I'd like to be able to point at either a specific ipk file, or a full package repository.
Happy to send in a PR implementing this if we can agree upon an approach.
Ideally, we could just throw paths into packages but it doesn't work for me as-is:
error: the string '/nix/store/76mxhprmm4hy537x6w9bgilhb56472fw-6rd_9-4_all.ipk' is not allowed to refer to a store path (such as '76mxhprmm4hy537x6w9bgilhb56472fw-6rd_9-4_all.ipk')
From code inspection, I can't immediately tell where that's falling apart. It feels kind of weird to me to use the existing packages argument for this as right now it's just a list of package names (strings possibly prefixed with a -), the sort of thing you could pass to make image PACKAGES=.... If we wanted to support paths as well, wouldn't we need to do some clever parsing of the filename to deduce the human readable package name so we could pass it into make image PACKAGES=...? Or perhaps I don't quite understand what the underlying openwrt imagebuilder Makefile supports?
Ideally, we could just throw paths into
packagesbut it doesn't work for me as-is:error: the string '/nix/store/76mxhprmm4hy537x6w9bgilhb56472fw-6rd_9-4_all.ipk' is not allowed to refer to a store path (such as '76mxhprmm4hy537x6w9bgilhb56472fw-6rd_9-4_all.ipk')
It won't work with packages, because packages is a list of package names (strings), like @jfly mentioned.
It could be implemented with a new attr, something like customPackages which will be a list of paths. And then the configurePhase would need to be modified to symlink ipk files from these paths into packages.
I was able to achieve it with the following override:
(openwrt-imagebuilder-lib.build config).overrideAttrs (final: previous: {
passAsFile = (previous.passAsFile or [ ]) ++ [ "customPackages" ];
customPackages = [ ... ];
configurePhase = ''
for pkg in $(cat $customPackagesPath); do
for ipk in $pkg/*.ipk; do
ln -s $ipk packages/$(stripHash $ipk)
done
done
${previous.configurePhase or ""}
'';
})
It's not perfect, as it assumes customPackages is a list of folders, but it should be easy to make it work with both files and folders.
Also: the dependencies for these custom packages have to be provided manually in packages.
@pedorich-n, I'm not totally understanding the code you shared. Don't you need to somehow invoke openwrt's underlying makefile with additional strings specified in the PACKAGES argument (as I've done here: https://github.com/jfly/nix-openwrt-imagebuilder/commit/53f1a8a1287ec024eb2aa1325b38ab60e701b02d#diff-cd5a1dc9ff54d6ea98c183cce514f03e0582473dfe2f71811709c6fa30728b40R111)?
@pedorich-n, I'm not totally understanding the code you shared. Don't you need to somehow invoke openwrt's underlying makefile with additional strings specified in the
PACKAGESargument (as I've done here: jfly@53f1a8a#diff-cd5a1dc9ff54d6ea98c183cce514f03e0582473dfe2f71811709c6fa30728b40R111)?
You are correct. Adding anipk to the packages just makes it available to the builder. I must've installed the package manually and forgot about it, thinking the builder added it 🤦♂️
@pedorich-n thanks for your recent changes! It looks like I can finally drop my awful fork to accomplish this =)
It's not ideal, you'll have to redefine the env variables like profile, disabled services, and packages, but at least you can do it now without a fork, with just an overrideAttrs.
Could we document these new capabilities with an example?
With my limited NixOS knowledge i've seem to be able to add a single ipk-package. I did it like this:
let
profiles = openwrt-imagebuilder.lib.profiles { inherit pkgs; };
unregulatoryIPK = builtins.fetchurl {
url = "https://orca.pet/unregulatory/openwrt/wireless-regdb_9999.0002_all.ipk";
sha256 = "1gfqgyd6vjdind4pl601gw3w4dqalz2s2c7p63aw51s4smvvlz5v";
};
unregulatoryPUB = builtins.fetchurl {
url = "https://orca.pet/unregulatory/unregulatory.pub";
sha256 = "0iy63flj51kdwb89fcql9v48890gzq41z7l9848j2wmycg0whwpn";
};
config = profiles.identifyProfile "ubnt_unifiac-mesh" // {
packages = [
"zabbix-agentd" "zabbix-extra-network" "zabbix-extra-mac80211" "zabbix-extra-wifi" "coreutils-who"
"watchcat" "luci-app-watchcat" "iperf3" "nano"
"usteer" "luci-app-usteer"
"-wpad-basic-mbedtls" "wpad-mbedtls" "hostapd-utils"
"luci" "luci-i18n-base-nl" "luci-mod-dashboard"
"-firewall4 -luci-app-firewall"
"ttyd" "luci-app-ttyd"
];
release = vars.openwrt.release;
target = "ath79";
variant = "generic";
profile = "ubnt_unifiac-mesh";
EXTRA_IMAGE_NAME = "ap-buiten";
disabledServices = [ "dnsmasq" "firewall" "odhcpd" ];
files = pkgs.runCommand "image-files" { } ''
mkdir -p $out/root
cp ${unregulatoryIPK} $out/root
cp ${unregulatoryPUB} $out/root
mkdir -p $out/etc/uci-defaults
cat > $out/etc/uci-defaults/99-orca <<EOF
echo "src/gz unregulatory https://orca.pet/unregulatory/openwrt" >> /etc/opkg/customfeeds.conf
opkg-key add /root/$(basename ${unregulatoryPUB}) && rm /root/$(basename ${unregulatoryPUB})
opkg install /root/$(basename ${unregulatoryIPK}) && rm /root/$(basename ${unregulatoryIPK})
EOF
'';
...