Merge branch 'master' into staging-next

This commit is contained in:
Jan Tojnar
2019-09-18 21:15:35 +02:00
167 changed files with 11105 additions and 6483 deletions

View File

@@ -157,6 +157,8 @@ in
# terminal instead of logging out of X11).
environment.variables = config.environment.sessionVariables;
environment.profileRelativeEnvVars = config.environment.profileRelativeSessionVariables;
environment.shellAliases = mapAttrs (name: mkDefault) {
ls = "ls --color=tty";
ll = "ls -l";

View File

@@ -8,6 +8,11 @@ let
cfg = config.environment;
pamProfiles =
map
(replaceStrings ["$HOME" "$USER"] ["@{HOME}" "@{PAM_USER}"])
cfg.profiles;
in
{
@@ -18,25 +23,76 @@ in
default = {};
description = ''
A set of environment variables used in the global environment.
These variables will be set by PAM.
The value of each variable can be either a string or a list of
strings. The latter is concatenated, interspersed with colon
characters.
These variables will be set by PAM early in the login process.
The value of each session variable can be either a string or a
list of strings. The latter is concatenated, interspersed with
colon characters.
Note, due to limitations in the PAM format values may not
contain the <literal>"</literal> character.
Also, these variables are merged into
<xref linkend="opt-environment.variables"/> and it is
therefore not possible to use PAM style variables such as
<code>@{HOME}</code>.
'';
type = with types; attrsOf (either str (listOf str));
apply = mapAttrs (n: v: if isList v then concatStringsSep ":" v else v);
};
environment.profileRelativeSessionVariables = mkOption {
type = types.attrsOf (types.listOf types.str);
example = { PATH = [ "/bin" ]; MANPATH = [ "/man" "/share/man" ]; };
description = ''
Attribute set of environment variable used in the global
environment. These variables will be set by PAM early in the
login process.
Variable substitution is available as described in
<citerefentry>
<refentrytitle>pam_env.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>.
Each attribute maps to a list of relative paths. Each relative
path is appended to the each profile of
<option>environment.profiles</option> to form the content of
the corresponding environment variable.
Also, these variables are merged into
<xref linkend="opt-environment.profileRelativeEnvVars"/> and it is
therefore not possible to use PAM style variables such as
<code>@{HOME}</code>.
'';
};
};
config = {
system.build.pamEnvironment = pkgs.writeText "pam-environment"
''
${concatStringsSep "\n" (
(mapAttrsToList (n: v: ''${n}="${concatStringsSep ":" v}"'')
(zipAttrsWith (const concatLists) ([ (mapAttrs (n: v: [ v ]) cfg.sessionVariables) ]))))}
'';
system.build.pamEnvironment =
let
suffixedVariables =
flip mapAttrs cfg.profileRelativeSessionVariables (envVar: suffixes:
flip concatMap pamProfiles (profile:
map (suffix: "${profile}${suffix}") suffixes
)
);
pamVariable = n: v:
''${n} DEFAULT="${concatStringsSep ":" (toList v)}"'';
pamVariables =
concatStringsSep "\n"
(mapAttrsToList pamVariable
(zipAttrsWith (n: concatLists)
[
(mapAttrs (n: toList) cfg.sessionVariables)
suffixedVariables
]));
in
pkgs.writeText "pam-environment" "${pamVariables}\n";
};

View File

@@ -12,7 +12,7 @@
source = "${config.system.path}/share/terminfo";
};
environment.profileRelativeEnvVars = {
environment.profileRelativeSessionVariables = {
TERMINFO_DIRS = [ "/share/terminfo" ];
};

View File

@@ -7,19 +7,19 @@ with lib;
type = types.bool;
default = true;
description = ''
Whether to install files to support the
Whether to install files to support the
<link xlink:href="https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html">XDG Icon Theme specification</link>.
'';
};
};
config = mkIf config.xdg.icons.enable {
environment.pathsToLink = [
"/share/icons"
"/share/pixmaps"
environment.pathsToLink = [
"/share/icons"
"/share/pixmaps"
];
environment.profileRelativeEnvVars = {
environment.profileRelativeSessionVariables = {
XCURSOR_PATH = [ "/share/icons" ];
};
};

View File

@@ -25,6 +25,7 @@ in
config = mkIf cfg.enable {
services.udev.packages = with pkgs; [ brightnessctl ];
environment.systemPackages = with pkgs; [ brightnessctl ];
};
}

View File

@@ -22,6 +22,8 @@ in
EDITOR = mkDefault "nano";
XCURSOR_PATH = [ "$HOME/.icons" ];
XDG_CONFIG_DIRS = [ "/etc/xdg" ]; # needs to be before profile-relative paths to allow changes through environment.etc
GTK_DATA_PREFIX = "${config.system.path}"; # needed for gtk2 apps to find themes
GTK_EXE_PREFIX = "${config.system.path}";
};
environment.profiles = mkAfter
@@ -30,7 +32,7 @@ in
];
# TODO: move most of these elsewhere
environment.profileRelativeEnvVars =
environment.profileRelativeSessionVariables =
{ PATH = [ "/bin" ];
INFOPATH = [ "/info" "/share/info" ];
KDEDIRS = [ "" ];

View File

@@ -415,7 +415,7 @@ let
# Session management.
${optionalString cfg.setEnvironment ''
session required pam_env.so envfile=${config.system.build.pamEnvironment}
session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0
''}
session required pam_unix.so
${optionalString cfg.setLoginUid

View File

@@ -193,7 +193,7 @@ in {
then ""
else
let pluginCmds = lib.attrsets.mapAttrsToList
(n: v: "cp ${v} ${cfg.home}/plugins/${n}.hpi")
(n: v: "cp ${v} ${cfg.home}/plugins/${n}.jpi")
cfg.plugins;
in ''
rm -r ${cfg.home}/plugins || true

View File

@@ -95,13 +95,7 @@ in {
environment.systemPackages = [ cfg.package editorScript desktopApplicationFile ];
environment.variables = {
# This is required so that GTK applications launched from Emacs
# get properly themed:
GTK_DATA_PREFIX = "${config.system.path}";
} // (if cfg.defaultEditor then {
EDITOR = mkOverride 900 "${editorScript}/bin/emacseditor";
} else {});
environment.variables.EDITOR = mkIf cfg.defaultEditor (mkOverride 900 "${editorScript}/bin/emacseditor");
};
meta.doc = ./emacs.xml;

View File

@@ -36,6 +36,37 @@ in
'';
};
services.minidlna.friendlyName = mkOption {
type = types.str;
default = "${config.networking.hostName} MiniDLNA";
defaultText = "$HOSTNAME MiniDLNA";
example = "rpi3";
description =
''
Name that the DLNA server presents to clients.
'';
};
services.minidlna.rootContainer = mkOption {
type = types.str;
default = ".";
example = "B";
description =
''
Use a different container as the root of the directory tree presented
to clients. The possible values are:
- "." - standard container
- "B" - "Browse Directory"
- "M" - "Music"
- "P" - "Pictures"
- "V" - "Video"
- Or, you can specify the ObjectID of your desired root container
(eg. 1$F for Music/Playlists)
If you specify "B" and the client device is audio-only then
"Music/Folders" will be used as root.
'';
};
services.minidlna.loglevel = mkOption {
type = types.str;
default = "warn";
@@ -66,7 +97,37 @@ in
services.minidlna.config = mkOption {
type = types.lines;
description = "The contents of MiniDLNA's configuration file.";
description =
''
The contents of MiniDLNA's configuration file.
When the service is activated, a basic template is generated
from the current options opened here.
'';
};
services.minidlna.extraConfig = mkOption {
type = types.lines;
default = "";
example = ''
# Not exhaustive example
# Support for streaming .jpg and .mp3 files to a TiVo supporting HMO.
enable_tivo=no
# SSDP notify interval, in seconds.
notify_interval=10
# maximum number of simultaneous connections
# note: many clients open several simultaneous connections while
# streaming
max_connections=50
# set this to yes to allow symlinks that point outside user-defined
# media_dirs.
wide_links=yes
'';
description =
''
Extra minidlna options not yet opened for configuration here
(strict_dlna, model_number, model_name, etc...). This is appended
to the current service already provided.
'';
};
};
@@ -75,13 +136,15 @@ in
services.minidlna.config =
''
port=${toString port}
friendly_name=${config.networking.hostName} MiniDLNA
friendly_name=${cfg.friendlyName}
db_dir=/var/cache/minidlna
log_level=${cfg.loglevel}
inotify=yes
root_container=${cfg.rootContainer}
${concatMapStrings (dir: ''
media_dir=${dir}
'') cfg.mediaDirs}
${cfg.extraConfig}
'';
users.users.minidlna = {

View File

@@ -45,6 +45,8 @@ let
$CFG->aspellpath = '${pkgs.aspell}/bin/aspell';
$CFG->pathtodot = '${pkgs.graphviz}/bin/dot';
${cfg.extraConfig}
require_once('${cfg.package}/share/moodle/lib/setup.php');
// There is no php closing tag in this file,
@@ -172,6 +174,19 @@ in
for details on configuration directives.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Any additional text to be appended to the config.php
configuration file. This is a PHP script. For configuration
details, see <link xlink:href="https://docs.moodle.org/37/en/Configuration_file"/>.
'';
example = ''
$CFG->disableupdatenotifications = true;
'';
};
};
# implementation

View File

@@ -48,10 +48,6 @@ in
services.xserver.desktopManager.session = [
{ name = "Enlightenment";
start = ''
# Set GTK_DATA_PREFIX so that GTK can find the themes
export GTK_DATA_PREFIX=${config.system.path}
# find theme engines
export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0
export XDG_MENU_PREFIX=e-
export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}"

View File

@@ -48,12 +48,6 @@ in
name = "mate";
bgSupport = true;
start = ''
# Set GTK_DATA_PREFIX so that GTK can find the themes
export GTK_DATA_PREFIX=${config.system.path}
# Find theme engines
export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0
export XDG_MENU_PREFIX=mate-
# Let caja find extensions

View File

@@ -79,8 +79,7 @@ in
Using Pantheon without LightDM as a displayManager will break screenlocking from the UI.
'';
services.xserver.displayManager.lightdm.enable = mkDefault true;
services.xserver.displayManager.lightdm.greeters.gtk.enable = mkDefault true;
services.xserver.displayManager.lightdm.greeters.pantheon.enable = mkDefault true;
# If not set manually Pantheon session cannot be started
# Known issue of https://github.com/NixOS/nixpkgs/pull/43992
@@ -98,10 +97,6 @@ in
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
fi
'') cfg.sessionPath}
# Settings from elementary-default-settings
export GTK_CSD=1
export GTK_MODULES=$GTK_MODULES:pantheon-filechooser-module
fi
'';
@@ -166,9 +161,14 @@ in
networkmanager-iodine networkmanager-l2tp; };
# Override GSettings schemas
environment.variables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
environment.variables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1";
environment.sessionVariables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1";
# Settings from elementary-default-settings
environment.sessionVariables.GTK_CSD = "1";
environment.sessionVariables.GTK_MODULES = "pantheon-filechooser-module";
environment.etc."gtk-3.0/settings.ini".source = "${pkgs.pantheon.elementary-default-settings}/etc/gtk-3.0/settings.ini";
environment.pathsToLink = [
# FIXME: modules should link subdirs of `/share` rather than relying on this

View File

@@ -107,12 +107,6 @@ in
start = ''
${cfg.extraSessionCommands}
# Set GTK_PATH so that GTK can find the theme engines.
export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0"
# Set GTK_DATA_PREFIX so that GTK can find the Xfce themes.
export GTK_DATA_PREFIX=${config.system.path}
${pkgs.runtimeShell} ${pkgs.xfce.xinitrc} &
waitPID=$!
'';

View File

@@ -114,12 +114,6 @@ in
name = "xfce4-14";
bgSupport = true;
start = ''
# Set GTK_PATH so that GTK can find the theme engines.
export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0"
# Set GTK_DATA_PREFIX so that GTK can find the Xfce themes.
export GTK_DATA_PREFIX=${config.system.path}
${pkgs.runtimeShell} ${pkgs.xfce4-14.xinitrc} &
waitPID=$!
'';

View File

@@ -142,8 +142,6 @@ in
GDM_X_SERVER_EXTRA_ARGS = toString
(filter (arg: arg != "-terminate") cfg.xserverArgs);
XDG_DATA_DIRS = "${cfg.session.desktops}/share/";
# Find the mouse
XCURSOR_PATH = "~/.icons:${pkgs.gnome3.adwaita-icon-theme}/share/icons";
} // optionalAttrs (xSessionWrapper != null) {
# Make GDM use this wrapper before running the session, which runs the
# configured setupCommands. This relies on a patched GDM which supports
@@ -262,7 +260,7 @@ in
password required pam_deny.so
session required pam_succeed_if.so audit quiet_success user = gdm
session required pam_env.so envfile=${config.system.build.pamEnvironment}
session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
session optional pam_keyinit.so force revoke
session optional pam_permit.so

View File

@@ -10,32 +10,6 @@ let
icons = cfg.iconTheme.package;
cursors = cfg.cursorTheme.package;
# We need a few things in the environment for the greeter to run with
# fonts/icons.
wrappedEnsoGreeter = pkgs.runCommand "lightdm-enso-os-greeter" {
buildInputs = [ pkgs.makeWrapper ];
preferLocalBuild = true;
} ''
# This wrapper ensures that we actually get themes
makeWrapper ${pkgs.lightdm-enso-os-greeter}/bin/pantheon-greeter \
$out/greeter \
--prefix PATH : "${pkgs.glibc.bin}/bin" \
--set GDK_PIXBUF_MODULE_FILE "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" \
--set GTK_PATH "${theme}:${pkgs.gtk3.out}" \
--set GTK_EXE_PREFIX "${theme}" \
--set GTK_DATA_PREFIX "${theme}" \
--set XDG_DATA_DIRS "${theme}/share:${icons}/share:${cursors}/share" \
--set XDG_CONFIG_HOME "${theme}/share"
cat - > $out/lightdm-enso-os-greeter.desktop << EOF
[Desktop Entry]
Name=LightDM Greeter
Comment=This runs the LightDM Greeter
Exec=$out/greeter
Type=Application
EOF
'';
ensoGreeterConf = pkgs.writeText "lightdm-enso-os-greeter.conf" ''
[greeter]
default-wallpaper=${ldmcfg.background}
@@ -144,10 +118,16 @@ in {
config = mkIf (ldmcfg.enable && cfg.enable) {
environment.etc."lightdm/greeter.conf".source = ensoGreeterConf;
environment.systemPackages = [
cursors
icons
theme
];
services.xserver.displayManager.lightdm = {
greeter = mkDefault {
package = wrappedEnsoGreeter;
name = "lightdm-enso-os-greeter";
package = pkgs.lightdm-enso-os-greeter.xgreeters;
name = "pantheon-greeter";
};
greeters = {

View File

@@ -15,34 +15,6 @@ let
icons = cfg.iconTheme.package;
cursors = cfg.cursorTheme.package;
# The default greeter provided with this expression is the GTK greeter.
# Again, we need a few things in the environment for the greeter to run with
# fonts/icons.
wrappedGtkGreeter = pkgs.runCommand "lightdm-gtk-greeter" {
buildInputs = [ pkgs.makeWrapper ];
preferLocalBuild = true;
} ''
# This wrapper ensures that we actually get themes
makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \
$out/greeter \
--prefix PATH : "${lib.getBin pkgs.stdenv.cc.libc}/bin" \
--set GDK_PIXBUF_MODULE_FILE "${pkgs.librsvg.out}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" \
--set GTK_PATH "${theme}:${pkgs.gtk3.out}" \
--set GTK_EXE_PREFIX "${theme}" \
--set GTK_DATA_PREFIX "${theme}" \
--set XDG_DATA_DIRS "${theme}/share:${icons}/share" \
--set XDG_CONFIG_HOME "${theme}/share" \
--set XCURSOR_PATH "${cursors}/share/icons"
cat - > $out/lightdm-gtk-greeter.desktop << EOF
[Desktop Entry]
Name=LightDM Greeter
Comment=This runs the LightDM Greeter
Exec=$out/greeter
Type=Application
EOF
'';
gtkGreeterConf = writeText "lightdm-gtk-greeter.conf"
''
[greeter]
@@ -185,10 +157,16 @@ in
config = mkIf (ldmcfg.enable && cfg.enable) {
services.xserver.displayManager.lightdm.greeter = mkDefault {
package = wrappedGtkGreeter;
package = pkgs.lightdm_gtk_greeter.xgreeters;
name = "lightdm-gtk-greeter";
};
environment.systemPackages = [
cursors
icons
theme
];
environment.etc."lightdm/lightdm-gtk-greeter.conf".source = gtkGreeterConf;
};

View File

@@ -8,11 +8,6 @@ let
ldmcfg = dmcfg.lightdm;
cfg = ldmcfg.greeters.mini;
xgreeters = pkgs.linkFarm "lightdm-mini-greeter-xgreeters" [{
path = "${pkgs.lightdm-mini-greeter}/share/xgreeters/lightdm-mini-greeter.desktop";
name = "lightdm-mini-greeter.desktop";
}];
miniGreeterConf = pkgs.writeText "lightdm-mini-greeter.conf"
''
[greeter]
@@ -90,7 +85,7 @@ in
services.xserver.displayManager.lightdm.greeters.gtk.enable = false;
services.xserver.displayManager.lightdm.greeter = mkDefault {
package = xgreeters;
package = pkgs.lightdm-mini-greeter.xgreeters;
name = "lightdm-mini-greeter";
};

View File

@@ -8,11 +8,6 @@ let
ldmcfg = dmcfg.lightdm;
cfg = ldmcfg.greeters.pantheon;
xgreeters = pkgs.linkFarm "pantheon-greeter-xgreeters" [{
path = "${pkgs.pantheon.elementary-greeter}/share/xgreeters/io.elementary.greeter.desktop";
name = "io.elementary.greeter.desktop";
}];
in
{
options = {
@@ -33,17 +28,10 @@ in
config = mkIf (ldmcfg.enable && cfg.enable) {
warnings = [
''
The Pantheon greeter is suboptimal in NixOS and can possibly put you in
a situation where you cannot start a session when switching desktopManagers.
''
];
services.xserver.displayManager.lightdm.greeters.gtk.enable = false;
services.xserver.displayManager.lightdm.greeter = mkDefault {
package = xgreeters;
package = pkgs.pantheon.elementary-greeter.xgreeters;
name = "io.elementary.greeter";
};

View File

@@ -249,7 +249,7 @@ in
password required pam_deny.so
session required pam_succeed_if.so audit quiet_success user = lightdm
session required pam_env.so envfile=${config.system.build.pamEnvironment}
session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
session optional pam_keyinit.so force revoke
session optional pam_permit.so

View File

@@ -219,8 +219,6 @@ in
# Load themes from system environment
QT_PLUGIN_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtPluginPrefix;
QML2_IMPORT_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtQmlPrefix;
XDG_DATA_DIRS = "/run/current-system/sw/share";
};
execCmd = "exec /run/current-system/sw/bin/sddm";
@@ -242,7 +240,7 @@ in
password required pam_deny.so
session required pam_succeed_if.so audit quiet_success user = sddm
session required pam_env.so envfile=${config.system.build.pamEnvironment}
session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0
session optional ${pkgs.systemd}/lib/security/pam_systemd.so
session optional pam_keyinit.so force revoke
session optional pam_permit.so

View File

@@ -292,6 +292,12 @@ in rec {
services.xserver.desktopManager.xfce.enable = true;
});
gnome3 = makeClosure ({ ... }:
{ services.xserver.enable = true;
services.xserver.displayManager.gdm.enable = true;
services.xserver.desktopManager.gnome3.enable = true;
});
# Linux/Apache/PostgreSQL/PHP stack.
lapp = makeClosure ({ pkgs, ... }:
{ services.httpd.enable = true;

View File

@@ -162,6 +162,7 @@ in
metabase = handleTest ./metabase.nix {};
miniflux = handleTest ./miniflux.nix {};
minio = handleTest ./minio.nix {};
minidlna = handleTest ./minidlna.nix {};
misc = handleTest ./misc.nix {};
mongodb = handleTest ./mongodb.nix {};
moodle = handleTest ./moodle.nix {};
@@ -204,6 +205,7 @@ in
# openstack-image-userdata doesn't work in a sandbox as the simulated openstack instance needs network access
#openstack-image-userdata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).userdata or {};
openstack-image-metadata = (handleTestOn ["x86_64-linux"] ./openstack-image.nix {}).metadata or {};
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
osquery = handleTest ./osquery.nix {};
osrm-backend = handleTest ./osrm-backend.nix {};
ostree = handleTest ./ostree.nix {};

View File

@@ -10,6 +10,7 @@ import ./make-test.nix ({ pkgs, ...} : {
{ users.users.alice = { isNormalUser = true; extraGroups = [ "proc" ]; };
users.users.sybil = { isNormalUser = true; group = "wheel"; };
imports = [ ../modules/profiles/hardened.nix ];
environment.memoryAllocator.provider = "graphene-hardened";
nix.useSandbox = false;
virtualisation.emptyDiskImages = [ 4096 ];
boot.initrd.postDeviceCommands = ''

39
nixos/tests/minidlna.nix Normal file
View File

@@ -0,0 +1,39 @@
import ./make-test.nix ({ pkgs, ... }: {
name = "minidlna";
nodes = {
server =
{ ... }:
{
imports = [ ../modules/profiles/minimal.nix ];
networking.firewall.allowedTCPPorts = [ 8200 ];
services.minidlna = {
enable = true;
loglevel = "error";
mediaDirs = [
"PV,/tmp/stuff"
];
friendlyName = "rpi3";
rootContainer = "B";
extraConfig =
''
album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg
album_art_names=AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg
album_art_names=Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg
notify_interval=60
'';
};
};
client = { ... }: { };
};
testScript =
''
startAll;
$server->succeed("mkdir -p /tmp/stuff && chown minidlna: /tmp/stuff");
$server->waitForUnit("minidlna");
$server->waitForOpenPort("8200");
$server->succeed("curl --fail http://localhost:8200/");
$client->succeed("curl --fail http://server:8200/");
'';
})

119
nixos/tests/os-prober.nix Normal file
View File

@@ -0,0 +1,119 @@
import ./make-test.nix ({pkgs, lib, ...}:
let
# A filesystem image with a (presumably) bootable debian
debianImage = pkgs.vmTools.diskImageFuns.debian9i386 {
# os-prober cannot detect systems installed on disks without a partition table
# so we create the disk ourselves
createRootFS = with pkgs; ''
${parted}/bin/parted --script /dev/vda mklabel msdos
${parted}/sbin/parted --script /dev/vda -- mkpart primary ext2 1M -1s
mkdir /mnt
${e2fsprogs}/bin/mkfs.ext4 /dev/vda1
${utillinux}/bin/mount -t ext4 /dev/vda1 /mnt
if test -e /mnt/.debug; then
exec ${bash}/bin/sh
fi
touch /mnt/.debug
mkdir /mnt/proc /mnt/dev /mnt/sys
'';
extraPackages = [
# /etc/os-release
"base-files"
# make the disk bootable-looking
"grub2" "linux-image-686"
];
# install grub
postInstall = ''
ln -sf /proc/self/mounts > /etc/mtab
PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
grub-install /dev/vda --force
PATH=/usr/bin:/bin:/usr/sbin:/sbin $chroot /mnt \
update-grub
'';
};
# options to add the disk to the test vm
QEMU_OPTS = "-drive index=2,file=${debianImage}/disk-image.qcow2,read-only,if=virtio";
# a part of the configuration of the test vm
simpleConfig = {
boot.loader.grub = {
enable = true;
useOSProber = true;
device = "/dev/vda";
# vda is a filesystem without partition table
forceInstall = true;
};
nix.binaryCaches = lib.mkForce [ ];
nix.extraOptions = ''
hashed-mirrors =
connect-timeout = 1
'';
services.udisks2.enable = lib.mkForce false;
};
# /etc/nixos/configuration.nix for the vm
configFile = pkgs.writeText "configuration.nix" ''
{config, pkgs, ...}: ({
imports =
[ ./hardware-configuration.nix
<nixpkgs/nixos/modules/testing/test-instrumentation.nix>
];
} // (builtins.fromJSON (builtins.readFile ${
pkgs.writeText "simpleConfig.json" (builtins.toJSON simpleConfig)
})))
'';
in {
name = "os-prober";
machine = { config, pkgs, ... }: (simpleConfig // {
imports = [ ../modules/profiles/installation-device.nix
../modules/profiles/base.nix ];
virtualisation.memorySize = 1024;
# The test cannot access the network, so any packages
# nixos-rebuild needs must be included in the VM.
system.extraDependencies = with pkgs;
[ sudo
libxml2.bin
libxslt.bin
desktop-file-utils
docbook5
docbook_xsl_ns
unionfs-fuse
ntp
nixos-artwork.wallpapers.simple-dark-gray-bottom
perlPackages.XMLLibXML
perlPackages.ListCompare
shared-mime-info
texinfo
xorg.lndir
grub2
# add curl so that rather than seeing the test attempt to download
# curl's tarball, we see what it's trying to download
curl
];
});
testScript = ''
# hack to add the secondary disk
$machine->{startCommand} = "QEMU_OPTS=\"\$QEMU_OPTS \"${lib.escapeShellArg QEMU_OPTS} ".$machine->{startCommand};
$machine->start;
$machine->succeed("udevadm settle");
$machine->waitForUnit("multi-user.target");
# check that os-prober works standalone
$machine->succeed("${pkgs.os-prober}/bin/os-prober | grep /dev/vdb1");
# rebuild and test that debian is available in the grub menu
$machine->succeed("nixos-generate-config");
$machine->copyFileFromHost(
"${configFile}",
"/etc/nixos/configuration.nix");
$machine->succeed("nixos-rebuild boot >&2");
$machine->succeed("egrep 'menuentry.*debian' /boot/grub/grub.cfg");
'';
})