1{
2 lib,
3 config,
4 pkgs,
5 ...
6}:
7
8{
9 meta = {
10 maintainers = lib.teams.lxc.members;
11 };
12
13 imports = [
14 ./lxc-instance-common.nix
15
16 (lib.mkRemovedOptionModule [
17 "virtualisation"
18 "lxc"
19 "nestedContainer"
20 ] "")
21 (lib.mkRemovedOptionModule [
22 "virtualisation"
23 "lxc"
24 "privilegedContainer"
25 ] "")
26 ];
27
28 options = { };
29
30 config =
31 let
32 initScript = if config.boot.initrd.systemd.enable then "prepare-root" else "init";
33 in
34 {
35 boot.isContainer = true;
36 boot.postBootCommands = ''
37 # After booting, register the contents of the Nix store in the Nix
38 # database.
39 if [ -f /nix-path-registration ]; then
40 ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
41 rm /nix-path-registration
42 fi
43
44 # nixos-rebuild also requires a "system" profile
45 ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
46 '';
47
48 # supplement 99-ethernet-default-dhcp which excludes veth
49 systemd.network = lib.mkIf config.networking.useDHCP {
50 networks."99-lxc-veth-default-dhcp" = {
51 matchConfig = {
52 Type = "ether";
53 Kind = "veth";
54 Name = [
55 "en*"
56 "eth*"
57 ];
58 };
59 DHCP = "yes";
60 networkConfig.IPv6PrivacyExtensions = "kernel";
61 };
62 };
63
64 system.nixos.tags = lib.mkOverride 99 [ "lxc" ];
65 image.extension = "tar.xz";
66 image.filePath = "tarball/${config.image.fileName}";
67 system.build.image = lib.mkOverride 99 config.system.build.tarball;
68
69 system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix {
70 fileName = config.image.baseName;
71 extraArgs = "--owner=0";
72
73 storeContents = [
74 {
75 object = config.system.build.toplevel;
76 symlink = "none";
77 }
78 ];
79
80 contents = [
81 {
82 source = config.system.build.toplevel + "/${initScript}";
83 target = "/sbin/init";
84 }
85 # Technically this is not required for lxc, but having also make this configuration work with systemd-nspawn.
86 # Nixos will setup the same symlink after start.
87 {
88 source = config.system.build.toplevel + "/etc/os-release";
89 target = "/etc/os-release";
90 }
91 ];
92
93 extraCommands = "mkdir -p proc sys dev";
94 };
95
96 system.build.squashfs = pkgs.callPackage ../../lib/make-squashfs.nix {
97 fileName = "nixos-lxc-image-${pkgs.stdenv.hostPlatform.system}";
98
99 hydraBuildProduct = true;
100 noStrip = true; # keep directory structure
101 comp = "zstd -Xcompression-level 6";
102
103 storeContents = [ config.system.build.toplevel ];
104
105 pseudoFiles = [
106 "/sbin d 0755 0 0"
107 "/sbin/init s 0555 0 0 ${config.system.build.toplevel}/${initScript}"
108 "/dev d 0755 0 0"
109 "/proc d 0555 0 0"
110 "/sys d 0555 0 0"
111 ];
112 };
113
114 system.build.installBootLoader = pkgs.writeScript "install-lxc-sbin-init.sh" ''
115 #!${pkgs.runtimeShell}
116 ${pkgs.coreutils}/bin/ln -fs "$1/${initScript}" /sbin/init
117 '';
118
119 # networkd depends on this, but systemd module disables this for containers
120 systemd.additionalUpstreamSystemUnits = [ "systemd-udev-trigger.service" ];
121
122 systemd.packages = [ pkgs.distrobuilder.generator ];
123
124 system.activationScripts.installInitScript = lib.mkForce ''
125 ln -fs $systemConfig/${initScript} /sbin/init
126 '';
127 };
128}