Add configs for a new kubernetes cluster on NixOS.
This commit is contained in:
331
nix/kubernetes/util/install_files/default.nix
Normal file
331
nix/kubernetes/util/install_files/default.nix
Normal file
@@ -0,0 +1,331 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.me.install;
|
||||
inherit (lib)
|
||||
filter
|
||||
attrNames
|
||||
;
|
||||
|
||||
get_shell_values =
|
||||
target:
|
||||
let
|
||||
homedir = config.users.users."${target.username}".home;
|
||||
group = config.users.users."${target.username}".group;
|
||||
in
|
||||
{
|
||||
source = lib.strings.escapeShellArg "${target.source}";
|
||||
destination = lib.strings.escapeShellArg "${homedir}/${target.target}";
|
||||
mode = lib.strings.escapeShellArg "${target.mode}";
|
||||
dir_mode = lib.strings.escapeShellArg "${target.dir_mode}";
|
||||
username = lib.strings.escapeShellArg "${target.username}";
|
||||
group = lib.strings.escapeShellArg "${group}";
|
||||
};
|
||||
install_user_file =
|
||||
let
|
||||
constructors = {
|
||||
"overwrite" = install_user_file_overwrite;
|
||||
"symlink" = install_user_file_symlink;
|
||||
};
|
||||
in
|
||||
stage: target: (constructors."${target.method}"."${stage}" target);
|
||||
install_user_file_overwrite = {
|
||||
"check" = (target: "");
|
||||
"install" = (
|
||||
target:
|
||||
let
|
||||
inherit (get_shell_values target)
|
||||
source
|
||||
destination
|
||||
mode
|
||||
dir_mode
|
||||
username
|
||||
group
|
||||
;
|
||||
flags = lib.strings.concatStringsSep " " [
|
||||
(if mode != "" then "-m ${mode}" else "")
|
||||
(if username != "" then "-o ${username}" else "")
|
||||
(if group != "" then "-g ${group}" else "")
|
||||
];
|
||||
dir_flags = lib.strings.concatStringsSep " " [
|
||||
(if dir_mode != "" then "-m ${dir_mode}" else "")
|
||||
(if username != "" then "-o ${username}" else "")
|
||||
(if group != "" then "-g ${group}" else "")
|
||||
];
|
||||
in
|
||||
if target.recursive then
|
||||
[
|
||||
''
|
||||
find ${source} -type f -print0 | while read -r -d "" file; do
|
||||
relative_path=$(realpath -s --relative-to ${source} "$file")
|
||||
full_dest=${destination}/"$relative_path"
|
||||
create_containing_directories "$full_dest" ${dir_flags}
|
||||
$DRY_RUN_CMD install $VERBOSE_ARG --compare ${flags} "$file" "$full_dest"
|
||||
done
|
||||
''
|
||||
]
|
||||
else
|
||||
[
|
||||
''
|
||||
create_containing_directories ${destination} ${dir_flags}
|
||||
$DRY_RUN_CMD install $VERBOSE_ARG --compare ${flags} ${source} ${destination}
|
||||
''
|
||||
]
|
||||
);
|
||||
"uninstall" = (
|
||||
target:
|
||||
let
|
||||
inherit (get_shell_values target)
|
||||
source
|
||||
destination
|
||||
;
|
||||
in
|
||||
if target.recursive then
|
||||
[
|
||||
''
|
||||
find ${source} -type f -print0 | while read -r -d "" file; do
|
||||
relative_path=$(realpath -s --relative-to ${source} "$file")
|
||||
full_dest=${destination}/"$relative_path"
|
||||
$DRY_RUN_CMD echo rm -f "$full_dest"
|
||||
done
|
||||
''
|
||||
]
|
||||
else
|
||||
[
|
||||
''
|
||||
$DRY_RUN_CMD echo rm -f ${destination}
|
||||
''
|
||||
]
|
||||
);
|
||||
};
|
||||
install_user_file_symlink = {
|
||||
"check" = (target: "");
|
||||
"install" = (
|
||||
target:
|
||||
let
|
||||
inherit (get_shell_values target)
|
||||
source
|
||||
destination
|
||||
mode
|
||||
dir_mode
|
||||
username
|
||||
group
|
||||
;
|
||||
owner = lib.strings.concatStringsSep ":" (
|
||||
filter (val: val != "") [
|
||||
username
|
||||
group
|
||||
]
|
||||
);
|
||||
dir_flags = lib.strings.concatStringsSep " " [
|
||||
(if dir_mode != "" then "-m ${dir_mode}" else "")
|
||||
(if username != "" then "-o ${username}" else "")
|
||||
(if group != "" then "-g ${group}" else "")
|
||||
];
|
||||
in
|
||||
if target.recursive then
|
||||
[
|
||||
''
|
||||
find ${source} -type f -print0 | while read -r -d "" file; do
|
||||
relative_path=$(realpath -s --relative-to ${source} "$file")
|
||||
full_dest=${destination}/"$relative_path"
|
||||
create_containing_directories "$full_dest" ${dir_flags}
|
||||
$DRY_RUN_CMD ln $VERBOSE_ARG -s "$file" "$full_dest"
|
||||
$DRY_RUN_CMD chown $VERBOSE_ARG -h ${owner} "$full_dest"
|
||||
done
|
||||
''
|
||||
]
|
||||
else
|
||||
[
|
||||
''
|
||||
create_containing_directories ${destination} ${dir_flags}
|
||||
$DRY_RUN_CMD ln $VERBOSE_ARG -s ${source} ${destination}
|
||||
$DRY_RUN_CMD chown $VERBOSE_ARG -h ${owner} ${destination}
|
||||
''
|
||||
]
|
||||
);
|
||||
"uninstall" = (
|
||||
target:
|
||||
let
|
||||
inherit (get_shell_values target)
|
||||
source
|
||||
destination
|
||||
;
|
||||
in
|
||||
if target.recursive then
|
||||
[
|
||||
''
|
||||
find ${source} -type f -print0 | while read -r -d "" file; do
|
||||
relative_path=$(realpath -s --relative-to ${source} "$file")
|
||||
full_dest=${destination}/"$relative_path"
|
||||
$DRY_RUN_CMD echo rm -f "$full_dest"
|
||||
done
|
||||
''
|
||||
]
|
||||
else
|
||||
[
|
||||
''
|
||||
$DRY_RUN_CMD echo rm -f ${destination}
|
||||
''
|
||||
]
|
||||
);
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ ];
|
||||
|
||||
options.me.install = {
|
||||
user = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, config, ... }:
|
||||
let
|
||||
username = name;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
defaultText = "enable";
|
||||
example = lib.literalExpression false;
|
||||
description = "Whether we want to install files in this user's home directory.";
|
||||
};
|
||||
|
||||
file = lib.mkOption {
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, config, ... }:
|
||||
let
|
||||
path = name;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
defaultText = "enable";
|
||||
example = lib.literalExpression false;
|
||||
description = "Whether we want to install this file in this user's home directory.";
|
||||
};
|
||||
username = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
defaultText = "username";
|
||||
example = "root";
|
||||
description = "The username for the user whose home directory will contain the file.";
|
||||
};
|
||||
target = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
defaultText = "target";
|
||||
example = ".local/share/foo/bar.txt";
|
||||
description = "The path where the file should be written.";
|
||||
};
|
||||
method = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"symlink"
|
||||
"overwrite"
|
||||
# "bind_mount" TODO: for directories?
|
||||
];
|
||||
default = "symlink";
|
||||
defaultText = "me.install.file.‹path›.method";
|
||||
example = "overwrite";
|
||||
description = "The way in which the file should be installed.";
|
||||
};
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0444";
|
||||
defaultText = "me.install.file.‹path›.mode";
|
||||
example = "0750";
|
||||
description = "The read, write, execute permission flags.";
|
||||
};
|
||||
dir_mode = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0755";
|
||||
defaultText = "dir_mode";
|
||||
example = "0755";
|
||||
description = "The read, write, execute permission flags for any parent directories that need to be created.";
|
||||
};
|
||||
source = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
defaultText = "me.install.file.‹path›.source";
|
||||
example = ./files/foo.txt;
|
||||
description = "The source file to install into the destination.";
|
||||
};
|
||||
recursive = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
defaultText = "recursive";
|
||||
example = lib.literalExpression false;
|
||||
description = "Whether we want to recurse through the directory doing individual installs for each file.";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
username = lib.mkDefault username;
|
||||
target = lib.mkDefault path;
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
all_users = builtins.map (username: cfg.user."${username}") (attrNames cfg.user);
|
||||
enabled_users = filter (user: user.enable) all_users;
|
||||
all_file_targets = lib.flatten (
|
||||
builtins.map (user: (builtins.map (path: user.file."${path}") (attrNames user.file))) enabled_users
|
||||
);
|
||||
enabled_file_targets = filter (target: target.enable) all_file_targets;
|
||||
check_commands = lib.flatten (builtins.map (install_user_file "check") enabled_file_targets);
|
||||
install_commands = lib.flatten (builtins.map (install_user_file "install") enabled_file_targets);
|
||||
uninstall_commands = lib.flatten (
|
||||
builtins.map (install_user_file "uninstall") enabled_file_targets
|
||||
);
|
||||
in
|
||||
{
|
||||
systemd.services.me-install-file = {
|
||||
enable = true;
|
||||
description = "me-install-file";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "multi-user.target" ];
|
||||
before = [ "multi-user.target" ];
|
||||
# path = with pkgs; [
|
||||
# zfs
|
||||
# ];
|
||||
unitConfig.DefaultDependencies = "no";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = "yes";
|
||||
};
|
||||
script = ''
|
||||
set -o pipefail
|
||||
IFS=$'\n\t'
|
||||
source ${./files/lib.bash}
|
||||
''
|
||||
+ (lib.strings.concatStringsSep "\n" (
|
||||
[
|
||||
]
|
||||
++ check_commands
|
||||
++ install_commands
|
||||
));
|
||||
preStop = ''
|
||||
set -o pipefail
|
||||
IFS=$'\n\t'
|
||||
source ${./files/lib.bash}
|
||||
''
|
||||
+ (lib.strings.concatStringsSep "\n" uninstall_commands);
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user