v1 of duckdns update service.
This commit is contained in:
		
							parent
							
								
									093a4d82e3
								
							
						
					
					
						commit
						45132109d7
					
				
					 8 changed files with 89 additions and 112 deletions
				
			
		
							
								
								
									
										6
									
								
								modules/nixos/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/nixos/default.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
{
 | 
			
		||||
  imports = [
 | 
			
		||||
    ./duckdns.nix
 | 
			
		||||
    ./hostopts.nix
 | 
			
		||||
  ];
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								modules/nixos/duckdns.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								modules/nixos/duckdns.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
{
 | 
			
		||||
  inputs,
 | 
			
		||||
  config,
 | 
			
		||||
  pkgs,
 | 
			
		||||
  lib,
 | 
			
		||||
  ...
 | 
			
		||||
}: let
 | 
			
		||||
  cfg = config.services.duckdns;
 | 
			
		||||
  urlFile = pkgs.writeText "curlurl" "url=https://www.duckdns.org/update?domains=@domains_placeholder@&token=@token_placeholder@&ip=";
 | 
			
		||||
in {
 | 
			
		||||
  # partially taken from https://github.com/NixOS/nixpkgs/pull/294489
 | 
			
		||||
  options = {
 | 
			
		||||
    services.duckdns = {
 | 
			
		||||
      enable = lib.mkEnableOption "Enable duckdns updating";
 | 
			
		||||
      tokenFile = lib.mkOption {
 | 
			
		||||
        default = null;
 | 
			
		||||
        type = lib.types.path;
 | 
			
		||||
        description = ''
 | 
			
		||||
          The path to a file containing the token
 | 
			
		||||
          used to authenticate with DuckDNS.
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
      domains = lib.mkOption {
 | 
			
		||||
        type = lib.types.nullOr (lib.types.listOf lib.types.str);
 | 
			
		||||
        example = ["examplehost"];
 | 
			
		||||
        description = lib.mdDoc ''
 | 
			
		||||
          The record(s) to update in DuckDNS
 | 
			
		||||
          (without the .duckdns.org prefix)
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
      domainsFile = lib.mkOption {
 | 
			
		||||
        default = null;
 | 
			
		||||
        type = lib.types.nullOr lib.types.path;
 | 
			
		||||
        description = ''
 | 
			
		||||
          The path to a file containing a
 | 
			
		||||
          newline-separated list of DuckDNS
 | 
			
		||||
          domain(s) to be updated
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
  assertions = [
 | 
			
		||||
    {
 | 
			
		||||
      assertion = cfg.domains != null || cfg.domainsFile != null;
 | 
			
		||||
      message = "services.duckdns.domains or services.duckdns.domainsFile has to be defined";
 | 
			
		||||
    }
 | 
			
		||||
  ];
 | 
			
		||||
  config = lib.mkIf cfg.enable {
 | 
			
		||||
    systemd.services.duckdns = {
 | 
			
		||||
      description = "DuckDNS Dynamic DNS Client";
 | 
			
		||||
      after = ["network.target"];
 | 
			
		||||
      wantedBy = ["multi-user.target"];
 | 
			
		||||
      # every 5 minutes
 | 
			
		||||
      startAt = "*:00/5:00";
 | 
			
		||||
      serviceConfig = {
 | 
			
		||||
        Type = "simple";
 | 
			
		||||
        DynamicUser = true;
 | 
			
		||||
        RuntimeDirectory = "duckdns-update";
 | 
			
		||||
        RuntimeDirectoryMode = "700";
 | 
			
		||||
      };
 | 
			
		||||
      script = ''
 | 
			
		||||
        install --mode 600 ${urlFile} $RUNTIME_DIRECTORY/curlurl
 | 
			
		||||
        # replace the token
 | 
			
		||||
        ${pkgs.replace-secret}/bin/replace-secret @token_placeholder@ ${cfg.tokenFile} $RUNTIME_DIRECTORY/curlurl
 | 
			
		||||
 | 
			
		||||
        # initalise the replacement file for the domains from the domains file if it exists, otherwise make it empty.
 | 
			
		||||
        install --mode 600 ${if (cfg.domainsFile != null) then cfg.domainsFile else "/dev/null"} $RUNTIME_DIRECTORY/domains
 | 
			
		||||
        # these are already in the nix store, so doesnt matter if they leak via cmdline.
 | 
			
		||||
        echo '${lib.strings.concatStringsSep "\n" cfg.domains}' >>  $RUNTIME_DIRECTORY/domains
 | 
			
		||||
        ${pkgs.gnused}/bin/sed -zi 's/\n/,/g' $RUNTIME_DIRECTORY/domains
 | 
			
		||||
        ${pkgs.replace-secret}/bin/replace-secret @domains_placeholder@ $RUNTIME_DIRECTORY/domains $RUNTIME_DIRECTORY/curlurl
 | 
			
		||||
 | 
			
		||||
        ${pkgs.curl}/bin/curl --no-progress-meter --insecure --config $RUNTIME_DIRECTORY/curlurl | ${pkgs.gnugrep}/bin/grep -v "KO"
 | 
			
		||||
      '';
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								modules/nixos/hostopts.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								modules/nixos/hostopts.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
{
 | 
			
		||||
  config,
 | 
			
		||||
  pkgs,
 | 
			
		||||
  lib,
 | 
			
		||||
  ...
 | 
			
		||||
}: {
 | 
			
		||||
  options = {
 | 
			
		||||
    host = {
 | 
			
		||||
      user = lib.mkOption {
 | 
			
		||||
        type = lib.types.str;
 | 
			
		||||
        description = "Primary human user";
 | 
			
		||||
      };
 | 
			
		||||
      fullName = lib.mkOption {
 | 
			
		||||
        type = lib.types.str;
 | 
			
		||||
        description = "Primary human users long name";
 | 
			
		||||
      };
 | 
			
		||||
      gui.enable = lib.mkEnableOption "enable GUI";
 | 
			
		||||
      isLaptop = lib.mkEnableOption "machine is a laptop";
 | 
			
		||||
      isVm = lib.mkEnableOption "machine is a virtual machine";
 | 
			
		||||
      isSever = lib.mkEnableOption "machine is primarily a server";
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue