1
0
Fork 0
mirror of https://github.com/LnL7/nix-darwin.git synced 2025-04-08 18:20:48 +00:00

Merge remote-tracking branch 'upstream/master' into kabir/one-sudo

This commit is contained in:
Kabir Oberai 2025-03-14 17:04:53 -04:00
commit 85652108db
14 changed files with 137 additions and 120 deletions

View file

@ -47,14 +47,12 @@ jobs:
sudo cp modules/examples/simple.nix /etc/nix-darwin/configuration.nix
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
etcHostsHash=$(shasum -a 256 /etc/hosts | cut -d ' ' -f 1)
sudo /usr/bin/sed -i.bak \
"s/# programs.fish.enable = true;/ \
imports = [ \
({ options, ... }: { \
nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; \
environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ]; \
environment.etc.hosts.knownSha256Hashes = [ \"$etcHostsHash\" ]; \
nix.nixPath = \
[ { darwin = \"${PWD////\/}\"; } ] \
++ options.nix.nixPath.default; \
@ -104,9 +102,8 @@ jobs:
pushd /etc/nix-darwin
sudo nix flake init -t $darwin
nixConfHash=$(shasum -a 256 /etc/nix/nix.conf | cut -d ' ' -f 1)
etcHostsHash=$(shasum -a 256 /etc/hosts | cut -d ' ' -f 1)
sudo /usr/bin/sed -i.bak \
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ]; environment.etc.hosts.knownSha256Hashes = [ \"$etcHostsHash\" ];/" \
"s/# programs.fish.enable = true;/nix.settings.access-tokens = [ \"github.com=\${{ secrets.GITHUB_TOKEN }}\" ]; environment.etc.\"nix\/nix.conf\".knownSha256Hashes = [ \"$nixConfHash\" ];/" \
flake.nix
sudo /usr/bin/sed -i.bak \
's/darwinConfigurations."simple"/darwinConfigurations."'$(scutil --get LocalHostName)'"/g' \

View file

@ -18,7 +18,7 @@ As the official Nix installer does not include an automated uninstaller, and man
* The [Nix installer from Determinate Systems](https://github.com/DeterminateSystems/nix-installer?tab=readme-ov-file#determinate-nix-installer) is only recommended for use with flake-based setups.
It can install one of two distributions of Nix:
* By default, it will install vanilla upstream [Nix](https://nixos.org/) with flakes enabled.
* To install the **recommended** vanilla upstream [Nix](https://nixos.org), you will need to explicitly say `no` when prompted to install `Determinate Nix`.
* When run with the `--determinate` flag, it will install the [Determinate](https://docs.determinate.systems/) distribution.
As Determinate manages the Nix installation itself, you will need to set `nix.enable = false;` in your configuration to disable nix-darwins own Nix management.

View file

@ -1,9 +0,0 @@
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost

View file

@ -137,7 +137,7 @@ let
config = {
brewBundleCmd = concatStringsSep " " (
optional (!config.autoUpdate) "HOMEBREW_NO_AUTO_UPDATE=1"
++ [ "brew bundle --file='${brewfileFile}' --no-lock" ]
++ [ "brew bundle --file='${brewfileFile}'" ]
++ optional (!config.upgrade) "--no-upgrade"
++ optional (config.cleanup == "uninstall") "--cleanup"
++ optional (config.cleanup == "zap") "--cleanup --zap"

View file

@ -39,11 +39,13 @@ in
ids.uids = {
nixbld = lib.mkDefault 350;
_prometheus-node-exporter = 534;
_dnscrypt-proxy = 535;
};
ids.gids = {
nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350);
_prometheus-node-exporter = 534;
_dnscrypt-proxy = 535;
};
};

View file

@ -62,6 +62,7 @@
./services/chunkwm.nix
./services/cachix-agent.nix
./services/dnsmasq.nix
./services/dnscrypt-proxy.nix
./services/emacs.nix
./services/eternal-terminal.nix
./services/github-runner

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }:
{ config, lib, ... }:
with lib;
@ -22,8 +22,6 @@ let
esac
'') cfg.knownNetworkServices}
'';
localhostMultiple = any (elem "localhost") (attrValues (removeAttrs cfg.hosts [ "127.0.0.1" "::1" ]));
in
{
@ -107,50 +105,9 @@ in
Battery powered devices may require being connected to power.
'';
};
networking.hosts = lib.mkOption {
type = types.attrsOf (types.listOf types.str);
example = literalExpression ''
{
"127.0.0.1" = [ "foo.bar.baz" ];
"192.168.0.2" = [ "fileserver.local" "nameserver.local" ];
};
'';
description = ''
Locally defined maps of hostnames to IP addresses.
'';
default = {};
};
networking.hostFiles = lib.mkOption {
type = types.listOf types.path;
defaultText = literalMD "Hosts from {option}`networking.hosts` and {option}`networking.extraHosts`";
example = literalExpression ''[ "''${pkgs.my-blocklist-package}/share/my-blocklist/hosts" ]'';
description = ''
Files that should be concatenated together to form {file}`/etc/hosts`.
'';
};
networking.extraHosts = lib.mkOption {
type = types.lines;
default = "";
example = "192.168.0.1 lanlocalhost";
description = ''
Additional verbatim entries to be appended to {file}`/etc/hosts`.
For adding hosts from derivation results, use {option}`networking.hostFiles` instead.
'';
};
};
config = {
assertions = [{
assertion = !localhostMultiple;
message = ''
`networking.hosts` maps "localhost" to something other than "127.0.0.1"
or "::1". This will break some applications. Please use
`networking.extraHosts` if you really want to add such a mapping.
'';
}];
warnings = [
(mkIf (cfg.knownNetworkServices == [] && cfg.dns != []) "networking.knownNetworkServices is empty, dns servers will not be configured.")
@ -175,38 +132,12 @@ in
${optionalString (cfg.wakeOnLan.enable != null) ''
systemsetup -setWakeOnNetworkAccess '${onOff cfg.wakeOnLan.enable}' &> /dev/null
''}
if [ -e /etc/hosts.before-nix-darwin ]; then
echo "restoring /etc/hosts..." >&2
sudo mv /etc/hosts{.before-nix-darwin,}
fi
'';
networking.hostFiles = let
# Note: localhostHosts has to appear first in /etc/hosts so that 127.0.0.1
# resolves back to "localhost" (as some applications assume) instead of
# the FQDN!
localhostHosts = pkgs.writeText "localhost-hosts" ''
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
'';
stringHosts =
let
oneToString = set: ip: ip + " " + concatStringsSep " " set.${ip} + "\n";
allToString = set: concatMapStrings (oneToString set) (attrNames set);
in pkgs.writeText "string-hosts" (allToString (filterAttrs (_: v: v != []) cfg.hosts));
extraHosts = pkgs.writeText "extra-hosts" cfg.extraHosts;
in mkBefore [ localhostHosts stringHosts extraHosts ];
environment.etc.hosts = {
knownSha256Hashes = [
# Comes from MacOS: Darwin 24.1.0 Darwin Kernel Version 24.1.0.
"c7dd0e2ed261ce76d76f852596c5b54026b9a894fa481381ffd399b556c0e2da"
];
source = pkgs.concatText "hosts" cfg.hostFiles;
};
};
}

View file

@ -35,6 +35,17 @@ in
'';
};
watchIdAuth = lib.mkEnableOption "" // {
description = ''
Use Apple Watch for sudo authentication, for devices without Touch ID or
laptops with lids closed, consider using this.
When enabled, you can use your Apple Watch to authenticate sudo commands.
If this doesn't work, you can go into `System Settings > Touch ID & Password`
and toggle the switch for your Apple Watch.
'';
};
reattach = lib.mkEnableOption "" // {
description = ''
Whether to enable reattaching a program to the user's bootstrap session.
@ -53,6 +64,7 @@ in
security.pam.services.sudo_local.text = lib.concatLines (
(lib.optional cfg.reattach "auth optional ${pkgs.pam-reattach}/lib/pam/pam_reattach.so")
++ (lib.optional cfg.touchIdAuth "auth sufficient pam_tid.so")
++ (lib.optional cfg.watchIdAuth "auth sufficient ${pkgs.pam-watchid}/lib/pam_watchid.so")
);
environment.etc."pam.d/sudo_local" = {

View file

@ -0,0 +1,81 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.dnscrypt-proxy;
format = pkgs.formats.toml { };
configFile = format.generate "dnscrypt-proxy.toml" cfg.settings;
in
{
options.services.dnscrypt-proxy = {
enable = lib.mkEnableOption "the dnscrypt-proxy service.";
package = lib.mkPackageOption pkgs "dnscrypt-proxy" { };
settings = lib.mkOption {
description = ''
Attrset that is converted and passed as TOML config file.
For available params, see: <https://github.com/DNSCrypt/dnscrypt-proxy/blob/${pkgs.dnscrypt-proxy.version}/dnscrypt-proxy/example-dnscrypt-proxy.toml>
'';
example = lib.literalExpression ''
{
sources.public-resolvers = {
urls = [ "https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md" ];
cache_file = "public-resolvers.md";
minisign_key = "RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3";
refresh_delay = 72;
};
}
'';
type = format.type;
default = { };
};
};
config = lib.mkIf cfg.enable {
users.users._dnscrypt-proxy = {
uid = config.ids.uids._dnscrypt-proxy;
gid = config.ids.gids._dnscrypt-proxy;
home = "/var/lib/dnscrypt-proxy";
createHome = true;
shell = "/usr/bin/false";
description = "System user for dnscrypt-proxy";
};
users.groups._dnscrypt-proxy = {
gid = config.ids.gids._dnscrypt-proxy;
description = "System group for dnscrypt-proxy";
};
users.knownUsers = [ "_dnscrypt-proxy" ];
users.knownGroups = [ "_dnscrypt-proxy" ];
launchd.daemons.dnscrypt-proxy = {
script = ''
${lib.getExe' cfg.package "dnscrypt-proxy"} -config ${configFile}
'';
serviceConfig =
let
logPath = config.users.users._dnscrypt-proxy.home + "/dnscrypt-proxy.log";
in
{
RunAtLoad = true;
KeepAlive = true;
StandardOutPath = logPath;
StandardErrorPath = logPath;
GroupName = "_dnscrypt-proxy";
UserName = "_dnscrypt-proxy";
};
};
};
}

View file

@ -30,8 +30,7 @@ in {
launchd.daemons.nextdns = {
path = [ nextdns ];
serviceConfig.ProgramArguments =
[ "${pkgs.nextdns}/bin/nextdns" "run" ] ++ cfg.arguments;
command = concatStringsSep " " (["${pkgs.nextdns}/bin/nextdns run"] ++ cfg.arguments);
serviceConfig.KeepAlive = true;
serviceConfig.RunAtLoad = true;
};

View file

@ -11,14 +11,14 @@ let
group = import ./group.nix;
user = import ./user.nix;
toGID = v: { "${toString v.gid}" = v.name; };
toUID = v: { "${toString v.uid}" = v.name; };
toGID = n: v: { "${toString v.gid}" = n; };
toUID = n: v: { "${toString v.uid}" = n; };
isCreated = list: name: elem name list;
isDeleted = attrs: name: ! elem name (mapAttrsToList (n: v: v.name) attrs);
gids = mapAttrsToList (n: toGID) (filterAttrs (n: v: isCreated cfg.knownGroups v.name) cfg.groups);
uids = mapAttrsToList (n: toUID) (filterAttrs (n: v: isCreated cfg.knownUsers v.name) cfg.users);
gids = mapAttrsToList toGID (filterAttrs (n: v: isCreated cfg.knownGroups v.name) cfg.groups);
uids = mapAttrsToList toUID (filterAttrs (n: v: isCreated cfg.knownUsers v.name) cfg.users);
createdGroups = mapAttrsToList (n: v: cfg.groups."${v}") cfg.gids;
createdUsers = mapAttrsToList (n: v: cfg.users."${v}") cfg.uids;
@ -112,14 +112,14 @@ in
in
!user.ignoreShellProgramCheck -> (s == shell || (shell == "bash" && s == "bash-interactive")) -> (config.programs.${shell}.enable == true);
message = ''
users.users.${user.name}.shell is set to ${shell}, but
users.users.${name}.shell is set to ${shell}, but
programs.${shell}.enable is not true. This will cause the ${shell}
shell to lack the basic Nix directories in its PATH and might make
logging in as that user impossible. You can fix it with:
programs.${shell}.enable = true;
If you know what you're doing and you are fine with the behavior,
set users.users.${user.name}.ignoreShellProgramCheck = true;
set users.users.${name}.ignoreShellProgramCheck = true;
instead.
'';
}) [
@ -331,7 +331,7 @@ in
environment.systemPackages = systemShells;
environment.etc = mapAttrs' (name: { packages, ... }: {
name = "profiles/per-user/${name}";
name = "profiles/per-user/${cfg.users.${name}.name}";
value.source = pkgs.buildEnv {
name = "user-environment";
paths = packages;

View file

@ -86,7 +86,6 @@ in {
tests.launchd-daemons = makeTest ./tests/launchd-daemons.nix;
tests.launchd-setenv = makeTest ./tests/launchd-setenv.nix;
tests.networking-hostname = makeTest ./tests/networking-hostname.nix;
tests.networking-hosts = makeTest ./tests/networking-hosts.nix;
tests.networking-networkservices = makeTest ./tests/networking-networkservices.nix;
tests.nix-enable = makeTest ./tests/nix-enable.nix;
tests.nixpkgs-overlays = makeTest ./tests/nixpkgs-overlays.nix;
@ -104,6 +103,7 @@ in {
tests.sockets-nix-daemon = makeTest ./tests/sockets-nix-daemon.nix;
tests.services-aerospace = makeTest ./tests/services-aerospace.nix;
tests.services-dnsmasq = makeTest ./tests/services-dnsmasq.nix;
tests.services-dnscrypt-proxy = makeTest ./tests/services-dnscrypt-proxy.nix;
tests.services-eternal-terminal = makeTest ./tests/services-eternal-terminal.nix;
tests.services-nix-gc = makeTest ./tests/services-nix-gc.nix;
tests.services-nix-optimise = makeTest ./tests/services-nix-optimise.nix;

View file

@ -1,20 +0,0 @@
{ config, pkgs, ... }:
{
networking.hosts = {
"127.0.0.1" = [ "my.super.host" ];
"10.0.0.1" = [ "my.super.host" "my.other.host" ];
};
test = ''
set -v
echo checking /etc/hosts file >&2
file=${config.out}/etc/hosts
grep '127.0.0.1' $file | head -n1 | grep localhost$
grep '127.0.0.1' $file | tail -n1 | grep my.super.host$
grep '::1' $file | grep localhost$
grep '10.0.0.1' $file | grep my.super.host\ my.other.host$
'';
}

View file

@ -0,0 +1,23 @@
{
config,
pkgs,
...
}:
let
dnscrypt-proxy = pkgs.runCommand "dnscrypt-proxy-0.0.0" { } "mkdir $out";
in
{
services.dnscrypt-proxy.enable = true;
services.dnscrypt-proxy.package = dnscrypt-proxy;
test = ''
echo >&2 "checking dnscrypt-proxy service in /Library/LaunchDaemons"
grep -q "org.nixos.dnscrypt-proxy" -- ${config.out}/Library/LaunchDaemons/org.nixos.dnscrypt-proxy.plist
grep -q "dnscrypt-proxy-start" -- ${config.out}/Library/LaunchDaemons/org.nixos.dnscrypt-proxy.plist
echo >&2 "checking dnscrypt-proxy system user in /Library/LaunchDaemons"
grep -q "_dnscrypt-proxy" -- ${config.out}/Library/LaunchDaemons/org.nixos.dnscrypt-proxy.plist
'';
}