feat: use treefmt-nix and split up flake.nix
This commit is contained in:
parent
442601f25a
commit
c81d7af356
8 changed files with 284 additions and 256 deletions
32
flake-modules/default.nix
Normal file
32
flake-modules/default.nix
Normal file
|
@ -0,0 +1,32 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.treefmt-nix.flakeModule
|
||||
./package.nix
|
||||
./overlay.nix
|
||||
./module.nix
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
# Setup formatters
|
||||
treefmt = {
|
||||
projectRootFile = "flake.nix";
|
||||
programs = {
|
||||
nixfmt.enable = true;
|
||||
rustfmt.enable = true;
|
||||
statix.enable = true;
|
||||
typos.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShellNoCC {
|
||||
packages = [
|
||||
pkgs.cargo-insta
|
||||
pkgs.cargo-udeps
|
||||
pkgs.mold
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
196
flake-modules/module.nix
Normal file
196
flake-modules/module.nix
Normal file
|
@ -0,0 +1,196 @@
|
|||
let
|
||||
module =
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.webnsupdate;
|
||||
inherit (lib)
|
||||
mkOption
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
types
|
||||
;
|
||||
in
|
||||
{
|
||||
options.services.webnsupdate = mkOption {
|
||||
description = "An HTTP server for nsupdate.";
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "webnsupdate";
|
||||
extraArgs = mkOption {
|
||||
description = ''
|
||||
Extra arguments to be passed to the webnsupdate server command.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--ip-source" ];
|
||||
};
|
||||
package = mkPackageOption pkgs "webnsupdate" { };
|
||||
bindIp = mkOption {
|
||||
description = ''
|
||||
IP address to bind to.
|
||||
|
||||
Setting it to anything other than localhost is very insecure as
|
||||
`webnsupdate` only supports plain HTTP and should always be behind a
|
||||
reverse proxy.
|
||||
'';
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
example = "0.0.0.0";
|
||||
};
|
||||
bindPort = mkOption {
|
||||
description = "Port to bind to.";
|
||||
type = types.port;
|
||||
default = 5353;
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
description = ''
|
||||
The file where the password is stored.
|
||||
|
||||
This file can be created by running `webnsupdate mkpasswd $USERNAME $PASSWORD`.
|
||||
'';
|
||||
type = types.path;
|
||||
example = "/secrets/webnsupdate.pass";
|
||||
};
|
||||
keyFile = mkOption {
|
||||
description = ''
|
||||
The TSIG key that `nsupdate` should use.
|
||||
|
||||
This file will be passed to `nsupdate` through the `-k` option, so look
|
||||
at `man 8 nsupdate` for information on the key's format.
|
||||
'';
|
||||
type = types.path;
|
||||
example = "/secrets/webnsupdate.key";
|
||||
};
|
||||
ttl = mkOption {
|
||||
description = "The TTL that should be set on the zone records created by `nsupdate`.";
|
||||
type = types.ints.positive;
|
||||
default = 60;
|
||||
example = 3600;
|
||||
};
|
||||
records = mkOption {
|
||||
description = ''
|
||||
The fqdn of records that should be updated.
|
||||
|
||||
Empty lines will be ignored, but whitespace will not be.
|
||||
'';
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
example = ''
|
||||
example.com.
|
||||
|
||||
example.org.
|
||||
ci.example.org.
|
||||
'';
|
||||
};
|
||||
recordsFile = mkOption {
|
||||
description = ''
|
||||
The fqdn of records that should be updated.
|
||||
|
||||
Empty lines will be ignored, but whitespace will not be.
|
||||
'';
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/secrets/webnsupdate.records";
|
||||
};
|
||||
user = mkOption {
|
||||
description = "The user to run as.";
|
||||
type = types.str;
|
||||
default = "named";
|
||||
};
|
||||
group = mkOption {
|
||||
description = "The group to run as.";
|
||||
type = types.str;
|
||||
default = "named";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
recordsFile =
|
||||
if cfg.recordsFile != null then cfg.recordsFile else pkgs.writeText "webnsrecords" cfg.records;
|
||||
args = lib.strings.escapeShellArgs (
|
||||
[
|
||||
"--records"
|
||||
recordsFile
|
||||
"--key-file"
|
||||
cfg.keyFile
|
||||
"--password-file"
|
||||
cfg.passwordFile
|
||||
"--address"
|
||||
cfg.bindIp
|
||||
"--port"
|
||||
(builtins.toString cfg.bindPort)
|
||||
"--ttl"
|
||||
(builtins.toString cfg.ttl)
|
||||
"--data-dir=%S/webnsupdate"
|
||||
]
|
||||
++ cfg.extraArgs
|
||||
);
|
||||
cmd = "${lib.getExe cfg.package} ${args}";
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
# warnings =
|
||||
# lib.optional (!config.services.bind.enable) "`webnsupdate` is expected to be used alongside `bind`. This is an unsopported configuration.";
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
(cfg.records != null || cfg.recordsFile != null)
|
||||
&& !(cfg.records != null && cfg.recordsFile != null);
|
||||
message = "Exactly one of `services.webnsupdate.records` and `services.webnsupdate.recordsFile` must be set.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.webnsupdate = {
|
||||
description = "Web interface for nsupdate.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"bind.service"
|
||||
];
|
||||
preStart = "${cmd} verify";
|
||||
path = [ pkgs.dig ];
|
||||
startLimitIntervalSec = 60;
|
||||
serviceConfig = {
|
||||
ExecStart = [ cmd ];
|
||||
Type = "exec";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
# User and group
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
# Runtime directory and mode
|
||||
RuntimeDirectory = "webnsupdate";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
# Cache directory and mode
|
||||
CacheDirectory = "webnsupdate";
|
||||
CacheDirectoryMode = "0750";
|
||||
# Logs directory and mode
|
||||
LogsDirectory = "webnsupdate";
|
||||
LogsDirectoryMode = "0750";
|
||||
# State directory and mode
|
||||
StateDirectory = "webnsupdate";
|
||||
StateDirectoryMode = "0750";
|
||||
# New file permissions
|
||||
UMask = "0027";
|
||||
# Security
|
||||
NoNewPrivileges = true;
|
||||
ProtectHome = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
flake.nixosModules = {
|
||||
default = module;
|
||||
webnsupdate = module;
|
||||
};
|
||||
}
|
5
flake-modules/overlay.nix
Normal file
5
flake-modules/overlay.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
flake = {
|
||||
overlays.default = _final: prev: { webnsupdate = prev.callPackage ../default.nix { }; };
|
||||
};
|
||||
}
|
24
flake-modules/package.nix
Normal file
24
flake-modules/package.nix
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
perSystem =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
packages =
|
||||
let
|
||||
webnsupdate = pkgs.callPackage ../default.nix { };
|
||||
in
|
||||
{
|
||||
inherit webnsupdate;
|
||||
default = webnsupdate;
|
||||
cargo-update = pkgs.writeShellApplication {
|
||||
name = "cargo-update-lockfile";
|
||||
runtimeInputs = with pkgs; [
|
||||
cargo
|
||||
gnused
|
||||
];
|
||||
text = ''
|
||||
CARGO_TERM_COLOR=never cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
23
flake.lock
23
flake.lock
|
@ -39,7 +39,8 @@
|
|||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"systems": "systems"
|
||||
"systems": "systems",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
@ -56,6 +57,26 @@
|
|||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1729613947,
|
||||
"narHash": "sha256-XGOvuIPW1XRfPgHtGYXd5MAmJzZtOuwlfKDgxX5KT3s=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "aac86347fb5063960eccb19493e0cadcdb4205ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
|
67
flake.nix
67
flake.nix
|
@ -7,73 +7,16 @@
|
|||
url = "github:hercules-ci/flake-parts";
|
||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
};
|
||||
treefmt-nix = {
|
||||
url = "github:numtide/treefmt-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs =
|
||||
inputs:
|
||||
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
imports = [ ./flake-modules ];
|
||||
systems = import inputs.systems;
|
||||
perSystem =
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
self',
|
||||
...
|
||||
}:
|
||||
{
|
||||
packages =
|
||||
let
|
||||
webnsupdate = pkgs.callPackage ./default.nix { };
|
||||
in
|
||||
{
|
||||
inherit webnsupdate;
|
||||
default = webnsupdate;
|
||||
cargo-update = pkgs.writeShellApplication {
|
||||
name = "cargo-update-lockfile";
|
||||
runtimeInputs = with pkgs; [
|
||||
cargo
|
||||
gnused
|
||||
];
|
||||
text = ''
|
||||
CARGO_TERM_COLOR=never cargo update 2>&1 | sed '/crates.io index/d' | tee -a cargo_update.log
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
formatter = pkgs.nixfmt-rfc-style;
|
||||
|
||||
checks = {
|
||||
fmtRust = pkgs.callPackage ./run-cmd.nix {
|
||||
src = inputs.self;
|
||||
name = "fmt-rust";
|
||||
extraNativeBuildInputs = [ pkgs.rustfmt ];
|
||||
cmd = "${lib.getExe pkgs.cargo} fmt --all --check --verbose";
|
||||
};
|
||||
fmtNix = pkgs.callPackage ./run-cmd.nix {
|
||||
src = inputs.self;
|
||||
name = "fmt-nix";
|
||||
cmd = "${lib.getExe self'.formatter} --check .";
|
||||
};
|
||||
lintNix = pkgs.callPackage ./run-cmd.nix {
|
||||
src = inputs.self;
|
||||
name = "lint-nix";
|
||||
cmd = "${lib.getExe pkgs.statix} check .";
|
||||
};
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = [
|
||||
pkgs.cargo-insta
|
||||
pkgs.cargo-udeps
|
||||
pkgs.mold
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake = {
|
||||
overlays.default = final: prev: { webnsupdate = final.callPackage ./default.nix { }; };
|
||||
|
||||
nixosModules.default = ./module.nix;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
177
module.nix
177
module.nix
|
@ -1,177 +0,0 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.webnsupdate;
|
||||
inherit (lib) mkOption mkEnableOption types;
|
||||
in
|
||||
{
|
||||
options.services.webnsupdate = mkOption {
|
||||
description = "An HTTP server for nsupdate.";
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "webnsupdate";
|
||||
extraArgs = mkOption {
|
||||
description = ''
|
||||
Extra arguments to be passed to the webnsupdate server command.
|
||||
'';
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--ip-source" ];
|
||||
};
|
||||
bindIp = mkOption {
|
||||
description = ''
|
||||
IP address to bind to.
|
||||
|
||||
Setting it to anything other than localhost is very insecure as
|
||||
`webnsupdate` only supports plain HTTP and should always be behind a
|
||||
reverse proxy.
|
||||
'';
|
||||
type = types.str;
|
||||
default = "localhost";
|
||||
example = "0.0.0.0";
|
||||
};
|
||||
bindPort = mkOption {
|
||||
description = "Port to bind to.";
|
||||
type = types.port;
|
||||
default = 5353;
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
description = ''
|
||||
The file where the password is stored.
|
||||
|
||||
This file can be created by running `webnsupdate mkpasswd $USERNAME $PASSWORD`.
|
||||
'';
|
||||
type = types.path;
|
||||
example = "/secrets/webnsupdate.pass";
|
||||
};
|
||||
keyFile = mkOption {
|
||||
description = ''
|
||||
The TSIG key that `nsupdate` should use.
|
||||
|
||||
This file will be passed to `nsupdate` through the `-k` option, so look
|
||||
at `man 8 nsupdate` for information on the key's format.
|
||||
'';
|
||||
type = types.path;
|
||||
example = "/secrets/webnsupdate.key";
|
||||
};
|
||||
ttl = mkOption {
|
||||
description = "The TTL that should be set on the zone records created by `nsupdate`.";
|
||||
type = types.ints.positive;
|
||||
default = 60;
|
||||
example = 3600;
|
||||
};
|
||||
records = mkOption {
|
||||
description = ''
|
||||
The fqdn of records that should be updated.
|
||||
|
||||
Empty lines will be ignored, but whitespace will not be.
|
||||
'';
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
example = ''
|
||||
example.com.
|
||||
|
||||
example.org.
|
||||
ci.example.org.
|
||||
'';
|
||||
};
|
||||
recordsFile = mkOption {
|
||||
description = ''
|
||||
The fqdn of records that should be updated.
|
||||
|
||||
Empty lines will be ignored, but whitespace will not be.
|
||||
'';
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
example = "/secrets/webnsupdate.records";
|
||||
};
|
||||
user = mkOption {
|
||||
description = "The user to run as.";
|
||||
type = types.str;
|
||||
default = "named";
|
||||
};
|
||||
group = mkOption {
|
||||
description = "The group to run as.";
|
||||
type = types.str;
|
||||
default = "named";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
recordsFile =
|
||||
if cfg.recordsFile != null then cfg.recordsFile else pkgs.writeText "webnsrecords" cfg.records;
|
||||
args = lib.strings.escapeShellArgs (
|
||||
[
|
||||
"--records"
|
||||
recordsFile
|
||||
"--key-file"
|
||||
cfg.keyFile
|
||||
"--password-file"
|
||||
cfg.passwordFile
|
||||
"--address"
|
||||
cfg.bindIp
|
||||
"--port"
|
||||
(builtins.toString cfg.bindPort)
|
||||
"--ttl"
|
||||
(builtins.toString cfg.ttl)
|
||||
]
|
||||
++ cfg.extraArgs
|
||||
);
|
||||
cmd = "${lib.getExe pkgs.webnsupdate} ${args}";
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
# warnings =
|
||||
# lib.optional (!config.services.bind.enable) "`webnsupdate` is expected to be used alongside `bind`. This is an unsopported configuration.";
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
(cfg.records != null || cfg.recordsFile != null)
|
||||
&& !(cfg.records != null && cfg.recordsFile != null);
|
||||
message = "Exactly one of `services.webnsupdate.records` and `services.webnsupdate.recordsFile` must be set.";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.services.webnsupdate = {
|
||||
description = "Web interface for nsupdate.";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"bind.service"
|
||||
];
|
||||
preStart = "${cmd} verify";
|
||||
path = [ pkgs.dig ];
|
||||
startLimitIntervalSec = 60;
|
||||
serviceConfig = {
|
||||
ExecStart = [ cmd ];
|
||||
Type = "exec";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
# User and group
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
# Runtime directory and mode
|
||||
RuntimeDirectory = "webnsupdate";
|
||||
RuntimeDirectoryMode = "0750";
|
||||
# Cache directory and mode
|
||||
CacheDirectory = "webnsupdate";
|
||||
CacheDirectoryMode = "0750";
|
||||
# Logs directory and mode
|
||||
LogsDirectory = "webnsupdate";
|
||||
LogsDirectoryMode = "0750";
|
||||
# New file permissions
|
||||
UMask = "0027";
|
||||
# Security
|
||||
NoNewPrivileges = true;
|
||||
ProtectHome = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
16
run-cmd.nix
16
run-cmd.nix
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
stdenvNoCC,
|
||||
src,
|
||||
name,
|
||||
cmd,
|
||||
extraBuildInputs ? [ ],
|
||||
extraNativeBuildInputs ? [ ],
|
||||
}:
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = "${name}-src";
|
||||
inherit src;
|
||||
buildInputs = extraBuildInputs;
|
||||
nativeBuildInputs = extraNativeBuildInputs;
|
||||
buildPhase = cmd;
|
||||
installPhase = "mkdir $out";
|
||||
}
|
Loading…
Reference in a new issue