at 22.05-pre 5.3 kB view raw
1{ lib, config, pkgs, ... }: 2 3with lib; 4 5let 6 templateSubmodule = { ... }: { 7 options = { 8 enable = mkEnableOption "this template"; 9 10 target = mkOption { 11 description = "Path in the container"; 12 type = types.path; 13 }; 14 template = mkOption { 15 description = ".tpl file for rendering the target"; 16 type = types.path; 17 }; 18 when = mkOption { 19 description = "Events which trigger a rewrite (create, copy)"; 20 type = types.listOf (types.str); 21 }; 22 properties = mkOption { 23 description = "Additional properties"; 24 type = types.attrs; 25 default = {}; 26 }; 27 }; 28 }; 29 30 toYAML = name: data: pkgs.writeText name (generators.toYAML {} data); 31 32 cfg = config.virtualisation.lxc; 33 templates = if cfg.templates != {} then let 34 list = mapAttrsToList (name: value: { inherit name; } // value) 35 (filterAttrs (name: value: value.enable) cfg.templates); 36 in 37 { 38 files = map (tpl: { 39 source = tpl.template; 40 target = "/templates/${tpl.name}.tpl"; 41 }) list; 42 properties = listToAttrs (map (tpl: nameValuePair tpl.target { 43 when = tpl.when; 44 template = "${tpl.name}.tpl"; 45 properties = tpl.properties; 46 }) list); 47 } 48 else { files = []; properties = {}; }; 49 50in 51{ 52 imports = [ 53 ../installer/cd-dvd/channel.nix 54 ../profiles/minimal.nix 55 ../profiles/clone-config.nix 56 ]; 57 58 options = { 59 virtualisation.lxc = { 60 templates = mkOption { 61 description = "Templates for LXD"; 62 type = types.attrsOf (types.submodule (templateSubmodule)); 63 default = {}; 64 example = literalExpression '' 65 { 66 # create /etc/hostname on container creation 67 "hostname" = { 68 enable = true; 69 target = "/etc/hostname"; 70 template = builtins.writeFile "hostname.tpl" "{{ container.name }}"; 71 when = [ "create" ]; 72 }; 73 # create /etc/nixos/hostname.nix with a configuration for keeping the hostname applied 74 "hostname-nix" = { 75 enable = true; 76 target = "/etc/nixos/hostname.nix"; 77 template = builtins.writeFile "hostname-nix.tpl" "{ ... }: { networking.hostName = "{{ container.name }}"; }"; 78 # copy keeps the file updated when the container is changed 79 when = [ "create" "copy" ]; 80 }; 81 # copy allow the user to specify a custom configuration.nix 82 "configuration-nix" = { 83 enable = true; 84 target = "/etc/nixos/configuration.nix"; 85 template = builtins.writeFile "configuration-nix" "{{ config_get(\"user.user-data\", properties.default) }}"; 86 when = [ "create" ]; 87 }; 88 }; 89 ''; 90 }; 91 }; 92 }; 93 94 config = { 95 boot.isContainer = true; 96 boot.postBootCommands = 97 '' 98 # After booting, register the contents of the Nix store in the Nix 99 # database. 100 if [ -f /nix-path-registration ]; then 101 ${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration && 102 rm /nix-path-registration 103 fi 104 105 # nixos-rebuild also requires a "system" profile 106 ${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system 107 ''; 108 109 system.build.metadata = pkgs.callPackage ../../lib/make-system-tarball.nix { 110 contents = [ 111 { 112 source = toYAML "metadata.yaml" { 113 architecture = builtins.elemAt (builtins.match "^([a-z0-9_]+).+" (toString pkgs.system)) 0; 114 creation_date = 1; 115 properties = { 116 description = "NixOS ${config.system.nixos.codeName} ${config.system.nixos.label} ${pkgs.system}"; 117 os = "nixos"; 118 release = "${config.system.nixos.codeName}"; 119 }; 120 templates = templates.properties; 121 }; 122 target = "/metadata.yaml"; 123 } 124 ] ++ templates.files; 125 }; 126 127 # TODO: build rootfs as squashfs for faster unpack 128 system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix { 129 extraArgs = "--owner=0"; 130 131 storeContents = [ 132 { 133 object = config.system.build.toplevel; 134 symlink = "none"; 135 } 136 ]; 137 138 contents = [ 139 { 140 source = config.system.build.toplevel + "/init"; 141 target = "/sbin/init"; 142 } 143 ]; 144 145 extraCommands = "mkdir -p proc sys dev"; 146 }; 147 148 # Add the overrides from lxd distrobuilder 149 systemd.extraConfig = '' 150 [Service] 151 ProtectProc=default 152 ProtectControlGroups=no 153 ProtectKernelTunables=no 154 ''; 155 156 # Allow the user to login as root without password. 157 users.users.root.initialHashedPassword = mkOverride 150 ""; 158 159 system.activationScripts.installInitScript = mkForce '' 160 ln -fs $systemConfig/init /sbin/init 161 ''; 162 163 # Some more help text. 164 services.getty.helpLine = 165 '' 166 167 Log in as "root" with an empty password. 168 ''; 169 170 # Containers should be light-weight, so start sshd on demand. 171 services.openssh.enable = mkDefault true; 172 services.openssh.startWhenNeeded = mkDefault true; 173 }; 174}