9ee30cd9b5
You can now say: systemd.containers.foo.config = { services.openssh.enable = true; services.openssh.ports = [ 2022 ]; users.extraUsers.root.openssh.authorizedKeys.keys = [ "ssh-dss ..." ]; }; which defines a NixOS instance with the given configuration running inside a lightweight container. You can also manage the configuration of the container independently from the host: systemd.containers.foo.path = "/nix/var/nix/profiles/containers/foo"; where "path" is a NixOS system profile. It can be created/updated by doing: $ nix-env --set -p /nix/var/nix/profiles/containers/foo \ -f '<nixos>' -A system -I nixos-config=foo.nix The container configuration (foo.nix) should define boot.isContainer = true; to optimise away the building of a kernel and initrd. This is done automatically when using the "config" route. On the host, a lightweight container appears as the service "container-<name>.service". The container is like a regular NixOS (virtual) machine, except that it doesn't have its own kernel. It has its own root file system (by default /var/lib/containers/<name>), but shares the Nix store of the host (as a read-only bind mount). It also has access to the network devices of the host. Currently, if the configuration of the container changes, running "nixos-rebuild switch" on the host will cause the container to be rebooted. In the future we may want to send some message to the container so that it can activate the new container configuration without rebooting. Containers are not perfectly isolated yet. In particular, the host's /sys/fs/cgroup is mounted (writable!) in the guest.
194 lines
5.3 KiB
Nix
194 lines
5.3 KiB
Nix
{ config, pkgs, modules, baseModules, ... }:
|
|
|
|
with pkgs.lib;
|
|
|
|
let
|
|
|
|
|
|
# This attribute is responsible for creating boot entries for
|
|
# child configuration. They are only (directly) accessible
|
|
# when the parent configuration is boot default. For example,
|
|
# you can provide an easy way to boot the same configuration
|
|
# as you use, but with another kernel
|
|
# !!! fix this
|
|
cloner = inheritParent: list: with pkgs.lib;
|
|
map (childConfig:
|
|
(import ../../../lib/eval-config.nix {
|
|
inherit baseModules;
|
|
modules =
|
|
(optionals inheritParent modules)
|
|
++ [ ./no-clone.nix ]
|
|
++ [ childConfig ];
|
|
}).config.system.build.toplevel
|
|
) list;
|
|
|
|
children =
|
|
cloner false config.nesting.children
|
|
++ cloner true config.nesting.clone;
|
|
|
|
|
|
systemBuilder =
|
|
let
|
|
kernelPath = "${config.boot.kernelPackages.kernel}/" +
|
|
"${config.system.boot.loader.kernelFile}";
|
|
in ''
|
|
mkdir $out
|
|
|
|
# Containers don't have their own kernel or initrd. They boot
|
|
# directly into stage 2.
|
|
${optionalString (!config.boot.isContainer) ''
|
|
if [ ! -f ${kernelPath} ]; then
|
|
echo "The bootloader cannot find the proper kernel image."
|
|
echo "(Expecting ${kernelPath})"
|
|
false
|
|
fi
|
|
|
|
ln -s ${kernelPath} $out/kernel
|
|
ln -s ${config.system.modulesTree} $out/kernel-modules
|
|
|
|
echo -n "$kernelParams" > $out/kernel-params
|
|
|
|
ln -s ${config.system.build.initialRamdisk}/initrd $out/initrd
|
|
|
|
ln -s ${config.hardware.firmware} $out/firmware
|
|
''}
|
|
|
|
echo "$activationScript" > $out/activate
|
|
substituteInPlace $out/activate --subst-var out
|
|
chmod u+x $out/activate
|
|
unset activationScript
|
|
|
|
cp ${config.system.build.bootStage2} $out/init
|
|
substituteInPlace $out/init --subst-var-by systemConfig $out
|
|
|
|
ln -s ${config.system.build.etc}/etc $out/etc
|
|
ln -s ${config.system.path} $out/sw
|
|
ln -s "$systemd" $out/systemd
|
|
|
|
echo -n "$configurationName" > $out/configuration-name
|
|
echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version
|
|
echo -n "$nixosVersion" > $out/nixos-version
|
|
|
|
mkdir $out/fine-tune
|
|
childCount=0
|
|
for i in $children; do
|
|
childCount=$(( childCount + 1 ))
|
|
ln -s $i $out/fine-tune/child-$childCount
|
|
done
|
|
|
|
mkdir $out/bin
|
|
substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration
|
|
chmod +x $out/bin/switch-to-configuration
|
|
|
|
${config.system.extraSystemBuilderCmds}
|
|
'';
|
|
|
|
|
|
# Putting it all together. This builds a store path containing
|
|
# symlinks to the various parts of the built configuration (the
|
|
# kernel, systemd units, init scripts, etc.) as well as a script
|
|
# `switch-to-configuration' that activates the configuration and
|
|
# makes it bootable.
|
|
system = pkgs.stdenv.mkDerivation {
|
|
name = "nixos-${config.system.nixosVersion}";
|
|
preferLocalBuild = true;
|
|
buildCommand = systemBuilder;
|
|
|
|
inherit (pkgs) utillinux coreutils;
|
|
systemd = config.systemd.package;
|
|
|
|
inherit children;
|
|
installBootLoader =
|
|
config.system.build.installBootLoader
|
|
or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true";
|
|
activationScript = config.system.activationScripts.script;
|
|
nixosVersion = config.system.nixosVersion;
|
|
|
|
configurationName = config.boot.loader.grub.configurationName;
|
|
|
|
# Needed by switch-to-configuration.
|
|
perl = "${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl";
|
|
};
|
|
|
|
|
|
in
|
|
|
|
{
|
|
options = {
|
|
|
|
system.build = mkOption {
|
|
internal = true;
|
|
default = {};
|
|
description = ''
|
|
Attribute set of derivations used to setup the system.
|
|
'';
|
|
};
|
|
|
|
nesting.children = mkOption {
|
|
default = [];
|
|
description = ''
|
|
Additional configurations to build.
|
|
'';
|
|
};
|
|
|
|
nesting.clone = mkOption {
|
|
default = [];
|
|
description = ''
|
|
Additional configurations to build based on the current
|
|
configuration which is has a lower priority.
|
|
'';
|
|
};
|
|
|
|
system.boot.loader.id = mkOption {
|
|
internal = true;
|
|
default = "";
|
|
description = ''
|
|
Id string of the used bootloader.
|
|
'';
|
|
};
|
|
|
|
system.boot.loader.kernelFile = mkOption {
|
|
internal = true;
|
|
default = pkgs.stdenv.platform.kernelTarget;
|
|
type = types.str;
|
|
description = ''
|
|
Name of the kernel file to be passed to the bootloader.
|
|
'';
|
|
};
|
|
|
|
system.copySystemConfiguration = mkOption {
|
|
type = types.bool;
|
|
default = false;
|
|
description = ''
|
|
If enabled, copies the NixOS configuration file
|
|
<literal>$NIXOS_CONFIG</literal> (usually
|
|
<filename>/etc/nixos/configuration.nix</filename>)
|
|
to the system store path.
|
|
'';
|
|
};
|
|
|
|
system.extraSystemBuilderCmds = mkOption {
|
|
type = types.lines;
|
|
internal = true;
|
|
default = "";
|
|
description = ''
|
|
This code will be added to the builder creating the system store path.
|
|
'';
|
|
};
|
|
|
|
};
|
|
|
|
|
|
config = {
|
|
|
|
system.extraSystemBuilderCmds =
|
|
optionalString
|
|
config.system.copySystemConfiguration
|
|
"cp ${maybeEnv "NIXOS_CONFIG" "/etc/nixos/configuration.nix"} $out";
|
|
|
|
system.build.toplevel = system;
|
|
|
|
};
|
|
|
|
}
|