Merge staging-next into staging

This commit is contained in:
Frederik Rietdijk 2020-07-11 09:00:18 +02:00
commit a3a40ac7cc
607 changed files with 11610 additions and 6590 deletions

View File

@ -639,6 +639,12 @@
githubId = 1296771;
name = "Anders Riutta";
};
arnarg = {
email = "arnarg@fastmail.com";
github = "arnarg";
githubId = 1291396;
name = "Arnar Ingason";
};
arnoldfarkas = {
email = "arnold.farkas@gmail.com";
github = "arnoldfarkas";
@ -1031,6 +1037,12 @@
githubId = 5718007;
name = "Bastian Köcher";
};
blaggacao = {
name = "David Arnold";
email = "dar@xoe.solutions";
github = "blaggacao";
githubId = 7548295;
};
blanky0230 = {
email = "blanky0230@gmail.com";
github = "blanky0230";
@ -1049,6 +1061,12 @@
githubId = 16330;
name = "Mathijs Kwik";
};
bmilanov = {
name = "Biser Milanov";
email = "bmilanov11+nixpkgs@gmail.com";
github = "bmilanov";
githubId = 30090366;
};
bobakker = {
email = "bobakk3r@gmail.com";
github = "bobakker";
@ -1628,6 +1646,16 @@
githubId = 411324;
name = "Carles Pagès";
};
cpu = {
email = "daniel@binaryparadox.net";
github = "cpu";
githubId = 292650;
name = "Daniel McCarney";
keys = [{
longkeyid = "rsa2048/0x08FB2BFC470E75B4";
fingerprint = "8026 D24A A966 BF9C D3CD CB3C 08FB 2BFC 470E 75B4";
}];
};
craigem = {
email = "craige@mcwhirter.io";
github = "craigem";
@ -1652,6 +1680,16 @@
githubId = 1222362;
name = "Matías Lang";
};
CRTified = {
email = "carl.schneider+nixos@rub.de";
github = "CRTified";
githubId = 2440581;
name = "Carl Richard Theodor Schneider";
keys = [{
longkeyid = "rsa4096/0x45BCC1E2709B1788";
fingerprint = "2017 E152 BB81 5C16 955C E612 45BC C1E2 709B 1788";
}];
};
cryptix = {
email = "cryptix@riseup.net";
github = "cryptix";
@ -1790,6 +1828,12 @@
githubId = 4971975;
name = "Janne Heß";
};
"dasj19" = {
email = "daniel@serbanescu.dk";
github = "dasj19";
githubId = 7589338;
name = "Daniel Șerbănescu";
};
dasuxullebt = {
email = "christoph.senjak@googlemail.com";
name = "Christoph-Simon Senjak";
@ -2656,6 +2700,12 @@
fingerprint = "F549 3B7F 9372 5578 FDD3 D0B8 A1BC 8428 323E CFE8";
}];
};
fionera = {
email = "nix@fionera.de";
github = "fionera";
githubId = 5741401;
name = "Tim Windelschmidt";
};
FireyFly = {
email = "nix@firefly.nu";
github = "FireyFly";
@ -6486,6 +6536,12 @@
githubId = 131856;
name = "Arnout Engelen";
};
RaghavSood = {
email = "r@raghavsood.com";
github = "RaghavSood";
githubId = 903072;
name = "Raghav Sood";
};
rafaelgg = {
email = "rafael.garcia.gallego@gmail.com";
github = "rafaelgg";
@ -7190,6 +7246,12 @@
githubId = 24496705;
name = "Scott Hamilton";
};
ShamrockLee = {
name = "Shamrock Lee";
email = "44064051+ShamrockLee@users.noreply.github.com";
github = "ShamrockLee";
githubId = 44064051;
};
shanemikel = {
email = "shanepearlman@pm.me";
github = "shanemikel";
@ -8110,6 +8172,12 @@
githubId = 1486805;
name = "Toon Nolten";
};
toschmidt = {
email = "tobias.schmidt@in.tum.de";
github = "toschmidt";
githubId = 27586264;
name = "Tobias Schmidt";
};
travisbhartwell = {
email = "nafai@travishartwell.net";
github = "travisbhartwell";
@ -9025,4 +9093,10 @@
github = "saulecabrera";
githubId = 1423601;
};
tfmoraes = {
name = "Thiago Franco de Moraes";
email = "351108+tfmoraes@users.noreply.github.com";
github = "tfmoraes";
githubId = 351108;
};
}

View File

@ -54,6 +54,7 @@ with lib.maintainers; {
hedning
jtojnar
worldofpeace
dasj19
];
scope = "Maintain GNOME desktop environment and platform.";
};

View File

@ -9,7 +9,6 @@
This profile just enables a <systemitem class="username">demo</systemitem>
user, with password <literal>demo</literal>, uid <literal>1000</literal>,
<systemitem class="groupname">wheel</systemitem> group and
<link linkend="opt-services.xserver.displayManager.sddm.autoLogin"> autologin
in the SDDM display manager</link>.
<link linkend="opt-services.xserver.displayManager.autoLogin">autologin in the SDDM display manager</link>.
</para>
</section>

View File

@ -90,10 +90,9 @@
using lightdm for a user <literal>alice</literal>:
<programlisting>
<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = true;
<xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin.enable"/> = true;
<xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin.user"/> = "alice";
<xref linkend="opt-services.xserver.displayManager.autoLogin.enable"/> = true;
<xref linkend="opt-services.xserver.displayManager.autoLogin.user"/> = "alice";
</programlisting>
The options are named identically for all other display managers.
</para>
</simplesect>
<simplesect xml:id="sec-x11--graphics-cards-intel">

View File

@ -49,7 +49,7 @@
</listitem>
<listitem>
<para>
Click on Settings / Display / Screen and select VBoxVGA as Graphics Controller
Click on Settings / Display / Screen and select VMSVGA as Graphics Controller
</para>
</listitem>
<listitem>

View File

@ -315,7 +315,7 @@
switch</command>), because the hardware and boot loader configuration in
the VM are different. The boot loader is installed on an automatically
generated virtual disk containing a <filename>/boot</filename>
partition, which is mounted read-only in the VM.
partition.
</para>
</listitem>
</varlistentry>

View File

@ -792,7 +792,7 @@ users.users.me =
The <option>services.xserver.displayManager.auto</option> module has been removed.
It was only intended for use in internal NixOS tests, and gave the false impression
of it being a special display manager when it's actually LightDM.
Please use the <xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin"/> options instead,
Please use the <option>services.xserver.displayManager.lightdm.autoLogin</option> options instead,
or any other display manager in NixOS as they all support auto-login. If you used this module specifically
because it permitted root auto-login you can override the lightdm-autologin pam module like:
<programlisting>

View File

@ -119,6 +119,11 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
feature is disabled by default.
</para>
</listitem>
<listitem>
<para>
<varname>services.postfix.sslCACert</varname> was replaced by <varname>services.postfix.tlsTrustedAuthorities</varname> which now defaults to system certifcate authorities.
</para>
</listitem>
</itemizedlist>
</section>
@ -514,6 +519,12 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
automatically if <literal>stateVersion</literal> is 20.09 or higher.
</para>
</listitem>
<listitem>
<para>
We now have a unified <xref linkend="opt-services.xserver.displayManager.autoLogin"/> option interface
to be used for every display-manager in NixOS.
</para>
</listitem>
</itemizedlist>
</section>
@ -682,6 +693,12 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
behaviour and keep the same VM state between different test runs.
</para>
</listitem>
<listitem>
<para>
The <link linkend="opt-nix.buildMachines">nix.buildMachines</link> option is now type-checked.
There are no functional changes, however this may require updating some configurations to use correct types for all attributes.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View File

@ -181,6 +181,7 @@ let format' = format; in let
export NIX_STATE_DIR=$TMPDIR/state
nix-store --load-db < ${closureInfo}/registration
chmod 755 "$TMPDIR"
echo "running nixos-install..."
nixos-install --root $root --no-bootloader --no-root-passwd \
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""

View File

@ -22,6 +22,7 @@ import subprocess
import sys
import tempfile
import time
import traceback
import unicodedata
CHAR_TO_KEY = {
@ -892,7 +893,8 @@ def run_tests() -> None:
try:
exec(tests, globals())
except Exception as e:
eprint("error: {}".format(str(e)))
eprint("error: ")
traceback.print_exc()
sys.exit(1)
else:
ptpython.repl.embed(locals(), globals())

View File

@ -6,6 +6,16 @@ let
ids = config.ids;
cfg = config.users;
# Check whether a password hash will allow login.
allowsLogin = hash:
hash == "" # login without password
|| !(lib.elem hash
[ null # password login disabled
"!" # password login disabled
"!!" # a variant of "!"
"*" # password unset
]);
passwordDescription = ''
The options <option>hashedPassword</option>,
<option>password</option> and <option>passwordFile</option>
@ -25,17 +35,19 @@ let
'';
hashedPasswordDescription = ''
To generate hashed password install <literal>mkpasswd</literal>
To generate a hashed password install the <literal>mkpasswd</literal>
package and run <literal>mkpasswd -m sha-512</literal>.
For password-less logins without password prompt, use
the empty string <literal>""</literal>.
If set to an empty string (<literal>""</literal>), this user will
be able to log in without being asked for a password (but not via remote
services such as SSH, or indirectly via <command>su</command> or
<command>sudo</command>). This should only be used for e.g. bootable
live systems. Note: this is different from setting an empty password,
which ca be achieved using <option>users.users.&lt;name?&gt;.password</option>.
For logins with a fixed password (including the empty-string password with
prompt), use one of the un-hashed password options instead, such as
<option>users.users.&lt;name?&gt;.password</option>.
Such unprotected logins should only be used for e.g. bootable live systems.
If set to <literal>null</literal> (default) this user will not
be able to log in using a password (i.e. via <command>login</command>
command).
'';
userOpts = { name, config, ... }: {
@ -415,6 +427,12 @@ in {
imports = [
(mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ])
(mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ])
(mkChangedOptionModule
[ "security" "initialRootPassword" ]
[ "users" "users" "root" "initialHashedPassword" ]
(cfg: if cfg.security.initialHashedPassword == "!"
then null
else cfg.security.initialHashedPassword))
];
###### interface
@ -486,14 +504,6 @@ in {
'';
};
# FIXME: obsolete - will remove.
security.initialRootPassword = mkOption {
type = types.str;
default = "!";
example = "";
visible = false;
};
};
@ -508,7 +518,6 @@ in {
home = "/root";
shell = mkDefault cfg.defaultUserShell;
group = "root";
initialHashedPassword = mkDefault config.security.initialRootPassword;
};
nobody = {
uid = ids.uids.nobody;
@ -597,7 +606,7 @@ in {
|| cfg.group == "wheel"
|| elem "wheel" cfg.extraGroups)
&&
((cfg.hashedPassword != null && cfg.hashedPassword != "!")
(allowsLogin cfg.hashedPassword
|| cfg.password != null
|| cfg.passwordFile != null
|| cfg.openssh.authorizedKeys.keys != []
@ -607,7 +616,17 @@ in {
Neither the root account nor any wheel user has a password or SSH authorized key.
You must set one to prevent being locked out of your system.'';
}
];
] ++ flip mapAttrsToList cfg.users (name: user:
{
assertion = (user.hashedPassword != null)
-> (builtins.match ".*:.*" user.hashedPassword == null);
message = ''
The password hash of user "${name}" contains a ":" character.
This is invalid and would break the login system because the fields
of /etc/shadow (file where hashes are stored) are colon-separated.
Please check the value of option `users.users."${name}".hashedPassword`.'';
}
);
warnings =
builtins.filter (x: x != null) (
@ -630,14 +649,13 @@ in {
content = "${base64}${sep}${base64}";
mcf = "^${sep}${scheme}${sep}${content}$";
in
if (user.hashedPassword != null
if (allowsLogin user.hashedPassword
&& user.hashedPassword != "" # login without password
&& builtins.match mcf user.hashedPassword == null)
then
''
then ''
The password hash of user "${name}" may be invalid. You must set a
valid hash or the user will be locked out of their account. Please
check the value of option `users.users."${name}".hashedPassword`.
''
check the value of option `users.users."${name}".hashedPassword`.''
else null
));

View File

@ -64,7 +64,7 @@ in
# Without dconf enabled it is impossible to use IBus
programs.dconf.enable = true;
programs.dconf.profiles.ibus = "${ibusPackage}/etc/dconf/profile/ibus";
programs.dconf.packages = [ ibusPackage ];
services.dbus.packages = [
ibusAutostart

View File

@ -11,15 +11,17 @@ with lib;
services.xserver.desktopManager.gnome3.enable = true;
services.xserver.displayManager.gdm = {
enable = true;
# autoSuspend makes the machine automatically suspend after inactivity.
# It's possible someone could/try to ssh'd into the machine and obviously
# have issues because it's inactive.
# See:
# * https://github.com/NixOS/nixpkgs/pull/63790
# * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
autoSuspend = false;
services.xserver.displayManager = {
gdm = {
enable = true;
# autoSuspend makes the machine automatically suspend after inactivity.
# It's possible someone could/try to ssh'd into the machine and obviously
# have issues because it's inactive.
# See:
# * https://github.com/NixOS/nixpkgs/pull/63790
# * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
autoSuspend = false;
};
autoLogin = {
enable = true;
user = "nixos";

View File

@ -16,8 +16,8 @@ with lib;
};
# Automatically login as nixos.
displayManager.sddm = {
enable = true;
displayManager = {
sddm.enable = true;
autoLogin = {
enable = true;
user = "nixos";

View File

@ -1,6 +1,6 @@
{
x86_64-linux = "/nix/store/j8dbv5w6jl34caywh2ygdy88knx1mdf7-nix-2.3.6";
i686-linux = "/nix/store/9fqvbdisahqp0238vrs7wn5anpri0a65-nix-2.3.6";
aarch64-linux = "/nix/store/72pwn0nm9bjqx9vpi8sgh4bl6g5wh814-nix-2.3.6";
x86_64-darwin = "/nix/store/g37vk77m90p5zcl5nixjlzp3vqpisfn5-nix-2.3.6";
x86_64-linux = "/nix/store/4vz8sh9ngx34ivi0bw5hlycxdhvy5hvz-nix-2.3.7";
i686-linux = "/nix/store/dzxkg9lpp60bjmzvagns42vqlz3yq5kx-nix-2.3.7";
aarch64-linux = "/nix/store/cfvf8nl8mwyw817by5y8zd3s8pnf5m9f-nix-2.3.7";
x86_64-darwin = "/nix/store/5ira7xgs92inqz1x8l0n1wci4r79hnd0-nix-2.3.7";
}

View File

@ -71,6 +71,17 @@ if ! test -e "$mountPoint"; then
exit 1
fi
# Verify permissions are okay-enough
checkPath="$(realpath "$mountPoint")"
while [[ "$checkPath" != "/" ]]; do
mode="$(stat -c '%a' "$checkPath")"
if [[ "${mode: -1}" -lt "5" ]]; then
echo "path $checkPath should have permissions 755, but had permissions $mode. Consider running 'chmod o+rx $checkPath'."
exit 1
fi
checkPath="$(dirname "$checkPath")"
done
# Get the path of the NixOS configuration file.
if [[ -z $NIXOS_CONFIG ]]; then
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix

View File

@ -607,6 +607,7 @@
./services/networking/dnscrypt-wrapper.nix
./services/networking/dnsdist.nix
./services/networking/dnsmasq.nix
./services/networking/ncdns.nix
./services/networking/ejabberd.nix
./services/networking/epmd.nix
./services/networking/ergo.nix
@ -938,6 +939,7 @@
./system/boot/grow-partition.nix
./system/boot/initrd-network.nix
./system/boot/initrd-ssh.nix
./system/boot/initrd-openvpn.nix
./system/boot/kernel.nix
./system/boot/kexec.nix
./system/boot/loader/efi.nix

View File

@ -11,9 +11,11 @@
uid = 1000;
};
services.xserver.displayManager.sddm.autoLogin = {
enable = true;
relogin = true;
user = "demo";
services.xserver.displayManager = {
autoLogin = {
enable = true;
user = "demo";
};
sddm.autoLogin.relogin = true;
};
}

View File

@ -4,13 +4,24 @@ with lib;
let
cfg = config.programs.dconf;
mkDconfProfile = name: path:
{
name = "dconf/profile/${name}";
value.source = path;
};
cfgDir = pkgs.symlinkJoin {
name = "dconf-system-config";
paths = map (x: "${x}/etc/dconf") cfg.packages;
postBuild = ''
mkdir -p $out/profile
mkdir -p $out/db
'' + (
concatStringsSep "\n" (
mapAttrsToList (
name: path: ''
ln -s ${path} $out/profile/${name}
''
) cfg.profiles
)
) + ''
${pkgs.dconf}/bin/dconf update $out/db
'';
};
in
{
###### interface
@ -22,18 +33,24 @@ in
profiles = mkOption {
type = types.attrsOf types.path;
default = {};
description = "Set of dconf profile files.";
description = "Set of dconf profile files, installed at <filename>/etc/dconf/profiles/<replaceable>name</replaceable></filename>.";
internal = true;
};
packages = mkOption {
type = types.listOf types.package;
default = [];
description = "A list of packages which provide dconf profiles and databases in <filename>/etc/dconf</filename>.";
};
};
};
###### implementation
config = mkIf (cfg.profiles != {} || cfg.enable) {
environment.etc = optionalAttrs (cfg.profiles != {})
(mapAttrs' mkDconfProfile cfg.profiles);
environment.etc.dconf = mkIf (cfg.profiles != {} || cfg.packages != []) {
source = cfgDir;
};
services.dbus.packages = [ pkgs.dconf ];

View File

@ -39,7 +39,7 @@ with lib;
The services.xserver.displayManager.auto module has been removed
because it was only intended for use in internal NixOS tests, and gave the
false impression of it being a special display manager when it's actually
LightDM. Please use the services.xserver.displayManager.lightdm.autoLogin options
LightDM. Please use the services.xserver.displayManager.autoLogin options
instead, or any other display manager in NixOS as they all support auto-login.
'')
(mkRemovedOptionModule [ "services" "dnscrypt-proxy" ] "Use services.dnscrypt-proxy2 instead")

View File

@ -302,6 +302,11 @@ in
lpath = "acme/${cert}";
apath = "/var/lib/${lpath}";
spath = "/var/lib/acme/.lego/${cert}";
keyName = builtins.replaceStrings ["*"] ["_"] data.domain;
requestedDomains = pipe ([ data.domain ] ++ (attrNames data.extraDomains)) [
(domains: sort builtins.lessThan domains)
(domains: concatStringsSep "," domains)
];
fileMode = if data.allowKeysForGroup then "640" else "600";
globalOpts = [ "-d" data.domain "--email" data.email "--path" "." "--key-type" data.keyType ]
++ optionals (cfg.acceptTerms) [ "--accept-tos" ]
@ -316,6 +321,7 @@ in
certOpts ++ data.extraLegoRenewFlags);
acmeService = {
description = "Renew ACME Certificate for ${cert}";
path = with pkgs; [ openssl ];
after = [ "network.target" "network-online.target" ];
wants = [ "network-online.target" ];
wantedBy = mkIf (!config.boot.isContainer) [ "multi-user.target" ];
@ -332,11 +338,18 @@ in
ExecStart = pkgs.writeScript "acme-start" ''
#!${pkgs.runtimeShell} -e
test -L ${spath}/accounts -o -d ${spath}/accounts || ln -s ../accounts ${spath}/accounts
${pkgs.lego}/bin/lego ${renewOpts} || ${pkgs.lego}/bin/lego ${runOpts}
LEGO_ARGS=(${runOpts})
if [ -e ${spath}/certificates/${keyName}.crt ]; then
REQUESTED_DOMAINS="${requestedDomains}"
EXISTING_DOMAINS="$(openssl x509 -in ${spath}/certificates/${keyName}.crt -noout -ext subjectAltName | tail -n1 | sed -e 's/ *DNS://g')"
if [ "''${REQUESTED_DOMAINS}" == "''${EXISTING_DOMAINS}" ]; then
LEGO_ARGS=(${renewOpts})
fi
fi
${pkgs.lego}/bin/lego ''${LEGO_ARGS[@]}
'';
ExecStartPost =
let
keyName = builtins.replaceStrings ["*"] ["_"] data.domain;
script = pkgs.writeScript "acme-post-start" ''
#!${pkgs.runtimeShell} -e
cd ${apath}

View File

@ -280,6 +280,17 @@ in
description = "Whether to enable smtp submission.";
};
enableSubmissions = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable smtp submission via smtps.
According to RFC 8314 this should be preferred
over STARTTLS for submission of messages by end user clients.
'';
};
submissionOptions = mkOption {
type = types.attrs;
default = {
@ -298,6 +309,29 @@ in
description = "Options for the submission config in master.cf";
};
submissionsOptions = mkOption {
type = types.attrs;
default = {
smtpd_sasl_auth_enable = "yes";
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
milter_macro_daemon_name = "ORIGINATING";
};
example = {
smtpd_sasl_auth_enable = "yes";
smtpd_sasl_type = "dovecot";
smtpd_client_restrictions = "permit_sasl_authenticated,reject";
milter_macro_daemon_name = "ORIGINATING";
};
description = ''
Options for the submission config via smtps in master.cf.
smtpd_tls_security_level will be set to encrypt, if it is missing
or has one of the values "may" or "none".
smtpd_tls_wrappermode with value "yes" will be added automatically.
'';
};
setSendmail = mkOption {
type = types.bool;
default = true;
@ -454,7 +488,7 @@ in
'';
example = {
mail_owner = "postfix";
smtp_use_tls = true;
smtp_tls_security_level = "may";
};
};
@ -466,18 +500,20 @@ in
";
};
tlsTrustedAuthorities = mkOption {
type = types.str;
default = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
description = ''
File containing trusted certification authorities (CA) to verify certificates of mailservers contacted for mail delivery. This basically sets smtp_tls_CAfile and enables opportunistic tls. Defaults to NixOS trusted certification authorities.
'';
};
sslCert = mkOption {
type = types.str;
default = "";
description = "SSL certificate to use.";
};
sslCACert = mkOption {
type = types.str;
default = "";
description = "SSL certificate of CA.";
};
sslKey = mkOption {
type = types.str;
default = "";
@ -771,18 +807,20 @@ in
recipient_canonical_classes = [ "envelope_recipient" ];
}
// optionalAttrs cfg.enableHeaderChecks { header_checks = [ "regexp:/etc/postfix/header_checks" ]; }
// optionalAttrs (cfg.tlsTrustedAuthorities != "") {
smtp_tls_CAfile = cfg.tlsTrustedAuthorities;
smtp_tls_security_level = "may";
}
// optionalAttrs (cfg.sslCert != "") {
smtp_tls_CAfile = cfg.sslCACert;
smtp_tls_cert_file = cfg.sslCert;
smtp_tls_key_file = cfg.sslKey;
smtp_use_tls = true;
smtp_tls_security_level = "may";
smtpd_tls_CAfile = cfg.sslCACert;
smtpd_tls_cert_file = cfg.sslCert;
smtpd_tls_key_file = cfg.sslKey;
smtpd_use_tls = true;
smtpd_tls_security_level = "may";
};
services.postfix.masterConfig = {
@ -878,6 +916,23 @@ in
command = "smtp";
args = [ "-o" "smtp_fallback_relay=" ];
};
} // optionalAttrs cfg.enableSubmissions {
submissions = {
type = "inet";
private = false;
command = "smtpd";
args = let
mkKeyVal = opt: val: [ "-o" (opt + "=" + val) ];
adjustSmtpTlsSecurityLevel = !(cfg.submissionsOptions ? smtpd_tls_security_level) ||
cfg.submissionsOptions.smtpd_tls_security_level == "none" ||
cfg.submissionsOptions.smtpd_tls_security_level == "may";
submissionsOptions = cfg.submissionsOptions // {
smtpd_tls_wrappermode = "yes";
} // optionalAttrs adjustSmtpTlsSecurityLevel {
smtpd_tls_security_level = "encrypt";
};
in concatLists (mapAttrsToList mkKeyVal submissionsOptions);
};
};
}
@ -900,4 +955,9 @@ in
services.postfix.mapFiles.client_access = checkClientAccessFile;
})
]);
imports = [
(mkRemovedOptionModule [ "services" "postfix" "sslCACert" ]
"services.postfix.sslCACert was replaced by services.postfix.tlsTrustedAuthorities. In case you intend that your server should validate requested client certificates use services.postfix.extraConfig.")
];
}

View File

@ -95,6 +95,18 @@ in
'';
};
maxAttachmentSize = mkOption {
type = types.int;
default = 18;
description = ''
The maximum attachment size in MB.
Note: Since roundcube only uses 70% of max upload values configured in php
30% is added automatically to <xref linkend="opt-services.roundcube.maxAttachmentSize"/>.
'';
apply = configuredMaxAttachmentSize: "${toString (configuredMaxAttachmentSize * 1.3)}M";
};
extraConfig = mkOption {
type = types.lines;
default = "";
@ -115,7 +127,7 @@ in
$config = array();
$config['db_dsnw'] = 'pgsql://${cfg.database.username}${lib.optionalString (!localDB) ":' . $password . '"}@${if localDB then "unix(/run/postgresql)" else cfg.database.host}/${cfg.database.dbname}';
$config['log_driver'] = 'syslog';
$config['max_message_size'] = '25M';
$config['max_message_size'] = '${cfg.maxAttachmentSize}';
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
$config['des_key'] = file_get_contents('/var/lib/roundcube/des_key');
$config['mime_types'] = '${pkgs.nginx}/conf/mime.types';
@ -172,8 +184,8 @@ in
phpOptions = ''
error_log = 'stderr'
log_errors = on
post_max_size = 25M
upload_max_filesize = 25M
post_max_size = ${cfg.maxAttachmentSize}
upload_max_filesize = ${cfg.maxAttachmentSize}
'';
settings = mapAttrs (name: mkDefault) {
"listen.owner" = "nginx";

View File

@ -193,50 +193,111 @@ in
};
buildMachines = mkOption {
type = types.listOf types.attrs;
type = types.listOf (types.submodule ({
options = {
hostName = mkOption {
type = types.str;
example = "nixbuilder.example.org";
description = ''
The hostname of the build machine.
'';
};
system = mkOption {
type = types.nullOr types.str;
default = null;
example = "x86_64-linux";
description = ''
The system type the build machine can execute derivations on.
Either this attribute or <varname>systems</varname> must be
present, where <varname>system</varname> takes precedence if
both are set.
'';
};
systems = mkOption {
type = types.listOf types.str;
default = [];
example = [ "x86_64-linux" "aarch64-linux" ];
description = ''
The system types the build machine can execute derivations on.
Either this attribute or <varname>system</varname> must be
present, where <varname>system</varname> takes precedence if
both are set.
'';
};
sshUser = mkOption {
type = types.nullOr types.str;
default = null;
example = "builder";
description = ''
The username to log in as on the remote host. This user must be
able to log in and run nix commands non-interactively. It must
also be privileged to build derivations, so must be included in
<option>nix.trustedUsers</option>.
'';
};
sshKey = mkOption {
type = types.nullOr types.str;
default = null;
example = "/root/.ssh/id_buildhost_builduser";
description = ''
The path to the SSH private key with which to authenticate on
the build machine. The private key must not have a passphrase.
If null, the building user (root on NixOS machines) must have an
appropriate ssh configuration to log in non-interactively.
Note that for security reasons, this path must point to a file
in the local filesystem, *not* to the nix store.
'';
};
maxJobs = mkOption {
type = types.int;
default = 1;
description = ''
The number of concurrent jobs the build machine supports. The
build machine will enforce its own limits, but this allows hydra
to schedule better since there is no work-stealing between build
machines.
'';
};
speedFactor = mkOption {
type = types.int;
default = 1;
description = ''
The relative speed of this builder. This is an arbitrary integer
that indicates the speed of this builder, relative to other
builders. Higher is faster.
'';
};
mandatoryFeatures = mkOption {
type = types.listOf types.str;
default = [];
example = [ "big-parallel" ];
description = ''
A list of features mandatory for this builder. The builder will
be ignored for derivations that don't require all features in
this list. All mandatory features are automatically included in
<varname>supportedFeatures</varname>.
'';
};
supportedFeatures = mkOption {
type = types.listOf types.str;
default = [];
example = [ "kvm" "big-parallel" ];
description = ''
A list of features supported by this builder. The builder will
be ignored for derivations that require features not in this
list.
'';
};
};
}));
default = [];
example = literalExample ''
[ { hostName = "voila.labs.cs.uu.nl";
sshUser = "nix";
sshKey = "/root/.ssh/id_buildfarm";
system = "powerpc-darwin";
maxJobs = 1;
}
{ hostName = "linux64.example.org";
sshUser = "buildfarm";
sshKey = "/root/.ssh/id_buildfarm";
system = "x86_64-linux";
maxJobs = 2;
speedFactor = 2;
supportedFeatures = [ "kvm" ];
mandatoryFeatures = [ "perf" ];
}
]
'';
description = ''
This option lists the machines to be used if distributed
builds are enabled (see
<option>nix.distributedBuilds</option>). Nix will perform
derivations on those machines via SSH by copying the inputs
to the Nix store on the remote machine, starting the build,
then copying the output back to the local Nix store. Each
element of the list should be an attribute set containing
the machine's host name (<varname>hostname</varname>), the
user name to be used for the SSH connection
(<varname>sshUser</varname>), the Nix system type
(<varname>system</varname>, e.g.,
<literal>"i686-linux"</literal>), the maximum number of
jobs to be run in parallel on that machine
(<varname>maxJobs</varname>), the path to the SSH private
key to be used to connect (<varname>sshKey</varname>), a
list of supported features of the machine
(<varname>supportedFeatures</varname>) and a list of
mandatory features of the machine
(<varname>mandatoryFeatures</varname>). The SSH private key
should not have a passphrase, and the corresponding public
key should be added to
<filename>~<replaceable>sshUser</replaceable>/authorized_keys</filename>
on the remote machine.
This option lists the machines to be used if distributed builds are
enabled (see <option>nix.distributedBuilds</option>).
Nix will perform derivations on those machines via SSH by copying the
inputs to the Nix store on the remote machine, starting the build,
then copying the output back to the local Nix store.
'';
};
@ -461,14 +522,14 @@ in
{ enable = cfg.buildMachines != [];
text =
concatMapStrings (machine:
"${if machine ? sshUser then "${machine.sshUser}@" else ""}${machine.hostName} "
+ machine.system or (concatStringsSep "," machine.systems)
+ " ${machine.sshKey or "-"} ${toString machine.maxJobs or 1} "
+ toString (machine.speedFactor or 1)
"${if machine.sshUser != null then "${machine.sshUser}@" else ""}${machine.hostName} "
+ (if machine.system != null then machine.system else concatStringsSep "," machine.systems)
+ " ${if machine.sshKey != null then machine.sshKey else "-"} ${toString machine.maxJobs} "
+ toString (machine.speedFactor)
+ " "
+ concatStringsSep "," (machine.mandatoryFeatures or [] ++ machine.supportedFeatures or [])
+ concatStringsSep "," (machine.mandatoryFeatures ++ machine.supportedFeatures)
+ " "
+ concatStringsSep "," machine.mandatoryFeatures or []
+ concatStringsSep "," machine.mandatoryFeatures
+ "\n"
) cfg.buildMachines;
};

View File

@ -0,0 +1,278 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfgs = config.services;
cfg = cfgs.ncdns;
dataDir = "/var/lib/ncdns";
username = "ncdns";
valueType = with types; oneOf [ int str bool path ]
// { description = "setting type (integer, string, bool or path)"; };
configType = with types; attrsOf (nullOr (either valueType configType))
// { description = ''
ncdns.conf configuration type. The format consists of an
attribute set of settings. Each setting can be either `null`,
a value or an attribute set. The allowed values are integers,
strings, booleans or paths.
'';
};
configFile = pkgs.runCommand "ncdns.conf"
{ json = builtins.toJSON cfg.settings;
passAsFile = [ "json" ];
}
"${pkgs.remarshal}/bin/json2toml < $jsonPath > $out";
defaultFiles = {
public = "${dataDir}/bit.key";
private = "${dataDir}/bit.private";
zonePublic = "${dataDir}/bit-zone.key";
zonePrivate = "${dataDir}/bit-zone.private";
};
# if all keys are the default value
needsKeygen = all id (flip mapAttrsToList cfg.dnssec.keys
(n: v: v == getAttr n defaultFiles));
mkDefaultAttrs = mapAttrs (n: v: mkDefault v);
in
{
###### interface
options = {
services.ncdns = {
enable = mkEnableOption ''
ncdns, a Go daemon to bridge Namecoin to DNS.
To resolve .bit domains set <literal>services.namecoind.enable = true;</literal>
and an RPC username/password
'';
address = mkOption {
type = types.str;
default = "127.0.0.1";
description = ''
The IP address the ncdns resolver will bind to. Leave this unchanged
if you do not wish to directly expose the resolver.
'';
};
port = mkOption {
type = types.port;
default = 5333;
description = ''
The port the ncdns resolver will bind to.
'';
};
identity.hostname = mkOption {
type = types.str;
default = config.networking.hostName;
example = "example.com";
description = ''
The hostname of this ncdns instance, which defaults to the machine
hostname. If specified, ncdns lists the hostname as an NS record at
the zone apex:
<programlisting>
bit. IN NS ns1.example.com.
</programlisting>
If unset ncdns will generate an internal psuedo-hostname under the
zone, which will resolve to the value of
<option>services.ncdns.identity.address</option>.
If you are only using ncdns locally you can ignore this.
'';
};
identity.hostmaster = mkOption {
type = types.str;
default = "";
example = "root@example.com";
description = ''
An email address for the SOA record at the bit zone.
If you are only using ncdns locally you can ignore this.
'';
};
identity.address = mkOption {
type = types.str;
default = "127.127.127.127";
description = ''
The IP address the hostname specified in
<option>services.ncdns.identity.hostname</option> should resolve to.
If you are only using ncdns locally you can ignore this.
'';
};
dnssec.enable = mkEnableOption ''
DNSSEC support in ncdns. This will generate KSK and ZSK keypairs
(unless provided via the options
<option>services.ncdns.dnssec.publicKey</option>,
<option>services.ncdns.dnssec.privateKey</option> etc.) and add a trust
anchor to recursive resolvers
'';
dnssec.keys.public = mkOption {
type = types.path;
default = defaultFiles.public;
description = ''
Path to the file containing the KSK public key.
The key can be generated using the <literal>dnssec-keygen</literal>
command, provided by the package <package>bind</package> as follows:
<programlisting>
$ dnssec-keygen -a RSASHA256 -3 -b 2048 -f KSK bit
</programlisting>
'';
};
dnssec.keys.private = mkOption {
type = types.path;
default = defaultFiles.private;
description = ''
Path to the file containing the KSK private key.
'';
};
dnssec.keys.zonePublic = mkOption {
type = types.path;
default = defaultFiles.zonePublic;
description = ''
Path to the file containing the ZSK public key.
The key can be generated using the <literal>dnssec-keygen</literal>
command, provided by the package <package>bind</package> as follows:
<programlisting>
$ dnssec-keygen -a RSASHA256 -3 -b 2048 bit
</programlisting>
'';
};
dnssec.keys.zonePrivate = mkOption {
type = types.path;
default = defaultFiles.zonePrivate;
description = ''
Path to the file containing the ZSK private key.
'';
};
settings = mkOption {
type = configType;
default = { };
example = literalExample ''
{ # enable webserver
ncdns.httplistenaddr = ":8202";
# synchronize TLS certs
certstore.nss = true;
# note: all paths are relative to the config file
certstore.nsscertdir = "../../var/lib/ncdns";
certstore.nssdbdir = "../../home/alice/.pki/nssdb";
}
'';
description = ''
ncdns settings. Use this option to configure ncds
settings not exposed in a NixOS option or to bypass one.
See the example ncdns.conf file at <link xlink:href="
https://git.io/JfX7g"/> for the available options.
'';
};
};
services.pdns-recursor.resolveNamecoin = mkOption {
type = types.bool;
default = false;
description = ''
Resolve <literal>.bit</literal> top-level domains using ncdns and namecoin.
'';
};
};
###### implementation
config = mkIf cfg.enable {
services.pdns-recursor = mkIf cfgs.pdns-recursor.resolveNamecoin {
forwardZonesRecurse.bit = "127.0.0.1:${toString cfg.port}";
luaConfig =
if cfg.dnssec.enable
then ''readTrustAnchorsFromFile("${cfg.dnssec.keys.public}")''
else ''addNTA("bit", "namecoin DNSSEC disabled")'';
};
# Avoid pdns-recursor not finding the DNSSEC keys
systemd.services.pdns-recursor = mkIf cfgs.pdns-recursor.resolveNamecoin {
after = [ "ncdns.service" ];
wants = [ "ncdns.service" ];
};
services.ncdns.settings = mkDefaultAttrs {
ncdns =
{ # Namecoin RPC
namecoinrpcaddress =
"${cfgs.namecoind.rpc.address}:${toString cfgs.namecoind.rpc.port}";
namecoinrpcusername = cfgs.namecoind.rpc.user;
namecoinrpcpassword = cfgs.namecoind.rpc.password;
# Identity
selfname = cfg.identity.hostname;
hostmaster = cfg.identity.hostmaster;
selfip = cfg.identity.address;
# Other
bind = "${cfg.address}:${toString cfg.port}";
}
// optionalAttrs cfg.dnssec.enable
{ # DNSSEC
publickey = "../.." + cfg.dnssec.keys.public;
privatekey = "../.." + cfg.dnssec.keys.private;
zonepublickey = "../.." + cfg.dnssec.keys.zonePublic;
zoneprivatekey = "../.." + cfg.dnssec.keys.zonePrivate;
};
# Daemon
service.daemon = true;
xlog.journal = true;
};
users.users.ncdns =
{ description = "ncdns daemon user"; };
systemd.services.ncdns = {
description = "ncdns daemon";
after = [ "namecoind.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "ncdns";
StateDirectory = "ncdns";
Restart = "on-failure";
ExecStart = "${pkgs.ncdns}/bin/ncdns -conf=${configFile}";
};
preStart = optionalString (cfg.dnssec.enable && needsKeygen) ''
cd ${dataDir}
if [ ! -e bit.key ]; then
${pkgs.bind}/bin/dnssec-keygen -a RSASHA256 -3 -b 2048 bit
mv Kbit.*.key bit-zone.key
mv Kbit.*.private bit-zone.private
${pkgs.bind}/bin/dnssec-keygen -a RSASHA256 -3 -b 2048 -f KSK bit
mv Kbit.*.key bit.key
mv Kbit.*.private bit.private
fi
'';
};
};
meta.maintainers = with lib.maintainers; [ rnhmjoj ];
}

View File

@ -122,7 +122,7 @@ in
ExecStart = ''
${cfg.package}/bin/xandikos \
--directory /var/lib/xandikos \
--listen_address ${cfg.address} \
--listen-address ${cfg.address} \
--port ${toString cfg.port} \
--route-prefix ${cfg.routePrefix} \
${lib.concatStringsSep " " cfg.extraOptions}

View File

@ -4,12 +4,21 @@ with lib;
let
cfg = config.services.nginx.sso;
pkg = getBin pkgs.nginx-sso;
pkg = getBin cfg.package;
configYml = pkgs.writeText "nginx-sso.yml" (builtins.toJSON cfg.configuration);
in {
options.services.nginx.sso = {
enable = mkEnableOption "nginx-sso service";
package = mkOption {
type = types.package;
default = pkgs.nginx-sso;
defaultText = "pkgs.nginx-sso";
description = ''
The nginx-sso package that should be used.
'';
};
configuration = mkOption {
type = types.attrsOf types.unspecified;
default = {};

View File

@ -321,7 +321,7 @@ in
fonts.fonts = with pkgs; [ noto-fonts hack-font ];
fonts.fontconfig.defaultFonts = {
monospace = [ "Hack" "Noto Mono" ];
monospace = [ "Hack" "Noto Sans Mono" ];
sansSerif = [ "Noto Sans" ];
serif = [ "Noto Serif" ];
};

View File

@ -332,12 +332,45 @@ in
};
# Configuration for automatic login. Common for all DM.
autoLogin = mkOption {
type = types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = cfg.displayManager.autoLogin.user != null;
description = ''
Automatically log in as <option>autoLogin.user</option>.
'';
};
user = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
User to be used for the automatic login.
'';
};
};
};
default = {};
description = ''
Auto login configuration attrset.
'';
};
};
};
config = {
assertions = [
{ assertion = cfg.displayManager.autoLogin.enable -> cfg.displayManager.autoLogin.user != null;
message = ''
services.xserver.displayManager.autoLogin.enable requires services.xserver.displayManager.autoLogin.user to be set
'';
}
{
assertion = cfg.desktopManager.default != null || cfg.windowManager.default != null -> cfg.displayManager.defaultSession == defaultSessionFromLegacyOptions;
message = "You cannot use both services.xserver.displayManager.defaultSession option and legacy options (services.xserver.desktopManager.default and services.xserver.windowManager.default).";

View File

@ -37,6 +37,22 @@ let
in
{
imports = [
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "gdm" "autoLogin" "enable" ] [
"services"
"xserver"
"displayManager"
"autoLogin"
"enable"
])
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "gdm" "autoLogin" "user" ] [
"services"
"xserver"
"displayManager"
"autoLogin"
"user"
])
];
meta = {
maintainers = teams.gnome.members;
@ -56,40 +72,13 @@ in
debugging messages in GDM
'';
autoLogin = mkOption {
default = {};
# Auto login options specific to GDM
autoLogin.delay = mkOption {
type = types.int;
default = 0;
description = ''
Auto login configuration attrset.
Seconds of inactivity after which the autologin will be performed.
'';
type = types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Automatically log in as the sepecified <option>autoLogin.user</option>.
'';
};
user = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
User to be used for the autologin.
'';
};
delay = mkOption {
type = types.int;
default = 0;
description = ''
Seconds of inactivity after which the autologin will be performed.
'';
};
};
};
};
wayland = mkOption {
@ -128,12 +117,6 @@ in
config = mkIf cfg.gdm.enable {
assertions = [
{ assertion = cfg.gdm.autoLogin.enable -> cfg.gdm.autoLogin.user != null;
message = "GDM auto-login requires services.xserver.displayManager.gdm.autoLogin.user to be set";
}
];
services.xserver.displayManager.lightdm.enable = false;
users.users.gdm =
@ -287,14 +270,14 @@ in
environment.etc."gdm/custom.conf".text = ''
[daemon]
WaylandEnable=${if cfg.gdm.wayland then "true" else "false"}
${optionalString cfg.gdm.autoLogin.enable (
${optionalString cfg.autoLogin.enable (
if cfg.gdm.autoLogin.delay > 0 then ''
TimedLoginEnable=true
TimedLogin=${cfg.gdm.autoLogin.user}
TimedLogin=${cfg.autoLogin.user}
TimedLoginDelay=${toString cfg.gdm.autoLogin.delay}
'' else ''
AutomaticLoginEnable=true
AutomaticLogin=${cfg.gdm.autoLogin.user}
AutomaticLogin=${cfg.autoLogin.user}
'')
}

View File

@ -43,7 +43,7 @@ in
services.xserver.displayManager.lightdm.extraSeatDefaults = "greeter-show-manual-login=true";
environment.etc."lightdm/io.elementary.greeter.conf".source = "${pkgs.pantheon.elementary-greeter}/etc/lightdm/io.elementary.greeter.conf";
environment.etc."wingpanel.d/io.elementary.greeter.whitelist".source = "${pkgs.pantheon.elementary-default-settings}/etc/wingpanel.d/io.elementary.greeter.whitelist";
environment.etc."wingpanel.d/io.elementary.greeter.allowed".source = "${pkgs.pantheon.elementary-default-settings}/etc/wingpanel.d/io.elementary.greeter.allowed";
};
}

View File

@ -53,8 +53,8 @@ let
${optionalString cfg.greeter.enable ''
greeter-session = ${cfg.greeter.name}
''}
${optionalString cfg.autoLogin.enable ''
autologin-user = ${cfg.autoLogin.user}
${optionalString dmcfg.autoLogin.enable ''
autologin-user = ${dmcfg.autoLogin.user}
autologin-user-timeout = ${toString cfg.autoLogin.timeout}
autologin-session = ${sessionData.autologinSession}
''}
@ -82,6 +82,20 @@ in
./lightdm-greeters/enso-os.nix
./lightdm-greeters/pantheon.nix
./lightdm-greeters/tiny.nix
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "lightdm" "autoLogin" "enable" ] [
"services"
"xserver"
"displayManager"
"autoLogin"
"enable"
])
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "lightdm" "autoLogin" "user" ] [
"services"
"xserver"
"displayManager"
"autoLogin"
"user"
])
];
options = {
@ -149,39 +163,13 @@ in
description = "Extra lines to append to SeatDefaults section.";
};
autoLogin = mkOption {
default = {};
# Configuration for automatic login specific to LightDM
autoLogin.timeout = mkOption {
type = types.int;
default = 0;
description = ''
Configuration for automatic login.
Show the greeter for this many seconds before automatic login occurs.
'';
type = types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Automatically log in as the specified <option>autoLogin.user</option>.
'';
};
user = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
User to be used for the automatic login.
'';
};
timeout = mkOption {
type = types.int;
default = 0;
description = ''
Show the greeter for this many seconds before automatic login occurs.
'';
};
};
};
};
};
@ -195,17 +183,12 @@ in
LightDM requires services.xserver.enable to be true
'';
}
{ assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null;
message = ''
LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set
'';
}
{ assertion = cfg.autoLogin.enable -> sessionData.autologinSession != null;
{ assertion = dmcfg.autoLogin.enable -> sessionData.autologinSession != null;
message = ''
LightDM auto-login requires that services.xserver.displayManager.defaultSession is set.
'';
}
{ assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0);
{ assertion = !cfg.greeter.enable -> (dmcfg.autoLogin.enable && cfg.autoLogin.timeout == 0);
message = ''
LightDM can only run without greeter if automatic login is enabled and the timeout for it
is set to zero.
@ -218,7 +201,7 @@ in
# Set default session in session chooser to a specified values basically ignore session history.
# Auto-login is already covered by a config value.
services.xserver.displayManager.job.preStart = optionalString (!cfg.autoLogin.enable && dmcfg.defaultSession != null) ''
services.xserver.displayManager.job.preStart = optionalString (!dmcfg.autoLogin.enable && dmcfg.defaultSession != null) ''
${setSessionScript}/bin/set-session ${dmcfg.defaultSession}
'';

View File

@ -61,9 +61,9 @@ let
EnableHidpi=${if cfg.enableHidpi then "true" else "false"}
SessionDir=${dmcfg.sessionData.desktops}/share/wayland-sessions
${optionalString cfg.autoLogin.enable ''
${optionalString dmcfg.autoLogin.enable ''
[Autologin]
User=${cfg.autoLogin.user}
User=${dmcfg.autoLogin.user}
Session=${autoLoginSessionName}.desktop
Relogin=${boolToString cfg.autoLogin.relogin}
''}
@ -78,6 +78,20 @@ in
imports = [
(mkRemovedOptionModule [ "services" "xserver" "displayManager" "sddm" "themes" ]
"Set the option `services.xserver.displayManager.sddm.package' instead.")
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "sddm" "autoLogin" "enable" ] [
"services"
"xserver"
"displayManager"
"autoLogin"
"enable"
])
(mkRenamedOptionModule [ "services" "xserver" "displayManager" "sddm" "autoLogin" "user" ] [
"services"
"xserver"
"displayManager"
"autoLogin"
"user"
])
];
options = {
@ -153,40 +167,14 @@ in
'';
};
autoLogin = mkOption {
default = {};
# Configuration for automatic login specific to SDDM
autoLogin.relogin = mkOption {
type = types.bool;
default = false;
description = ''
Configuration for automatic login.
If true automatic login will kick in again on session exit (logout), otherwise it
will only log in automatically when the display-manager is started.
'';
type = types.submodule {
options = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Automatically log in as <option>autoLogin.user</option>.
'';
};
user = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
User to be used for the automatic login.
'';
};
relogin = mkOption {
type = types.bool;
default = false;
description = ''
If true automatic login will kick in again on session exit (logout), otherwise it
will only log in automatically when the display-manager is started.
'';
};
};
};
};
};
@ -201,12 +189,7 @@ in
SDDM requires services.xserver.enable to be true
'';
}
{ assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null;
message = ''
SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set
'';
}
{ assertion = cfg.autoLogin.enable -> autoLoginSessionName != null;
{ assertion = dmcfg.autoLogin.enable -> autoLoginSessionName != null;
message = ''
SDDM auto-login requires that services.xserver.displayManager.defaultSession is set.
'';

View File

@ -0,0 +1,81 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.boot.initrd.network.openvpn;
in
{
options = {
boot.initrd.network.openvpn.enable = mkOption {
type = types.bool;
default = false;
description = ''
Starts an OpenVPN client during initrd boot. It can be used to e.g.
remotely accessing the SSH service controlled by
<option>boot.initrd.network.ssh</option> or other network services
included. Service is killed when stage-1 boot is finished.
'';
};
boot.initrd.network.openvpn.configuration = mkOption {
type = types.path; # Same type as boot.initrd.secrets
description = ''
The configuration file for OpenVPN.
<warning>
<para>
Unless your bootloader supports initrd secrets, this configuration
is stored insecurely in the global Nix store.
</para>
</warning>
'';
example = "./configuration.ovpn";
};
};
config = mkIf (config.boot.initrd.network.enable && cfg.enable) {
assertions = [
{
assertion = cfg.configuration != null;
message = "You should specify a configuration for initrd OpenVPN";
}
];
# Add kernel modules needed for OpenVPN
boot.initrd.kernelModules = [ "tun" "tap" ];
# Add openvpn and ip binaries to the initrd
# The shared libraries are required for DNS resolution
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.openvpn}/bin/openvpn
copy_bin_and_libs ${pkgs.iproute}/bin/ip
cp -pv ${pkgs.glibc}/lib/libresolv.so.2 $out/lib
cp -pv ${pkgs.glibc}/lib/libnss_dns.so.2 $out/lib
'';
boot.initrd.secrets = {
"/etc/initrd.ovpn" = cfg.configuration;
};
# openvpn --version would exit with 1 instead of 0
boot.initrd.extraUtilsCommandsTest = ''
$out/bin/openvpn --show-gateway
'';
# Add `iproute /bin/ip` to the config, to ensure that openvpn
# is able to set the routes
boot.initrd.network.postCommands = ''
(cat /etc/initrd.ovpn; echo -e '\niproute /bin/ip') | \
openvpn /dev/stdin &
'';
};
}

View File

@ -61,6 +61,7 @@ let
inherit (efi) canTouchEfiVariables;
inherit (cfg)
version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber
extraGrubInstallArgs
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels
default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios gfxpayloadEfi gfxpayloadBios;
path = with pkgs; makeBinPath (
@ -298,6 +299,33 @@ in
'';
};
extraGrubInstallArgs = mkOption {
default = [ ];
example = [ "--modules=nativedisk ahci pata part_gpt part_msdos diskfilter mdraid1x lvm ext2" ];
type = types.listOf types.str;
description = ''
Additional arguments passed to <literal>grub-install</literal>.
A use case for this is to build specific GRUB2 modules
directly into the GRUB2 kernel image, so that they are available
and activated even in the <literal>grub rescue</literal> shell.
They are also necessary when the BIOS/UEFI is bugged and cannot
correctly read large disks (e.g. above 2 TB), so GRUB2's own
<literal>nativedisk</literal> and related modules can be used
to use its own disk drivers. The example shows one such case.
This is also useful for booting from USB.
See the
<link xlink:href="http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/commands/nativedisk.c?h=grub-2.04#n326">
GRUB source code
</link>
for which disk modules are available.
The list elements are passed directly as <literal>argv</literal>
arguments to the <literal>grub-install</literal> program, in order.
'';
};
extraPerEntryConfig = mkOption {
default = "";
example = "root (hd0)";
@ -669,7 +697,7 @@ in
in pkgs.writeScript "install-grub.sh" (''
#!${pkgs.runtimeShell}
set -e
export PERL5LIB=${with pkgs.perlPackages; makePerlPath [ FileSlurp XMLLibXML XMLSAX XMLSAXBase ListCompare ]}
export PERL5LIB=${with pkgs.perlPackages; makePerlPath [ FileSlurp XMLLibXML XMLSAX XMLSAXBase ListCompare JSON ]}
${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"}
'' + flip concatMapStrings cfg.mirroredBoots (args: ''
${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@

View File

@ -8,6 +8,7 @@ use File::stat;
use File::Copy;
use File::Slurp;
use File::Temp;
use JSON;
require List::Compare;
use POSIX;
use Cwd;
@ -20,6 +21,16 @@ my $dom = XML::LibXML->load_xml(location => $ARGV[0]);
sub get { my ($name) = @_; return $dom->findvalue("/expr/attrs/attr[\@name = '$name']/*/\@value"); }
sub getList {
my ($name) = @_;
my @list = ();
foreach my $entry ($dom->findnodes("/expr/attrs/attr[\@name = '$name']/list/string/\@value")) {
$entry = $entry->findvalue(".") or die;
push(@list, $entry);
}
return @list;
}
sub readFile {
my ($fn) = @_; local $/ = undef;
open FILE, "<$fn" or return undef; my $s = <FILE>; close FILE;
@ -241,7 +252,7 @@ if ($grubVersion == 1) {
timeout $timeout
";
if ($splashImage) {
copy $splashImage, "$bootPath/background.xpm.gz" or die "cannot copy $splashImage to $bootPath\n";
copy $splashImage, "$bootPath/background.xpm.gz" or die "cannot copy $splashImage to $bootPath: $!\n";
$conf .= "splashimage " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background.xpm.gz\n";
}
}
@ -319,7 +330,7 @@ else {
";
if ($font) {
copy $font, "$bootPath/converted-font.pf2" or die "cannot copy $font to $bootPath\n";
copy $font, "$bootPath/converted-font.pf2" or die "cannot copy $font to $bootPath: $!\n";
$conf .= "
insmod font
if loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/converted-font.pf2; then
@ -347,7 +358,7 @@ else {
background_color '$backgroundColor'
";
}
copy $splashImage, "$bootPath/background$suffix" or die "cannot copy $splashImage to $bootPath\n";
copy $splashImage, "$bootPath/background$suffix" or die "cannot copy $splashImage to $bootPath: $!\n";
$conf .= "
insmod " . substr($suffix, 1) . "
if background_image --mode '$splashMode' " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background$suffix; then
@ -381,8 +392,8 @@ sub copyToKernelsDir {
# kernels or initrd if this script is ever interrupted.
if (! -e $dst) {
my $tmp = "$dst.tmp";
copy $path, $tmp or die "cannot copy $path to $tmp\n";
rename $tmp, $dst or die "cannot rename $tmp to $dst\n";
copy $path, $tmp or die "cannot copy $path to $tmp: $!\n";
rename $tmp, $dst or die "cannot rename $tmp to $dst: $!\n";
}
$copied{$dst} = 1;
return ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/kernels/$name";
@ -405,10 +416,10 @@ sub addEntry {
# Make sure initrd is not world readable (won't work if /boot is FAT)
umask 0137;
my $initrdSecretsPathTemp = File::Temp::mktemp("$initrdSecretsPath.XXXXXXXX");
system("$path/append-initrd-secrets", $initrdSecretsPathTemp) == 0 or die "failed to create initrd secrets\n";
system("$path/append-initrd-secrets", $initrdSecretsPathTemp) == 0 or die "failed to create initrd secrets: $!\n";
# Check whether any secrets were actually added
if (-e $initrdSecretsPathTemp && ! -z _) {
rename $initrdSecretsPathTemp, $initrdSecretsPath or die "failed to move initrd secrets into place\n";
rename $initrdSecretsPathTemp, $initrdSecretsPath or die "failed to move initrd secrets into place: $!\n";
$copied{$initrdSecretsPath} = 1;
$initrd .= " " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/kernels/$initrdName-secrets";
} else {
@ -575,7 +586,7 @@ if (get("useOSProber") eq "true") {
}
# Atomically switch to the new config
rename $tmpFile, $confFile or die "cannot rename $tmpFile to $confFile\n";
rename $tmpFile, $confFile or die "cannot rename $tmpFile to $confFile: $!\n";
# Remove obsolete files from $bootPath/kernels.
@ -596,9 +607,12 @@ struct(GrubState => {
efi => '$',
devices => '$',
efiMountPoint => '$',
extraGrubInstallArgs => '@',
});
# If you add something to the state file, only add it to the end
# because it is read line-by-line.
sub readGrubState {
my $defaultGrubState = GrubState->new(name => "", version => "", efi => "", devices => "", efiMountPoint => "" );
my $defaultGrubState = GrubState->new(name => "", version => "", efi => "", devices => "", efiMountPoint => "", extraGrubInstallArgs => () );
open FILE, "<$bootPath/grub/state" or return $defaultGrubState;
local $/ = "\n";
my $name = <FILE>;
@ -611,24 +625,37 @@ sub readGrubState {
chomp($devices);
my $efiMountPoint = <FILE>;
chomp($efiMountPoint);
# Historically, arguments in the state file were one per each line, but that
# gets really messy when newlines are involved, structured arguments
# like lists are needed (they have to have a separator encoding), or even worse,
# when we need to remove a setting in the future. Thus, the 6th line is a JSON
# object that can store structured data, with named keys, and all new state
# should go in there.
my $jsonStateLine = <FILE>;
# For historical reasons we do not check the values above for un-definedness
# (that is, when the state file has too few lines and EOF is reached),
# because the above come from the first version of this logic and are thus
# guaranteed to be present.
$jsonStateLine = defined $jsonStateLine ? $jsonStateLine : '{}'; # empty JSON object
chomp($jsonStateLine);
if ($jsonStateLine eq "") {
$jsonStateLine = '{}'; # empty JSON object
}
my %jsonState = %{decode_json($jsonStateLine)};
my @extraGrubInstallArgs = exists($jsonState{'extraGrubInstallArgs'}) ? @{$jsonState{'extraGrubInstallArgs'}} : ();
close FILE;
my $grubState = GrubState->new(name => $name, version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint );
my $grubState = GrubState->new(name => $name, version => $version, efi => $efi, devices => $devices, efiMountPoint => $efiMountPoint, extraGrubInstallArgs => \@extraGrubInstallArgs );
return $grubState
}
sub getDeviceTargets {
my @devices = ();
foreach my $dev ($dom->findnodes('/expr/attrs/attr[@name = "devices"]/list/string/@value')) {
$dev = $dev->findvalue(".") or die;
push(@devices, $dev);
}
return @devices;
}
my @deviceTargets = getDeviceTargets();
my @deviceTargets = getList('devices');
my $prevGrubState = readGrubState();
my @prevDeviceTargets = split/,/, $prevGrubState->devices;
my @extraGrubInstallArgs = getList('extraGrubInstallArgs');
my @prevExtraGrubInstallArgs = $prevGrubState->extraGrubInstallArgs;
my $devicesDiffer = scalar (List::Compare->new( '-u', '-a', \@deviceTargets, \@prevDeviceTargets)->get_symmetric_difference());
my $extraGrubInstallArgsDiffer = scalar (List::Compare->new( '-u', '-a', \@extraGrubInstallArgs, \@prevExtraGrubInstallArgs)->get_symmetric_difference());
my $nameDiffer = get("fullName") ne $prevGrubState->name;
my $versionDiffer = get("fullVersion") ne $prevGrubState->version;
my $efiDiffer = $efiTarget ne $prevGrubState->efi;
@ -637,25 +664,25 @@ if (($ENV{'NIXOS_INSTALL_GRUB'} // "") eq "1") {
warn "NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER";
$ENV{'NIXOS_INSTALL_BOOTLOADER'} = "1";
}
my $requireNewInstall = $devicesDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_BOOTLOADER'} // "") eq "1");
my $requireNewInstall = $devicesDiffer || $extraGrubInstallArgsDiffer || $nameDiffer || $versionDiffer || $efiDiffer || $efiMountPointDiffer || (($ENV{'NIXOS_INSTALL_BOOTLOADER'} // "") eq "1");
# install a symlink so that grub can detect the boot drive
my $tmpDir = File::Temp::tempdir(CLEANUP => 1) or die "Failed to create temporary space";
symlink "$bootPath", "$tmpDir/boot" or die "Failed to symlink $tmpDir/boot";
my $tmpDir = File::Temp::tempdir(CLEANUP => 1) or die "Failed to create temporary space: $!";
symlink "$bootPath", "$tmpDir/boot" or die "Failed to symlink $tmpDir/boot: $!";
# install non-EFI GRUB
if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
foreach my $dev (@deviceTargets) {
next if $dev eq "nodev";
print STDERR "installing the GRUB $grubVersion boot loader on $dev...\n";
my @command = ("$grub/sbin/grub-install", "--recheck", "--root-directory=$tmpDir", Cwd::abs_path($dev));
my @command = ("$grub/sbin/grub-install", "--recheck", "--root-directory=$tmpDir", Cwd::abs_path($dev), @extraGrubInstallArgs);
if ($forceInstall eq "true") {
push @command, "--force";
}
if ($grubTarget ne "") {
push @command, "--target=$grubTarget";
}
(system @command) == 0 or die "$0: installation of GRUB on $dev failed\n";
(system @command) == 0 or die "$0: installation of GRUB on $dev failed: $!\n";
}
}
@ -663,7 +690,7 @@ if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
# install EFI GRUB
if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n";
my @command = ("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint");
my @command = ("$grubEfi/sbin/grub-install", "--recheck", "--target=$grubTargetEfi", "--boot-directory=$bootPath", "--efi-directory=$efiSysMountPoint", @extraGrubInstallArgs);
if ($forceInstall eq "true") {
push @command, "--force";
}
@ -674,17 +701,29 @@ if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both"))
push @command, "--removable" if $efiInstallAsRemovable eq "true";
}
(system @command) == 0 or die "$0: installation of GRUB EFI into $efiSysMountPoint failed\n";
(system @command) == 0 or die "$0: installation of GRUB EFI into $efiSysMountPoint failed: $!\n";
}
# update GRUB state file
if ($requireNewInstall != 0) {
open FILE, ">$bootPath/grub/state" or die "cannot create $bootPath/grub/state: $!\n";
# Temp file for atomic rename.
my $stateFile = "$bootPath/grub/state";
my $stateFileTmp = $stateFile . ".tmp";
open FILE, ">$stateFileTmp" or die "cannot create $stateFileTmp: $!\n";
print FILE get("fullName"), "\n" or die;
print FILE get("fullVersion"), "\n" or die;
print FILE $efiTarget, "\n" or die;
print FILE join( ",", @deviceTargets ), "\n" or die;
print FILE $efiSysMountPoint, "\n" or die;
my %jsonState = (
extraGrubInstallArgs => \@extraGrubInstallArgs
);
my $jsonStateLine = encode_json(\%jsonState);
print FILE $jsonStateLine, "\n" or die;
close FILE or die;
# Atomically switch to the new state file
rename $stateFileTmp, $stateFile or die "cannot rename $stateFileTmp to $stateFile: $!\n";
}

View File

@ -140,7 +140,7 @@ let
umount /crypt-ramfs 2>/dev/null
'';
openCommand = name': { name, device, header, keyFile, keyFileSize, keyFileOffset, allowDiscards, yubikey, gpgCard, fido2, fallbackToPassword, ... }: assert name' == name;
openCommand = name': { name, device, header, keyFile, keyFileSize, keyFileOffset, allowDiscards, yubikey, gpgCard, fido2, fallbackToPassword, preOpenCommands, postOpenCommands,... }: assert name' == name;
let
csopen = "cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} ${optionalString (header != null) "--header=${header}"}";
cschange = "cryptsetup luksChangeKey ${device} ${optionalString (header != null) "--header=${header}"}";
@ -412,11 +412,17 @@ let
}
''}
# commands to run right before we mount our device
${preOpenCommands}
${if (luks.yubikeySupport && (yubikey != null)) || (luks.gpgSupport && (gpgCard != null)) || (luks.fido2Support && (fido2.credential != null)) then ''
open_with_hardware
'' else ''
open_normally
''}
# commands to run right after we mounted our device
${postOpenCommands}
'';
askPass = pkgs.writeScriptBin "cryptsetup-askpass" ''
@ -735,6 +741,30 @@ in
};
});
};
preOpenCommands = mkOption {
type = types.lines;
default = "";
example = ''
mkdir -p /tmp/persistent
mount -t zfs rpool/safe/persistent /tmp/persistent
'';
description = ''
Commands that should be run right before we try to mount our LUKS device.
This can be useful, if the keys needed to open the drive is on another partion.
'';
};
postOpenCommands = mkOption {
type = types.lines;
default = "";
example = ''
umount /tmp/persistent
'';
description = ''
Commands that should be run right after we have mounted our LUKS device.
'';
};
};
}));
};

View File

@ -28,7 +28,7 @@ with lib;
Any additional configuration to be appended to the generated
<filename>modprobe.conf</filename>. This is typically used to
specify module options. See
<citerefentry><refentrytitle>modprobe.conf</refentrytitle>
<citerefentry><refentrytitle>modprobe.d</refentrytitle>
<manvolnum>5</manvolnum></citerefentry> for details.
'';
type = types.lines;

View File

@ -488,7 +488,7 @@ let
vlanConfig = mkOption {
default = {};
example = { Id = "4"; };
example = { Id = 4; };
type = types.addCheck (types.attrsOf unitOption) checkVlan;
description = ''
Each attribute in this set specifies an option in the

View File

@ -265,8 +265,8 @@ in {
restartIfChanged = false;
};
systemd.sockets.libvirtd .wantedBy = [ "sockets.target" ];
systemd.sockets.libvirtd-tcp.wantedBy = [ "sockets.target" ];
# https://libvirt.org/daemons.html#monolithic-systemd-integration
systemd.sockets.libvirtd.wantedBy = [ "sockets.target" ];
security.polkit.extraConfig = ''
polkit.addRule(function(action, subject) {

View File

@ -81,6 +81,7 @@ let
drivesCmdLine = drives: concatStringsSep " " (imap1 driveCmdline drives);
# Creates a device name from a 1-based a numerical index, e.g.
# * `driveDeviceName 1` -> `/dev/vda`
# * `driveDeviceName 2` -> `/dev/vdb`
@ -99,6 +100,13 @@ let
addDeviceNames =
imap1 (idx: drive: drive // { device = driveDeviceName idx; });
efiPrefix =
if (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) then "${pkgs.OVMF.fd}/FV/OVMF"
else if pkgs.stdenv.isAarch64 then "${pkgs.OVMF.fd}/FV/AAVMF"
else throw "No EFI firmware available for platform";
efiFirmware = "${efiPrefix}_CODE.fd";
efiVarsDefault = "${efiPrefix}_VARS.fd";
# Shell script to start the VM.
startVM =
''
@ -124,10 +132,14 @@ let
# A writable boot disk can be booted from automatically.
${qemu}/bin/qemu-img create -f qcow2 -b ${bootDisk}/disk.img $TMPDIR/disk.img || exit 1
NIX_EFI_VARS=$(readlink -f ''${NIX_EFI_VARS:-${cfg.efiVars}})
${if cfg.useEFIBoot then ''
# VM needs a writable flash BIOS.
cp ${bootDisk}/bios.bin $TMPDIR || exit 1
chmod 0644 $TMPDIR/bios.bin || exit 1
# VM needs writable EFI vars
if ! test -e "$NIX_EFI_VARS"; then
cp ${bootDisk}/efi-vars.fd "$NIX_EFI_VARS" || exit 1
chmod 0644 "$NIX_EFI_VARS" || exit 1
fi
'' else ''
''}
'' else ''
@ -164,6 +176,8 @@ let
# Generate a hard disk image containing a /boot partition and GRUB
# in the MBR. Used when the `useBootLoader' option is set.
# Uses `runInLinuxVM` to create the image in a throwaway VM.
# See note [Disk layout with `useBootLoader`].
# FIXME: use nixos/lib/make-disk-image.nix.
bootDisk =
pkgs.vmTools.runInLinuxVM (
@ -172,21 +186,22 @@ let
''
mkdir $out
diskImage=$out/disk.img
bootFlash=$out/bios.bin
${qemu}/bin/qemu-img create -f qcow2 $diskImage "40M"
${qemu}/bin/qemu-img create -f qcow2 $diskImage "60M"
${if cfg.useEFIBoot then ''
cp ${pkgs.OVMF-CSM.fd}/FV/OVMF.fd $bootFlash
chmod 0644 $bootFlash
efiVars=$out/efi-vars.fd
cp ${efiVarsDefault} $efiVars
chmod 0644 $efiVars
'' else ''
''}
'';
buildInputs = [ pkgs.utillinux ];
QEMU_OPTS = if cfg.useEFIBoot
then "-pflash $out/bios.bin -nographic -serial pty"
else "-nographic -serial pty";
QEMU_OPTS = "-nographic -serial stdio -monitor none"
+ lib.optionalString cfg.useEFIBoot (
" -drive if=pflash,format=raw,unit=0,readonly=on,file=${efiFirmware}"
+ " -drive if=pflash,format=raw,unit=1,file=$efiVars");
}
''
# Create a /boot EFI partition with 40M and arbitrary but fixed GUIDs for reproducibility
# Create a /boot EFI partition with 60M and arbitrary but fixed GUIDs for reproducibility
${pkgs.gptfdisk}/bin/sgdisk \
--set-alignment=1 --new=1:34:2047 --change-name=1:BIOSBootPartition --typecode=1:ef02 \
--set-alignment=512 --largest-new=2 --change-name=2:EFISystem --typecode=2:ef00 \
@ -197,6 +212,19 @@ let
--partition-guid=2:970C694F-AFD0-4B99-B750-CDB7A329AB6F \
--hybrid 2 \
--recompute-chs /dev/vda
${optionalString (config.boot.loader.grub.device != "/dev/vda")
# In this throwaway VM, we only have the /dev/vda disk, but the
# actual VM described by `config` (used by `switch-to-configuration`
# below) may set `boot.loader.grub.device` to a different device
# that's nonexistent in the throwaway VM.
# Create a symlink for that device, so that the `grub-install`
# by `switch-to-configuration` will hit /dev/vda anyway.
''
ln -s /dev/vda ${config.boot.loader.grub.device}
''
}
${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda2
export MTOOLS_SKIP_CHECK=1
${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
@ -210,6 +238,10 @@ let
mkdir /boot
mount /dev/vda2 /boot
${optionalString config.boot.loader.efi.canTouchEfiVariables ''
mount -t efivarfs efivarfs /sys/firmware/efi/efivars
''}
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
mkdir /boot/grub
echo '(hd0) /dev/vda' > /boot/grub/device.map
@ -467,6 +499,16 @@ in
'';
};
virtualisation.efiVars =
mkOption {
default = "./${vmName}-efi-vars.fd";
description =
''
Path to nvram image containing UEFI variables. The will be created
on startup if it does not exist.
'';
};
virtualisation.bios =
mkOption {
default = null;
@ -483,7 +525,27 @@ in
config = {
boot.loader.grub.device = mkVMOverride cfg.bootDevice;
# Note [Disk layout with `useBootLoader`]
#
# If `useBootLoader = true`, we configure 2 drives:
# `/dev/?da` for the root disk, and `/dev/?db` for the boot disk
# which has the `/boot` partition and the boot loader.
# Concretely:
#
# * The second drive's image `disk.img` is created in `bootDisk = ...`
# using a throwaway VM. Note that there the disk is always `/dev/vda`,
# even though in the final VM it will be at `/dev/*b`.
# * The disks are attached in `virtualisation.qemu.drives`.
# Their order makes them appear as devices `a`, `b`, etc.
# * `fileSystems."/boot"` is adjusted to be on device `b`.
# If `useBootLoader`, GRUB goes to the second disk, see
# note [Disk layout with `useBootLoader`].
boot.loader.grub.device = mkVMOverride (
if cfg.useBootLoader
then driveDeviceName 2 # second disk
else cfg.bootDevice
);
boot.initrd.extraUtilsCommands =
''
@ -556,7 +618,8 @@ in
''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"''
])
(mkIf cfg.useEFIBoot [
"-pflash $TMPDIR/bios.bin"
"-drive if=pflash,format=raw,unit=0,readonly,file=${efiFirmware}"
"-drive if=pflash,format=raw,unit=1,file=$NIX_EFI_VARS"
])
(mkIf (cfg.bios != null) [
"-bios ${cfg.bios}/bios.bin"
@ -574,6 +637,8 @@ in
driveExtraOpts.werror = "report";
}]
(mkIf cfg.useBootLoader [
# The order of this list determines the device names, see
# note [Disk layout with `useBootLoader`].
{
name = "boot";
file = "$TMPDIR/disk.img";
@ -628,9 +693,9 @@ in
};
} // optionalAttrs cfg.useBootLoader
{ "/boot" =
{ device = "${lookupDriveDeviceName "boot" cfg.qemu.drives}2";
# see note [Disk layout with `useBootLoader`]
{ device = "${lookupDriveDeviceName "boot" cfg.qemu.drives}2"; # 2 for e.g. `vdb2`, as created in `bootDisk`
fsType = "vfat";
options = [ "ro" ];
noCheck = true; # fsck fails on a r/o filesystem
};
});

View File

@ -68,7 +68,7 @@ in
SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
'';
} (mkIf cfg.x11 {
services.xserver.videoDrivers = mkOverride 50 [ "virtualbox" "modesetting" ];
services.xserver.videoDrivers = mkOverride 50 [ "vmware" "virtualbox" "modesetting" ];
services.xserver.config =
''

View File

@ -72,6 +72,7 @@ in {
audiocontroller = "ac97";
audio = "alsa";
audioout = "on";
graphicscontroller = "vmsvga";
rtcuseutc = "on";
usb = "on";
usbehci = "on";

View File

@ -151,6 +151,7 @@ in
incron = handleTest ./incron.nix {};
influxdb = handleTest ./influxdb.nix {};
initrd-network-ssh = handleTest ./initrd-network-ssh {};
initrd-network-openvpn = handleTest ./initrd-network-openvpn {};
initrdNetwork = handleTest ./initrd-network.nix {};
installer = handleTest ./installer.nix {};
iodine = handleTest ./iodine.nix {};
@ -220,6 +221,7 @@ in
nat.firewall = handleTest ./nat.nix { withFirewall = true; };
nat.firewall-conntrack = handleTest ./nat.nix { withFirewall = true; withConntrackHelpers = true; };
nat.standalone = handleTest ./nat.nix { withFirewall = false; };
ncdns = handleTest ./ncdns.nix {};
ndppd = handleTest ./ndppd.nix {};
neo4j = handleTest ./neo4j.nix {};
specialisation = handleTest ./specialisation.nix {};
@ -266,7 +268,9 @@ in
php = handleTest ./php {};
plasma5 = handleTest ./plasma5.nix {};
plotinus = handleTest ./plotinus.nix {};
podman = handleTest ./podman.nix {};
podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
postfix = handleTest ./postfix.nix {};
postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
postgis = handleTest ./postgis.nix {};
postgresql = handleTest ./postgresql.nix {};
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
@ -320,7 +324,7 @@ in
systemd = handleTest ./systemd.nix {};
systemd-analyze = handleTest ./systemd-analyze.nix {};
systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.nix {};
systemd-boot = handleTestOn ["x86_64-linux"] ./systemd-boot.nix {};
systemd-boot = handleTest ./systemd-boot.nix {};
systemd-confinement = handleTest ./systemd-confinement.nix {};
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};

View File

@ -41,8 +41,8 @@ in
config = mkIf cfg.enable {
services.xserver.displayManager.lightdm = {
enable = true;
services.xserver.displayManager = {
lightdm.enable = true;
autoLogin = {
enable = true;
user = cfg.user;

View File

@ -90,13 +90,22 @@ import ./make-test-python.nix ({ pkgs, ... }: {
with subtest("Ensure Docker images can use an unstable date"):
docker.succeed(
"docker load --input='${examples.bash}'"
"docker load --input='${examples.unstableDate}'"
)
assert unix_time_second1 not in docker.succeed(
"docker inspect ${examples.unstableDate.imageName} "
+ "| ${pkgs.jq}/bin/jq -r .[].Created"
)
with subtest("Ensure Layered Docker images can use an unstable date"):
docker.succeed(
"docker load --input='${examples.unstableDateLayered}'"
)
assert unix_time_second1 not in docker.succeed(
"docker inspect ${examples.unstableDateLayered.imageName} "
+ "| ${pkgs.jq}/bin/jq -r .[].Created"
)
with subtest("Ensure Layered Docker images work"):
docker.succeed(
"docker load --input='${examples.layered-image}'",
@ -178,5 +187,12 @@ import ./make-test-python.nix ({ pkgs, ... }: {
# This check may be loosened to allow an *empty* store rather than *no* store.
docker.succeed("docker run --rm no-store-paths ls /")
docker.fail("docker run --rm no-store-paths ls /nix/store")
with subtest("Ensure buildLayeredImage does not change store path contents."):
docker.succeed(
"docker load --input='${pkgs.dockerTools.examples.filesInStore}'",
"docker run --rm file-in-store nix-store --verify --check-contents",
"docker run --rm file-in-store |& grep 'some data'",
)
'';
})

View File

@ -12,8 +12,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
services.xserver.enable = true;
services.xserver.displayManager.gdm = {
enable = true;
services.xserver.displayManager = {
gdm.enable = true;
autoLogin = {
enable = true;
user = user.name;

View File

@ -11,8 +11,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
services.xserver.enable = true;
services.xserver.displayManager.gdm = {
enable = true;
services.xserver.displayManager = {
gdm.enable = true;
autoLogin = {
enable = true;
user = "alice";

View File

@ -2,6 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
let
configDir = "/var/lib/foobar";
mqttUsername = "homeassistant";
mqttPassword = "secret";
in {
name = "home-assistant";
@ -11,6 +12,15 @@ in {
nodes.hass = { pkgs, ... }: {
environment.systemPackages = with pkgs; [ mosquitto ];
services.mosquitto = {
enable = true;
users = {
"${mqttUsername}" = {
acl = [ "pattern readwrite #" ];
password = mqttPassword;
};
};
};
services.home-assistant = {
inherit configDir;
enable = true;
@ -23,8 +33,11 @@ in {
elevation = 0;
};
frontend = {};
# uses embedded mqtt broker
mqtt.password = mqttPassword;
mqtt = {
broker = "127.0.0.1";
username = mqttUsername;
password = mqttPassword;
};
binary_sensor = [{
platform = "mqtt";
state_topic = "home-assistant/test";
@ -64,10 +77,10 @@ in {
with subtest("Toggle a binary sensor using MQTT"):
# wait for broker to become available
hass.wait_until_succeeds(
"mosquitto_sub -V mqttv311 -t home-assistant/test -u homeassistant -P '${mqttPassword}' -W 1 -t '*'"
"mosquitto_sub -V mqttv311 -t home-assistant/test -u ${mqttUsername} -P '${mqttPassword}' -W 1 -t '*'"
)
hass.succeed(
"mosquitto_pub -V mqttv311 -t home-assistant/test -u homeassistant -P '${mqttPassword}' -m let_there_be_light"
"mosquitto_pub -V mqttv311 -t home-assistant/test -u ${mqttUsername} -P '${mqttPassword}' -m let_there_be_light"
)
with subtest("Print log to ease debugging"):
output_log = hass.succeed("cat ${configDir}/home-assistant.log")

View File

@ -1,5 +1,11 @@
{ system ? builtins.currentSystem,
config ? {},
pkgs ? import ../.. { inherit system config; }
}:
let
f = backend: import ./make-test-python.nix ({ pkgs, ... }: {
inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
f = backend: makeTest {
name = "ihatemoney-${backend}";
machine = { lib, ... }: {
services.ihatemoney = {
@ -24,9 +30,10 @@ let
testScript = ''
machine.wait_for_open_port(8000)
machine.wait_for_unit("uwsgi.service")
machine.wait_until_succeeds("curl http://localhost:8000")
assert '"yay"' in machine.succeed(
"curl -X POST http://localhost:8000/api/projects -d 'name=yay&id=yay&password=yay&contact_email=yay\@example.com'"
"curl -X POST http://localhost:8000/api/projects -d 'name=yay&id=yay&password=yay&contact_email=yay@example.com'"
)
owner, timestamp = machine.succeed(
"stat --printf %U:%G___%Y /var/lib/ihatemoney/secret_key"
@ -48,7 +55,7 @@ let
assert "ihatemoney" in machine.succeed("curl http://localhost:8000")
'';
});
};
in {
ihatemoney-sqlite = f "sqlite";
ihatemoney-postgresql = f "postgresql";

View File

@ -0,0 +1,145 @@
import ../make-test-python.nix ({ lib, ...}:
{
name = "initrd-network-openvpn";
nodes =
let
# Inlining of the shared secret for the
# OpenVPN server and client
secretblock = ''
secret [inline]
<secret>
${lib.readFile ./shared.key}
</secret>
'';
in
{
# Minimal test case to check a successful boot, even with invalid config
minimalboot =
{ ... }:
{
boot.initrd.network = {
enable = true;
openvpn = {
enable = true;
configuration = "/dev/null";
};
};
};
# initrd VPN client
ovpnclient =
{ ... }:
{
virtualisation.useBootLoader = true;
virtualisation.vlans = [ 1 ];
boot.initrd = {
# This command does not fork to keep the VM in the state where
# only the initramfs is loaded
preLVMCommands =
''
/bin/nc -p 1234 -lke /bin/echo TESTVALUE
'';
network = {
enable = true;
# Work around udhcpc only getting a lease on eth0
postCommands = ''
/bin/ip addr add 192.168.1.2/24 dev eth1
'';
# Example configuration for OpenVPN
# This is the main reason for this test
openvpn = {
enable = true;
configuration = "${./initrd.ovpn}";
};
};
};
};
# VPN server and gateway for ovpnclient between vlan 1 and 2
ovpnserver =
{ ... }:
{
virtualisation.vlans = [ 1 2 ];
# Enable NAT and forward port 12345 to port 1234
networking.nat = {
enable = true;
internalInterfaces = [ "tun0" ];
externalInterface = "eth2";
forwardPorts = [ { destination = "10.8.0.2:1234";
sourcePort = 12345; } ];
};
# Trust tun0 and allow the VPN Server to be reached
networking.firewall = {
trustedInterfaces = [ "tun0" ];
allowedUDPPorts = [ 1194 ];
};
# Minimal OpenVPN server configuration
services.openvpn.servers.testserver =
{
config = ''
dev tun0
ifconfig 10.8.0.1 10.8.0.2
${secretblock}
'';
};
};
# Client that resides in the "external" VLAN
testclient =
{ ... }:
{
virtualisation.vlans = [ 2 ];
};
};
testScript =
''
# Minimal test case, checks whether enabling (with invalid config) harms
# the boot process
with subtest("Check for successful boot with broken openvpn config"):
minimalboot.start()
# If we get to multi-user.target, we booted successfully
minimalboot.wait_for_unit("multi-user.target")
minimalboot.shutdown()
# Elaborated test case where the ovpnclient (where this module is used)
# can be reached by testclient only over ovpnserver.
# This is an indirect test for success.
with subtest("Check for connection from initrd VPN client, config as file"):
ovpnserver.start()
testclient.start()
ovpnclient.start()
# Wait until the OpenVPN Server is available
ovpnserver.wait_for_unit("openvpn-testserver.service")
ovpnserver.succeed("ping -c 1 10.8.0.1")
# Wait for the client to connect
ovpnserver.wait_until_succeeds("ping -c 1 10.8.0.2")
# Wait until the testclient has network
testclient.wait_for_unit("network.target")
# Check that ovpnclient is reachable over vlan 1
ovpnserver.succeed("nc -w 2 192.168.1.2 1234 | grep -q TESTVALUE")
# Check that ovpnclient is reachable over tun0
ovpnserver.succeed("nc -w 2 10.8.0.2 1234 | grep -q TESTVALUE")
# Check that ovpnclient is reachable from testclient over the gateway
testclient.succeed("nc -w 2 192.168.2.3 12345 | grep -q TESTVALUE")
'';
})

View File

@ -0,0 +1,29 @@
remote 192.168.1.3
dev tun
ifconfig 10.8.0.2 10.8.0.1
# Only force VLAN 2 through the VPN
route 192.168.2.0 255.255.255.0 10.8.0.1
secret [inline]
<secret>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
553aabe853acdfe51cd6fcfea93dcbb0
c8797deadd1187606b1ea8f2315eb5e6
67c0d7e830f50df45686063b189d6c6b
aab8bb3430cc78f7bb1f78628d5c3742
0cef4f53a5acab2894905f4499f95d8e
e69b7b6748b17016f89e19e91481a9fd
bf8c10651f41a1d4fdf5f438925a6733
13cec8f04701eb47b8f7ffc48bc3d7af
65f07bce766015b87c3db4d668c655ff
be5a69522a8e60ccb217f8521681b45d
27c0b70bdfbfbb426c7646d80adf7482
3ddac58b25cb1c1bb100de974478b4c6
8b45a94261a2405e99810cb2b3abd49f
21b3198ada87ff3c4e656a008e540a8d
e7811584363597599cce2040a68ac00e
f2125540e0f7f4adc37cb3f0d922eeb7
-----END OpenVPN Static key V1-----
</secret>

View File

@ -0,0 +1,21 @@
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
553aabe853acdfe51cd6fcfea93dcbb0
c8797deadd1187606b1ea8f2315eb5e6
67c0d7e830f50df45686063b189d6c6b
aab8bb3430cc78f7bb1f78628d5c3742
0cef4f53a5acab2894905f4499f95d8e
e69b7b6748b17016f89e19e91481a9fd
bf8c10651f41a1d4fdf5f438925a6733
13cec8f04701eb47b8f7ffc48bc3d7af
65f07bce766015b87c3db4d668c655ff
be5a69522a8e60ccb217f8521681b45d
27c0b70bdfbfbb426c7646d80adf7482
3ddac58b25cb1c1bb100de974478b4c6
8b45a94261a2405e99810cb2b3abd49f
21b3198ada87ff3c4e656a008e540a8d
e7811584363597599cce2040a68ac00e
f2125540e0f7f4adc37cb3f0d922eeb7
-----END OpenVPN Static key V1-----

View File

@ -5,16 +5,12 @@ makeInstalledTest {
testConfig = {
i18n.inputMethod.enabled = "ibus";
systemd.user.services.ibus-daemon = {
serviceConfig.ExecStart = "${pkgs.ibus}/bin/ibus-daemon --xim --verbose";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
};
};
preTestScript = ''
# ibus has ibus-desktop-testing-runner but it tries to manage desktop session so we just spawn ibus-daemon ourselves
machine.succeed("ibus-daemon --daemonize --verbose")
'';
withX11 = true;
# TODO: ibus-daemon is currently crashing or something
# maybe make ibus systemd service that auto-restarts?
meta.broken = true;
}

77
nixos/tests/ncdns.nix Normal file
View File

@ -0,0 +1,77 @@
import ./make-test-python.nix ({ pkgs, ... }:
let
fakeReply = pkgs.writeText "namecoin-reply.json" ''
{ "error": null,
"id": 1,
"result": {
"address": "T31q8ucJ4dI1xzhxQ5QispfECld5c7Xw",
"expired": false,
"expires_in": 2248,
"height": 438155,
"name": "d/test",
"txid": "db61c0b2540ba0c1a2c8cc92af703a37002e7566ecea4dbf8727c7191421edfb",
"value": "{\"ip\": \"1.2.3.4\", \"email\": \"root@test.bit\",\"info\": \"Fake record\"}",
"vout": 0
}
}
'';
in
{
name = "ncdns";
nodes.server = { ... }: {
networking.nameservers = [ "127.0.0.1" ];
services.namecoind.rpc = {
address = "127.0.0.1";
user = "namecoin";
password = "secret";
port = 8332;
};
# Fake namecoin RPC server because we can't
# run a full node in a test.
systemd.services.namecoind = {
wantedBy = [ "multi-user.target" ];
script = ''
while true; do
echo -e "HTTP/1.1 200 OK\n\n $(<${fakeReply})\n" \
| ${pkgs.netcat}/bin/nc -N -l 127.0.0.1 8332
done
'';
};
services.ncdns = {
enable = true;
dnssec.enable = true;
};
services.pdns-recursor = {
enable = true;
dns.allowFrom = [ "127.0.0.0/8" ];
settings.loglevel = 8;
resolveNamecoin = true;
};
environment.systemPackages = [ pkgs.dnsutils ];
};
testScript = ''
with subtest("DNSSEC keys have been generated"):
server.wait_for_unit("ncdns")
server.wait_for_file("/var/lib/ncdns/bit.key")
server.wait_for_file("/var/lib/ncdns/bit-zone.key")
with subtest("DNSKEY bit record is present"):
server.wait_for_unit("pdns-recursor")
server.wait_for_open_port("53")
server.succeed("host -t DNSKEY bit")
with subtest("can resolve a .bit name"):
server.wait_for_unit("namecoind")
server.wait_for_open_port("8332")
assert "1.2.3.4" in server.succeed("host -t A test.bit")
'';
})

View File

@ -14,7 +14,7 @@ import ./make-test-python.nix ({ pkgs, ...} :
services.xserver.displayManager.sddm.enable = true;
services.xserver.displayManager.defaultSession = "plasma5";
services.xserver.desktopManager.plasma5.enable = true;
services.xserver.displayManager.sddm.autoLogin = {
services.xserver.displayManager.autoLogin = {
enable = true;
user = "alice";
};

View File

@ -0,0 +1,44 @@
let
certs = import ./common/acme/server/snakeoil-certs.nix;
in
import ./make-test-python.nix {
name = "postfix";
machine = { pkgs, ... }: {
imports = [ common/user-account.nix ];
services.postfix = {
enable = true;
enableSubmissions = true;
submissionsOptions = {
smtpd_tls_security_level = "none";
};
};
environment.systemPackages = let
checkConfig = pkgs.writeScriptBin "check-config" ''
#!${pkgs.python3.interpreter}
import sys
state = 1
success = False
with open("/etc/postfix/master.cf") as masterCf:
for line in masterCf:
if state == 1 and line.startswith("submissions"):
state = 2
elif state == 2 and line.startswith(" ") and "smtpd_tls_security_level=encrypt" in line:
success = True
elif state == 2 and not line.startswith(" "):
state == 3
if not success:
sys.exit(1)
'';
in [ checkConfig ];
};
testScript = ''
machine.wait_for_unit("postfix.service")
machine.succeed("check-config")
'';
}

76
nixos/tests/postfix.nix Normal file
View File

@ -0,0 +1,76 @@
let
certs = import ./common/acme/server/snakeoil-certs.nix;
in
import ./make-test-python.nix {
name = "postfix";
machine = { pkgs, ... }: {
imports = [ common/user-account.nix ];
services.postfix = {
enable = true;
enableSubmission = true;
enableSubmissions = true;
sslCACert = certs.ca.cert;
sslCert = certs."acme.test".cert;
sslKey = certs."acme.test".key;
submissionsOptions = {
smtpd_sasl_auth_enable = "yes";
smtpd_client_restrictions = "permit";
milter_macro_daemon_name = "ORIGINATING";
};
};
security.pki.certificateFiles = [
certs.ca.cert
];
networking.extraHosts = ''
127.0.0.1 acme.test
'';
environment.systemPackages = let
sendTestMail = pkgs.writeScriptBin "send-testmail" ''
#!${pkgs.python3.interpreter}
import smtplib
with smtplib.SMTP('acme.test') as smtp:
smtp.sendmail('root@localhost', 'alice@localhost', 'Subject: Test\n\nTest data.')
smtp.quit()
'';
sendTestMailStarttls = pkgs.writeScriptBin "send-testmail-starttls" ''
#!${pkgs.python3.interpreter}
import smtplib
import ssl
ctx = ssl.create_default_context()
with smtplib.SMTP('acme.test') as smtp:
smtp.ehlo()
smtp.starttls(context=ctx)
smtp.ehlo()
smtp.sendmail('root@localhost', 'alice@localhost', 'Subject: Test STARTTLS\n\nTest data.')
smtp.quit()
'';
sendTestMailSmtps = pkgs.writeScriptBin "send-testmail-smtps" ''
#!${pkgs.python3.interpreter}
import smtplib
import ssl
ctx = ssl.create_default_context()
with smtplib.SMTP_SSL(host='acme.test', context=ctx) as smtp:
smtp.sendmail('root@localhost', 'alice@localhost', 'Subject: Test SMTPS\n\nTest data.')
smtp.quit()
'';
in [ sendTestMail sendTestMailStarttls sendTestMailSmtps ];
};
testScript = ''
machine.wait_for_unit("postfix.service")
machine.succeed("send-testmail")
machine.succeed("send-testmail-starttls")
machine.succeed("send-testmail-smtps")
'';
}

View File

@ -44,8 +44,8 @@ let
machine = { ... }: {
imports = [ ./common/user-account.nix ];
services.xserver.enable = true;
services.xserver.displayManager.sddm = {
enable = true;
services.xserver.displayManager = {
sddm.enable = true;
autoLogin = {
enable = true;
user = "alice";

View File

@ -1,16 +1,52 @@
import ./make-test-python.nix ({ lib, ... }:
import ./make-test-python.nix ({ lib, pkgs, ... }:
let
mungekey = "mungeverryweakkeybuteasytointegratoinatest";
slurmconfig = {
controlMachine = "control";
nodeName = [ "node[1-3] CPUs=1 State=UNKNOWN" ];
partitionName = [ "debug Nodes=node[1-3] Default=YES MaxTime=INFINITE State=UP" ];
extraConfig = ''
AccountingStorageHost=dbd
AccountingStorageType=accounting_storage/slurmdbd
'';
services.slurm = {
controlMachine = "control";
nodeName = [ "node[1-3] CPUs=1 State=UNKNOWN" ];
partitionName = [ "debug Nodes=node[1-3] Default=YES MaxTime=INFINITE State=UP" ];
extraConfig = ''
AccountingStorageHost=dbd
AccountingStorageType=accounting_storage/slurmdbd
'';
};
environment.systemPackages = [ mpitest ];
networking.firewall.enable = false;
systemd.tmpfiles.rules = [
"f /etc/munge/munge.key 0400 munge munge - mungeverryweakkeybuteasytointegratoinatest"
];
};
mpitest = let
mpitestC = pkgs.writeText "mpitest.c" ''
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int
main (int argc, char *argv[])
{
int rank, size, length;
char name[512];
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &rank);
MPI_Comm_size (MPI_COMM_WORLD, &size);
MPI_Get_processor_name (name, &length);
if ( rank == 0 ) printf("size=%d\n", size);
printf ("%s: hello world from process %d of %d\n", name, rank, size);
MPI_Finalize ();
return EXIT_SUCCESS;
}
'';
in pkgs.runCommandNoCC "mpitest" {} ''
mkdir -p $out/bin
${pkgs.openmpi}/bin/mpicc ${mpitestC} -o $out/bin/mpitest
'';
in {
name = "slurm";
@ -21,37 +57,40 @@ in {
computeNode =
{ ...}:
{
imports = [ slurmconfig ];
# TODO slurmd port and slurmctld port should be configurations and
# automatically allowed by the firewall.
networking.firewall.enable = false;
services.slurm = {
client.enable = true;
} // slurmconfig;
};
};
in {
control =
{ ...}:
{
networking.firewall.enable = false;
imports = [ slurmconfig ];
services.slurm = {
server.enable = true;
} // slurmconfig;
};
};
submit =
{ ...}:
{
networking.firewall.enable = false;
imports = [ slurmconfig ];
services.slurm = {
enableStools = true;
} // slurmconfig;
};
};
dbd =
{ pkgs, ... } :
{
networking.firewall.enable = false;
systemd.tmpfiles.rules = [
"f /etc/munge/munge.key 0400 munge munge - mungeverryweakkeybuteasytointegratoinatest"
];
services.slurm.dbdserver = {
enable = true;
storagePass = "password123";
@ -87,24 +126,7 @@ in {
''
start_all()
# Set up authentification across the cluster
for node in [submit, control, dbd, node1, node2, node3]:
node.wait_for_unit("default.target")
node.succeed("mkdir /etc/munge")
node.succeed(
"echo '${mungekey}' > /etc/munge/munge.key"
)
node.succeed("chmod 0400 /etc/munge/munge.key")
node.succeed("chown munge:munge /etc/munge/munge.key")
node.succeed("systemctl restart munged")
node.wait_for_unit("munged")
# Restart the services since they have probably failed due to the munge init
# failure
# Make sure DBD is up after DB initialzation
with subtest("can_start_slurmdbd"):
dbd.succeed("systemctl restart slurmdbd")
dbd.wait_for_unit("slurmdbd.service")
@ -137,5 +159,8 @@ in {
# find the srun job from above in the database
control.succeed("sleep 5")
control.succeed("sacct | grep hostname")
with subtest("run_PMIx_mpitest"):
submit.succeed("srun -N 3 --mpi=pmix mpitest | grep size=3")
'';
})

View File

@ -11,6 +11,8 @@ let
virtualisation.useBootLoader = true;
virtualisation.useEFIBoot = true;
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
environment.systemPackages = [ pkgs.efibootmgr ];
};
in
{
@ -31,6 +33,36 @@ in
machine.succeed(
"test -e /sys/firmware/efi/efivars/LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
)
# "bootctl install" should have created an EFI entry
machine.succeed('efibootmgr | grep "Linux Boot Manager"')
'';
};
# Boot without having created an EFI entry--instead using default "/EFI/BOOT/BOOTX64.EFI"
fallback = makeTest {
name = "systemd-boot-fallback";
meta.maintainers = with pkgs.stdenv.lib.maintainers; [ danielfullmer ];
machine = { pkgs, lib, ... }: {
imports = [ common ];
boot.loader.efi.canTouchEfiVariables = mkForce false;
};
testScript = ''
machine.start()
machine.wait_for_unit("multi-user.target")
machine.succeed("test -e /boot/loader/entries/nixos-generation-1.conf")
# Ensure we actually booted using systemd-boot
# Magic number is the vendor UUID used by systemd-boot.
machine.succeed(
"test -e /sys/firmware/efi/efivars/LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
)
# "bootctl install" should _not_ have created an EFI entry
machine.fail('efibootmgr | grep "Linux Boot Manager"')
'';
};

View File

@ -17,7 +17,7 @@ import ./make-test-python.nix (
services.xandikos.enable = true;
services.xandikos.address = "localhost";
services.xandikos.port = 8080;
services.xandikos.routePrefix = "/xandikos/";
services.xandikos.routePrefix = "/xandikos-prefix/";
services.xandikos.extraOptions = [
"--defaults"
];
@ -28,7 +28,7 @@ import ./make-test-python.nix (
serverName = "xandikos.local";
basicAuth.xandikos = "snakeOilPassword";
locations."/xandikos/" = {
proxyPass = "http://localhost:8080/";
proxyPass = "http://localhost:8080/xandikos-prefix/";
};
};
};

View File

@ -11,8 +11,8 @@ import ./make-test-python.nix ({ pkgs, ...} : {
services.xserver.enable = true;
services.xserver.displayManager.lightdm = {
enable = true;
services.xserver.displayManager = {
lightdm.enable = true;
autoLogin = {
enable = true;
user = "alice";

View File

@ -2,11 +2,11 @@
mkDerivation rec {
pname = "drumkv1";
version = "0.9.14";
version = "0.9.15";
src = fetchurl {
url = "mirror://sourceforge/drumkv1/${pname}-${version}.tar.gz";
sha256 = "0fr7pkp55zvjxf7p22drs93fsjgvqhbd55vxi0srhp2s2wzz5qak";
sha256 = "108jk8p1sbm99plipf98ssij6dxaip1lmznibg8y2c4x0v2la6ab";
};
buildInputs = [ libjack2 alsaLib libsndfile liblo lv2 qt5.qtbase qt5.qttools ];

View File

@ -2,13 +2,13 @@
stdenv.mkDerivation rec {
pname = "GxPlugins.lv2";
version = "0.7";
version = "0.8";
src = fetchFromGitHub {
owner = "brummer10";
repo = pname;
rev = "v${version}";
sha256 = "0jqdqnkg7pg9plcbxy49p7gcs1aj6h0xf7y9gndmjmkw5yjn2940";
sha256 = "11iv7bwvvspm74pisqvcpsxpg9xi6b08hq4i8q67mri4mvy9hmal";
fetchSubmodules = true;
};

View File

@ -3,12 +3,12 @@
mkDerivation rec {
pname = "jamulus";
version = "3.5.6";
version = "3.5.8";
src = fetchFromGitHub {
owner = "corrados";
repo = "jamulus";
rev = "r${stdenv.lib.replaceStrings [ "." ] [ "_" ] version}";
sha256 = "00vd6kffsf3vqfwaxjvln63x3n0q32f385qc51fn5iyj54410x0f";
sha256 = "0mkrlfaw85pxlacrxfhb45731i4jnn67v411lzx5kb42ncar1586";
};
nativeBuildInputs = [ pkg-config qmake ];

View File

@ -23,7 +23,7 @@
python3.pkgs.buildPythonApplication rec {
pname = "lollypop";
version = "1.2.35";
version = "1.3.2";
format = "other";
doCheck = false;
@ -32,7 +32,7 @@ python3.pkgs.buildPythonApplication rec {
url = "https://gitlab.gnome.org/World/lollypop";
rev = "refs/tags/${version}";
fetchSubmodules = true;
sha256 = "19nw9qh17yyi9ih1nwngbbwjx1vr26haqhmzsdqf0yjgsgf9vldx";
sha256 = "14854j1dhq67s1vzs0lqy345vbl6f5w8nb36n4i33fmpva2flsk3";
};
nativeBuildInputs = [

View File

@ -2,11 +2,11 @@
python3Packages.buildPythonApplication rec {
pname = "Mopidy-Iris";
version = "3.49.0";
version = "3.50.0";
src = python3Packages.fetchPypi {
inherit pname version;
sha256 = "0zddm7286iwx437gjz47m4g28s8gdcxnm2hmly9w1dzi08aa4fas";
sha256 = "04miwf0dqb8jir9g7xkfnn3l62bdn74ap03kqzz2v3byg64f1p0g";
};
propagatedBuildInputs = [

View File

@ -7,13 +7,13 @@
stdenv.mkDerivation rec {
pname = "osmid";
version = "0.6.8";
version = "0.8.0";
src = fetchFromGitHub {
owner = "llloret";
repo = "osmid";
rev = "v${version}";
sha256 = "1yl25abf343yvd49nfsgxsz7jf956zrsi5n4xyqb5ldlp2hifk15";
sha256 = "1s1wsrp6g6wb0y61xzxvaj59mwycrgy52r4h456086zkz10ls6hw";
};
nativeBuildInputs = [ cmake ];

View File

@ -2,11 +2,11 @@
mkDerivation rec {
pname = "padthv1";
version = "0.9.14";
version = "0.9.15";
src = fetchurl {
url = "mirror://sourceforge/padthv1/${pname}-${version}.tar.gz";
sha256 = "079iwwlkl1gscyv70v9ambad8shxbs0ixdfp0vsl6dbh87b09qzh";
sha256 = "18ma429kamifcvjmsv0hysxk7qn2r9br4fia929bvfccapck98y1";
};
buildInputs = [ libjack2 alsaLib libsndfile liblo lv2 qt5.qtbase qt5.qttools fftw ];

View File

@ -46,13 +46,13 @@ let
];
in stdenv.mkDerivation rec {
pname = "pulseeffects";
version = "4.7.2";
version = "4.7.3";
src = fetchFromGitHub {
owner = "wwmm";
repo = "pulseeffects";
rev = "v${version}";
sha256 = "1yga25da5bpg12zkikp6dn4wqhn9f7r10awvjzfcz8s6w9xlz6rx";
sha256 = "1xsw3v9vapd8q1dxacdgy2wk0xf3adqwbmcqiimdkd34llbdv88f";
};
nativeBuildInputs = [

View File

@ -3,12 +3,12 @@
, liblo, libsamplerate, libsndfile, lirc ? null, lrdf, qtbase }:
stdenv.mkDerivation (rec {
version = "19.12";
version = "20.06";
pname = "rosegarden";
src = fetchurl {
url = "mirror://sourceforge/rosegarden/${pname}-${version}.tar.bz2";
sha256 = "1qcaxc6hdzva7kwxxhgl95437fagjbxzv4mihsgpr7y9qk08ppw1";
sha256 = "1i9x9rkqwwdrk77xl5ra8i48cjirbc7fbisnj0nnclccwaq0wk6r";
};
patchPhase = ''

View File

@ -23,17 +23,17 @@
rustPlatform.buildRustPackage rec {
pname = "shortwave";
version = "1.0.1";
version = "1.1.1";
src = fetchFromGitLab {
domain = "gitlab.gnome.org";
owner = "World";
repo = "Shortwave";
rev = version;
sha256 = "13lhlh75vw02vkcknl4nvy0yvpdf0qx811mmyja8bzs4rj1j9kr8";
sha256 = "1vlhp2ss06j41simjrrjg38alp85jddhqyvccy6bhfzm0gzynwld";
};
cargoSha256 = "0aph5z54a6i5p8ga5ghhx1c9hjc8zdw5pkv9inmanca0bq3hkdlh";
cargoSha256 = "181699rlpr5dszc18wg0kbss3gfskxaz9lpxpgsc4yfb6ip89qnk";
nativeBuildInputs = [
cargo

View File

@ -1,30 +1,36 @@
{ stdenv, mkDerivation, fetchFromGitHub, pkgconfig, autoreconfHook, openssl, db53, boost
{ stdenv, mkDerivation, fetchFromGitHub, pkgconfig, cmake, openssl, db53, boost
, zlib, miniupnpc, qtbase ? null , qttools ? null, utillinux, protobuf, qrencode, libevent
, withGui }:
, withGui, python3, jemalloc, zeromq4 }:
with stdenv.lib;
mkDerivation rec {
name = "bitcoin" + (toString (optional (!withGui) "d")) + "-abc-" + version;
version = "0.21.5";
version = "0.21.10";
src = fetchFromGitHub {
owner = "bitcoin-ABC";
repo = "bitcoin-abc";
rev = "v${version}";
sha256 = "1jx33n8dhn16iaxvmc56cxw0i5qk0ga5nf7qf9frwwq6zkglknga";
sha256 = "1m210g6db8f09m66v75ia1fdd1dlvs1srgk2jhd3wqbvnmjqa77f";
};
patches = [ ./fix-bitcoin-qt-build.patch ];
nativeBuildInputs = [ pkgconfig autoreconfHook ];
buildInputs = [ openssl db53 boost zlib
nativeBuildInputs = [ pkgconfig cmake ];
buildInputs = [ openssl db53 boost zlib python3 jemalloc zeromq4
miniupnpc utillinux protobuf libevent ]
++ optionals withGui [ qtbase qttools qrencode ];
configureFlags = [ "--with-boost-libdir=${boost.out}/lib" ]
++ optionals withGui [ "--with-gui=qt5" ];
cmakeFlags = optionals (!withGui) [
"-DBUILD_BITCOIN_QT=OFF"
];
# many of the generated scripts lack execute permissions
postConfigure = ''
find ./. -type f -iname "*.sh" -exec chmod +x {} \;
'';
enableParallelBuilding = true;

View File

@ -2,12 +2,12 @@
let
pname = "ledger-live-desktop";
version = "2.6.0";
version = "2.8.0";
name = "${pname}-${version}";
src = fetchurl {
url = "https://github.com/LedgerHQ/${pname}/releases/download/v${version}/${pname}-${version}-linux-x86_64.AppImage";
sha256 = "0c58bx6fgykz0fl2yjbpbg6h5bv31zmjwgd1m3qi8afqryf52m5w";
sha256 = "1nj7fjbf99zpmq82kci6wp9nzml8ij1bz96zc77gwzsi0dacjrv5";
};
appimageContents = appimageTools.extractType2 {

View File

@ -12,13 +12,13 @@ with stdenv.lib;
stdenv.mkDerivation rec {
pname = "monero-gui";
version = "0.16.0.0";
version = "0.16.0.2";
src = fetchFromGitHub {
owner = "monero-project";
repo = "monero-gui";
rev = "v${version}";
sha256 = "06vdrsj5y9k0zn32hspyxc7sw1kkyrvi3chzkdbnxk9jvyj8k4ld";
sha256 = "1b1m8vhs0hdh81ysm8s8vfwqskqsihylb51wz16kc98ba40r9gqg";
};
nativeBuildInputs = [ qmake pkgconfig wrapQtAppsHook ];

View File

@ -1,5 +1,5 @@
{ fetchFromGitHub, stdenv, pkgconfig, autoreconfHook, wrapQtAppsHook ? null
, openssl_1_0_2, db48, boost, zlib, miniupnpc, gmp
, openssl, db48, boost, zlib, miniupnpc, gmp
, qrencode, glib, protobuf, yasm, libevent
, utillinux, qtbase ? null, qttools ? null
, enableUpnp ? false
@ -10,17 +10,17 @@
with stdenv.lib;
stdenv.mkDerivation rec {
name = "pivx-${version}";
version = "4.0.2";
version = "4.1.1";
src = fetchFromGitHub {
owner = "PIVX-Project";
repo= "PIVX";
rev = "v${version}";
sha256 = "12lnp318k8dx1sar24zfmv2imnzs30srssnlpb31y7hcxhz0wpc5";
sha256 = "03ndk46h6093v8s18d5iffz48zhlshq7jrk6vgpjfs6z2iqgd2sy";
};
nativeBuildInputs = [ pkgconfig autoreconfHook ] ++ optionals withGui [ wrapQtAppsHook ];
buildInputs = [ glib gmp openssl_1_0_2 db48 yasm boost zlib libevent miniupnpc protobuf utillinux ]
buildInputs = [ glib gmp openssl db48 yasm boost zlib libevent miniupnpc protobuf utillinux ]
++ optionals withGui [ qtbase qttools qrencode ];
configureFlags = [ "--with-boost-libdir=${boost.out}/lib" ]
@ -28,7 +28,6 @@ stdenv.mkDerivation rec {
++ optional disableWallet "--disable-wallet"
++ optional disableDaemon "--disable-daemon"
++ optionals withGui [ "--with-gui=yes"
"--with-unsupported-ssl" # TODO remove this ASAP
"--with-qt-bindir=${qtbase.dev}/bin:${qttools.dev}/bin"
];
@ -56,9 +55,5 @@ stdenv.mkDerivation rec {
homepage = "https://www.dash.org";
maintainers = with maintainers; [ wucke13 ];
platforms = platforms.unix;
# TODO
# upstream doesn't support newer openssl versions
# https://github.com/PIVX-Project/PIVX/issues/748
# openssl_1_0_2 should be replaced with openssl ASAP
};
}

View File

@ -40,11 +40,11 @@
stdenv.mkDerivation rec {
pname = "gnome-builder";
version = "3.36.0";
version = "3.36.1";
src = fetchurl {
url = "mirror://gnome/sources/${pname}/${stdenv.lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
sha256 = "02ni81jyncycgfwslvaav0a62wzx3r9bi86xf0x7jvvk6plfaj8v";
sha256 = "17pvmd5jypar8dkr6w56hvf7jnq4l1wih2wwgkrv7sblr7rkkar2";
};
nativeBuildInputs = [

View File

@ -2,16 +2,16 @@
rustPlatform.buildRustPackage rec {
pname = "gnvim-unwrapped";
version = "0.1.5";
version = "0.1.6";
src = fetchFromGitHub {
owner = "vhakulinen";
repo = "gnvim";
rev = version;
sha256 = "11gb59lhc1sp5dxj2fdm6072f4nxxay0war3kmchdwsk41nvxlrh";
rev = "v${version}";
sha256 = "1cc3yk04v9icdjr5cn58mqc3ba1wqmlzhf9ly7biy9m8yk30w9y0";
};
cargoSha256 = "0ay7hx5bzchp772ywgxzia12c44kbyarrshl689cmqh59wphsrx5";
cargoSha256 = "1fyn8nsabzrfl9ykf2gk2p8if0yjp6k0ybrmp0pw67pbwaxpb9ym";
buildInputs = [ gtk webkitgtk ];

View File

@ -2,7 +2,7 @@
, lib
, fetchurl
, makeWrapper
, electron_5
, electron_8
, dpkg
, gtk3
, glib
@ -14,11 +14,11 @@
stdenv.mkDerivation rec {
pname = "typora";
version = "0.9.73";
version = "0.9.89";
src = fetchurl {
url = "https://www.typora.io/linux/typora_${version}_amd64.deb";
sha256 = "1fgcb4bx5pw8ah5j30d38gw7qi1cmqarfhvgdns9f2n0d57bvvw3";
sha256 = "0gk8j13z1ymad34zzcy4vqwyjgd5khgyw5xjj9rbzm5v537kqmx6";
};
nativeBuildInputs = [
@ -33,7 +33,8 @@ stdenv.mkDerivation rec {
gtk3
];
unpackPhase = "dpkg-deb -x $src .";
# The deb contains setuid permission on `chrome-sandbox`, which will actually not get installed.
unpackPhase = "dpkg-deb --fsys-tarfile $src | tar -x --no-same-permissions --no-same-owner";
dontWrapGApps = true;
@ -51,7 +52,7 @@ stdenv.mkDerivation rec {
'';
postFixup = ''
makeWrapper ${electron_5}/bin/electron $out/bin/typora \
makeWrapper ${electron_8}/bin/electron $out/bin/typora \
--add-flags $out/share/typora \
"''${gappsWrapperArgs[@]}" \
${lib.optionalString withPandoc ''--prefix PATH : "${lib.makeBinPath [ pandoc ]}"''} \

View File

@ -1,5 +1,3 @@
# TODO tidy up eg The patchelf code is patching gvim even if you don't build it..
# but I have gvim with python support now :) - Marc
{ source ? "default", callPackage, stdenv, ncurses, pkgconfig, gettext
, writeText, config, glib, gtk2-x11, gtk3-x11, lua, python, perl, tcl, ruby
, libX11, libXext, libSM, libXpm, libXt, libXaw, libXau, libXmu
@ -156,7 +154,12 @@ in stdenv.mkDerivation rec {
'' + stdenv.lib.optionalString stdenv.isLinux ''
patchelf --set-rpath \
"$(patchelf --print-rpath $out/bin/vim):${stdenv.lib.makeLibraryPath buildInputs}" \
"$out"/bin/{vim,gvim}
"$out"/bin/vim
if [[ -e "$out"/bin/gvim ]]; then
patchelf --set-rpath \
"$(patchelf --print-rpath $out/bin/vim):${stdenv.lib.makeLibraryPath buildInputs}" \
"$out"/bin/gvim
fi
ln -sfn '${nixosRuntimepath}' "$out"/share/vim/vimrc
'' + stdenv.lib.optionalString wrapPythonDrv ''

View File

@ -11,11 +11,11 @@
stdenv.mkDerivation rec {
pname = "drawio";
version = "13.3.5";
version = "13.3.9";
src = fetchurl {
url = "https://github.com/jgraph/drawio-desktop/releases/download/v${version}/draw.io-x86_64-${version}.rpm";
sha256 = "16pds6sip90davrlrk17a7ms5nh1bs8js5i0hbci1l8gsfyx22i7";
sha256 = "1i1idjy80x6a0w40lziivyhg8nnlbpri7xdqxikxy982vffgihwp";
};
nativeBuildInputs = [

View File

@ -2,6 +2,7 @@
, lib
, fetchurl
, substituteAll
, autoreconfHook
, pkgconfig
, intltool
, babl
@ -28,9 +29,10 @@
, ghostscript
, aalib
, shared-mime-info
, python2Packages
, python2
, libexif
, gettext
, makeWrapper
, xorg
, glib-networking
, libmypaint
@ -47,7 +49,7 @@
}:
let
inherit (python2Packages) pygtk wrapPython python;
python = python2.withPackages (pp: [ pp.pygtk ]);
in stdenv.mkDerivation rec {
pname = "gimp";
version = "2.10.20";
@ -59,11 +61,25 @@ in stdenv.mkDerivation rec {
sha256 = "4S+fh0saAHxCd7YKqB4LZzML5+YVPldJ6tg5uQL8ezw=";
};
patches = [
# to remove compiler from the runtime closure, reference was retained via
# gimp --version --verbose output
(substituteAll {
src = ./remove-cc-reference.patch;
cc_version = stdenv.cc.cc.name;
})
# Use absolute paths instead of relying on PATH
# to make sure plug-ins are loaded by the correct interpreter.
./hardcode-plugin-interpreters.patch
];
nativeBuildInputs = [
autoreconfHook # hardcode-plugin-interpreters.patch changes Makefile.am
pkgconfig
intltool
gettext
wrapPython
makeWrapper
];
buildInputs = [
@ -97,7 +113,6 @@ in stdenv.mkDerivation rec {
libwebp
libheif
python
pygtk
libexif
xorg.libXpm
glib-networking
@ -116,8 +131,6 @@ in stdenv.mkDerivation rec {
gegl
];
pythonPath = [ pygtk ];
# Check if librsvg was built with --disable-pixbuf-loader.
PKG_CONFIG_GDK_PIXBUF_2_0_GDK_PIXBUF_MODULEDIR = "${librsvg}/${gdk-pixbuf.moduleDir}";
@ -126,19 +139,8 @@ in stdenv.mkDerivation rec {
export GIO_EXTRA_MODULES="${glib-networking}/lib/gio/modules:$GIO_EXTRA_MODULES"
'';
patches = [
# to remove compiler from the runtime closure, reference was retained via
# gimp --version --verbose output
(substituteAll {
src = ./remove-cc-reference.patch;
cc_version = stdenv.cc.cc.name;
})
];
postFixup = ''
wrapPythonProgramsIn $out/lib/gimp/${passthru.majorVersion}/plug-ins/
wrapProgram $out/bin/gimp-${lib.versions.majorMinor version} \
--prefix PYTHONPATH : "$PYTHONPATH" \
--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE"
'';

View File

@ -0,0 +1,11 @@
--- a/plug-ins/pygimp/Makefile.am
+++ b/plug-ins/pygimp/Makefile.am
@@ -157,7 +157,7 @@ install-interp-file:
echo 'python=$(PYBIN_PATH)' > '$(DESTDIR)$(pyinterpfile)'
echo 'python2=$(PYBIN_PATH)' >> '$(DESTDIR)$(pyinterpfile)'
echo '/usr/bin/python=$(PYBIN_PATH)' >> '$(DESTDIR)$(pyinterpfile)'
- echo ":Python:E::py::`basename $(PYTHON)`:" >> '$(DESTDIR)$(pyinterpfile)'
+ echo ":Python:E::py::$(PYTHON):" >> '$(DESTDIR)$(pyinterpfile)'
install-data-local: install-env-file install-interp-file

View File

@ -10,11 +10,11 @@ with stdenv.lib;
perlPackages.buildPerlPackage rec {
pname = "gscan2pdf";
version = "2.6.5";
version = "2.8.0";
src = fetchurl {
url = "mirror://sourceforge/gscan2pdf/${version}/${pname}-${version}.tar.xz";
sha256 = "0x8931i5zs4zl3iqjhlp7h8y6ssklxiqsddz5kh84nl3p0izbg0y";
sha256 = "0rqx41hkppil3lp1dhkxwlhv0kwp8w8fkgzlapryq1yd9pgkx6lw";
};
nativeBuildInputs = [ wrapGAppsHook ];
@ -64,6 +64,7 @@ perlPackages.buildPerlPackage rec {
# Add runtime dependencies
wrapProgram "$out/bin/gscan2pdf" \
--prefix PATH : "${sane-backends}/bin" \
--prefix PATH : "${imagemagick}/bin" \
--prefix PATH : "${libtiff}/bin" \
--prefix PATH : "${djvulibre}/bin" \

View File

@ -10,11 +10,11 @@
mkDerivation rec {
pname = "krita";
version = "4.2.9";
version = "4.3.0";
src = fetchurl {
url = "https://download.kde.org/stable/${pname}/${version}/${pname}-${version}.tar.xz";
sha256 = "0rvm9mpaq66lxyq4f09x9w6xxhgys0phza223hm5zv6kgn413xsf";
sha256 = "19qlpp9ds60bab73pwi64dq1zn4zn2hcdkrxhjr1j438mc4pflsd";
};
# *somtimes* fails with can't find ui_manager.h, also see https://github.com/NixOS/nixpkgs/issues/35359

View File

@ -19,13 +19,13 @@ assert withOpenCL -> ocl-icd != null;
mkDerivation rec {
pname = "mandelbulber";
version = "2.21";
version = "2.22";
src = fetchFromGitHub {
owner = "buddhi1980";
repo = "mandelbulber2";
rev = version;
sha256 = "1bmk71vbxc1n8cnizlmzfqlvgxjb95cydbzxlvq1s5givxr2jwli";
sha256 = "011y2nl0jakf29cxprjmj1ifqc9iva61q5f4kk47b03gq7jw8sl4";
};
nativeBuildInputs = [

View File

@ -2,7 +2,7 @@
, sane-backends, meson, ninja }:
stdenv.mkDerivation rec {
pname = "sane-airscan";
version = "0.99.3";
version = "0.99.8";
nativeBuildInputs = [ meson ninja pkg-config ];
buildInputs = [ avahi libsoup libjpeg libpng sane-backends ];
@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
owner = "alexpevzner";
repo = pname;
rev = version;
sha256 = "1sxp207vzjzi0ad5202n46acbha4dfmzcijl2v0b9j9lj4k42a8k";
sha256 = "0sdlnbzhnfn4i5mkqhc8zmjywbbjqkbnsiz2gpqhy6fypshryahz";
};
meta = with lib; {

View File

@ -1,5 +1,5 @@
{ stdenv
, pythonPackages
, python3Packages
, fetchurl
, gettext
, gobject-introspection
@ -9,15 +9,15 @@
, libnotify
}:
pythonPackages.buildPythonApplication rec {
python3Packages.buildPythonApplication rec {
pname = "bleachbit";
version = "3.2.0";
version = "4.0.0";
format = "other";
src = fetchurl {
url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.bz2";
sha256 = "1sszpn7ifiry0wwmkzdppzh61zvgrfypm9g7wk6q1ya20qhb5b51";
sha256 = "1dn3h6lr9ldbfpvgq9sdlk972sxhwalgj2f377qbqibm3yfxzpil";
};
nativeBuildInputs = [
@ -32,7 +32,7 @@ pythonPackages.buildPythonApplication rec {
libnotify
];
propagatedBuildInputs = with pythonPackages; [
propagatedBuildInputs = with python3Packages; [
chardet
pygobject3
requests
@ -51,6 +51,12 @@ pythonPackages.buildPythonApplication rec {
"prefix=${placeholder "out"}"
];
# prevent double wrapping from wrapGApps and wrapPythonProgram
dontWrapGApps = true;
makeWrapperArgs = [
''''${gappsWrapperArgs[@]}''
];
strictDeps = false;
meta = with stdenv.lib; {

View File

@ -0,0 +1,30 @@
{ stdenv, mkDerivation, fetchFromGitHub, cmake, pkgconfig, libchewing, qtbase
, qttools }:
mkDerivation rec {
pname = "chewing-editor";
version = "0.1.1";
src = fetchFromGitHub {
owner = "chewing";
repo = "${pname}";
rev = "${version}";
sha256 = "0kc2hjx1gplm3s3p1r5sn0cyxw3k1q4gyv08q9r6rs4sg7xh2w7w";
};
doCheck = true;
nativeBuildInputs = [ cmake pkgconfig ];
buildInputs = [ libchewing qtbase qttools ];
meta = with stdenv.lib; {
description = "Cross platform chewing user phrase editor";
longDescription = ''
chewing-editor is a cross platform chewing user phrase editor. It provides a easy way to manage user phrase. With it, user can customize their user phrase to increase input performance.
'';
homepage = "https://github.com/chewing/chewing-editor";
license = licenses.gpl2Plus;
maintainers = [ maintainers.ShamrockLee ];
platforms = platforms.all;
};
}

View File

@ -7,7 +7,7 @@
stdenv.mkDerivation rec {
pname = "dbeaver-ce";
version = "7.1.1";
version = "7.1.2";
desktopItem = makeDesktopItem {
name = "dbeaver";
@ -30,7 +30,7 @@ stdenv.mkDerivation rec {
src = fetchurl {
url = "https://dbeaver.io/files/${version}/dbeaver-ce-${version}-linux.gtk.x86_64.tar.gz";
sha256 = "11c9jvpjg72xkwnni4clwg3inig77s7jz3ik52gk52m6f09brxhs";
sha256 = "131v8y5la2pv3cqf2qknd816z24dvhf2c4f7js8vfzrfw5vwsqbq";
};
installPhase = ''

View File

@ -4,13 +4,13 @@
stdenv.mkDerivation rec {
pname = "dmenu-wayland-unstable";
version = "2020-04-03";
version = "2020-07-06";
src = fetchFromGitHub {
owner = "nyyManni";
repo = "dmenu-wayland";
rev = "550a7c39f3f925b803d51c616609c8cb6c0ea543";
sha256 = "0az3w1csn4x6mjyacg6lf70kykdfqamic3hbr57mj83i5jjv0jlv";
rev = "304c8e917651ee02b16ebf0b7097a5c53fa2236b";
sha256 = "0rkpmpk7xkcfbnv9vpg8n65423z5xpgp0hm2vg0rxf9354bjin7k";
};
outputs = [ "out" "man" ];

View File

@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
owner = "tud-zih-energy";
repo = "FIRESTARTER";
rev = "v${version}";
sha256 = "161mg0h1hvp6bxfjdhyfqrljvphys896mfd36254rbgzxm38ibi7";
sha256 = "0zqfqb7hf48z39g1qhbl1iraf8rz4d629h1q6ikizckpzfq23kd0";
};
nativeBuildInputs = [ python3 ];
@ -33,7 +33,7 @@ stdenv.mkDerivation rec {
homepage = "https://tu-dresden.de/zih/forschung/projekte/firestarter";
description = "Processor Stress Test Utility";
platforms = platforms.linux;
maintainers = with maintainers; [ astro ];
maintainers = with maintainers; [ astro marenz ];
license = licenses.gpl3;
};
}

View File

@ -0,0 +1,23 @@
{ stdenv, lib, fetchgit, pkg-config, meson, ninja, wayland, pixman, cairo, librsvg, wayland-protocols, wlroots, libxkbcommon, scdoc, git, tllist, fcft}:
stdenv.mkDerivation rec {
pname = "fuzzel";
version = "1.3.0";
src = fetchgit {
url = "https://codeberg.org/dnkl/fuzzel";
rev = "${version}";
sha256 = "12jv5iwmksygw8nfkxbd9rbi03wnpgb30hczq009aqgy7lyi5zmp";
};
nativeBuildInputs = [ pkg-config meson ninja scdoc git ];
buildInputs = [ wayland pixman cairo librsvg wayland-protocols wlroots libxkbcommon tllist fcft ];
meta = with lib; {
description = "Wayland-native application launcher, similar to rofis drun mode";
homepage = "https://codeberg.org/dnkl/fuzzel";
license = licenses.mit;
maintainers = with maintainers; [ fionera ];
platforms = with platforms; linux;
};
}

View File

@ -6,6 +6,7 @@
, qttools
, darwin
, asciidoctor
, curl
, glibcLocales
, libXi
@ -39,13 +40,13 @@ with stdenv.lib;
stdenv.mkDerivation rec {
pname = "keepassxc";
version = "2.5.4";
version = "2.6.0";
src = fetchFromGitHub {
owner = "keepassxreboot";
repo = "keepassxc";
rev = version;
sha256 = "1xih9q1pxszalc0l29fmjxwn1vrrrrbnhc8gmi8brw5sclhbs6bh";
sha256 = "0yi6kxnsrqirjn6hxhwym2krzf86qxf3kc6bfpkmiaggnd2kqpkp";
};
NIX_CFLAGS_COMPILE = stdenv.lib.optionalString stdenv.cc.isClang [
@ -63,11 +64,6 @@ stdenv.mkDerivation rec {
patches = [
./darwin.patch
# use wl-copy on Wayland - can be dropped with the next version update
(fetchpatch {
url = "https://github.com/keepassxreboot/keepassxc/commit/6128e5d58294f26411160f44da91087ebe7f4b07.patch";
sha256 = "16q0h7kijqjdbskmk4ar6p3g8vcxr0bq1zrlq2bk16pk10nv4bh1";
})
];
cmakeFlags = [
@ -97,6 +93,7 @@ stdenv.mkDerivation rec {
nativeBuildInputs = [ cmake wrapQtAppsHook qttools ];
buildInputs = [
asciidoctor
curl
glibcLocales
libXi

View File

@ -37,6 +37,7 @@
, wine
, fluidsynth
, xorgserver
, xorg
}:
let
@ -55,6 +56,8 @@ let
wine
fluidsynth
xorgserver
xorg.setxkbmap
xorg.xkbcomp
];
gstDeps = with gst_all_1; [

View File

@ -1,19 +1,25 @@
{ appimageTools, fetchurl, lib }:
{ appimageTools, fetchurl, lib, gsettings-desktop-schemas, gtk3 }:
let
pname = "marktext";
version = "v0.16.0-rc.2";
version = "v0.16.2";
in
appimageTools.wrapType2 rec {
name = "${pname}-${version}-binary";
src = fetchurl {
url = "https://github.com/marktext/marktext/releases/download/${version}/marktext-x86_64.AppImage";
sha256 = "1w1mxa1j94zr36xhvlhzq8d77pi359vdxqb2j8mnz2bib9khxk9k";
sha256 = "0ivf9lvv2jk7dvxmqprzcsxgya3617xmx5bppjvik44z14b5x8r7";
};
profile = ''
export LC_ALL=C.UTF-8
''
# Fixes file open dialog error
# GLib-GIO-ERROR **: 20:36:48.243: No GSettings schemas are installed on the system
# See https://github.com/NixOS/nixpkgs/pull/83701#issuecomment-608034097
+ ''
export XDG_DATA_DIRS=${gsettings-desktop-schemas}/share/gsettings-schemas/${gsettings-desktop-schemas.name}:${gtk3}/share/gsettings-schemas/${gtk3.name}:$XDG_DATA_DIRS
'';
multiPkgs = null; # no 32bit needed

View File

@ -5,13 +5,13 @@
mkDerivation rec {
pname = "megasync";
version = "4.3.0.8";
version = "4.3.1.0";
src = fetchFromGitHub {
owner = "meganz";
repo = "MEGAsync";
rev = "v${version}_Linux";
sha256 = "1rhxkc6j3039rcsi8cxy3n00g6w7acir82ymnksbpsnp4yxqv5r3";
sha256 = "0b68wpif8a0wf1vfn1nr19dmz8f31dprb27jpldxrxhyfslc43yj";
fetchSubmodules = true;
};

View File

@ -6,11 +6,11 @@ stdenv.mkDerivation rec {
name = "netsurf-${libname}-${version}";
libname = "libnsbmp";
version = "0.1.5";
version = "0.1.6";
src = fetchurl {
url = "http://download.netsurf-browser.org/libs/releases/${libname}-${version}-src.tar.gz";
sha256 = "0lib2m07d1i0k80m4blkwnj0g7rha4jbm5vrgd0wwbkyfa0hvk35";
sha256 = "0krjg69a2amxjsahdgm3wmy9ngnyr3gfs2a1zhdlbvb0z1jr7i3r";
};
nativeBuildInputs = [ pkgconfig ];

View File

@ -0,0 +1,68 @@
{ stdenv
, fetchFromGitHub
, fetchpatch
, vala
, meson
, ninja
, pkgconfig
, python3
, libgee
, gsettings-desktop-schemas
, gnome3
, pantheon
, wrapGAppsHook
, gtk3
, json-glib
, glib
, glib-networking
}:
stdenv.mkDerivation rec {
pname = "olifant";
version = "0.2.1-beta5";
src = fetchFromGitHub {
owner = "cleac";
repo = pname;
rev = version;
sha256 = "1fpyg3nii75vmsdhp8x4yvhi3npvp3xnbqmd0qcidn05mbsam68r";
};
nativeBuildInputs = [
meson
ninja
pkgconfig
python3
vala
wrapGAppsHook
];
buildInputs = [
glib
glib-networking
gnome3.libsoup
gsettings-desktop-schemas
gtk3
json-glib
libgee
pantheon.granite
];
postPatch = ''
chmod +x meson/post_install.py
patchShebangs meson/post_install.py
'';
passthru = {
updateScript = pantheon.updateScript {
attrPath = pname;
};
};
meta = with stdenv.lib; {
description = "A simple Mastodon client designed for elementary OS, originally developed by @bleakgrey";
homepage = "https://github.com/cleac/olifant";
license = licenses.gpl3;
maintainers = with maintainers; [ worldofpeace ];
};
}

Some files were not shown because too many files have changed in this diff Show More