I’m trying to create a simple flake to abstract away the process of multiarch docker manifests and I’m not sure how to define the interface for my flake’s outputs.
Currently I have a function pushAll under lib but it’s awkward because pushAll takes pkgs which isn’t very idiomatic for something that is not really a lib function but is more of a package.
I think you might be getting mixed up just because:
Flake packages are defined on a per-system basis, so you are trying to create a package dynamically for each system. This makes sense.
Your pushAll function looks like it expects to push multiple architectures from one flake package in one script. This is much more complicated.
We need to be clear that there’s a difference between generating multi-arch flake packages (default.x86_64-linux, default.aarch64-linux, etc.) and actually cross-compiling Docker push.
If you just want to be able to push a Docker package from any supported system, I think something like this would most likely work (I haven’t tested it):
I figured an app would be better than a package because you probably have no reason to just build it on your own. Instead you would run it directly as an app: nix run .. From any system, it would automatically run on its own architecture. Of course, you could also make it a package and it would behave nearly the same way (nix build .; ./result/bin/push).
If you really want a single script to push all architectures, then I’m not sure but you might need to check out the cross-compiling options. I’m not confident that you can simply use Docker pkgs from other architectures natively.
Let me explain some of my thoughts and motivations. I used this script building process before with a couple of my other repositories and it works great for building and pushing multiarch containers since I have cross compilation setup on my desktop. So it’s not a matter of working.
I was more concerned with the user interface for other people consuming my the flake.
This is certainly fine if I’m the only one using my script:
but this doesn’t let me abstract away the process of building the script since it’s quite verbose including all this code in every flake that publishes multiarch docker builds.
If it’s working as a flake, then I’m a bit confused as to where the issue is.
I was more concerned with the user interface for other people consuming my the flake.
If users can just run nix build ., is that not good enough? Maybe you can elaborate on what kind of interface to your flake you are hoping to create.
but this doesn’t let me abstract away the process of building the script since it’s quite verbose including all this code in every flake that publishes multiarch docker builds.
If your issue is copy-pasting between flakes, you could create a central/utility flake that defines this function as an output (package or overlay). Then have your other flakes use your central flake as an input?
I have it working in another flake where everything is hard-coded. All the functions take up a lot of space so I thought I would abstract them out into another flake.
Users can’t just run nix build because the function requires systems and their docker image as input. The could include all of the sub functions that make up the script but that would take up a lot of space in their flake as I mentioned above.
This is the interface I hope to create as I mentioned in my first post:
packages.${system}.pushAllDockerImages = docker-utils.packages.pushAll { systems = [...]; dockerImage = ...;};
I want the consumer flake to pick the systems they want to build and supply their docker image. Copying an pasting the code is not a good option since that’s a lot of code to carry around with all your projects, and sure you could define a central flake which would carry the functions needed to create the script which is exactly what I’m trying to do.
I think I have what I want now. Essentially I use lib like packages I wrap forAllSystems outside of lib and then build my docker script that way. I can still use arguments and I map the proper system.