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