-
Notifications
You must be signed in to change notification settings - Fork 38
/
nixos-shell-config.nix
127 lines (111 loc) · 5.21 KB
/
nixos-shell-config.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
{ lib, options, config, pkgs, ... }:
let
cfg = config.nixos-shell;
home = builtins.getEnv "HOME";
mkVMDefault = lib.mkOverride 900;
in {
config =
let
user = builtins.getEnv "USER";
shell' = builtins.baseNameOf (builtins.getEnv "SHELL");
# fish seems to do funky stuff: https://github.com/Mic92/nixos-shell/issues/42
shell = if shell' == "fish" then "bash" else shell';
# Enable the module of the user's shell for some sensible defaults.
maybeSetShell = lib.optional (options.programs ? ${shell}.enable && shell != "bash") {
programs.${shell}.enable = mkVMDefault true;
};
in
lib.mkMerge (maybeSetShell ++ [
(lib.mkIf (pkgs ? ${shell}) {
users.extraUsers.root.shell = mkVMDefault pkgs.${shell};
})
(
lib.mkIf (home != "" && cfg.mounts.mountHome) {
users.extraUsers.root.home = lib.mkVMOverride home;
}
)
# Allow passwordless ssh login with the user's key if it exists.
(
let
keys = map (key: "${builtins.getEnv "HOME"}/.ssh/${key}")
[ "id_rsa.pub" "id_ecdsa.pub" "id_ed25519.pub" ];
in
{
users.users.root.openssh.authorizedKeys.keyFiles = lib.filter builtins.pathExists keys;
}
)
{
# Allow the user to login as root without password.
users.extraUsers.root.initialHashedPassword = "";
# see https://wiki.qemu.org/Documentation/9psetup#Performance_Considerations
# == 100M
# FIXME? currently 500K seems to be the limit?
virtualisation.msize = mkVMDefault 104857600;
services.getty.helpLine = ''
If you are connect via serial console:
Type Ctrl-a c to switch to the qemu console
and `quit` to stop the VM.
'';
services.getty.autologinUser = "root";
virtualisation = {
graphics = mkVMDefault false;
memorySize = mkVMDefault 700;
qemu.consoles = lib.mkIf (!config.virtualisation.graphics) [ "tty0" "hvc0" ];
qemu.options =
let
nixProfile = "/nix/var/nix/profiles/per-user/${user}/profile/";
in
lib.optionals (!config.virtualisation.graphics) [
"-serial null"
"-device virtio-serial"
"-chardev stdio,mux=on,id=char0,signal=off"
"-mon chardev=char0,mode=readline"
"-device virtconsole,chardev=char0,nr=0"
] ++
lib.optional cfg.mounts.mountHome "-virtfs local,path=${home},security_model=none,mount_tag=home" ++
lib.optional (cfg.mounts.mountNixProfile && builtins.pathExists nixProfile) "-virtfs local,path=${nixProfile},security_model=none,mount_tag=nixprofile" ++
lib.mapAttrsToList (target: mount: "-virtfs local,path=${builtins.toString mount.target},security_model=none,mount_tag=${mount.tag}") cfg.mounts.extraMounts;
};
# build-vm overrides our filesystem settings in nixos-config
boot.initrd.postMountCommands =
(lib.optionalString cfg.mounts.mountHome ''
mkdir -p $targetRoot/${lib.escapeShellArg home}
mount -t 9p home $targetRoot/${lib.escapeShellArg home} -o trans=virtio,version=9p2000.L,cache=${cfg.mounts.cache},msize=${toString config.virtualisation.msize}
'') +
(lib.optionalString (user != "" && cfg.mounts.mountNixProfile) ''
mkdir -p $targetRoot/nix/var/nix/profiles/per-user/${user}/profile/
mount -t 9p nixprofile $targetRoot/nix/var/nix/profiles/per-user/${user}/profile/ -o trans=virtio,version=9p2000.L,cache=${cfg.mounts.cache},msize=${toString config.virtualisation.msize}
'') +
builtins.concatStringsSep " " (lib.mapAttrsToList
(target: mount: ''
mkdir -p $targetRoot/${target}
mount -t 9p ${mount.tag} $targetRoot/${target} -o trans=virtio,version=9p2000.L,cache=${mount.cache},msize=${toString config.virtualisation.msize}
'')
cfg.mounts.extraMounts);
# avoid leaking incompatible host binaries into the VM
system.activationScripts.shadow-nix-profile = lib.mkIf (options.virtualisation.host.pkgs.isDefined && config.virtualisation.host.pkgs.stdenv.hostPlatform != pkgs.stdenv.hostPlatform) (lib.stringAfter [ "specialfs" "users" "groups" ] ''
mkdir -p ${lib.escapeShellArg home}/.nix-profile/
mount --bind ${config.system.path} ${lib.escapeShellArg home}/.nix-profile/
'');
environment = {
systemPackages = with pkgs; [
xterm # for resize command
];
loginShellInit =
let
pwd = builtins.getEnv "PWD";
term = builtins.getEnv "TERM";
path = builtins.getEnv "PATH";
in
''
# if terminal with stdout, fix terminal size
if [ -t 1 ]; then eval "$(resize)"; fi
${lib.optionalString (pwd != "") "cd '${pwd}' 2>/dev/null"}
${lib.optionalString (term != "") "export TERM='${term}'"}
${lib.optionalString (path != "") "export PATH=\"${path}:$PATH\""}
'';
};
networking.firewall.enable = mkVMDefault false;
}
]);
}