at 24.11-pre 2.8 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.virtualisation.amazon-init; 7 8 script = '' 9 #!${pkgs.runtimeShell} -eu 10 11 echo "attempting to fetch configuration from EC2 user data..." 12 13 export HOME=/root 14 export PATH=${pkgs.lib.makeBinPath [ config.nix.package config.systemd.package pkgs.gnugrep pkgs.git pkgs.gnutar pkgs.gzip pkgs.gnused pkgs.xz config.system.build.nixos-rebuild]}:$PATH 15 export NIX_PATH=nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels 16 17 userData=/etc/ec2-metadata/user-data 18 19 # Check if user-data looks like a shell script and execute it with the 20 # runtime shell if it does. Otherwise treat it as a nixos configuration 21 # expression 22 if IFS= LC_ALL=C read -rN2 shebang < $userData && [ "$shebang" = '#!' ]; then 23 # NB: we cannot chmod the $userData file, this is why we execute it via 24 # `pkgs.runtimeShell`. This means we have only limited support for shell 25 # scripts compatible with the `pkgs.runtimeShell`. 26 exec ${pkgs.runtimeShell} $userData 27 fi 28 29 if [ -s "$userData" ]; then 30 # If the user-data looks like it could be a nix expression, 31 # copy it over. Also, look for a magic three-hash comment and set 32 # that as the channel. 33 if sed '/^\(#\|SSH_HOST_.*\)/d' < "$userData" | grep -q '\S'; then 34 channels="$(grep '^###' "$userData" | sed 's|###\s*||')" 35 while IFS= read -r channel; do 36 echo "writing channel: $channel" 37 done < <(printf "%s\n" "$channels") 38 39 if [[ -n "$channels" ]]; then 40 printf "%s" "$channels" > /root/.nix-channels 41 nix-channel --update 42 fi 43 44 echo "setting configuration from EC2 user data" 45 cp "$userData" /etc/nixos/configuration.nix 46 else 47 echo "user data does not appear to be a Nix expression; ignoring" 48 exit 49 fi 50 else 51 echo "no user data is available" 52 exit 53 fi 54 55 nixos-rebuild switch 56 ''; 57in { 58 59 options.virtualisation.amazon-init = { 60 enable = mkOption { 61 default = true; 62 type = types.bool; 63 description = '' 64 Enable or disable the amazon-init service. 65 ''; 66 }; 67 }; 68 69 config = mkIf cfg.enable { 70 systemd.services.amazon-init = { 71 inherit script; 72 description = "Reconfigure the system from EC2 userdata on startup"; 73 74 wantedBy = [ "multi-user.target" ]; 75 after = [ "multi-user.target" ]; 76 requires = [ "network-online.target" ]; 77 78 restartIfChanged = false; 79 unitConfig.X-StopOnRemoval = false; 80 81 serviceConfig = { 82 Type = "oneshot"; 83 RemainAfterExit = true; 84 }; 85 }; 86 }; 87 meta.maintainers = with maintainers; [ arianvp ]; 88}