96 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, pkgs, lib, ... }:
 | 
						|
with lib;
 | 
						|
let
 | 
						|
  cfg = config.virtualisation.digitalOcean;
 | 
						|
  defaultConfigFile = pkgs.writeText "digitalocean-configuration.nix" ''
 | 
						|
    { modulesPath, lib, ... }:
 | 
						|
    {
 | 
						|
      imports = lib.optional (builtins.pathExists ./do-userdata.nix) ./do-userdata.nix ++ [
 | 
						|
        (modulesPath + "/virtualisation/digital-ocean-config.nix")
 | 
						|
      ];
 | 
						|
    }
 | 
						|
  '';
 | 
						|
in {
 | 
						|
  options.virtualisation.digitalOcean.rebuildFromUserData = mkOption {
 | 
						|
    type = types.bool;
 | 
						|
    default = true;
 | 
						|
    example = true;
 | 
						|
    description = "Whether to reconfigure the system from Digital Ocean user data";
 | 
						|
  };
 | 
						|
  options.virtualisation.digitalOcean.defaultConfigFile = mkOption {
 | 
						|
    type = types.path;
 | 
						|
    default = defaultConfigFile;
 | 
						|
    defaultText = ''
 | 
						|
      The default configuration imports user-data if applicable and
 | 
						|
      <literal>(modulesPath + "/virtualisation/digital-ocean-config.nix")</literal>.
 | 
						|
    '';
 | 
						|
    description = ''
 | 
						|
      A path to a configuration file which will be placed at
 | 
						|
      <literal>/etc/nixos/configuration.nix</literal> and be used when switching to
 | 
						|
      a new configuration.
 | 
						|
    '';
 | 
						|
  };
 | 
						|
 | 
						|
  config = {
 | 
						|
    systemd.services.digitalocean-init = mkIf cfg.rebuildFromUserData {
 | 
						|
      description = "Reconfigure the system from Digital Ocean userdata on startup";
 | 
						|
      wantedBy = [ "network-online.target" ];
 | 
						|
      unitConfig = {
 | 
						|
        ConditionPathExists = "!/etc/nixos/do-userdata.nix";
 | 
						|
        After = [ "digitalocean-metadata.service" "network-online.target" ];
 | 
						|
        Requires = [ "digitalocean-metadata.service" ];
 | 
						|
        X-StopOnRemoval = false;
 | 
						|
      };
 | 
						|
      serviceConfig = {
 | 
						|
        Type = "oneshot";
 | 
						|
        RemainAfterExit = true;
 | 
						|
      };
 | 
						|
      restartIfChanged = false;
 | 
						|
      path = [ pkgs.jq pkgs.gnused pkgs.gnugrep pkgs.systemd config.nix.package config.system.build.nixos-rebuild ];
 | 
						|
      environment = {
 | 
						|
        HOME = "/root";
 | 
						|
        NIX_PATH = concatStringsSep ":" [
 | 
						|
          "/nix/var/nix/profiles/per-user/root/channels/nixos"
 | 
						|
          "nixos-config=/etc/nixos/configuration.nix"
 | 
						|
          "/nix/var/nix/profiles/per-user/root/channels"
 | 
						|
        ];
 | 
						|
      };
 | 
						|
      script = ''
 | 
						|
        set -e
 | 
						|
        echo "attempting to fetch configuration from Digital Ocean user data..."
 | 
						|
        userData=$(mktemp)
 | 
						|
        if jq -er '.user_data' /run/do-metadata/v1.json > $userData; then
 | 
						|
          # If the user-data looks like it could be a nix expression,
 | 
						|
          # copy it over. Also, look for a magic three-hash comment and set
 | 
						|
          # that as the channel.
 | 
						|
          if nix-instantiate --parse $userData > /dev/null; then
 | 
						|
            channels="$(grep '^###' "$userData" | sed 's|###\s*||')"
 | 
						|
            printf "%s" "$channels" | while read channel; do
 | 
						|
              echo "writing channel: $channel"
 | 
						|
            done
 | 
						|
 | 
						|
            if [[ -n "$channels" ]]; then
 | 
						|
              printf "%s" "$channels" > /root/.nix-channels
 | 
						|
              nix-channel --update
 | 
						|
            fi
 | 
						|
 | 
						|
            echo "setting configuration from Digital Ocean user data"
 | 
						|
            cp "$userData" /etc/nixos/do-userdata.nix
 | 
						|
            if [[ ! -e /etc/nixos/configuration.nix ]]; then
 | 
						|
              install -m0644 ${cfg.defaultConfigFile} /etc/nixos/configuration.nix
 | 
						|
            fi
 | 
						|
          else
 | 
						|
            echo "user data does not appear to be a Nix expression; ignoring"
 | 
						|
            exit
 | 
						|
          fi
 | 
						|
 | 
						|
          nixos-rebuild switch
 | 
						|
        else
 | 
						|
          echo "no user data is available"
 | 
						|
        fi
 | 
						|
        '';
 | 
						|
    };
 | 
						|
  };
 | 
						|
  meta.maintainers = with maintainers; [ arianvp eamsden ];
 | 
						|
}
 |