deploy-rs
deploy-rs copied to clipboard
add support for asynchronous building and pushing of profiles
NB: I have opened this Pull Request as a draft since I intend to continue working on it by improving the logging output. Since the builds are started concurrently, the build progress information is pretty much useless and flickers a lot.
Problem
The current implementation builds every single profile synchronously, including remote builds. Since remote builds were introduced back in #175, remote builds could be pipelined to deploy new configurations in a more time-efficient manner.
Solution
Build configurations that support remote builds concurrently.
Sidenote: I have decided to continue building local builds in a synchronous manner because I have run into hardware deadlocks previously when trying to evaluate and/or build multiple systems at the same time.
I have tested this code by deploying to my personal infrastructure (https://github.com/philtaken/dotfiles) and it works as intended.
mentioning #46 for visibility
the current version works as expected, the only issue is the log flickering with multiple invocations of nix writing to stdout in parallel. I was considering utilising the raw-internal-json output similarly to how nix-output-monitor does it but that might be out of scope here 🤔
activation is fully synchronous but that is usually the part that takes the least amount of time
The new approach seems good 👍
there are a still lot of unwraps that need to be handled better, this pr is still far from finished but progress has been made:
I added some progress indicators using the indicatif crate for each concurrent build 🥳
This is what they look like (image the spinner spinning and the text changing as nix builds stuff:
For remote and builds each host gets its own progress spinner that is reused for all of that hosts profiles since they are built in order anyways. This could be adjusted for multi-profile hosts since indicatif also supports nested tree-like progress bars.
I changed some data structures around to make working with them in async contexts easier. The nested references are somewhat ok until you have to make them work in a async context where you need send objects. deep cloning by hand really isn't a great solution and it really doesnt make any difference performance-wise to add some clones here and there. Nobody is going to deploy to >10k hosts and if they would, cloning the deploy data a few times would be the least of their problems. This also removes a bunch of generic lifetime specifiers which I am not sad about.
With these two last commits I would declare this PR somewhat usable 🥳
If anyone wants to try it out with their own setups I would be very happy to hear how it works for you, I am always open for feedback of any kind
Hi all, I tried this out, with my setup in ManoftheSea/SeaofDirac/trunk, on targets [littlecreek, crunchbits, technetium]. I saw that it ran the checks for all the systems, which meant building them locally, then proceeded with pushing profiles to the systems in parallel (which resulted in building them remotely, I believe). After all three were ready, they deployed in sequence, and as it was just an update, they all completed happily.
This works well for these three systems, which are a pair of VPSes and a local (to me) server; were I trying to deploy all the systems in my home network, I would prefer instead that my development machine (personal laptop) be able to push the profiles to a single server (technetium), so that it can then act as a substituter for e.g. aluminium and nickel. Maybe provide a "build-host" attribute per-host, with a default of the hostself? e.g. deploy.nickel.buildHost = "technetium"; deploy.littlecreek.buildHost = "littlecreek";