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