nixpkgs/nixos/modules/virtualisation/lxc-container.nix
pennae bd56368848 nixos/*: md-convert hidden plaintext options
most of these are hidden because they're either part of a submodule that
doesn't have its type rendered (eg because the submodule type is used in
an either type) or because they are explicitly hidden. some of them are
merely hidden from nix-doc-munge by how their option is put together.
2022-08-31 16:32:54 +02:00

174 lines
5.3 KiB
Nix

{ lib, config, pkgs, ... }:
with lib;
let
templateSubmodule = { ... }: {
options = {
enable = mkEnableOption (lib.mdDoc "this template");
target = mkOption {
description = lib.mdDoc "Path in the container";
type = types.path;
};
template = mkOption {
description = lib.mdDoc ".tpl file for rendering the target";
type = types.path;
};
when = mkOption {
description = lib.mdDoc "Events which trigger a rewrite (create, copy)";
type = types.listOf (types.str);
};
properties = mkOption {
description = lib.mdDoc "Additional properties";
type = types.attrs;
default = {};
};
};
};
toYAML = name: data: pkgs.writeText name (generators.toYAML {} data);
cfg = config.virtualisation.lxc;
templates = if cfg.templates != {} then let
list = mapAttrsToList (name: value: { inherit name; } // value)
(filterAttrs (name: value: value.enable) cfg.templates);
in
{
files = map (tpl: {
source = tpl.template;
target = "/templates/${tpl.name}.tpl";
}) list;
properties = listToAttrs (map (tpl: nameValuePair tpl.target {
when = tpl.when;
template = "${tpl.name}.tpl";
properties = tpl.properties;
}) list);
}
else { files = []; properties = {}; };
in
{
imports = [
../installer/cd-dvd/channel.nix
../profiles/minimal.nix
../profiles/clone-config.nix
];
options = {
virtualisation.lxc = {
templates = mkOption {
description = lib.mdDoc "Templates for LXD";
type = types.attrsOf (types.submodule (templateSubmodule));
default = {};
example = literalExpression ''
{
# create /etc/hostname on container creation. also requires networking.hostName = "" to be set
"hostname" = {
enable = true;
target = "/etc/hostname";
template = builtins.toFile "hostname.tpl" "{{ container.name }}";
when = [ "create" ];
};
# create /etc/nixos/hostname.nix with a configuration for keeping the hostname applied
"hostname-nix" = {
enable = true;
target = "/etc/nixos/hostname.nix";
template = builtins.toFile "hostname-nix.tpl" "{ ... }: { networking.hostName = \"{{ container.name }}\"; }";
# copy keeps the file updated when the container is changed
when = [ "create" "copy" ];
};
# copy allow the user to specify a custom configuration.nix
"configuration-nix" = {
enable = true;
target = "/etc/nixos/configuration.nix";
template = builtins.toFile "configuration-nix" "{{ config_get(\"user.user-data\", properties.default) }}";
when = [ "create" ];
};
};
'';
};
};
};
config = {
boot.isContainer = true;
boot.postBootCommands =
''
# After booting, register the contents of the Nix store in the Nix
# database.
if [ -f /nix-path-registration ]; then
${config.nix.package.out}/bin/nix-store --load-db < /nix-path-registration &&
rm /nix-path-registration
fi
# nixos-rebuild also requires a "system" profile
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
'';
system.build.metadata = pkgs.callPackage ../../lib/make-system-tarball.nix {
contents = [
{
source = toYAML "metadata.yaml" {
architecture = builtins.elemAt (builtins.match "^([a-z0-9_]+).+" (toString pkgs.system)) 0;
creation_date = 1;
properties = {
description = "NixOS ${config.system.nixos.codeName} ${config.system.nixos.label} ${pkgs.system}";
os = "nixos";
release = "${config.system.nixos.codeName}";
};
templates = templates.properties;
};
target = "/metadata.yaml";
}
] ++ templates.files;
};
# TODO: build rootfs as squashfs for faster unpack
system.build.tarball = pkgs.callPackage ../../lib/make-system-tarball.nix {
extraArgs = "--owner=0";
storeContents = [
{
object = config.system.build.toplevel;
symlink = "none";
}
];
contents = [
{
source = config.system.build.toplevel + "/init";
target = "/sbin/init";
}
];
extraCommands = "mkdir -p proc sys dev";
};
# Add the overrides from lxd distrobuilder
systemd.extraConfig = ''
[Service]
ProtectProc=default
ProtectControlGroups=no
ProtectKernelTunables=no
'';
# Allow the user to login as root without password.
users.users.root.initialHashedPassword = mkOverride 150 "";
system.activationScripts.installInitScript = mkForce ''
ln -fs $systemConfig/init /sbin/init
'';
# Some more help text.
services.getty.helpLine =
''
Log in as "root" with an empty password.
'';
# Containers should be light-weight, so start sshd on demand.
services.openssh.enable = mkDefault true;
services.openssh.startWhenNeeded = mkDefault true;
};
}