2022-06-06 13:29:04 +02:00
testModuleArgs @ {
config ,
lib ,
hostPkgs ,
nodes ,
. . .
} :
let
2023-05-07 17:39:08 +02:00
inherit ( lib )
literalExpression
literalMD
mapAttrs
mkDefault
mkIf
2025-03-21 17:14:23 +00:00
mkMerge
2023-05-07 17:39:08 +02:00
mkOption
mkForce
optional
2023-05-07 17:47:29 +02:00
optionalAttrs
2023-05-07 17:39:08 +02:00
types
;
2022-06-06 13:29:04 +02:00
2024-10-26 14:22:26 +02:00
inherit ( hostPkgs . stdenv ) hostPlatform ;
2024-03-01 21:33:14 -08:00
guestSystem =
if hostPlatform . isLinux then
hostPlatform . system
else
let
hostToGuest = {
" x 8 6 _ 6 4 - d a r w i n " = " x 8 6 _ 6 4 - l i n u x " ;
" a a r c h 6 4 - d a r w i n " = " a a r c h 6 4 - l i n u x " ;
} ;
supportedHosts = lib . concatStringsSep " , " ( lib . attrNames hostToGuest ) ;
message = " N i x O S T e s t : d o n ' t k n o w w h i c h V M g u e s t s y s t e m t o p a i r w i t h V M h o s t s y s t e m : ${ hostPlatform . system } . P e r h a p s y o u i n t e n d e d t o r u n t h e t e s t s o n a L i n u x h o s t , o r o n e o f t h e f o l l o w i n g s y s t e m s t h a t m a y r u n N i x O S t e s t s : ${ supportedHosts } " ;
in
hostToGuest . ${ hostPlatform . system } or ( throw message ) ;
2024-12-10 20:26:33 +01:00
2022-06-06 13:29:04 +02:00
baseOS = import ../eval-config.nix {
2023-06-03 19:43:20 -07:00
inherit lib ;
2023-05-07 15:38:58 +02:00
system = null ; # use modularly defined system
2022-06-06 13:29:04 +02:00
inherit ( config . node ) specialArgs ;
modules = [ config . defaults ] ;
baseModules = ( import ../../modules/module-list.nix ) ++ [
2022-06-22 01:12:01 +02:00
./nixos-test-base.nix
2022-06-27 20:07:08 +02:00
{
key = " n o d e s " ;
_module . args . nodes = config . nodesCompat ;
}
2022-06-06 13:29:04 +02:00
(
{ config , . . . }:
{
virtualisation . qemu . package = testModuleArgs . config . qemu . package ;
2024-03-01 21:33:14 -08:00
virtualisation . host . pkgs = hostPkgs ;
2023-05-07 15:38:58 +02:00
}
)
2023-10-06 08:29:58 +03:00
(
{ options , . . . }:
{
2023-05-07 15:44:54 +02:00
key = " n o d e s . n i x - p k g s " ;
2023-10-06 23:52:04 +03:00
config = optionalAttrs ( ! config . node . pkgsReadOnly ) (
mkIf ( ! options . nixpkgs . pkgs . isDefined ) {
# TODO: switch to nixpkgs.hostPlatform and make sure containers-imperative test still evaluates.
2024-03-01 21:33:14 -08:00
nixpkgs . system = guestSystem ;
2023-10-06 23:52:04 +03:00
}
) ;
2023-05-07 15:38:58 +02:00
}
)
2022-09-17 14:34:14 +01:00
testModuleArgs . config . extraBaseModules
2022-12-20 14:28:47 +01:00
] ;
2022-06-06 13:29:04 +02:00
} ;
in
{
options = {
2025-03-21 17:14:23 +00:00
sshBackdoor = {
enable = mkOption {
default = false ;
type = types . bool ;
2025-04-26 12:20:10 +02:00
description = " W h e t h e r t o t u r n o n t h e V S O C K - b a s e d a c c e s s t o a l l V M s . T h i s p r o v i d e s a n u n a u t h e n t i c a t e d a c c e s s i n t e n d e d f o r d e b u g g i n g . " ;
2025-03-21 17:14:23 +00:00
} ;
2025-05-09 10:07:15 +02:00
vsockOffset = mkOption {
default = 2 ;
type = types . ints . between 2 4294967296 ;
description = ''
2025-05-10 10:38:38 +02:00
This field is only relevant when multiple users run the ( interactive )
2025-05-09 19:15:51 +02:00
driver outside the sandbox and with the SSH backdoor activated .
The typical symptom for this being a problem are error messages like this :
` vhost-vsock : unable to set guest cid : Address already in use `
2025-05-09 10:07:15 +02:00
This option allows to assign an offset to each vsock number to
resolve this .
This is a 3 2 bit number . The lowest possible vsock number is ` 3 `
( i . e . with the lowest node number being ` 1 ` , this is 2 + 1 ) .
'' ;
} ;
2025-03-21 17:14:23 +00:00
} ;
2022-06-06 13:29:04 +02:00
node . type = mkOption {
type = types . raw ;
default = baseOS . type ;
internal = true ;
} ;
nodes = mkOption {
type = types . lazyAttrsOf config . node . type ;
2022-06-27 20:06:30 +02:00
visible = " s h a l l o w " ;
2024-04-01 16:58:23 -07:00
description = ''
2022-06-27 20:06:30 +02:00
An attribute set of NixOS configuration modules .
2022-09-29 12:41:59 +02:00
The configurations are augmented by the [ ` defaults ` ] ( #test-opt-defaults) option.
2022-06-27 20:06:30 +02:00
They are assigned network addresses according to the ` nixos/lib/testing/network.nix ` module .
A few special options are available , that aren't in a plain NixOS configuration . See [ Configuring the nodes ] ( #sec-nixos-test-nodes)
'' ;
2022-06-06 13:29:04 +02:00
} ;
defaults = mkOption {
2024-04-01 16:58:23 -07:00
description = ''
2022-09-29 12:41:59 +02:00
NixOS configuration that is applied to all [ { option } ` nodes ` ] ( #test-opt-nodes).
2022-06-27 20:06:30 +02:00
'' ;
type = types . deferredModule ;
default = { } ;
} ;
extraBaseModules = mkOption {
2024-04-01 16:58:23 -07:00
description = ''
2022-09-29 12:41:59 +02:00
NixOS configuration that , like [ { option } ` defaults ` ] ( #test-opt-defaults), is applied to all [{option}`nodes`](#test-opt-nodes) and can not be undone with [`specialisation.<name>.inheritParentConfig`](https://search.nixos.org/options?show=specialisation.%3Cname%3E.inheritParentConfig&from=0&size=50&sort=relevance&type=packages&query=specialisation).
2022-06-06 13:29:04 +02:00
'' ;
type = types . deferredModule ;
default = { } ;
} ;
2023-05-07 17:10:40 +02:00
node . pkgs = mkOption {
2024-04-01 16:58:23 -07:00
description = ''
2023-05-07 17:10:40 +02:00
The Nixpkgs to use for the nodes .
Setting this will make the ` nixpkgs . * ` options read-only , to avoid mistakenly testing with a Nixpkgs configuration that diverges from regular use .
'' ;
type = types . nullOr types . pkgs ;
default = null ;
defaultText = literalMD ''
` null ` , so construct ` pkgs ` according to the ` nixpkgs . * ` options as usual .
'' ;
} ;
2023-05-07 17:39:08 +02:00
node . pkgsReadOnly = mkOption {
2024-04-01 16:58:23 -07:00
description = ''
2023-05-07 17:39:08 +02:00
Whether to make the ` nixpkgs . * ` options read-only . This is only relevant when [ ` node . pkgs ` ] ( #test-opt-node.pkgs) is set.
Set this to ` false ` when any of the [ ` nodes ` ] ( #test-opt-nodes) needs to configure any of the `nixpkgs.*` options. This will slow down evaluation of your test a bit.
'' ;
type = types . bool ;
default = config . node . pkgs != null ;
defaultText = literalExpression '' n o d e . p k g s ! = n u l l '' ;
} ;
2022-06-06 13:29:04 +02:00
node . specialArgs = mkOption {
type = types . lazyAttrsOf types . raw ;
default = { } ;
2024-04-01 16:58:23 -07:00
description = ''
2022-06-27 20:06:30 +02:00
An attribute set of arbitrary values that will be made available as module arguments during the resolution of module ` imports ` .
Note that it is not possible to override these from within the NixOS configurations . If you argument is not relevant to ` imports ` , consider setting { option } ` defaults . _module . args . <name> ` instead .
'' ;
2022-06-06 13:29:04 +02:00
} ;
nodesCompat = mkOption {
internal = true ;
2024-04-01 16:58:23 -07:00
description = ''
2022-06-27 20:06:30 +02:00
Basically ` _module . args . nodes ` , but with backcompat and warnings added .
This will go away .
'' ;
2022-06-06 13:29:04 +02:00
} ;
} ;
config = {
_module . args . nodes = config . nodesCompat ;
nodesCompat = mapAttrs (
name : config :
config
// {
2024-10-08 11:14:24 +02:00
config =
lib . warnIf ( lib . oldestSupportedReleaseIsAtLeast 2211 )
2022-06-06 13:29:04 +02:00
" M o d u l e a r g u m e n t ` n o d e s . ${ name } . c o n f i g ` i s d e p r e c a t e d . U s e ` n o d e s . ${ name } ` i n s t e a d . "
config ;
}
) config . nodes ;
passthru . nodes = config . nodesCompat ;
2023-05-07 17:10:40 +02:00
2025-05-08 10:50:35 +02:00
extraDriverArgs = mkIf config . sshBackdoor . enable [
2025-05-09 10:07:15 +02:00
" - - d u m p - v s o c k s = ${ toString config . sshBackdoor . vsockOffset } "
2025-05-08 10:50:35 +02:00
] ;
2025-03-21 17:14:23 +00:00
defaults = mkMerge [
( mkIf config . node . pkgsReadOnly {
nixpkgs . pkgs = config . node . pkgs ;
imports = [ ../../modules/misc/nixpkgs/read-only.nix ] ;
} )
2025-05-10 10:38:38 +02:00
( mkIf config . sshBackdoor . enable (
let
inherit ( config . sshBackdoor ) vsockOffset ;
in
{ config , . . . }:
{
services . openssh = {
enable = true ;
settings = {
PermitRootLogin = " y e s " ;
PermitEmptyPasswords = " y e s " ;
} ;
} ;
security . pam . services . sshd = {
allowNullPassword = true ;
} ;
virtualisation . qemu . options = [
" - d e v i c e v h o s t - v s o c k - p c i , g u e s t - c i d = ${
toString ( config . virtualisation . test . nodeNumber + vsockOffset )
} "
] ;
}
) )
2025-03-21 17:14:23 +00:00
] ;
2023-05-07 17:10:40 +02:00
2022-06-06 13:29:04 +02:00
} ;
}