mirror of
https://github.com/LnL7/nix-darwin.git
synced 2024-12-14 11:57:34 +00:00
generalized module for write-text
- use custom etc activation script
This commit is contained in:
parent
380bdd293b
commit
cd49cc1ab3
5 changed files with 186 additions and 68 deletions
|
@ -8,10 +8,11 @@ let
|
|||
modules =
|
||||
[ config
|
||||
./modules/system.nix
|
||||
./modules/system/activation-scripts.nix
|
||||
./modules/system/etc.nix
|
||||
./modules/environment.nix
|
||||
./modules/launchd
|
||||
./modules/tmux.nix
|
||||
<nixpkgs/nixos/modules/system/etc/etc.nix>
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -6,35 +6,9 @@ let
|
|||
|
||||
cfg = config.system;
|
||||
|
||||
script =
|
||||
{ config, name, ... }:
|
||||
{ options = {
|
||||
text = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
default = null;
|
||||
description = "Text of the file.";
|
||||
};
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = "Path of the source file.";
|
||||
};
|
||||
in
|
||||
|
||||
deps = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
config = {
|
||||
source = pkgs.writeScript "activate-${name}" ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
|
||||
#### Activation script snippet ${name}:
|
||||
${config.text}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
in {
|
||||
{
|
||||
options = {
|
||||
|
||||
system.build = mkOption {
|
||||
|
@ -58,49 +32,10 @@ in {
|
|||
default = "16.09";
|
||||
};
|
||||
|
||||
system.activationScripts = mkOption {
|
||||
internal = true;
|
||||
type = types.attrsOf (types.submodule script);
|
||||
default = {};
|
||||
description = ''
|
||||
A set of shell script fragments that are executed when a NixOS
|
||||
system configuration is activated. Examples are updating
|
||||
/etc, creating accounts, and so on. Since these are executed
|
||||
every time you boot the system or run
|
||||
<command>nixos-rebuild</command>, it's important that they are
|
||||
idempotent and fast.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
system.activationScripts.script.text = ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
|
||||
systemConfig=@out@
|
||||
|
||||
_status=0
|
||||
trap "_status=1" ERR
|
||||
|
||||
# Ensure a consistent umask.
|
||||
umask 0022
|
||||
|
||||
# Make this configuration the current configuration.
|
||||
# The readlink is there to ensure that when $systemConfig = /system
|
||||
# (which is a symlink to the store), /run/current-system is still
|
||||
# used as a garbage collection root.
|
||||
ln -sfn "$(readlink -f "$systemConfig")" /run/current-system
|
||||
|
||||
# Prevent the current configuration from being garbage-collected.
|
||||
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
|
||||
|
||||
${cfg.activationScripts.etc.text}
|
||||
|
||||
exit $_status
|
||||
'';
|
||||
|
||||
system.build.toplevel = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "nixdarwin-system-${cfg.nixdarwinLabel}";
|
||||
preferLocalBuild = true;
|
||||
|
|
63
modules/system/activation-scripts.nix
Normal file
63
modules/system/activation-scripts.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.system;
|
||||
|
||||
script = import ./write-text.nix {
|
||||
inherit lib;
|
||||
mkTextDerivation = name: text: pkgs.writeScript "activate-${name}" text;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
|
||||
system.activationScripts = mkOption {
|
||||
internal = true;
|
||||
type = types.attrsOf (types.submodule script);
|
||||
default = {};
|
||||
description = ''
|
||||
A set of shell script fragments that are executed when a NixOS
|
||||
system configuration is activated. Examples are updating
|
||||
/etc, creating accounts, and so on. Since these are executed
|
||||
every time you boot the system or run
|
||||
<command>nixos-rebuild</command>, it's important that they are
|
||||
idempotent and fast.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
system.activationScripts.script.text = ''
|
||||
#! ${pkgs.stdenv.shell}
|
||||
|
||||
systemConfig=@out@
|
||||
|
||||
_status=0
|
||||
trap "_status=1" ERR
|
||||
|
||||
# Ensure a consistent umask.
|
||||
umask 0022
|
||||
|
||||
# Make this configuration the current configuration.
|
||||
# The readlink is there to ensure that when $systemConfig = /system
|
||||
# (which is a symlink to the store), /run/current-system is still
|
||||
# used as a garbage collection root.
|
||||
ln -sfn "$(readlink -f "$systemConfig")" /run/current-system
|
||||
|
||||
# Prevent the current configuration from being garbage-collected.
|
||||
ln -sfn /run/current-system /nix/var/nix/gcroots/current-system
|
||||
|
||||
${cfg.activationScripts.etc.text}
|
||||
|
||||
exit $_status
|
||||
'';
|
||||
|
||||
};
|
||||
}
|
63
modules/system/etc.nix
Normal file
63
modules/system/etc.nix
Normal file
|
@ -0,0 +1,63 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
text = import ./write-text.nix {
|
||||
inherit lib;
|
||||
mkTextDerivation = name: text: pkgs.writeText "etc-${name}" text;
|
||||
};
|
||||
|
||||
etc = filter (f: f.enable) (attrValues config.environment.etc);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
|
||||
environment.etc = mkOption {
|
||||
type = types.loaOf (types.submodule text);
|
||||
default = {};
|
||||
description = ''
|
||||
Set of files that have to be linked in <filename>/etc</filename>.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
system.build.etc = pkgs.runCommand "etc" {} ''
|
||||
mkdir -p $out/etc
|
||||
cd $out/etc
|
||||
${concatMapStringsSep "\n" (attr: "ln -s '${attr.source}' '${attr.target}'") etc}
|
||||
'';
|
||||
|
||||
system.activationScripts.etc.text = ''
|
||||
# Set up the statically computed bits of /etc.
|
||||
echo "setting up /etc..."
|
||||
|
||||
ln -sfn "$(readlink -f $systemConfig/etc)" /etc/static
|
||||
|
||||
for link in $(ls /etc/static/); do
|
||||
if [ -e "/etc/$link" ]; then
|
||||
if [ ! -L "/etc/$link" ]; then
|
||||
echo "warning: /etc/$link is a file, skipping..." >&2
|
||||
fi
|
||||
else
|
||||
ln -sfn "/etc/static/$link" "/etc/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
for link in $(find /etc/ -maxdepth 1 -type l); do
|
||||
if [[ "$(readlink $link)" == /etc/static/* ]]; then
|
||||
if [ ! -e "$(readlink -f $link)" ]; then
|
||||
rm $link
|
||||
fi
|
||||
fi
|
||||
done
|
||||
'';
|
||||
|
||||
};
|
||||
}
|
56
modules/system/write-text.nix
Normal file
56
modules/system/write-text.nix
Normal file
|
@ -0,0 +1,56 @@
|
|||
{ lib, mkTextDerivation }:
|
||||
|
||||
with lib;
|
||||
|
||||
{ config, name, ... }:
|
||||
let
|
||||
|
||||
sourceDrv = mkTextDerivation name config.text;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
options = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether this /etc file should be generated. This
|
||||
option allows specific /etc files to be disabled.
|
||||
'';
|
||||
};
|
||||
|
||||
text = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.lines;
|
||||
description = ''
|
||||
Text of the file.
|
||||
'';
|
||||
};
|
||||
|
||||
target = mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
Name of symlink (relative to
|
||||
<filename>/etc</filename>). Defaults to the attribute
|
||||
name.
|
||||
'';
|
||||
};
|
||||
|
||||
source = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of the source file.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
source = mkIf (config.text != null) (mkDefault sourceDrv);
|
||||
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue