1{
2 config,
3 pkgs,
4 lib,
5 ...
6}:
7
8with lib;
9
10{
11 imports = [
12 ../image/file-options.nix
13 ];
14
15 options.proxmoxLXC = {
16 enable = mkOption {
17 default = true;
18 type = types.bool;
19 description = "Whether to enable the Proxmox VE LXC module.";
20 };
21 privileged = mkOption {
22 type = types.bool;
23 default = false;
24 description = ''
25 Whether to enable privileged mounts
26 '';
27 };
28 manageNetwork = mkOption {
29 type = types.bool;
30 default = false;
31 description = ''
32 Whether to manage network interfaces through nix options
33 When false, systemd-networkd is enabled to accept network
34 configuration from proxmox.
35 '';
36 };
37 manageHostName = mkOption {
38 type = types.bool;
39 default = false;
40 description = ''
41 Whether to manage hostname through nix options
42 When false, the hostname is picked up from /etc/hostname
43 populated by proxmox.
44 '';
45 };
46 };
47
48 config =
49 let
50 cfg = config.proxmoxLXC;
51 in
52 mkIf cfg.enable {
53 system.nixos.tags = [
54 "proxmox"
55 "lxc"
56 ];
57 image.extension = "tar.xz";
58 image.filePath = "tarball/${config.image.fileName}";
59 system.build.image = config.system.build.tarball;
60 system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix {
61 fileName = config.image.baseName;
62 storeContents = [
63 {
64 object = config.system.build.toplevel;
65 symlink = "none";
66 }
67 ];
68
69 contents = [
70 {
71 source = config.system.build.toplevel + "/init";
72 target = "/sbin/init";
73 }
74 ];
75
76 extraCommands = "mkdir -p root etc/systemd/network";
77 };
78
79 boot.postBootCommands = ''
80 # After booting, register the contents of the Nix store in the Nix
81 # database.
82 if [ -f /nix-path-registration ]; then
83 ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
84 rm /nix-path-registration
85 fi
86
87 # nixos-rebuild also requires a "system" profile
88 ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
89 '';
90
91 boot = {
92 isContainer = true;
93 loader.initScript.enable = true;
94 };
95
96 console.enable = true;
97
98 networking = mkIf (!cfg.manageNetwork) {
99 useDHCP = false;
100 useHostResolvConf = false;
101 useNetworkd = true;
102 # pick up hostname from /etc/hostname generated by proxmox
103 hostName = mkIf (!cfg.manageHostName) (mkForce "");
104 };
105
106 # unprivileged LXCs can't set net.ipv4.ping_group_range
107 security.wrappers.ping = mkIf (!cfg.privileged) {
108 owner = "root";
109 group = "root";
110 capabilities = "cap_net_raw+p";
111 source = "${pkgs.iputils.out}/bin/ping";
112 };
113
114 services.openssh = {
115 enable = mkDefault true;
116 startWhenNeeded = mkDefault true;
117 };
118
119 systemd = {
120 mounts = mkIf (!cfg.privileged) [
121 {
122 enable = false;
123 where = "/sys/kernel/debug";
124 }
125 ];
126
127 # By default only starts getty on tty0 but first on LXC is tty1
128 services."autovt@".unitConfig.ConditionPathExists = [
129 ""
130 "/dev/%I"
131 ];
132
133 # These are disabled by `console.enable` but console via tty is the default in Proxmox
134 services."getty@tty1".enable = lib.mkForce true;
135 services."autovt@".enable = lib.mkForce true;
136 };
137
138 };
139}