Run commands along with `nixos-install`

I want to be able to declare inside of my configuration.nix file some commands that need to run as a part of nixos-install, preferably either after the command finishes everything else, or after a specified user gets created. The commands I am going to run are cloning some Git repos (some user dotfiles I’ll specify with Home Manager to have it pick them up and get them into the Nix store, along with the repo where I store configuration.nix), making some folders (where I would clone said Git repos, basically creating the directory structure for my dotfiles and other repos inside of my home directory), making some symlinks (linking configuration.nix from the Git repos I clone to /etc/), and likely also setting up Home Manager for a user I specify for Nix to create for me.

I do not know how to phrase this differently, but it is my third attempt to ask almost the same question. This is basically the same question as this and this, it’s just that I adjusted myself to the answers I’ve got in these previous topics.

Can anyone help me please? It’s the last step towards seriously giving NixOS a try as a daily driver, but I cannot continue without doing this. I really don’t want to do something manually in an OS all about automation.

1 Like

I haven’t had a chance to look into it, but I have had git-repo-manager in the back of my mind for a while to handle “declarative git repo management”. I’m particularly interested because I want to run a single command to ensure my ~/code tree is all pushed to git, such that I can run another command on another machine and make sure it’s similarly all pulled from git.

My goals are to have a set of development repos that are in-sync across machines, and also so that I can randomly boot a “bigger dev machine” for 8 hours at a time and know that all my repos are cloned and ready to go.

I wonder if git-repo-manager along with a home-manager systemd user service to run it every so often could be interesting.

You might consider defining a systemd service in your configuration that runs on boot and has the ConditionPathExists=!/path/to/repos directive(s) to check that your dotfiles path doesn’t exist before running the various command(s) (or a script with the commands). You just put all the commands into a script, or define multipleExecStart or ExecStartPre lines.

You can also look into systemd-tmpfiles for creating directories/links.

Hmm… is this better than the solution I thought of here? It does basically the same thing

Also, how can I be sure all this is going to happen before the first user log in?

And, I’m probably nitpicking here, but I’ll run my configurations on laptops too. The first boot into the system will not have an internet connection because the WiFi isn’t configured, but it would be in the live install system. That’s why I want it to run while nixos-install runs. In the live media I use to install NixOS I would’ve already configured my internet connection. What I want as a result of these commands running is that the first boot is fully configured (which I will make sure will happen with my scripts), and does not require some waiting/an internet connection

I would clone four repos, this wouldn’t really help me as it is made to clone many repos. Plus, how do I install and run it before the first boot too?

Well, maybe look at system.ActivationScipts. Just ensure you have logic at the beginning of the script to exit quickly if it detects that the directories you want to create already exist. This should run during the initial setup as well as during subsequent boots/rebuilds.

Alright. My only other question is: I know it runs on nixos-install, as well as on nixos-rebuild, and I need some simple logic to make the script run only once, but when does it run while nixos-install runs? I’d need environment.systemPackages to get installed first so that I can get Git to clone the repos with, and I would need users declared in users.users to get created first as well, so that I can su into my user and get home-manager set up too.

Unless I’m missing something, that’s the beauty of a declarative system: if it’s declared in the configuration, Nix will figure out what needs to happen to put the system into that state.

GIve it a try in a VM and see if it works for you.

So you’re telling me that just because my activation script contains git commands it’ll ensure git is installed and because I su into my user it’ll ensure the user exists before those commands run? I managed to write my entire activation script but I didn’t get around to testing it yet.