Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modules: introduce hostctl (static dns for development) #75

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion devshell.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
imports = [
"language.go"
"language.go",
"dns.hostctl"
]

[devshell]
Expand Down Expand Up @@ -45,3 +46,8 @@ category = "utilites"
help = "golang linter"
package = "golangci-lint"
category = "linters"

[hostctl]
enable = true
dns."test.domain.local" = "172.0.0.1"
dns."shared.domain.link-local" = "169.254.0.5"
61 changes: 61 additions & 0 deletions extra/dns/hostctl.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{ lib, pkgs, config, ... }:
with lib;
let
cfg = config.hostctl;
profile = toLower config.devshell.name;

etcHosts = pkgs.writeText "${profile}-etchosts" (
concatStringsSep "\n"
(mapAttrsToList (host: ip: ip + " " + host) cfg.dns)
);

# Execute this script to install the project's static dns entries
install-hostctl-dns = pkgs.writeShellScriptBin "install-hostctl-dns" ''
set -euo pipefail
shopt -s nullglob

log() {
IFS=$'\n' loglines=($*)
for line in ${"$"}{loglines[@]}; do echo -e "[hostctl] $line" >&2; done
}

# Install local CA into system, java and nss (includes Firefox) trust stores
log "Update static dns entries..."
sudo -K
log $(sudo ${pkgs.hostctl}/bin/hostctl add ${profile} --from ${etcHosts} 2>&1)

uninstall() {
log $(sudo ${pkgs.hostctl}/bin/hostctl remove ${profile} 2>&1)
}

# TODO: Uninstall when leaving the devshell
# trap uninstall EXIT
Comment on lines +31 to +32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems hard to get right, particularly because when the user runs two dev-shells and exits one.

Modifying the system is a bit heavy-handed for a development shell. I was secretly hoping for an unprivileged solution when I saw this PR. Perhaps (userns) containers are a more appropriate solution for most use cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is indeed a long term heavily politically involved solution to this: https://github.com/apetresc/nss-hostslocal. That would require lobbying for changing the way how linux system generally resolve hostfiles these days.

This particular PR is not going to get merged for this reason.

However, in a dev team setting, where you can exert certain powers over an individual's machine, this is a solution that (somewhat) works.


'';
in
{
options.hostctl = {
enable = mkEnableOption "manage temporary /etc/host entries for development from within the shell";

dns = mkOption {
type = types.attrs;
default = {};
description = "configure static dns entries";
example =
{
dns."some.host" = "1.2.3.4";
dns."another.host" = "4.3.2.1";
};
};
};

config = mkIf cfg.enable {
commands = [ { package = pkgs.hostctl; category = "dns"; } ];
devshell = {
packages = [ install-hostctl-dns ];
startup.install-hostctl-dns.text = "
$DEVSHELL_DIR/bin/install-hostctl-dns
";
};
};
}