nix-openwrt-imagebuilder icon indicating copy to clipboard operation
nix-openwrt-imagebuilder copied to clipboard

How to install custom packages?

Open jfly opened this issue 1 year ago • 9 comments

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.

jfly avatar Feb 28 '24 06:02 jfly

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')

astro avatar Feb 28 '24 11:02 astro

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?

jfly avatar Feb 28 '24 18:02 jfly

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')

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 avatar May 25 '24 12:05 pedorich-n

@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)?

jfly avatar May 27 '24 17:05 jfly

@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: 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 avatar May 28 '24 09:05 pedorich-n

@pedorich-n thanks for your recent changes! It looks like I can finally drop my awful fork to accomplish this =)

jfly avatar Jun 13 '24 06:06 jfly

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.

pedorich-n avatar Jun 13 '24 10:06 pedorich-n

Could we document these new capabilities with an example?

astro avatar Jun 15 '24 20:06 astro

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
            '';
...

GrumpyMeow avatar Dec 09 '24 09:12 GrumpyMeow