at 24.11-pre 3.5 kB view raw
1{ config, pkgs, lib, ... }: 2with lib; 3let 4 cfg = config.virtualisation.digitalOcean; 5 defaultConfigFile = pkgs.writeText "digitalocean-configuration.nix" '' 6 { modulesPath, lib, ... }: 7 { 8 imports = lib.optional (builtins.pathExists ./do-userdata.nix) ./do-userdata.nix ++ [ 9 (modulesPath + "/virtualisation/digital-ocean-config.nix") 10 ]; 11 } 12 ''; 13in { 14 options.virtualisation.digitalOcean.rebuildFromUserData = mkOption { 15 type = types.bool; 16 default = true; 17 example = true; 18 description = "Whether to reconfigure the system from Digital Ocean user data"; 19 }; 20 options.virtualisation.digitalOcean.defaultConfigFile = mkOption { 21 type = types.path; 22 default = defaultConfigFile; 23 defaultText = literalMD '' 24 The default configuration imports user-data if applicable and 25 `(modulesPath + "/virtualisation/digital-ocean-config.nix")`. 26 ''; 27 description = '' 28 A path to a configuration file which will be placed at 29 `/etc/nixos/configuration.nix` and be used when switching to 30 a new configuration. 31 ''; 32 }; 33 34 config = { 35 systemd.services.digitalocean-init = mkIf cfg.rebuildFromUserData { 36 description = "Reconfigure the system from Digital Ocean userdata on startup"; 37 wantedBy = [ "network-online.target" ]; 38 unitConfig = { 39 ConditionPathExists = "!/etc/nixos/do-userdata.nix"; 40 After = [ "digitalocean-metadata.service" "network-online.target" ]; 41 Requires = [ "digitalocean-metadata.service" ]; 42 X-StopOnRemoval = false; 43 }; 44 serviceConfig = { 45 Type = "oneshot"; 46 RemainAfterExit = true; 47 }; 48 restartIfChanged = false; 49 path = [ pkgs.jq pkgs.gnused pkgs.gnugrep config.systemd.package config.nix.package config.system.build.nixos-rebuild ]; 50 environment = { 51 HOME = "/root"; 52 NIX_PATH = concatStringsSep ":" [ 53 "/nix/var/nix/profiles/per-user/root/channels/nixos" 54 "nixos-config=/etc/nixos/configuration.nix" 55 "/nix/var/nix/profiles/per-user/root/channels" 56 ]; 57 }; 58 script = '' 59 set -e 60 echo "attempting to fetch configuration from Digital Ocean user data..." 61 userData=$(mktemp) 62 if jq -er '.user_data' /run/do-metadata/v1.json > $userData; then 63 # If the user-data looks like it could be a nix expression, 64 # copy it over. Also, look for a magic three-hash comment and set 65 # that as the channel. 66 if nix-instantiate --parse $userData > /dev/null; then 67 channels="$(grep '^###' "$userData" | sed 's|###\s*||')" 68 printf "%s" "$channels" | while read channel; do 69 echo "writing channel: $channel" 70 done 71 72 if [[ -n "$channels" ]]; then 73 printf "%s" "$channels" > /root/.nix-channels 74 nix-channel --update 75 fi 76 77 echo "setting configuration from Digital Ocean user data" 78 cp "$userData" /etc/nixos/do-userdata.nix 79 if [[ ! -e /etc/nixos/configuration.nix ]]; then 80 install -m0644 ${cfg.defaultConfigFile} /etc/nixos/configuration.nix 81 fi 82 else 83 echo "user data does not appear to be a Nix expression; ignoring" 84 exit 85 fi 86 87 nixos-rebuild switch 88 else 89 echo "no user data is available" 90 fi 91 ''; 92 }; 93 }; 94 meta.maintainers = with maintainers; [ arianvp eamsden ]; 95}