Implement initial containers module
This commit is contained in:
parent
5ef6684df4
commit
67114c1336
6
flake.lock
generated
6
flake.lock
generated
@ -150,11 +150,11 @@
|
||||
},
|
||||
"impermanence": {
|
||||
"locked": {
|
||||
"lastModified": 1644623728,
|
||||
"narHash": "sha256-aG+JnIaFXTM9YqcE5uyBgPlPrkmX4bs+yY5YCfA/vBQ=",
|
||||
"lastModified": 1647189769,
|
||||
"narHash": "sha256-6PJ4wqDuFMIw34gM/LxQ9qZPw8vPls4xC7UCeweSvKs=",
|
||||
"owner": "devplayer0",
|
||||
"repo": "impermanence",
|
||||
"rev": "74be13a87a3bbcbbaf94aea66f9576a1163db4f0",
|
||||
"rev": "723c1a7535b7cd194c3a2a693a2566ba1e047a89",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -92,9 +92,11 @@
|
||||
|
||||
configs = [
|
||||
# Systems
|
||||
nixos/boxes/colony.nix
|
||||
nixos/installer.nix
|
||||
|
||||
nixos/boxes/colony.nix
|
||||
nixos/containers/vaultwarden.nix
|
||||
|
||||
# Homes
|
||||
home-manager/configs/castle.nix
|
||||
home-manager/configs/macsimum.nix
|
||||
@ -109,6 +111,7 @@
|
||||
};
|
||||
|
||||
nixos.secretsPath = ./secrets;
|
||||
deploy-rs.deploy.sshOpts = [ "-i" ".keys/deploy.key" ];
|
||||
}
|
||||
|
||||
# Not an internal part of the module system apparently, but it doesn't have any dependencies other than lib
|
||||
|
2
lib.nix
2
lib.nix
@ -134,6 +134,6 @@ rec {
|
||||
|
||||
sshKeyFiles = {
|
||||
me = .keys/me.pub;
|
||||
deploy = .keys/deploy.key;
|
||||
deploy = .keys/deploy.pub;
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
{
|
||||
nixos.systems.colony = {
|
||||
system = "x86_64-linux";
|
||||
nixpkgs = "stable";
|
||||
nixpkgs = "unstable";
|
||||
home-manager = "unstable";
|
||||
docCustom = false;
|
||||
|
||||
configuration = { lib, pkgs, modulesPath, config, ... }:
|
||||
let
|
||||
@ -32,9 +31,10 @@
|
||||
};
|
||||
};
|
||||
server.enable = true;
|
||||
tmproot.unsaved.ignore = [
|
||||
"/var/db/dhcpcd/enp1s0.lease"
|
||||
];
|
||||
|
||||
containers = {
|
||||
instances.vaultwarden = {};
|
||||
};
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
@ -58,6 +58,8 @@
|
||||
enp1s0.useDHCP = true;
|
||||
};
|
||||
};
|
||||
|
||||
#systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
61
nixos/containers/vaultwarden.nix
Normal file
61
nixos/containers/vaultwarden.nix
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
nixos.systems.vaultwarden = {
|
||||
system = "x86_64-linux";
|
||||
nixpkgs = "unstable";
|
||||
|
||||
configuration = { lib, config, ... }:
|
||||
let
|
||||
inherit (lib) mkMerge mkIf mkForce;
|
||||
|
||||
vwData = "/var/lib/vaultwarden";
|
||||
vwSecrets = "vaultwarden.env";
|
||||
in
|
||||
{
|
||||
config = mkMerge [
|
||||
{
|
||||
my = {
|
||||
server.enable = true;
|
||||
|
||||
secrets = {
|
||||
files."${vwSecrets}" = {};
|
||||
};
|
||||
|
||||
firewall = {
|
||||
tcp.allowed = [ 80 3012 ];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.vaultwarden.serviceConfig.StateDirectory = mkForce "vaultwarden";
|
||||
services = {
|
||||
vaultwarden = {
|
||||
enable = true;
|
||||
config = {
|
||||
dataFolder = vwData;
|
||||
webVaultEnabled = true;
|
||||
|
||||
rocketPort = 80;
|
||||
websocketEnabled = true;
|
||||
websocketPort = 3012;
|
||||
};
|
||||
environmentFile = config.age.secrets."${vwSecrets}".path;
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf config.my.build.isDevVM {
|
||||
my.tmproot.persistence.config.directories = [
|
||||
{
|
||||
directory = vwData;
|
||||
user = config.users.users.vaultwarden.name;
|
||||
group = config.users.groups.vaultwarden.name;
|
||||
}
|
||||
];
|
||||
virtualisation = {
|
||||
forwardPorts = [
|
||||
{ from = "host"; host.port = 8080; guest.port = 80; }
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
@ -37,7 +37,7 @@ let
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Put the inputs in specialArgs to avoid infinite recursion when modules try to do imports
|
||||
specialArgs = { inherit inputs; };
|
||||
specialArgs = { inherit inputs; inherit (cfg) systems; };
|
||||
|
||||
# `baseModules` informs the manual which modules to document
|
||||
baseModules =
|
||||
|
@ -9,5 +9,6 @@
|
||||
server = ./server.nix;
|
||||
deploy-rs = ./deploy-rs.nix;
|
||||
secrets = ./secrets.nix;
|
||||
containers = ./containers.nix;
|
||||
};
|
||||
}
|
||||
|
@ -31,6 +31,15 @@ let
|
||||
}
|
||||
];
|
||||
};
|
||||
asContainer = extendModules {
|
||||
# TODO: see previous
|
||||
specialArgs = { inherit baseModules; };
|
||||
modules = [
|
||||
{
|
||||
boot.isContainer = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
options = with lib.types; {
|
||||
@ -46,13 +55,19 @@ in
|
||||
inherit (asDevVM) type;
|
||||
default = { };
|
||||
visible = "shallow";
|
||||
description = "Configuration as a development VM";
|
||||
description = "Configuration as a development VM.";
|
||||
};
|
||||
asISO = mkOption {
|
||||
inherit (asISO) type;
|
||||
default = { };
|
||||
visible = "shallow";
|
||||
description = "Configuration as a bootable .iso image";
|
||||
description = "Configuration as a bootable .iso image.";
|
||||
};
|
||||
asContainer = mkOption {
|
||||
inherit (asContainer) type;
|
||||
default = { };
|
||||
visible = "shallow";
|
||||
description = "Configuration as a container.";
|
||||
};
|
||||
|
||||
buildAs = options.system.build;
|
||||
@ -76,6 +91,7 @@ in
|
||||
# The meta.mainProgram should probably be set upstream but oh well...
|
||||
devVM = recursiveUpdate config.my.asDevVM.system.build.vm { meta.mainProgram = "run-${config.system.name}-vm"; };
|
||||
iso = config.my.asISO.system.build.isoImage;
|
||||
container = config.my.asContainer.system.build.toplevel;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -97,18 +97,15 @@ in
|
||||
|
||||
networking = {
|
||||
domain = mkDefault "int.nul.ie";
|
||||
useDHCP = mkDefault false;
|
||||
useDHCP = false;
|
||||
enableIPv6 = mkDefault true;
|
||||
};
|
||||
virtualisation = {
|
||||
forwardPorts = flatten [
|
||||
(optional config.services.openssh.openFirewall { from = "host"; host.port = 2222; guest.port = 22; })
|
||||
];
|
||||
useNetworkd = mkDefault true;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
bash-completion
|
||||
vim
|
||||
ldns
|
||||
];
|
||||
|
||||
programs = {
|
||||
@ -146,6 +143,11 @@ in
|
||||
})
|
||||
(mkIf config.my.build.isDevVM {
|
||||
networking.interfaces.eth0.useDHCP = mkDefault true;
|
||||
virtualisation = {
|
||||
forwardPorts = flatten [
|
||||
(optional config.services.openssh.openFirewall { from = "host"; host.port = 2222; guest.port = 22; })
|
||||
];
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
|
161
nixos/modules/containers.nix
Normal file
161
nixos/modules/containers.nix
Normal file
@ -0,0 +1,161 @@
|
||||
{ lib, options, config, systems, ... }:
|
||||
let
|
||||
inherit (builtins) attrNames attrValues mapAttrs;
|
||||
inherit (lib) concatMapStringsSep filterAttrs mkDefault mkIf mkMerge mkAliasDefinitions mkVMOverride mkAfter;
|
||||
inherit (lib.my) mkOpt';
|
||||
|
||||
cfg = config.my.containers;
|
||||
|
||||
devVMKeyPath = "/run/dev.key";
|
||||
|
||||
containerOpts = with lib.types; { name, ... }: {
|
||||
options = {
|
||||
system = mkOpt' unspecified systems."${name}".configuration.config.my.buildAs.container
|
||||
"Top-level system configuration.";
|
||||
opts = mkOpt' lib.my.naiveModule { } "Options to pass to `containers.*name*`.";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.my.containers = with lib.types; {
|
||||
networking = {
|
||||
bridgeName = mkOpt' str "containers" "Name of host bridge.";
|
||||
hostAddresses = mkOpt' (either str (listOf str)) "172.16.137.1/24" "Addresses for the host bridge.";
|
||||
};
|
||||
persistDir = mkOpt' str "/persist/containers" "Where to store container persistence data.";
|
||||
instances = mkOpt' (attrsOf (submodule containerOpts)) { } "Individual containers.";
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (cfg.instances != { }) {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.systemd.network.enable;
|
||||
message = "Containers currently require systemd-networkd!";
|
||||
}
|
||||
];
|
||||
|
||||
my.firewall.trustedInterfaces = [ cfg.networking.bridgeName ];
|
||||
|
||||
systemd = {
|
||||
network = {
|
||||
netdevs."25-container-bridge".netdevConfig = {
|
||||
Name = cfg.networking.bridgeName;
|
||||
Kind = "bridge";
|
||||
};
|
||||
# Based on the pre-installed 80-container-vz
|
||||
networks."80-container-vb" = {
|
||||
matchConfig = {
|
||||
Name = "vb-*";
|
||||
Driver = "veth";
|
||||
};
|
||||
networkConfig = {
|
||||
# systemd LLDP doesn't work on bridge interfaces
|
||||
LLDP = true;
|
||||
EmitLLDP = "customer-bridge";
|
||||
# Although nspawn will set the veth's master, systemd will clear it (systemd 250 adds a `KeepMaster`
|
||||
# to avoid this)
|
||||
Bridge = cfg.networking.bridgeName;
|
||||
};
|
||||
};
|
||||
networks."80-containers-bridge" = {
|
||||
matchConfig = {
|
||||
Name = cfg.networking.bridgeName;
|
||||
Driver = "bridge";
|
||||
};
|
||||
networkConfig = {
|
||||
Address = cfg.networking.hostAddresses;
|
||||
DHCPServer = true;
|
||||
# TODO: Configuration for routed IPv6 (and maybe IPv4)
|
||||
IPMasquerade = "both";
|
||||
IPv6SendRA = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
tmpfiles.rules = map (n: "d ${cfg.persistDir}/${n} 0755 root root") (attrNames cfg.instances);
|
||||
};
|
||||
|
||||
containers = mapAttrs (n: c: mkMerge [
|
||||
{
|
||||
path = "/nix/var/nix/profiles/per-container/${n}";
|
||||
ephemeral = true;
|
||||
autoStart = mkDefault true;
|
||||
bindMounts = {
|
||||
"/persist" = {
|
||||
hostPath = "${cfg.persistDir}/${n}";
|
||||
isReadOnly = false;
|
||||
};
|
||||
};
|
||||
|
||||
privateNetwork = true;
|
||||
hostBridge = cfg.networking.bridgeName;
|
||||
additionalCapabilities = [ "CAP_NET_ADMIN" ];
|
||||
}
|
||||
c.opts
|
||||
|
||||
(mkIf config.my.build.isDevVM {
|
||||
path = mkVMOverride c.system;
|
||||
bindMounts."${devVMKeyPath}" = {
|
||||
hostPath = config.my.secrets.vmKeyPath;
|
||||
isReadOnly = true;
|
||||
};
|
||||
})
|
||||
]) cfg.instances;
|
||||
})
|
||||
|
||||
# Inside container
|
||||
(mkIf config.boot.isContainer {
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.systemd.network.enable;
|
||||
message = "Containers currently require systemd-networkd!";
|
||||
}
|
||||
];
|
||||
|
||||
my = {
|
||||
tmproot.enable = true;
|
||||
};
|
||||
|
||||
system.activationScripts = {
|
||||
# impermanence will throw a fit and bail the whole activation script if this already exists (the container
|
||||
# start script pre-creates it for some reason)
|
||||
clearMachineId.text = "rm -f /etc/machine-id";
|
||||
createPersistentStorageDirs.deps = [ "clearMachineId" ];
|
||||
|
||||
# Ordinarily I think the Nix daemon does this but ofc it doesn't in the container
|
||||
createNixPerUserDirs = {
|
||||
text =
|
||||
let
|
||||
users = attrValues (filterAttrs (_: u: u.isNormalUser) config.users.users);
|
||||
in
|
||||
concatMapStringsSep "\n"
|
||||
(u: ''install -d -o ${u.name} -g ${u.group} /nix/var/nix/{profiles,gcroots}/per-user/"${u.name}"'') users;
|
||||
deps = [ "users" "groups" ];
|
||||
};
|
||||
};
|
||||
|
||||
networking = {
|
||||
useHostResolvConf = false;
|
||||
};
|
||||
# Based on the pre-installed 80-container-host0
|
||||
systemd.network.networks."80-container-eth0" = {
|
||||
matchConfig = {
|
||||
Name = "eth0";
|
||||
Virtualization = "container";
|
||||
};
|
||||
networkConfig = {
|
||||
DHCP = "yes";
|
||||
LLDP = true;
|
||||
EmitLLDP = "customer-bridge";
|
||||
};
|
||||
dhcpConfig = {
|
||||
UseTimezone = true;
|
||||
};
|
||||
};
|
||||
|
||||
# If the host is a dev VM
|
||||
age.identityPaths = [ devVMKeyPath ];
|
||||
})
|
||||
];
|
||||
}
|
@ -4,6 +4,7 @@ let
|
||||
inherit (lib.my) parseIPPort mkOpt' mkBoolOpt';
|
||||
|
||||
cfg = config.my.firewall;
|
||||
iptCfg = config.networking.firewall;
|
||||
in
|
||||
{
|
||||
options.my.firewall = with lib.types; {
|
||||
@ -31,9 +32,9 @@ in
|
||||
enable = true;
|
||||
ruleset =
|
||||
let
|
||||
trusted' = "{ ${concatStringsSep ", " cfg.trustedInterfaces} }";
|
||||
openTCP = cfg.tcp.allowed ++ config.networking.firewall.allowedTCPPorts;
|
||||
openUDP = cfg.udp.allowed ++ config.networking.firewall.allowedUDPPorts;
|
||||
trusted' = "{ ${concatStringsSep ", " (cfg.trustedInterfaces ++ iptCfg.trustedInterfaces)} }";
|
||||
openTCP = cfg.tcp.allowed ++ iptCfg.allowedTCPPorts;
|
||||
openUDP = cfg.udp.allowed ++ iptCfg.allowedUDPPorts;
|
||||
in
|
||||
''
|
||||
table inet filter {
|
||||
|
@ -8,6 +8,7 @@ let
|
||||
in
|
||||
{
|
||||
options.my.secrets = with lib.types; {
|
||||
vmKeyPath = mkOpt' str "/tmp/xchg/dev.key" "Path to dev key when in a dev VM.";
|
||||
key = mkOpt' (nullOr str) null "Public key that secrets for this system should be encrypted for.";
|
||||
files = mkOpt' (attrsOf unspecified) { } "Secrets to decrypt with agenix.";
|
||||
};
|
||||
@ -19,7 +20,7 @@ in
|
||||
} // opts) cfg.files;
|
||||
}
|
||||
(mkIf config.my.build.isDevVM {
|
||||
age.identityPaths = [ "/tmp/xchg/dev.key" ];
|
||||
age.identityPaths = [ cfg.vmKeyPath ];
|
||||
})
|
||||
];
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{ config, lib, ... }:
|
||||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
inherit (lib) mkIf mkDefault;
|
||||
inherit (lib.my) mkBoolOpt';
|
||||
inherit (lib.my) mkBoolOpt' mkDefault';
|
||||
|
||||
cfg = config.my.server;
|
||||
uname = if config.my.user.enable then config.my.user.config.name else "root";
|
||||
@ -17,6 +17,12 @@ in
|
||||
my.user.homeConfig = {
|
||||
my.gui.enable = false;
|
||||
};
|
||||
|
||||
documentation.nixos.enable = mkDefault' false;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
tcpdump
|
||||
];
|
||||
};
|
||||
|
||||
meta.buildDocsInSandbox = false;
|
||||
|
@ -1,10 +1,12 @@
|
||||
{ lib, pkgs, config, ... }:
|
||||
{ lib, pkgs, options, config, ... }:
|
||||
let
|
||||
inherit (lib) optionalString concatStringsSep concatMap concatMapStringsSep mkIf mkDefault mkMerge mkVMOverride;
|
||||
inherit (lib)
|
||||
optionalString concatStringsSep concatMap concatMapStringsSep mkIf mkDefault mkMerge mkForce mkVMOverride
|
||||
mkAliasDefinitions;
|
||||
inherit (lib.my) mkOpt' mkBoolOpt' mkVMOverride';
|
||||
|
||||
cfg = config.my.tmproot;
|
||||
enablePersistence = cfg.persistDir != null;
|
||||
enablePersistence = cfg.persistence.dir != null;
|
||||
|
||||
showUnsaved =
|
||||
''
|
||||
@ -58,8 +60,11 @@ in
|
||||
options = with lib.types; {
|
||||
my.tmproot = {
|
||||
enable = mkBoolOpt' true "Whether to enable tmproot.";
|
||||
persistDir = mkOpt' (nullOr str) "/persist" "Path where persisted files are stored.";
|
||||
size = mkOpt' str "2G" "Size of tmpfs root";
|
||||
persistence = {
|
||||
dir = mkOpt' (nullOr str) "/persist" "Path where persisted files are stored.";
|
||||
config = mkOpt' options.environment.persistence.type.nestedTypes.elemType { } "Persistence configuration";
|
||||
};
|
||||
unsaved = {
|
||||
showMotd = mkBoolOpt' true "Whether to show unsaved files with `dynamic-motd`.";
|
||||
ignore = mkOpt' (listOf str) [ ] "Path prefixes to ignore if unsaved.";
|
||||
@ -77,33 +82,53 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
my.tmproot.unsaved.ignore = [
|
||||
"/tmp"
|
||||
my.tmproot = {
|
||||
unsaved.ignore = [
|
||||
"/tmp"
|
||||
|
||||
# setup-etc.pl will create this for us
|
||||
"/etc/NIXOS"
|
||||
# setup-etc.pl will create this for us
|
||||
"/etc/NIXOS"
|
||||
|
||||
# Once mutableUsers is disabled, we should be all clear here
|
||||
"/etc/passwd"
|
||||
"/etc/group"
|
||||
"/etc/shadow"
|
||||
"/etc/subuid"
|
||||
"/etc/subgid"
|
||||
# Once mutableUsers is disabled, we should be all clear here
|
||||
"/etc/passwd"
|
||||
"/etc/group"
|
||||
"/etc/shadow"
|
||||
"/etc/subuid"
|
||||
"/etc/subgid"
|
||||
|
||||
# Lock file for /etc/{passwd,shadow}
|
||||
"/etc/.pwd.lock"
|
||||
# Lock file for /etc/{passwd,shadow}
|
||||
"/etc/.pwd.lock"
|
||||
|
||||
# systemd last updated? I presume they'll get updated on boot...
|
||||
"/etc/.updated"
|
||||
"/var/.updated"
|
||||
# systemd last updated? I presume they'll get updated on boot...
|
||||
"/etc/.updated"
|
||||
"/var/.updated"
|
||||
|
||||
# Specifies obsolete files that should be deleted on activation - we'll never have those!
|
||||
"/etc/.clean"
|
||||
# Specifies obsolete files that should be deleted on activation - we'll never have those!
|
||||
"/etc/.clean"
|
||||
|
||||
# These are set in environment.etc by the sshd module, but because their mode needs to be changed,
|
||||
# setup-etc will copy them instead of symlinking
|
||||
"/etc/ssh/authorized_keys.d"
|
||||
];
|
||||
# These are set in environment.etc by the sshd module, but because their mode needs to be changed,
|
||||
# setup-etc will copy them instead of symlinking
|
||||
"/etc/ssh/authorized_keys.d"
|
||||
];
|
||||
persistence.config = {
|
||||
# In impermanence the key in `environment.persistence.*` (aka name passed the attrsOf submodule) sets the
|
||||
# default value, so we need to override it when we mkAliasDefinitions
|
||||
_module.args.name = mkForce cfg.persistence.dir;
|
||||
|
||||
hideMounts = mkDefault true;
|
||||
directories = [
|
||||
"/var/log"
|
||||
# In theory we'd include only the files needed individually (i.e. the {U,G}ID map files that track deleted
|
||||
# users and groups), but `update-users-groups.pl` actually deletes the original files for "atomic update".
|
||||
# Also the script runs before impermanence does.
|
||||
"/var/lib/nixos"
|
||||
"/var/lib/systemd"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeScriptBin "tmproot-unsaved" showUnsaved)
|
||||
@ -119,7 +144,7 @@ in
|
||||
echo -e "\t\e[31;1;4mWarning:\e[0m $count file(s) on / will be lost on shutdown!"
|
||||
echo -e '\tTo see them, run `tmproot-unsaved` as root.'
|
||||
${optionalString enablePersistence ''
|
||||
echo -e '\tAdd these files to `environment.persistence."${cfg.persistDir}"` to keep them!'
|
||||
echo -e '\tAdd these files to `my.tmproot.persistence.config` to keep them!'
|
||||
''}
|
||||
echo -e "\tIf they don't need to be kept, add them to \`my.tmproot.unsaved.ignore\`."
|
||||
echo
|
||||
@ -149,8 +174,8 @@ in
|
||||
{
|
||||
assertions = [
|
||||
{
|
||||
assertion = config.fileSystems ? "${cfg.persistDir}";
|
||||
message = "The 'fileSystems' option does not specify your persistence file system (${cfg.persistDir}).";
|
||||
assertion = (config.fileSystems ? "${cfg.persistence.dir}") || config.boot.isContainer;
|
||||
message = "The 'fileSystems' option does not specify your persistence file system (${cfg.persistence.dir}).";
|
||||
}
|
||||
];
|
||||
|
||||
@ -172,7 +197,7 @@ in
|
||||
sourceDir = "${d.persistentStoragePath}${d.directory}";
|
||||
in
|
||||
''([ "$device" = "/mnt-root${sourceDir}" ] && ensurePersistSource "${sourceDir}" "${d.mode}")'')
|
||||
config.environment.persistence."${cfg.persistDir}".directories}
|
||||
cfg.persistence.config.directories}
|
||||
|
||||
waitDevice "$@"
|
||||
}
|
||||
@ -181,33 +206,20 @@ in
|
||||
alias waitDevice=_waitDevice
|
||||
'';
|
||||
|
||||
environment.persistence."${cfg.persistDir}" = {
|
||||
hideMounts = mkDefault true;
|
||||
directories = [
|
||||
"/var/log"
|
||||
# In theory we'd include only the files needed individually (i.e. the {U,G}ID map files that track deleted
|
||||
# users and groups), but `update-users-groups.pl` actually deletes the original files for "atomic update".
|
||||
# Also the script runs before impermanence does.
|
||||
"/var/lib/nixos"
|
||||
"/var/lib/systemd"
|
||||
];
|
||||
files = [
|
||||
"/etc/machine-id"
|
||||
];
|
||||
};
|
||||
environment.persistence."${cfg.persistence.dir}" = mkAliasDefinitions options.my.tmproot.persistence.config;
|
||||
|
||||
virtualisation = {
|
||||
diskImage = "./.vms/${config.system.name}-persist.qcow2";
|
||||
};
|
||||
}
|
||||
(mkIf config.services.openssh.enable {
|
||||
environment.persistence."${cfg.persistDir}".files =
|
||||
my.tmproot.persistence.config.files =
|
||||
concatMap (k: [ k.path "${k.path}.pub" ]) config.services.openssh.hostKeys;
|
||||
})
|
||||
(mkIf config.my.build.isDevVM {
|
||||
fileSystems = mkVMOverride {
|
||||
# Hijack the "root" device for persistence in the VM
|
||||
"${cfg.persistDir}" = {
|
||||
"${cfg.persistence.dir}" = {
|
||||
device = config.virtualisation.bootDevice;
|
||||
neededForBoot = true;
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ let
|
||||
|
||||
cfg = config.my.user;
|
||||
user' = cfg.config;
|
||||
user = config.users.users.${user'.name};
|
||||
in
|
||||
{
|
||||
options.my.user = with lib.types; {
|
||||
@ -37,9 +38,33 @@ in
|
||||
in mkIf (shell != null) (mkDefault' shell);
|
||||
openssh.authorizedKeys.keyFiles = [ lib.my.sshKeyFiles.me ];
|
||||
};
|
||||
# In order for this option to evaluate on its own, home-manager expects the `name` (which is derived from the
|
||||
# parent attr name) to be the users name, aka `home-manager.users.<name>`
|
||||
homeConfig = { _module.args.name = lib.mkForce user'.name; };
|
||||
homeConfig = {
|
||||
# In order for this option to evaluate on its own, home-manager expects the `name` (which is derived from the
|
||||
# parent attr name) to be the users name, aka `home-manager.users.<name>`
|
||||
_module.args.name = lib.mkForce user'.name;
|
||||
};
|
||||
};
|
||||
tmproot.persistence.config =
|
||||
let
|
||||
perms = {
|
||||
mode = "0700";
|
||||
user = user.name;
|
||||
group = user.group;
|
||||
};
|
||||
in {
|
||||
files = map (file: {
|
||||
inherit file;
|
||||
parentDirectory = perms;
|
||||
}) [
|
||||
"/home/${user'.name}/.bash_history"
|
||||
];
|
||||
directories = map (directory: {
|
||||
inherit directory;
|
||||
} // perms) [
|
||||
# Persist all of fish; it's not easy to persist just the history fish won't let you move it to a different
|
||||
# directory. Also it does some funny stuff and can't really be a symlink it seems.
|
||||
"/home/${user'.name}/.local/share/fish"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
|
8
secrets/vaultwarden.env.age
Normal file
8
secrets/vaultwarden.env.age
Normal file
@ -0,0 +1,8 @@
|
||||
age-encryption.org/v1
|
||||
-> X25519 Lm6m9mqSeFYvQ3bo73i9KrAzADgWLRcxmUg31JwqgWw
|
||||
FXbd6LUIA9OlCiMb1Us3T3/RkbQbxWD3pZ77/y3UuDM
|
||||
-> C3L/E-grease -7Y+*Gh
|
||||
UEBPiPpYXfbZltNeUQrX4ahsDakgciN6sSLLHkPsX69oGtLuGRQeoDC6tvEtG2Ws
|
||||
wJEX57JORoAWfZsUtF0Oj+hN++ANcCm1andG45Yf
|
||||
--- 1Pr1sAqpDFUZBGe97NYMyN3AEgv/EJgBl9DK4Ga93oc
|
||||
•Ö”’0˜ü`LVoÖ\åÃoÐ¥ëÜyÍýmèÃÃn^Ä×ûär|Q@†µáq{ÄÖ…f¬ƒéîÏ‹<){ucÈu–<75>Þ–ÅÆH¾ð<C2BE>»!U+7FYhh°W¶ÅkˆÐ;RO¶
|
Loading…
Reference in New Issue
Block a user