2021-02-22 11:45:12 +01:00
|
|
|
{ config, lib, pkgs, ... }:
|
2022-06-12 17:26:32 +02:00
|
|
|
|
2019-12-01 00:39:16 +01:00
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
2019-12-09 22:52:53 +01:00
|
|
|
# TODO: move to flake
|
2020-03-25 19:52:13 +01:00
|
|
|
nixcloud-webservices = pkgs.fetchFromGitHub {
|
|
|
|
owner = "nixcloud";
|
|
|
|
repo = "nixcloud-webservices";
|
|
|
|
rev = "3a0767f0536fac811065eb87e6342f27eac085aa";
|
|
|
|
sha256 = "vC0vBu+0HchrevuWsmE7giouKnSt/q4F0TffwhuNJv8=";
|
2019-12-09 22:52:53 +01:00
|
|
|
};
|
2021-10-31 19:00:03 +01:00
|
|
|
inherit (import "${nixcloud-webservices}/pkgs" { inherit pkgs; }) nixcloud;
|
2019-12-09 22:52:53 +01:00
|
|
|
|
2019-12-01 00:39:16 +01:00
|
|
|
profilesDir = "/nix/var/nix/profiles/lxc";
|
2021-10-31 19:00:03 +01:00
|
|
|
inherit (config.lxc) containers;
|
|
|
|
inherit (config.nix) nixPath;
|
2019-12-01 04:13:26 +01:00
|
|
|
|
|
|
|
toLxcConfig' = path: a:
|
2021-02-22 11:45:12 +01:00
|
|
|
if builtins.isString a then ''
|
|
|
|
${path} = ${a}
|
|
|
|
'' else if builtins.isInt a then ''
|
|
|
|
${path} = ${toString a}
|
|
|
|
'' else if builtins.isAttrs a then
|
|
|
|
lib.concatMapStrings (name:
|
|
|
|
let path' = if path == "" then name else "${path}.${name}";
|
|
|
|
in toLxcConfig' path' (builtins.getAttr name a)) (builtins.attrNames a)
|
|
|
|
else if builtins.isList a then
|
|
|
|
lib.concatMapStrings (toLxcConfig' path) a
|
|
|
|
else
|
|
|
|
throw "Invalid LXC config value";
|
2019-12-01 04:13:26 +01:00
|
|
|
toLxcConfig = toLxcConfig' "";
|
|
|
|
|
2021-02-22 11:45:12 +01:00
|
|
|
lxc-rootfs = pkgs.runCommand "lxc-rootfs" { } ''
|
|
|
|
mkdir -p $out/share/lxc/rootfs/{dev,nix/store,proc,run,sys,tmp}
|
2019-12-01 04:13:26 +01:00
|
|
|
'';
|
2019-12-01 00:39:16 +01:00
|
|
|
in {
|
|
|
|
options = with types; {
|
|
|
|
lxc.containers = mkOption {
|
|
|
|
type = attrs;
|
2021-02-22 11:45:12 +01:00
|
|
|
default = { };
|
2019-12-01 00:39:16 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-02-22 11:45:12 +01:00
|
|
|
config = mkIf (containers != { }) {
|
2019-12-09 22:52:53 +01:00
|
|
|
virtualisation.lxc.enable = true;
|
|
|
|
environment.systemPackages = [ nixcloud.container ];
|
|
|
|
|
|
|
|
virtualisation.lxc.defaultConfig = ''
|
|
|
|
lxc.id_map = u 0 100000 65536
|
|
|
|
lxc.id_map = g 0 100000 65536
|
|
|
|
'';
|
2021-02-22 11:45:12 +01:00
|
|
|
users.users.root.subGidRanges = [{
|
|
|
|
count = 65536;
|
|
|
|
startGid = 100000;
|
|
|
|
}];
|
|
|
|
users.users.root.subUidRanges = [{
|
|
|
|
count = 65536;
|
|
|
|
startUid = 100000;
|
|
|
|
}];
|
2019-12-01 00:39:16 +01:00
|
|
|
|
2021-02-22 11:45:12 +01:00
|
|
|
systemd.services = if true then
|
|
|
|
{ }
|
|
|
|
else
|
2019-12-01 00:39:16 +01:00
|
|
|
builtins.foldl' (services: name:
|
|
|
|
let
|
2019-12-01 04:13:26 +01:00
|
|
|
systemDir = "/${profilesDir}/${name}/system";
|
|
|
|
lxcDefaults = {
|
|
|
|
lxc = {
|
|
|
|
uts.name = name;
|
|
|
|
rootfs.path = "/run/current-system/sw/share/lxc/rootfs";
|
|
|
|
mount.entry = [
|
|
|
|
"${systemDir}/init /init none bind,ro 0 0"
|
|
|
|
"/nix/store /nix/store none bind,ro 0 0"
|
|
|
|
];
|
|
|
|
autodev = 1;
|
|
|
|
include = "/run/current-system/sw/share/lxc/config/common.conf";
|
|
|
|
apparmor.profile = "generated";
|
|
|
|
environment = "TERM=linux";
|
|
|
|
};
|
|
|
|
};
|
2019-12-01 00:39:16 +01:00
|
|
|
config = builtins.getAttr name containers;
|
2019-12-01 04:13:26 +01:00
|
|
|
lxcConfig = builtins.toFile "lxc-container-${name}.conf"
|
2019-12-09 22:52:53 +01:00
|
|
|
# TODO: more intelligent merging?
|
2019-12-01 04:13:26 +01:00
|
|
|
(toLxcConfig (lxcDefaults // config.lxc));
|
|
|
|
|
2019-12-01 00:39:16 +01:00
|
|
|
builder = {
|
|
|
|
description = "Build NixOS for lxc container ${name}";
|
|
|
|
wants = [ "nix-daemon.socket" ];
|
|
|
|
after = [ "nix-daemon.service" ];
|
|
|
|
|
|
|
|
path = with pkgs; [ coreutils nix ];
|
|
|
|
|
|
|
|
serviceConfig = {
|
|
|
|
Type = "oneshot";
|
|
|
|
RemainAfterExit = true;
|
2021-02-22 11:45:12 +01:00
|
|
|
Environment = [ "NIX_PATH=${builtins.concatStringsSep ":" nixPath}" ];
|
2022-06-12 17:26:32 +02:00
|
|
|
};
|
2019-12-01 00:39:16 +01:00
|
|
|
|
|
|
|
script = ''
|
|
|
|
mkdir -p ${profilesDir}/${name}
|
|
|
|
|
|
|
|
nix-env -p ${profilesDir}/${name}/system \
|
|
|
|
-I nixos-config=${config.nixos-config} \
|
|
|
|
-f '<nixpkgs/nixos>' \
|
|
|
|
--set -A system
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
starter = {
|
|
|
|
description = "LXC container ${name}";
|
2019-12-01 04:13:26 +01:00
|
|
|
requires = [ "lxc-container-${name}-builder.service" ];
|
|
|
|
after = [ "lxc-container-${name}-builder.service" ];
|
2019-12-01 00:39:16 +01:00
|
|
|
|
2019-12-01 04:13:26 +01:00
|
|
|
path = with pkgs; [ lxc apparmor-parser ];
|
2019-12-01 00:39:16 +01:00
|
|
|
|
|
|
|
script = ''
|
2019-12-01 04:13:26 +01:00
|
|
|
mkdir -p /var/lib/lxc/${name}
|
|
|
|
ln -fs ${lxcConfig} /var/lib/lxc/${name}/config
|
2019-12-01 00:39:16 +01:00
|
|
|
lxc-start -F -n ${name}
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
in services // {
|
|
|
|
"lxc-container-${name}-builder" = builder;
|
|
|
|
"lxc-container-${name}" = starter;
|
2021-02-22 11:45:12 +01:00
|
|
|
}) { } (builtins.attrNames containers);
|
2019-12-01 00:39:16 +01:00
|
|
|
};
|
|
|
|
}
|