Merge master into staging-next
This commit is contained in:
commit
ae8eee9c3f
|
@ -639,6 +639,12 @@
|
||||||
githubId = 1296771;
|
githubId = 1296771;
|
||||||
name = "Anders Riutta";
|
name = "Anders Riutta";
|
||||||
};
|
};
|
||||||
|
arnarg = {
|
||||||
|
email = "arnarg@fastmail.com";
|
||||||
|
github = "arnarg";
|
||||||
|
githubId = 1291396;
|
||||||
|
name = "Arnar Ingason";
|
||||||
|
};
|
||||||
arnoldfarkas = {
|
arnoldfarkas = {
|
||||||
email = "arnold.farkas@gmail.com";
|
email = "arnold.farkas@gmail.com";
|
||||||
github = "arnoldfarkas";
|
github = "arnoldfarkas";
|
||||||
|
@ -1031,6 +1037,12 @@
|
||||||
githubId = 5718007;
|
githubId = 5718007;
|
||||||
name = "Bastian Köcher";
|
name = "Bastian Köcher";
|
||||||
};
|
};
|
||||||
|
blaggacao = {
|
||||||
|
name = "David Arnold";
|
||||||
|
email = "dar@xoe.solutions";
|
||||||
|
github = "blaggacao";
|
||||||
|
githubId = 7548295;
|
||||||
|
};
|
||||||
blanky0230 = {
|
blanky0230 = {
|
||||||
email = "blanky0230@gmail.com";
|
email = "blanky0230@gmail.com";
|
||||||
github = "blanky0230";
|
github = "blanky0230";
|
||||||
|
@ -1049,6 +1061,12 @@
|
||||||
githubId = 16330;
|
githubId = 16330;
|
||||||
name = "Mathijs Kwik";
|
name = "Mathijs Kwik";
|
||||||
};
|
};
|
||||||
|
bmilanov = {
|
||||||
|
name = "Biser Milanov";
|
||||||
|
email = "bmilanov11+nixpkgs@gmail.com";
|
||||||
|
github = "bmilanov";
|
||||||
|
githubId = 30090366;
|
||||||
|
};
|
||||||
bobakker = {
|
bobakker = {
|
||||||
email = "bobakk3r@gmail.com";
|
email = "bobakk3r@gmail.com";
|
||||||
github = "bobakker";
|
github = "bobakker";
|
||||||
|
@ -1628,6 +1646,16 @@
|
||||||
githubId = 411324;
|
githubId = 411324;
|
||||||
name = "Carles Pagès";
|
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 = {
|
craigem = {
|
||||||
email = "craige@mcwhirter.io";
|
email = "craige@mcwhirter.io";
|
||||||
github = "craigem";
|
github = "craigem";
|
||||||
|
@ -1652,6 +1680,16 @@
|
||||||
githubId = 1222362;
|
githubId = 1222362;
|
||||||
name = "Matías Lang";
|
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 = {
|
cryptix = {
|
||||||
email = "cryptix@riseup.net";
|
email = "cryptix@riseup.net";
|
||||||
github = "cryptix";
|
github = "cryptix";
|
||||||
|
@ -1790,6 +1828,12 @@
|
||||||
githubId = 4971975;
|
githubId = 4971975;
|
||||||
name = "Janne Heß";
|
name = "Janne Heß";
|
||||||
};
|
};
|
||||||
|
"dasj19" = {
|
||||||
|
email = "daniel@serbanescu.dk";
|
||||||
|
github = "dasj19";
|
||||||
|
githubId = 7589338;
|
||||||
|
name = "Daniel Șerbănescu";
|
||||||
|
};
|
||||||
dasuxullebt = {
|
dasuxullebt = {
|
||||||
email = "christoph.senjak@googlemail.com";
|
email = "christoph.senjak@googlemail.com";
|
||||||
name = "Christoph-Simon Senjak";
|
name = "Christoph-Simon Senjak";
|
||||||
|
@ -2656,6 +2700,12 @@
|
||||||
fingerprint = "F549 3B7F 9372 5578 FDD3 D0B8 A1BC 8428 323E CFE8";
|
fingerprint = "F549 3B7F 9372 5578 FDD3 D0B8 A1BC 8428 323E CFE8";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
fionera = {
|
||||||
|
email = "nix@fionera.de";
|
||||||
|
github = "fionera";
|
||||||
|
githubId = 5741401;
|
||||||
|
name = "Tim Windelschmidt";
|
||||||
|
};
|
||||||
FireyFly = {
|
FireyFly = {
|
||||||
email = "nix@firefly.nu";
|
email = "nix@firefly.nu";
|
||||||
github = "FireyFly";
|
github = "FireyFly";
|
||||||
|
@ -6486,6 +6536,12 @@
|
||||||
githubId = 131856;
|
githubId = 131856;
|
||||||
name = "Arnout Engelen";
|
name = "Arnout Engelen";
|
||||||
};
|
};
|
||||||
|
RaghavSood = {
|
||||||
|
email = "r@raghavsood.com";
|
||||||
|
github = "RaghavSood";
|
||||||
|
githubId = 903072;
|
||||||
|
name = "Raghav Sood";
|
||||||
|
};
|
||||||
rafaelgg = {
|
rafaelgg = {
|
||||||
email = "rafael.garcia.gallego@gmail.com";
|
email = "rafael.garcia.gallego@gmail.com";
|
||||||
github = "rafaelgg";
|
github = "rafaelgg";
|
||||||
|
@ -7190,6 +7246,12 @@
|
||||||
githubId = 24496705;
|
githubId = 24496705;
|
||||||
name = "Scott Hamilton";
|
name = "Scott Hamilton";
|
||||||
};
|
};
|
||||||
|
ShamrockLee = {
|
||||||
|
name = "Shamrock Lee";
|
||||||
|
email = "44064051+ShamrockLee@users.noreply.github.com";
|
||||||
|
github = "ShamrockLee";
|
||||||
|
githubId = 44064051;
|
||||||
|
};
|
||||||
shanemikel = {
|
shanemikel = {
|
||||||
email = "shanepearlman@pm.me";
|
email = "shanepearlman@pm.me";
|
||||||
github = "shanemikel";
|
github = "shanemikel";
|
||||||
|
@ -8110,6 +8172,12 @@
|
||||||
githubId = 1486805;
|
githubId = 1486805;
|
||||||
name = "Toon Nolten";
|
name = "Toon Nolten";
|
||||||
};
|
};
|
||||||
|
toschmidt = {
|
||||||
|
email = "tobias.schmidt@in.tum.de";
|
||||||
|
github = "toschmidt";
|
||||||
|
githubId = 27586264;
|
||||||
|
name = "Tobias Schmidt";
|
||||||
|
};
|
||||||
travisbhartwell = {
|
travisbhartwell = {
|
||||||
email = "nafai@travishartwell.net";
|
email = "nafai@travishartwell.net";
|
||||||
github = "travisbhartwell";
|
github = "travisbhartwell";
|
||||||
|
@ -9025,4 +9093,10 @@
|
||||||
github = "saulecabrera";
|
github = "saulecabrera";
|
||||||
githubId = 1423601;
|
githubId = 1423601;
|
||||||
};
|
};
|
||||||
|
tfmoraes = {
|
||||||
|
name = "Thiago Franco de Moraes";
|
||||||
|
email = "351108+tfmoraes@users.noreply.github.com";
|
||||||
|
github = "tfmoraes";
|
||||||
|
githubId = 351108;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ with lib.maintainers; {
|
||||||
hedning
|
hedning
|
||||||
jtojnar
|
jtojnar
|
||||||
worldofpeace
|
worldofpeace
|
||||||
|
dasj19
|
||||||
];
|
];
|
||||||
scope = "Maintain GNOME desktop environment and platform.";
|
scope = "Maintain GNOME desktop environment and platform.";
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
This profile just enables a <systemitem class="username">demo</systemitem>
|
This profile just enables a <systemitem class="username">demo</systemitem>
|
||||||
user, with password <literal>demo</literal>, uid <literal>1000</literal>,
|
user, with password <literal>demo</literal>, uid <literal>1000</literal>,
|
||||||
<systemitem class="groupname">wheel</systemitem> group and
|
<systemitem class="groupname">wheel</systemitem> group and
|
||||||
<link linkend="opt-services.xserver.displayManager.sddm.autoLogin"> autologin
|
<link linkend="opt-services.xserver.displayManager.autoLogin">autologin in the SDDM display manager</link>.
|
||||||
in the SDDM display manager</link>.
|
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -90,10 +90,9 @@
|
||||||
using lightdm for a user <literal>alice</literal>:
|
using lightdm for a user <literal>alice</literal>:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
<xref linkend="opt-services.xserver.displayManager.lightdm.enable"/> = true;
|
<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.autoLogin.enable"/> = true;
|
||||||
<xref linkend="opt-services.xserver.displayManager.lightdm.autoLogin.user"/> = "alice";
|
<xref linkend="opt-services.xserver.displayManager.autoLogin.user"/> = "alice";
|
||||||
</programlisting>
|
</programlisting>
|
||||||
The options are named identically for all other display managers.
|
|
||||||
</para>
|
</para>
|
||||||
</simplesect>
|
</simplesect>
|
||||||
<simplesect xml:id="sec-x11--graphics-cards-intel">
|
<simplesect xml:id="sec-x11--graphics-cards-intel">
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Click on Settings / Display / Screen and select VBoxVGA as Graphics Controller
|
Click on Settings / Display / Screen and select VMSVGA as Graphics Controller
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -315,7 +315,7 @@
|
||||||
switch</command>), because the hardware and boot loader configuration in
|
switch</command>), because the hardware and boot loader configuration in
|
||||||
the VM are different. The boot loader is installed on an automatically
|
the VM are different. The boot loader is installed on an automatically
|
||||||
generated virtual disk containing a <filename>/boot</filename>
|
generated virtual disk containing a <filename>/boot</filename>
|
||||||
partition, which is mounted read-only in the VM.
|
partition.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -792,7 +792,7 @@ users.users.me =
|
||||||
The <option>services.xserver.displayManager.auto</option> module has been removed.
|
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
|
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.
|
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
|
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:
|
because it permitted root auto-login you can override the lightdm-autologin pam module like:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
|
|
|
@ -119,6 +119,11 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ];
|
||||||
feature is disabled by default.
|
feature is disabled by default.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</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>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -514,6 +519,12 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
automatically if <literal>stateVersion</literal> is 20.09 or higher.
|
automatically if <literal>stateVersion</literal> is 20.09 or higher.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</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>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -682,6 +693,12 @@ systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/www" ];
|
||||||
behaviour and keep the same VM state between different test runs.
|
behaviour and keep the same VM state between different test runs.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</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>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -181,6 +181,7 @@ let format' = format; in let
|
||||||
export NIX_STATE_DIR=$TMPDIR/state
|
export NIX_STATE_DIR=$TMPDIR/state
|
||||||
nix-store --load-db < ${closureInfo}/registration
|
nix-store --load-db < ${closureInfo}/registration
|
||||||
|
|
||||||
|
chmod 755 "$TMPDIR"
|
||||||
echo "running nixos-install..."
|
echo "running nixos-install..."
|
||||||
nixos-install --root $root --no-bootloader --no-root-passwd \
|
nixos-install --root $root --no-bootloader --no-root-passwd \
|
||||||
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
|
--system ${config.system.build.toplevel} --channel ${channelSources} --substituters ""
|
||||||
|
|
|
@ -22,6 +22,7 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
import traceback
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
CHAR_TO_KEY = {
|
CHAR_TO_KEY = {
|
||||||
|
@ -892,7 +893,8 @@ def run_tests() -> None:
|
||||||
try:
|
try:
|
||||||
exec(tests, globals())
|
exec(tests, globals())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
eprint("error: {}".format(str(e)))
|
eprint("error: ")
|
||||||
|
traceback.print_exc()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
ptpython.repl.embed(locals(), globals())
|
ptpython.repl.embed(locals(), globals())
|
||||||
|
|
|
@ -6,6 +6,16 @@ let
|
||||||
ids = config.ids;
|
ids = config.ids;
|
||||||
cfg = config.users;
|
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 = ''
|
passwordDescription = ''
|
||||||
The options <option>hashedPassword</option>,
|
The options <option>hashedPassword</option>,
|
||||||
<option>password</option> and <option>passwordFile</option>
|
<option>password</option> and <option>passwordFile</option>
|
||||||
|
@ -25,17 +35,19 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
hashedPasswordDescription = ''
|
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>.
|
package and run <literal>mkpasswd -m sha-512</literal>.
|
||||||
|
|
||||||
For password-less logins without password prompt, use
|
If set to an empty string (<literal>""</literal>), this user will
|
||||||
the empty string <literal>""</literal>.
|
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.<name?>.password</option>.
|
||||||
|
|
||||||
For logins with a fixed password (including the empty-string password with
|
If set to <literal>null</literal> (default) this user will not
|
||||||
prompt), use one of the un-hashed password options instead, such as
|
be able to log in using a password (i.e. via <command>login</command>
|
||||||
<option>users.users.<name?>.password</option>.
|
command).
|
||||||
|
|
||||||
Such unprotected logins should only be used for e.g. bootable live systems.
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
userOpts = { name, config, ... }: {
|
userOpts = { name, config, ... }: {
|
||||||
|
@ -415,6 +427,12 @@ in {
|
||||||
imports = [
|
imports = [
|
||||||
(mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ])
|
(mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ])
|
||||||
(mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ])
|
(mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ])
|
||||||
|
(mkChangedOptionModule
|
||||||
|
[ "security" "initialRootPassword" ]
|
||||||
|
[ "users" "users" "root" "initialHashedPassword" ]
|
||||||
|
(cfg: if cfg.security.initialHashedPassword == "!"
|
||||||
|
then null
|
||||||
|
else cfg.security.initialHashedPassword))
|
||||||
];
|
];
|
||||||
|
|
||||||
###### interface
|
###### 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";
|
home = "/root";
|
||||||
shell = mkDefault cfg.defaultUserShell;
|
shell = mkDefault cfg.defaultUserShell;
|
||||||
group = "root";
|
group = "root";
|
||||||
initialHashedPassword = mkDefault config.security.initialRootPassword;
|
|
||||||
};
|
};
|
||||||
nobody = {
|
nobody = {
|
||||||
uid = ids.uids.nobody;
|
uid = ids.uids.nobody;
|
||||||
|
@ -597,7 +606,7 @@ in {
|
||||||
|| cfg.group == "wheel"
|
|| cfg.group == "wheel"
|
||||||
|| elem "wheel" cfg.extraGroups)
|
|| elem "wheel" cfg.extraGroups)
|
||||||
&&
|
&&
|
||||||
((cfg.hashedPassword != null && cfg.hashedPassword != "!")
|
(allowsLogin cfg.hashedPassword
|
||||||
|| cfg.password != null
|
|| cfg.password != null
|
||||||
|| cfg.passwordFile != null
|
|| cfg.passwordFile != null
|
||||||
|| cfg.openssh.authorizedKeys.keys != []
|
|| cfg.openssh.authorizedKeys.keys != []
|
||||||
|
@ -607,7 +616,17 @@ in {
|
||||||
Neither the root account nor any wheel user has a password or SSH authorized key.
|
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.'';
|
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 =
|
warnings =
|
||||||
builtins.filter (x: x != null) (
|
builtins.filter (x: x != null) (
|
||||||
|
@ -630,14 +649,13 @@ in {
|
||||||
content = "${base64}${sep}${base64}";
|
content = "${base64}${sep}${base64}";
|
||||||
mcf = "^${sep}${scheme}${sep}${content}$";
|
mcf = "^${sep}${scheme}${sep}${content}$";
|
||||||
in
|
in
|
||||||
if (user.hashedPassword != null
|
if (allowsLogin user.hashedPassword
|
||||||
|
&& user.hashedPassword != "" # login without password
|
||||||
&& builtins.match mcf user.hashedPassword == null)
|
&& builtins.match mcf user.hashedPassword == null)
|
||||||
then
|
then ''
|
||||||
''
|
|
||||||
The password hash of user "${name}" may be invalid. You must set a
|
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
|
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
|
else null
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ in
|
||||||
# Without dconf enabled it is impossible to use IBus
|
# Without dconf enabled it is impossible to use IBus
|
||||||
programs.dconf.enable = true;
|
programs.dconf.enable = true;
|
||||||
|
|
||||||
programs.dconf.profiles.ibus = "${ibusPackage}/etc/dconf/profile/ibus";
|
programs.dconf.packages = [ ibusPackage ];
|
||||||
|
|
||||||
services.dbus.packages = [
|
services.dbus.packages = [
|
||||||
ibusAutostart
|
ibusAutostart
|
||||||
|
|
|
@ -11,15 +11,17 @@ with lib;
|
||||||
|
|
||||||
services.xserver.desktopManager.gnome3.enable = true;
|
services.xserver.desktopManager.gnome3.enable = true;
|
||||||
|
|
||||||
services.xserver.displayManager.gdm = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
gdm = {
|
||||||
# autoSuspend makes the machine automatically suspend after inactivity.
|
enable = true;
|
||||||
# It's possible someone could/try to ssh'd into the machine and obviously
|
# autoSuspend makes the machine automatically suspend after inactivity.
|
||||||
# have issues because it's inactive.
|
# It's possible someone could/try to ssh'd into the machine and obviously
|
||||||
# See:
|
# have issues because it's inactive.
|
||||||
# * https://github.com/NixOS/nixpkgs/pull/63790
|
# See:
|
||||||
# * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
|
# * https://github.com/NixOS/nixpkgs/pull/63790
|
||||||
autoSuspend = false;
|
# * https://gitlab.gnome.org/GNOME/gnome-control-center/issues/22
|
||||||
|
autoSuspend = false;
|
||||||
|
};
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "nixos";
|
user = "nixos";
|
||||||
|
|
|
@ -16,8 +16,8 @@ with lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
# Automatically login as nixos.
|
# Automatically login as nixos.
|
||||||
displayManager.sddm = {
|
displayManager = {
|
||||||
enable = true;
|
sddm.enable = true;
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "nixos";
|
user = "nixos";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
x86_64-linux = "/nix/store/j8dbv5w6jl34caywh2ygdy88knx1mdf7-nix-2.3.6";
|
x86_64-linux = "/nix/store/4vz8sh9ngx34ivi0bw5hlycxdhvy5hvz-nix-2.3.7";
|
||||||
i686-linux = "/nix/store/9fqvbdisahqp0238vrs7wn5anpri0a65-nix-2.3.6";
|
i686-linux = "/nix/store/dzxkg9lpp60bjmzvagns42vqlz3yq5kx-nix-2.3.7";
|
||||||
aarch64-linux = "/nix/store/72pwn0nm9bjqx9vpi8sgh4bl6g5wh814-nix-2.3.6";
|
aarch64-linux = "/nix/store/cfvf8nl8mwyw817by5y8zd3s8pnf5m9f-nix-2.3.7";
|
||||||
x86_64-darwin = "/nix/store/g37vk77m90p5zcl5nixjlzp3vqpisfn5-nix-2.3.6";
|
x86_64-darwin = "/nix/store/5ira7xgs92inqz1x8l0n1wci4r79hnd0-nix-2.3.7";
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,17 @@ if ! test -e "$mountPoint"; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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.
|
# Get the path of the NixOS configuration file.
|
||||||
if [[ -z $NIXOS_CONFIG ]]; then
|
if [[ -z $NIXOS_CONFIG ]]; then
|
||||||
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
|
NIXOS_CONFIG=$mountPoint/etc/nixos/configuration.nix
|
||||||
|
|
|
@ -607,6 +607,7 @@
|
||||||
./services/networking/dnscrypt-wrapper.nix
|
./services/networking/dnscrypt-wrapper.nix
|
||||||
./services/networking/dnsdist.nix
|
./services/networking/dnsdist.nix
|
||||||
./services/networking/dnsmasq.nix
|
./services/networking/dnsmasq.nix
|
||||||
|
./services/networking/ncdns.nix
|
||||||
./services/networking/ejabberd.nix
|
./services/networking/ejabberd.nix
|
||||||
./services/networking/epmd.nix
|
./services/networking/epmd.nix
|
||||||
./services/networking/ergo.nix
|
./services/networking/ergo.nix
|
||||||
|
@ -938,6 +939,7 @@
|
||||||
./system/boot/grow-partition.nix
|
./system/boot/grow-partition.nix
|
||||||
./system/boot/initrd-network.nix
|
./system/boot/initrd-network.nix
|
||||||
./system/boot/initrd-ssh.nix
|
./system/boot/initrd-ssh.nix
|
||||||
|
./system/boot/initrd-openvpn.nix
|
||||||
./system/boot/kernel.nix
|
./system/boot/kernel.nix
|
||||||
./system/boot/kexec.nix
|
./system/boot/kexec.nix
|
||||||
./system/boot/loader/efi.nix
|
./system/boot/loader/efi.nix
|
||||||
|
|
|
@ -11,9 +11,11 @@
|
||||||
uid = 1000;
|
uid = 1000;
|
||||||
};
|
};
|
||||||
|
|
||||||
services.xserver.displayManager.sddm.autoLogin = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
autoLogin = {
|
||||||
relogin = true;
|
enable = true;
|
||||||
user = "demo";
|
user = "demo";
|
||||||
|
};
|
||||||
|
sddm.autoLogin.relogin = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,24 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.programs.dconf;
|
cfg = config.programs.dconf;
|
||||||
|
cfgDir = pkgs.symlinkJoin {
|
||||||
mkDconfProfile = name: path:
|
name = "dconf-system-config";
|
||||||
{
|
paths = map (x: "${x}/etc/dconf") cfg.packages;
|
||||||
name = "dconf/profile/${name}";
|
postBuild = ''
|
||||||
value.source = path;
|
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
|
in
|
||||||
{
|
{
|
||||||
###### interface
|
###### interface
|
||||||
|
@ -22,18 +33,24 @@ in
|
||||||
profiles = mkOption {
|
profiles = mkOption {
|
||||||
type = types.attrsOf types.path;
|
type = types.attrsOf types.path;
|
||||||
default = {};
|
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;
|
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
|
###### implementation
|
||||||
|
|
||||||
config = mkIf (cfg.profiles != {} || cfg.enable) {
|
config = mkIf (cfg.profiles != {} || cfg.enable) {
|
||||||
environment.etc = optionalAttrs (cfg.profiles != {})
|
environment.etc.dconf = mkIf (cfg.profiles != {} || cfg.packages != []) {
|
||||||
(mapAttrs' mkDconfProfile cfg.profiles);
|
source = cfgDir;
|
||||||
|
};
|
||||||
|
|
||||||
services.dbus.packages = [ pkgs.dconf ];
|
services.dbus.packages = [ pkgs.dconf ];
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ with lib;
|
||||||
The services.xserver.displayManager.auto module has been removed
|
The services.xserver.displayManager.auto module has been removed
|
||||||
because it was only intended for use in internal NixOS tests, and gave the
|
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
|
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.
|
instead, or any other display manager in NixOS as they all support auto-login.
|
||||||
'')
|
'')
|
||||||
(mkRemovedOptionModule [ "services" "dnscrypt-proxy" ] "Use services.dnscrypt-proxy2 instead")
|
(mkRemovedOptionModule [ "services" "dnscrypt-proxy" ] "Use services.dnscrypt-proxy2 instead")
|
||||||
|
|
|
@ -302,6 +302,11 @@ in
|
||||||
lpath = "acme/${cert}";
|
lpath = "acme/${cert}";
|
||||||
apath = "/var/lib/${lpath}";
|
apath = "/var/lib/${lpath}";
|
||||||
spath = "/var/lib/acme/.lego/${cert}";
|
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";
|
fileMode = if data.allowKeysForGroup then "640" else "600";
|
||||||
globalOpts = [ "-d" data.domain "--email" data.email "--path" "." "--key-type" data.keyType ]
|
globalOpts = [ "-d" data.domain "--email" data.email "--path" "." "--key-type" data.keyType ]
|
||||||
++ optionals (cfg.acceptTerms) [ "--accept-tos" ]
|
++ optionals (cfg.acceptTerms) [ "--accept-tos" ]
|
||||||
|
@ -316,6 +321,7 @@ in
|
||||||
certOpts ++ data.extraLegoRenewFlags);
|
certOpts ++ data.extraLegoRenewFlags);
|
||||||
acmeService = {
|
acmeService = {
|
||||||
description = "Renew ACME Certificate for ${cert}";
|
description = "Renew ACME Certificate for ${cert}";
|
||||||
|
path = with pkgs; [ openssl ];
|
||||||
after = [ "network.target" "network-online.target" ];
|
after = [ "network.target" "network-online.target" ];
|
||||||
wants = [ "network-online.target" ];
|
wants = [ "network-online.target" ];
|
||||||
wantedBy = mkIf (!config.boot.isContainer) [ "multi-user.target" ];
|
wantedBy = mkIf (!config.boot.isContainer) [ "multi-user.target" ];
|
||||||
|
@ -332,11 +338,18 @@ in
|
||||||
ExecStart = pkgs.writeScript "acme-start" ''
|
ExecStart = pkgs.writeScript "acme-start" ''
|
||||||
#!${pkgs.runtimeShell} -e
|
#!${pkgs.runtimeShell} -e
|
||||||
test -L ${spath}/accounts -o -d ${spath}/accounts || ln -s ../accounts ${spath}/accounts
|
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 =
|
ExecStartPost =
|
||||||
let
|
let
|
||||||
keyName = builtins.replaceStrings ["*"] ["_"] data.domain;
|
|
||||||
script = pkgs.writeScript "acme-post-start" ''
|
script = pkgs.writeScript "acme-post-start" ''
|
||||||
#!${pkgs.runtimeShell} -e
|
#!${pkgs.runtimeShell} -e
|
||||||
cd ${apath}
|
cd ${apath}
|
||||||
|
|
|
@ -280,6 +280,17 @@ in
|
||||||
description = "Whether to enable smtp submission.";
|
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 {
|
submissionOptions = mkOption {
|
||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
default = {
|
default = {
|
||||||
|
@ -298,6 +309,29 @@ in
|
||||||
description = "Options for the submission config in master.cf";
|
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 {
|
setSendmail = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
@ -454,7 +488,7 @@ in
|
||||||
'';
|
'';
|
||||||
example = {
|
example = {
|
||||||
mail_owner = "postfix";
|
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 {
|
sslCert = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
description = "SSL certificate to use.";
|
description = "SSL certificate to use.";
|
||||||
};
|
};
|
||||||
|
|
||||||
sslCACert = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
description = "SSL certificate of CA.";
|
|
||||||
};
|
|
||||||
|
|
||||||
sslKey = mkOption {
|
sslKey = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
|
@ -771,18 +807,20 @@ in
|
||||||
recipient_canonical_classes = [ "envelope_recipient" ];
|
recipient_canonical_classes = [ "envelope_recipient" ];
|
||||||
}
|
}
|
||||||
// optionalAttrs cfg.enableHeaderChecks { header_checks = [ "regexp:/etc/postfix/header_checks" ]; }
|
// 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 != "") {
|
// optionalAttrs (cfg.sslCert != "") {
|
||||||
smtp_tls_CAfile = cfg.sslCACert;
|
|
||||||
smtp_tls_cert_file = cfg.sslCert;
|
smtp_tls_cert_file = cfg.sslCert;
|
||||||
smtp_tls_key_file = cfg.sslKey;
|
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_cert_file = cfg.sslCert;
|
||||||
smtpd_tls_key_file = cfg.sslKey;
|
smtpd_tls_key_file = cfg.sslKey;
|
||||||
|
|
||||||
smtpd_use_tls = true;
|
smtpd_tls_security_level = "may";
|
||||||
};
|
};
|
||||||
|
|
||||||
services.postfix.masterConfig = {
|
services.postfix.masterConfig = {
|
||||||
|
@ -878,6 +916,23 @@ in
|
||||||
command = "smtp";
|
command = "smtp";
|
||||||
args = [ "-o" "smtp_fallback_relay=" ];
|
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;
|
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.")
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
extraConfig = mkOption {
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
default = "";
|
default = "";
|
||||||
|
@ -115,7 +127,7 @@ in
|
||||||
$config = array();
|
$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['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['log_driver'] = 'syslog';
|
||||||
$config['max_message_size'] = '25M';
|
$config['max_message_size'] = '${cfg.maxAttachmentSize}';
|
||||||
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
$config['plugins'] = [${concatMapStringsSep "," (p: "'${p}'") cfg.plugins}];
|
||||||
$config['des_key'] = file_get_contents('/var/lib/roundcube/des_key');
|
$config['des_key'] = file_get_contents('/var/lib/roundcube/des_key');
|
||||||
$config['mime_types'] = '${pkgs.nginx}/conf/mime.types';
|
$config['mime_types'] = '${pkgs.nginx}/conf/mime.types';
|
||||||
|
@ -172,8 +184,8 @@ in
|
||||||
phpOptions = ''
|
phpOptions = ''
|
||||||
error_log = 'stderr'
|
error_log = 'stderr'
|
||||||
log_errors = on
|
log_errors = on
|
||||||
post_max_size = 25M
|
post_max_size = ${cfg.maxAttachmentSize}
|
||||||
upload_max_filesize = 25M
|
upload_max_filesize = ${cfg.maxAttachmentSize}
|
||||||
'';
|
'';
|
||||||
settings = mapAttrs (name: mkDefault) {
|
settings = mapAttrs (name: mkDefault) {
|
||||||
"listen.owner" = "nginx";
|
"listen.owner" = "nginx";
|
||||||
|
|
|
@ -193,50 +193,111 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
buildMachines = mkOption {
|
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 = [];
|
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 = ''
|
description = ''
|
||||||
This option lists the machines to be used if distributed
|
This option lists the machines to be used if distributed builds are
|
||||||
builds are enabled (see
|
enabled (see <option>nix.distributedBuilds</option>).
|
||||||
<option>nix.distributedBuilds</option>). Nix will perform
|
Nix will perform derivations on those machines via SSH by copying the
|
||||||
derivations on those machines via SSH by copying the inputs
|
inputs to the Nix store on the remote machine, starting the build,
|
||||||
to the Nix store on the remote machine, starting the build,
|
then copying the output back to the local Nix store.
|
||||||
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.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -461,14 +522,14 @@ in
|
||||||
{ enable = cfg.buildMachines != [];
|
{ enable = cfg.buildMachines != [];
|
||||||
text =
|
text =
|
||||||
concatMapStrings (machine:
|
concatMapStrings (machine:
|
||||||
"${if machine ? sshUser then "${machine.sshUser}@" else ""}${machine.hostName} "
|
"${if machine.sshUser != null then "${machine.sshUser}@" else ""}${machine.hostName} "
|
||||||
+ machine.system or (concatStringsSep "," machine.systems)
|
+ (if machine.system != null then machine.system else concatStringsSep "," machine.systems)
|
||||||
+ " ${machine.sshKey or "-"} ${toString machine.maxJobs or 1} "
|
+ " ${if machine.sshKey != null then machine.sshKey else "-"} ${toString machine.maxJobs} "
|
||||||
+ toString (machine.speedFactor or 1)
|
+ toString (machine.speedFactor)
|
||||||
+ " "
|
+ " "
|
||||||
+ concatStringsSep "," (machine.mandatoryFeatures or [] ++ machine.supportedFeatures or [])
|
+ concatStringsSep "," (machine.mandatoryFeatures ++ machine.supportedFeatures)
|
||||||
+ " "
|
+ " "
|
||||||
+ concatStringsSep "," machine.mandatoryFeatures or []
|
+ concatStringsSep "," machine.mandatoryFeatures
|
||||||
+ "\n"
|
+ "\n"
|
||||||
) cfg.buildMachines;
|
) cfg.buildMachines;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 ];
|
||||||
|
|
||||||
|
}
|
|
@ -122,7 +122,7 @@ in
|
||||||
ExecStart = ''
|
ExecStart = ''
|
||||||
${cfg.package}/bin/xandikos \
|
${cfg.package}/bin/xandikos \
|
||||||
--directory /var/lib/xandikos \
|
--directory /var/lib/xandikos \
|
||||||
--listen_address ${cfg.address} \
|
--listen-address ${cfg.address} \
|
||||||
--port ${toString cfg.port} \
|
--port ${toString cfg.port} \
|
||||||
--route-prefix ${cfg.routePrefix} \
|
--route-prefix ${cfg.routePrefix} \
|
||||||
${lib.concatStringsSep " " cfg.extraOptions}
|
${lib.concatStringsSep " " cfg.extraOptions}
|
||||||
|
|
|
@ -4,12 +4,21 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.nginx.sso;
|
cfg = config.services.nginx.sso;
|
||||||
pkg = getBin pkgs.nginx-sso;
|
pkg = getBin cfg.package;
|
||||||
configYml = pkgs.writeText "nginx-sso.yml" (builtins.toJSON cfg.configuration);
|
configYml = pkgs.writeText "nginx-sso.yml" (builtins.toJSON cfg.configuration);
|
||||||
in {
|
in {
|
||||||
options.services.nginx.sso = {
|
options.services.nginx.sso = {
|
||||||
enable = mkEnableOption "nginx-sso service";
|
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 {
|
configuration = mkOption {
|
||||||
type = types.attrsOf types.unspecified;
|
type = types.attrsOf types.unspecified;
|
||||||
default = {};
|
default = {};
|
||||||
|
|
|
@ -321,7 +321,7 @@ in
|
||||||
|
|
||||||
fonts.fonts = with pkgs; [ noto-fonts hack-font ];
|
fonts.fonts = with pkgs; [ noto-fonts hack-font ];
|
||||||
fonts.fontconfig.defaultFonts = {
|
fonts.fontconfig.defaultFonts = {
|
||||||
monospace = [ "Hack" "Noto Mono" ];
|
monospace = [ "Hack" "Noto Sans Mono" ];
|
||||||
sansSerif = [ "Noto Sans" ];
|
sansSerif = [ "Noto Sans" ];
|
||||||
serif = [ "Noto Serif" ];
|
serif = [ "Noto Serif" ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 = {
|
config = {
|
||||||
assertions = [
|
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;
|
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).";
|
message = "You cannot use both services.xserver.displayManager.defaultSession option and legacy options (services.xserver.desktopManager.default and services.xserver.windowManager.default).";
|
||||||
|
|
|
@ -37,6 +37,22 @@ let
|
||||||
in
|
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 = {
|
meta = {
|
||||||
maintainers = teams.gnome.members;
|
maintainers = teams.gnome.members;
|
||||||
|
@ -56,40 +72,13 @@ in
|
||||||
debugging messages in GDM
|
debugging messages in GDM
|
||||||
'';
|
'';
|
||||||
|
|
||||||
autoLogin = mkOption {
|
# Auto login options specific to GDM
|
||||||
default = {};
|
autoLogin.delay = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
description = ''
|
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 {
|
wayland = mkOption {
|
||||||
|
@ -128,12 +117,6 @@ in
|
||||||
|
|
||||||
config = mkIf cfg.gdm.enable {
|
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;
|
services.xserver.displayManager.lightdm.enable = false;
|
||||||
|
|
||||||
users.users.gdm =
|
users.users.gdm =
|
||||||
|
@ -287,14 +270,14 @@ in
|
||||||
environment.etc."gdm/custom.conf".text = ''
|
environment.etc."gdm/custom.conf".text = ''
|
||||||
[daemon]
|
[daemon]
|
||||||
WaylandEnable=${if cfg.gdm.wayland then "true" else "false"}
|
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 ''
|
if cfg.gdm.autoLogin.delay > 0 then ''
|
||||||
TimedLoginEnable=true
|
TimedLoginEnable=true
|
||||||
TimedLogin=${cfg.gdm.autoLogin.user}
|
TimedLogin=${cfg.autoLogin.user}
|
||||||
TimedLoginDelay=${toString cfg.gdm.autoLogin.delay}
|
TimedLoginDelay=${toString cfg.gdm.autoLogin.delay}
|
||||||
'' else ''
|
'' else ''
|
||||||
AutomaticLoginEnable=true
|
AutomaticLoginEnable=true
|
||||||
AutomaticLogin=${cfg.gdm.autoLogin.user}
|
AutomaticLogin=${cfg.autoLogin.user}
|
||||||
'')
|
'')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ in
|
||||||
services.xserver.displayManager.lightdm.extraSeatDefaults = "greeter-show-manual-login=true";
|
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."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";
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,8 @@ let
|
||||||
${optionalString cfg.greeter.enable ''
|
${optionalString cfg.greeter.enable ''
|
||||||
greeter-session = ${cfg.greeter.name}
|
greeter-session = ${cfg.greeter.name}
|
||||||
''}
|
''}
|
||||||
${optionalString cfg.autoLogin.enable ''
|
${optionalString dmcfg.autoLogin.enable ''
|
||||||
autologin-user = ${cfg.autoLogin.user}
|
autologin-user = ${dmcfg.autoLogin.user}
|
||||||
autologin-user-timeout = ${toString cfg.autoLogin.timeout}
|
autologin-user-timeout = ${toString cfg.autoLogin.timeout}
|
||||||
autologin-session = ${sessionData.autologinSession}
|
autologin-session = ${sessionData.autologinSession}
|
||||||
''}
|
''}
|
||||||
|
@ -82,6 +82,20 @@ in
|
||||||
./lightdm-greeters/enso-os.nix
|
./lightdm-greeters/enso-os.nix
|
||||||
./lightdm-greeters/pantheon.nix
|
./lightdm-greeters/pantheon.nix
|
||||||
./lightdm-greeters/tiny.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 = {
|
options = {
|
||||||
|
@ -149,39 +163,13 @@ in
|
||||||
description = "Extra lines to append to SeatDefaults section.";
|
description = "Extra lines to append to SeatDefaults section.";
|
||||||
};
|
};
|
||||||
|
|
||||||
autoLogin = mkOption {
|
# Configuration for automatic login specific to LightDM
|
||||||
default = {};
|
autoLogin.timeout = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 0;
|
||||||
description = ''
|
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
|
LightDM requires services.xserver.enable to be true
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
{ assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null;
|
{ assertion = dmcfg.autoLogin.enable -> sessionData.autologinSession != null;
|
||||||
message = ''
|
|
||||||
LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
{ assertion = cfg.autoLogin.enable -> sessionData.autologinSession != null;
|
|
||||||
message = ''
|
message = ''
|
||||||
LightDM auto-login requires that services.xserver.displayManager.defaultSession is set.
|
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 = ''
|
message = ''
|
||||||
LightDM can only run without greeter if automatic login is enabled and the timeout for it
|
LightDM can only run without greeter if automatic login is enabled and the timeout for it
|
||||||
is set to zero.
|
is set to zero.
|
||||||
|
@ -218,7 +201,7 @@ in
|
||||||
|
|
||||||
# Set default session in session chooser to a specified values – basically ignore session history.
|
# Set default session in session chooser to a specified values – basically ignore session history.
|
||||||
# Auto-login is already covered by a config value.
|
# 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}
|
${setSessionScript}/bin/set-session ${dmcfg.defaultSession}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
|
@ -61,9 +61,9 @@ let
|
||||||
EnableHidpi=${if cfg.enableHidpi then "true" else "false"}
|
EnableHidpi=${if cfg.enableHidpi then "true" else "false"}
|
||||||
SessionDir=${dmcfg.sessionData.desktops}/share/wayland-sessions
|
SessionDir=${dmcfg.sessionData.desktops}/share/wayland-sessions
|
||||||
|
|
||||||
${optionalString cfg.autoLogin.enable ''
|
${optionalString dmcfg.autoLogin.enable ''
|
||||||
[Autologin]
|
[Autologin]
|
||||||
User=${cfg.autoLogin.user}
|
User=${dmcfg.autoLogin.user}
|
||||||
Session=${autoLoginSessionName}.desktop
|
Session=${autoLoginSessionName}.desktop
|
||||||
Relogin=${boolToString cfg.autoLogin.relogin}
|
Relogin=${boolToString cfg.autoLogin.relogin}
|
||||||
''}
|
''}
|
||||||
|
@ -78,6 +78,20 @@ in
|
||||||
imports = [
|
imports = [
|
||||||
(mkRemovedOptionModule [ "services" "xserver" "displayManager" "sddm" "themes" ]
|
(mkRemovedOptionModule [ "services" "xserver" "displayManager" "sddm" "themes" ]
|
||||||
"Set the option `services.xserver.displayManager.sddm.package' instead.")
|
"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 = {
|
options = {
|
||||||
|
@ -153,40 +167,14 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
autoLogin = mkOption {
|
# Configuration for automatic login specific to SDDM
|
||||||
default = {};
|
autoLogin.relogin = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
description = ''
|
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
|
SDDM requires services.xserver.enable to be true
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
{ assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null;
|
{ assertion = dmcfg.autoLogin.enable -> autoLoginSessionName != null;
|
||||||
message = ''
|
|
||||||
SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
{ assertion = cfg.autoLogin.enable -> autoLoginSessionName != null;
|
|
||||||
message = ''
|
message = ''
|
||||||
SDDM auto-login requires that services.xserver.displayManager.defaultSession is set.
|
SDDM auto-login requires that services.xserver.displayManager.defaultSession is set.
|
||||||
'';
|
'';
|
||||||
|
|
|
@ -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 &
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ let
|
||||||
inherit (efi) canTouchEfiVariables;
|
inherit (efi) canTouchEfiVariables;
|
||||||
inherit (cfg)
|
inherit (cfg)
|
||||||
version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber
|
version extraConfig extraPerEntryConfig extraEntries forceInstall useOSProber
|
||||||
|
extraGrubInstallArgs
|
||||||
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels
|
extraEntriesBeforeNixOS extraPrepareConfig configurationLimit copyKernels
|
||||||
default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios gfxpayloadEfi gfxpayloadBios;
|
default fsIdentifier efiSupport efiInstallAsRemovable gfxmodeEfi gfxmodeBios gfxpayloadEfi gfxpayloadBios;
|
||||||
path = with pkgs; makeBinPath (
|
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 {
|
extraPerEntryConfig = mkOption {
|
||||||
default = "";
|
default = "";
|
||||||
example = "root (hd0)";
|
example = "root (hd0)";
|
||||||
|
@ -669,7 +697,7 @@ in
|
||||||
in pkgs.writeScript "install-grub.sh" (''
|
in pkgs.writeScript "install-grub.sh" (''
|
||||||
#!${pkgs.runtimeShell}
|
#!${pkgs.runtimeShell}
|
||||||
set -e
|
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"}
|
${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"}
|
||||||
'' + flip concatMapStrings cfg.mirroredBoots (args: ''
|
'' + flip concatMapStrings cfg.mirroredBoots (args: ''
|
||||||
${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@
|
${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@
|
||||||
|
|
|
@ -8,6 +8,7 @@ use File::stat;
|
||||||
use File::Copy;
|
use File::Copy;
|
||||||
use File::Slurp;
|
use File::Slurp;
|
||||||
use File::Temp;
|
use File::Temp;
|
||||||
|
use JSON;
|
||||||
require List::Compare;
|
require List::Compare;
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use Cwd;
|
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 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 {
|
sub readFile {
|
||||||
my ($fn) = @_; local $/ = undef;
|
my ($fn) = @_; local $/ = undef;
|
||||||
open FILE, "<$fn" or return undef; my $s = <FILE>; close FILE;
|
open FILE, "<$fn" or return undef; my $s = <FILE>; close FILE;
|
||||||
|
@ -241,7 +252,7 @@ if ($grubVersion == 1) {
|
||||||
timeout $timeout
|
timeout $timeout
|
||||||
";
|
";
|
||||||
if ($splashImage) {
|
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";
|
$conf .= "splashimage " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background.xpm.gz\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +330,7 @@ else {
|
||||||
";
|
";
|
||||||
|
|
||||||
if ($font) {
|
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 .= "
|
$conf .= "
|
||||||
insmod font
|
insmod font
|
||||||
if loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/converted-font.pf2; then
|
if loadfont " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/converted-font.pf2; then
|
||||||
|
@ -347,7 +358,7 @@ else {
|
||||||
background_color '$backgroundColor'
|
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 .= "
|
$conf .= "
|
||||||
insmod " . substr($suffix, 1) . "
|
insmod " . substr($suffix, 1) . "
|
||||||
if background_image --mode '$splashMode' " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/background$suffix; then
|
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.
|
# kernels or initrd if this script is ever interrupted.
|
||||||
if (! -e $dst) {
|
if (! -e $dst) {
|
||||||
my $tmp = "$dst.tmp";
|
my $tmp = "$dst.tmp";
|
||||||
copy $path, $tmp or die "cannot copy $path to $tmp\n";
|
copy $path, $tmp or die "cannot copy $path to $tmp: $!\n";
|
||||||
rename $tmp, $dst or die "cannot rename $tmp to $dst\n";
|
rename $tmp, $dst or die "cannot rename $tmp to $dst: $!\n";
|
||||||
}
|
}
|
||||||
$copied{$dst} = 1;
|
$copied{$dst} = 1;
|
||||||
return ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/kernels/$name";
|
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)
|
# Make sure initrd is not world readable (won't work if /boot is FAT)
|
||||||
umask 0137;
|
umask 0137;
|
||||||
my $initrdSecretsPathTemp = File::Temp::mktemp("$initrdSecretsPath.XXXXXXXX");
|
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
|
# Check whether any secrets were actually added
|
||||||
if (-e $initrdSecretsPathTemp && ! -z _) {
|
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;
|
$copied{$initrdSecretsPath} = 1;
|
||||||
$initrd .= " " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/kernels/$initrdName-secrets";
|
$initrd .= " " . ($grubBoot->path eq "/" ? "" : $grubBoot->path) . "/kernels/$initrdName-secrets";
|
||||||
} else {
|
} else {
|
||||||
|
@ -575,7 +586,7 @@ if (get("useOSProber") eq "true") {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Atomically switch to the new config
|
# 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.
|
# Remove obsolete files from $bootPath/kernels.
|
||||||
|
@ -596,9 +607,12 @@ struct(GrubState => {
|
||||||
efi => '$',
|
efi => '$',
|
||||||
devices => '$',
|
devices => '$',
|
||||||
efiMountPoint => '$',
|
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 {
|
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;
|
open FILE, "<$bootPath/grub/state" or return $defaultGrubState;
|
||||||
local $/ = "\n";
|
local $/ = "\n";
|
||||||
my $name = <FILE>;
|
my $name = <FILE>;
|
||||||
|
@ -611,24 +625,37 @@ sub readGrubState {
|
||||||
chomp($devices);
|
chomp($devices);
|
||||||
my $efiMountPoint = <FILE>;
|
my $efiMountPoint = <FILE>;
|
||||||
chomp($efiMountPoint);
|
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;
|
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
|
return $grubState
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getDeviceTargets {
|
my @deviceTargets = getList('devices');
|
||||||
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 $prevGrubState = readGrubState();
|
my $prevGrubState = readGrubState();
|
||||||
my @prevDeviceTargets = split/,/, $prevGrubState->devices;
|
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 $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 $nameDiffer = get("fullName") ne $prevGrubState->name;
|
||||||
my $versionDiffer = get("fullVersion") ne $prevGrubState->version;
|
my $versionDiffer = get("fullVersion") ne $prevGrubState->version;
|
||||||
my $efiDiffer = $efiTarget ne $prevGrubState->efi;
|
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";
|
warn "NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER";
|
||||||
$ENV{'NIXOS_INSTALL_BOOTLOADER'} = "1";
|
$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
|
# 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";
|
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";
|
symlink "$bootPath", "$tmpDir/boot" or die "Failed to symlink $tmpDir/boot: $!";
|
||||||
|
|
||||||
# install non-EFI GRUB
|
# install non-EFI GRUB
|
||||||
if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
|
if (($requireNewInstall != 0) && ($efiTarget eq "no" || $efiTarget eq "both")) {
|
||||||
foreach my $dev (@deviceTargets) {
|
foreach my $dev (@deviceTargets) {
|
||||||
next if $dev eq "nodev";
|
next if $dev eq "nodev";
|
||||||
print STDERR "installing the GRUB $grubVersion boot loader on $dev...\n";
|
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") {
|
if ($forceInstall eq "true") {
|
||||||
push @command, "--force";
|
push @command, "--force";
|
||||||
}
|
}
|
||||||
if ($grubTarget ne "") {
|
if ($grubTarget ne "") {
|
||||||
push @command, "--target=$grubTarget";
|
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
|
# install EFI GRUB
|
||||||
if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
|
if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both")) {
|
||||||
print STDERR "installing the GRUB $grubVersion EFI boot loader into $efiSysMountPoint...\n";
|
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") {
|
if ($forceInstall eq "true") {
|
||||||
push @command, "--force";
|
push @command, "--force";
|
||||||
}
|
}
|
||||||
|
@ -674,17 +701,29 @@ if (($requireNewInstall != 0) && ($efiTarget eq "only" || $efiTarget eq "both"))
|
||||||
push @command, "--removable" if $efiInstallAsRemovable eq "true";
|
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
|
# update GRUB state file
|
||||||
if ($requireNewInstall != 0) {
|
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("fullName"), "\n" or die;
|
||||||
print FILE get("fullVersion"), "\n" or die;
|
print FILE get("fullVersion"), "\n" or die;
|
||||||
print FILE $efiTarget, "\n" or die;
|
print FILE $efiTarget, "\n" or die;
|
||||||
print FILE join( ",", @deviceTargets ), "\n" or die;
|
print FILE join( ",", @deviceTargets ), "\n" or die;
|
||||||
print FILE $efiSysMountPoint, "\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;
|
close FILE or die;
|
||||||
|
|
||||||
|
# Atomically switch to the new state file
|
||||||
|
rename $stateFileTmp, $stateFile or die "cannot rename $stateFileTmp to $stateFile: $!\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ let
|
||||||
umount /crypt-ramfs 2>/dev/null
|
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
|
let
|
||||||
csopen = "cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} ${optionalString (header != null) "--header=${header}"}";
|
csopen = "cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} ${optionalString (header != null) "--header=${header}"}";
|
||||||
cschange = "cryptsetup luksChangeKey ${device} ${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 ''
|
${if (luks.yubikeySupport && (yubikey != null)) || (luks.gpgSupport && (gpgCard != null)) || (luks.fido2Support && (fido2.credential != null)) then ''
|
||||||
open_with_hardware
|
open_with_hardware
|
||||||
'' else ''
|
'' else ''
|
||||||
open_normally
|
open_normally
|
||||||
''}
|
''}
|
||||||
|
|
||||||
|
# commands to run right after we mounted our device
|
||||||
|
${postOpenCommands}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
askPass = pkgs.writeScriptBin "cryptsetup-askpass" ''
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,7 @@ with lib;
|
||||||
Any additional configuration to be appended to the generated
|
Any additional configuration to be appended to the generated
|
||||||
<filename>modprobe.conf</filename>. This is typically used to
|
<filename>modprobe.conf</filename>. This is typically used to
|
||||||
specify module options. See
|
specify module options. See
|
||||||
<citerefentry><refentrytitle>modprobe.conf</refentrytitle>
|
<citerefentry><refentrytitle>modprobe.d</refentrytitle>
|
||||||
<manvolnum>5</manvolnum></citerefentry> for details.
|
<manvolnum>5</manvolnum></citerefentry> for details.
|
||||||
'';
|
'';
|
||||||
type = types.lines;
|
type = types.lines;
|
||||||
|
|
|
@ -488,7 +488,7 @@ let
|
||||||
|
|
||||||
vlanConfig = mkOption {
|
vlanConfig = mkOption {
|
||||||
default = {};
|
default = {};
|
||||||
example = { Id = "4"; };
|
example = { Id = 4; };
|
||||||
type = types.addCheck (types.attrsOf unitOption) checkVlan;
|
type = types.addCheck (types.attrsOf unitOption) checkVlan;
|
||||||
description = ''
|
description = ''
|
||||||
Each attribute in this set specifies an option in the
|
Each attribute in this set specifies an option in the
|
||||||
|
|
|
@ -265,8 +265,8 @@ in {
|
||||||
restartIfChanged = false;
|
restartIfChanged = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.sockets.libvirtd .wantedBy = [ "sockets.target" ];
|
# https://libvirt.org/daemons.html#monolithic-systemd-integration
|
||||||
systemd.sockets.libvirtd-tcp.wantedBy = [ "sockets.target" ];
|
systemd.sockets.libvirtd.wantedBy = [ "sockets.target" ];
|
||||||
|
|
||||||
security.polkit.extraConfig = ''
|
security.polkit.extraConfig = ''
|
||||||
polkit.addRule(function(action, subject) {
|
polkit.addRule(function(action, subject) {
|
||||||
|
|
|
@ -81,6 +81,7 @@ let
|
||||||
|
|
||||||
drivesCmdLine = drives: concatStringsSep " " (imap1 driveCmdline drives);
|
drivesCmdLine = drives: concatStringsSep " " (imap1 driveCmdline drives);
|
||||||
|
|
||||||
|
|
||||||
# Creates a device name from a 1-based a numerical index, e.g.
|
# Creates a device name from a 1-based a numerical index, e.g.
|
||||||
# * `driveDeviceName 1` -> `/dev/vda`
|
# * `driveDeviceName 1` -> `/dev/vda`
|
||||||
# * `driveDeviceName 2` -> `/dev/vdb`
|
# * `driveDeviceName 2` -> `/dev/vdb`
|
||||||
|
@ -99,6 +100,13 @@ let
|
||||||
addDeviceNames =
|
addDeviceNames =
|
||||||
imap1 (idx: drive: drive // { device = driveDeviceName idx; });
|
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.
|
# Shell script to start the VM.
|
||||||
startVM =
|
startVM =
|
||||||
''
|
''
|
||||||
|
@ -124,10 +132,14 @@ let
|
||||||
# A writable boot disk can be booted from automatically.
|
# 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
|
${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 ''
|
${if cfg.useEFIBoot then ''
|
||||||
# VM needs a writable flash BIOS.
|
# VM needs writable EFI vars
|
||||||
cp ${bootDisk}/bios.bin $TMPDIR || exit 1
|
if ! test -e "$NIX_EFI_VARS"; then
|
||||||
chmod 0644 $TMPDIR/bios.bin || exit 1
|
cp ${bootDisk}/efi-vars.fd "$NIX_EFI_VARS" || exit 1
|
||||||
|
chmod 0644 "$NIX_EFI_VARS" || exit 1
|
||||||
|
fi
|
||||||
'' else ''
|
'' else ''
|
||||||
''}
|
''}
|
||||||
'' else ''
|
'' else ''
|
||||||
|
@ -164,6 +176,8 @@ let
|
||||||
|
|
||||||
# Generate a hard disk image containing a /boot partition and GRUB
|
# Generate a hard disk image containing a /boot partition and GRUB
|
||||||
# in the MBR. Used when the `useBootLoader' option is set.
|
# 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.
|
# FIXME: use nixos/lib/make-disk-image.nix.
|
||||||
bootDisk =
|
bootDisk =
|
||||||
pkgs.vmTools.runInLinuxVM (
|
pkgs.vmTools.runInLinuxVM (
|
||||||
|
@ -172,21 +186,22 @@ let
|
||||||
''
|
''
|
||||||
mkdir $out
|
mkdir $out
|
||||||
diskImage=$out/disk.img
|
diskImage=$out/disk.img
|
||||||
bootFlash=$out/bios.bin
|
${qemu}/bin/qemu-img create -f qcow2 $diskImage "60M"
|
||||||
${qemu}/bin/qemu-img create -f qcow2 $diskImage "40M"
|
|
||||||
${if cfg.useEFIBoot then ''
|
${if cfg.useEFIBoot then ''
|
||||||
cp ${pkgs.OVMF-CSM.fd}/FV/OVMF.fd $bootFlash
|
efiVars=$out/efi-vars.fd
|
||||||
chmod 0644 $bootFlash
|
cp ${efiVarsDefault} $efiVars
|
||||||
|
chmod 0644 $efiVars
|
||||||
'' else ''
|
'' else ''
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
buildInputs = [ pkgs.utillinux ];
|
buildInputs = [ pkgs.utillinux ];
|
||||||
QEMU_OPTS = if cfg.useEFIBoot
|
QEMU_OPTS = "-nographic -serial stdio -monitor none"
|
||||||
then "-pflash $out/bios.bin -nographic -serial pty"
|
+ lib.optionalString cfg.useEFIBoot (
|
||||||
else "-nographic -serial pty";
|
" -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 \
|
${pkgs.gptfdisk}/bin/sgdisk \
|
||||||
--set-alignment=1 --new=1:34:2047 --change-name=1:BIOSBootPartition --typecode=1:ef02 \
|
--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 \
|
--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 \
|
--partition-guid=2:970C694F-AFD0-4B99-B750-CDB7A329AB6F \
|
||||||
--hybrid 2 \
|
--hybrid 2 \
|
||||||
--recompute-chs /dev/vda
|
--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
|
${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda2
|
||||||
export MTOOLS_SKIP_CHECK=1
|
export MTOOLS_SKIP_CHECK=1
|
||||||
${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
|
${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
|
||||||
|
@ -210,6 +238,10 @@ let
|
||||||
mkdir /boot
|
mkdir /boot
|
||||||
mount /dev/vda2 /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.
|
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
|
||||||
mkdir /boot/grub
|
mkdir /boot/grub
|
||||||
echo '(hd0) /dev/vda' > /boot/grub/device.map
|
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 =
|
virtualisation.bios =
|
||||||
mkOption {
|
mkOption {
|
||||||
default = null;
|
default = null;
|
||||||
|
@ -483,7 +525,27 @@ in
|
||||||
|
|
||||||
config = {
|
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 =
|
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"''
|
''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"''
|
||||||
])
|
])
|
||||||
(mkIf cfg.useEFIBoot [
|
(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) [
|
(mkIf (cfg.bios != null) [
|
||||||
"-bios ${cfg.bios}/bios.bin"
|
"-bios ${cfg.bios}/bios.bin"
|
||||||
|
@ -574,6 +637,8 @@ in
|
||||||
driveExtraOpts.werror = "report";
|
driveExtraOpts.werror = "report";
|
||||||
}]
|
}]
|
||||||
(mkIf cfg.useBootLoader [
|
(mkIf cfg.useBootLoader [
|
||||||
|
# The order of this list determines the device names, see
|
||||||
|
# note [Disk layout with `useBootLoader`].
|
||||||
{
|
{
|
||||||
name = "boot";
|
name = "boot";
|
||||||
file = "$TMPDIR/disk.img";
|
file = "$TMPDIR/disk.img";
|
||||||
|
@ -628,9 +693,9 @@ in
|
||||||
};
|
};
|
||||||
} // optionalAttrs cfg.useBootLoader
|
} // optionalAttrs cfg.useBootLoader
|
||||||
{ "/boot" =
|
{ "/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";
|
fsType = "vfat";
|
||||||
options = [ "ro" ];
|
|
||||||
noCheck = true; # fsck fails on a r/o filesystem
|
noCheck = true; # fsck fails on a r/o filesystem
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -68,7 +68,7 @@ in
|
||||||
SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
|
SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
|
||||||
'';
|
'';
|
||||||
} (mkIf cfg.x11 {
|
} (mkIf cfg.x11 {
|
||||||
services.xserver.videoDrivers = mkOverride 50 [ "virtualbox" "modesetting" ];
|
services.xserver.videoDrivers = mkOverride 50 [ "vmware" "virtualbox" "modesetting" ];
|
||||||
|
|
||||||
services.xserver.config =
|
services.xserver.config =
|
||||||
''
|
''
|
||||||
|
|
|
@ -72,6 +72,7 @@ in {
|
||||||
audiocontroller = "ac97";
|
audiocontroller = "ac97";
|
||||||
audio = "alsa";
|
audio = "alsa";
|
||||||
audioout = "on";
|
audioout = "on";
|
||||||
|
graphicscontroller = "vmsvga";
|
||||||
rtcuseutc = "on";
|
rtcuseutc = "on";
|
||||||
usb = "on";
|
usb = "on";
|
||||||
usbehci = "on";
|
usbehci = "on";
|
||||||
|
|
|
@ -151,6 +151,7 @@ in
|
||||||
incron = handleTest ./incron.nix {};
|
incron = handleTest ./incron.nix {};
|
||||||
influxdb = handleTest ./influxdb.nix {};
|
influxdb = handleTest ./influxdb.nix {};
|
||||||
initrd-network-ssh = handleTest ./initrd-network-ssh {};
|
initrd-network-ssh = handleTest ./initrd-network-ssh {};
|
||||||
|
initrd-network-openvpn = handleTest ./initrd-network-openvpn {};
|
||||||
initrdNetwork = handleTest ./initrd-network.nix {};
|
initrdNetwork = handleTest ./initrd-network.nix {};
|
||||||
installer = handleTest ./installer.nix {};
|
installer = handleTest ./installer.nix {};
|
||||||
iodine = handleTest ./iodine.nix {};
|
iodine = handleTest ./iodine.nix {};
|
||||||
|
@ -220,6 +221,7 @@ in
|
||||||
nat.firewall = handleTest ./nat.nix { withFirewall = true; };
|
nat.firewall = handleTest ./nat.nix { withFirewall = true; };
|
||||||
nat.firewall-conntrack = handleTest ./nat.nix { withFirewall = true; withConntrackHelpers = true; };
|
nat.firewall-conntrack = handleTest ./nat.nix { withFirewall = true; withConntrackHelpers = true; };
|
||||||
nat.standalone = handleTest ./nat.nix { withFirewall = false; };
|
nat.standalone = handleTest ./nat.nix { withFirewall = false; };
|
||||||
|
ncdns = handleTest ./ncdns.nix {};
|
||||||
ndppd = handleTest ./ndppd.nix {};
|
ndppd = handleTest ./ndppd.nix {};
|
||||||
neo4j = handleTest ./neo4j.nix {};
|
neo4j = handleTest ./neo4j.nix {};
|
||||||
specialisation = handleTest ./specialisation.nix {};
|
specialisation = handleTest ./specialisation.nix {};
|
||||||
|
@ -266,7 +268,9 @@ in
|
||||||
php = handleTest ./php {};
|
php = handleTest ./php {};
|
||||||
plasma5 = handleTest ./plasma5.nix {};
|
plasma5 = handleTest ./plasma5.nix {};
|
||||||
plotinus = handleTest ./plotinus.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 {};
|
postgis = handleTest ./postgis.nix {};
|
||||||
postgresql = handleTest ./postgresql.nix {};
|
postgresql = handleTest ./postgresql.nix {};
|
||||||
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
|
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
|
||||||
|
@ -320,7 +324,7 @@ in
|
||||||
systemd = handleTest ./systemd.nix {};
|
systemd = handleTest ./systemd.nix {};
|
||||||
systemd-analyze = handleTest ./systemd-analyze.nix {};
|
systemd-analyze = handleTest ./systemd-analyze.nix {};
|
||||||
systemd-binfmt = handleTestOn ["x86_64-linux"] ./systemd-binfmt.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-confinement = handleTest ./systemd-confinement.nix {};
|
||||||
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
|
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
|
||||||
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};
|
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};
|
||||||
|
|
|
@ -41,8 +41,8 @@ in
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
services.xserver.displayManager.lightdm = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
lightdm.enable = true;
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
|
|
|
@ -90,13 +90,22 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
|
|
||||||
with subtest("Ensure Docker images can use an unstable date"):
|
with subtest("Ensure Docker images can use an unstable date"):
|
||||||
docker.succeed(
|
docker.succeed(
|
||||||
"docker load --input='${examples.bash}'"
|
"docker load --input='${examples.unstableDate}'"
|
||||||
)
|
)
|
||||||
assert unix_time_second1 not in docker.succeed(
|
assert unix_time_second1 not in docker.succeed(
|
||||||
"docker inspect ${examples.unstableDate.imageName} "
|
"docker inspect ${examples.unstableDate.imageName} "
|
||||||
+ "| ${pkgs.jq}/bin/jq -r .[].Created"
|
+ "| ${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"):
|
with subtest("Ensure Layered Docker images work"):
|
||||||
docker.succeed(
|
docker.succeed(
|
||||||
"docker load --input='${examples.layered-image}'",
|
"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.
|
# This check may be loosened to allow an *empty* store rather than *no* store.
|
||||||
docker.succeed("docker run --rm no-store-paths ls /")
|
docker.succeed("docker run --rm no-store-paths ls /")
|
||||||
docker.fail("docker run --rm no-store-paths ls /nix/store")
|
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'",
|
||||||
|
)
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|
|
@ -12,8 +12,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
|
||||||
|
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
|
|
||||||
services.xserver.displayManager.gdm = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
gdm.enable = true;
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = user.name;
|
user = user.name;
|
||||||
|
|
|
@ -11,8 +11,8 @@ import ./make-test-python.nix ({ pkgs, lib, ...} : {
|
||||||
|
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
|
|
||||||
services.xserver.displayManager.gdm = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
gdm.enable = true;
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "alice";
|
user = "alice";
|
||||||
|
|
|
@ -2,6 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
configDir = "/var/lib/foobar";
|
configDir = "/var/lib/foobar";
|
||||||
|
mqttUsername = "homeassistant";
|
||||||
mqttPassword = "secret";
|
mqttPassword = "secret";
|
||||||
in {
|
in {
|
||||||
name = "home-assistant";
|
name = "home-assistant";
|
||||||
|
@ -11,6 +12,15 @@ in {
|
||||||
|
|
||||||
nodes.hass = { pkgs, ... }: {
|
nodes.hass = { pkgs, ... }: {
|
||||||
environment.systemPackages = with pkgs; [ mosquitto ];
|
environment.systemPackages = with pkgs; [ mosquitto ];
|
||||||
|
services.mosquitto = {
|
||||||
|
enable = true;
|
||||||
|
users = {
|
||||||
|
"${mqttUsername}" = {
|
||||||
|
acl = [ "pattern readwrite #" ];
|
||||||
|
password = mqttPassword;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
services.home-assistant = {
|
services.home-assistant = {
|
||||||
inherit configDir;
|
inherit configDir;
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -23,8 +33,11 @@ in {
|
||||||
elevation = 0;
|
elevation = 0;
|
||||||
};
|
};
|
||||||
frontend = {};
|
frontend = {};
|
||||||
# uses embedded mqtt broker
|
mqtt = {
|
||||||
mqtt.password = mqttPassword;
|
broker = "127.0.0.1";
|
||||||
|
username = mqttUsername;
|
||||||
|
password = mqttPassword;
|
||||||
|
};
|
||||||
binary_sensor = [{
|
binary_sensor = [{
|
||||||
platform = "mqtt";
|
platform = "mqtt";
|
||||||
state_topic = "home-assistant/test";
|
state_topic = "home-assistant/test";
|
||||||
|
@ -64,10 +77,10 @@ in {
|
||||||
with subtest("Toggle a binary sensor using MQTT"):
|
with subtest("Toggle a binary sensor using MQTT"):
|
||||||
# wait for broker to become available
|
# wait for broker to become available
|
||||||
hass.wait_until_succeeds(
|
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(
|
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"):
|
with subtest("Print log to ease debugging"):
|
||||||
output_log = hass.succeed("cat ${configDir}/home-assistant.log")
|
output_log = hass.succeed("cat ${configDir}/home-assistant.log")
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
{ system ? builtins.currentSystem,
|
||||||
|
config ? {},
|
||||||
|
pkgs ? import ../.. { inherit system config; }
|
||||||
|
}:
|
||||||
|
|
||||||
let
|
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}";
|
name = "ihatemoney-${backend}";
|
||||||
machine = { lib, ... }: {
|
machine = { lib, ... }: {
|
||||||
services.ihatemoney = {
|
services.ihatemoney = {
|
||||||
|
@ -24,9 +30,10 @@ let
|
||||||
testScript = ''
|
testScript = ''
|
||||||
machine.wait_for_open_port(8000)
|
machine.wait_for_open_port(8000)
|
||||||
machine.wait_for_unit("uwsgi.service")
|
machine.wait_for_unit("uwsgi.service")
|
||||||
|
machine.wait_until_succeeds("curl http://localhost:8000")
|
||||||
|
|
||||||
assert '"yay"' in machine.succeed(
|
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(
|
owner, timestamp = machine.succeed(
|
||||||
"stat --printf %U:%G___%Y /var/lib/ihatemoney/secret_key"
|
"stat --printf %U:%G___%Y /var/lib/ihatemoney/secret_key"
|
||||||
|
@ -48,7 +55,7 @@ let
|
||||||
|
|
||||||
assert "ihatemoney" in machine.succeed("curl http://localhost:8000")
|
assert "ihatemoney" in machine.succeed("curl http://localhost:8000")
|
||||||
'';
|
'';
|
||||||
});
|
};
|
||||||
in {
|
in {
|
||||||
ihatemoney-sqlite = f "sqlite";
|
ihatemoney-sqlite = f "sqlite";
|
||||||
ihatemoney-postgresql = f "postgresql";
|
ihatemoney-postgresql = f "postgresql";
|
||||||
|
|
|
@ -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")
|
||||||
|
'';
|
||||||
|
})
|
|
@ -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>
|
|
@ -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-----
|
|
@ -5,16 +5,12 @@ makeInstalledTest {
|
||||||
|
|
||||||
testConfig = {
|
testConfig = {
|
||||||
i18n.inputMethod.enabled = "ibus";
|
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;
|
withX11 = true;
|
||||||
|
|
||||||
# TODO: ibus-daemon is currently crashing or something
|
|
||||||
# maybe make ibus systemd service that auto-restarts?
|
|
||||||
meta.broken = true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
'';
|
||||||
|
})
|
|
@ -14,7 +14,7 @@ import ./make-test-python.nix ({ pkgs, ...} :
|
||||||
services.xserver.displayManager.sddm.enable = true;
|
services.xserver.displayManager.sddm.enable = true;
|
||||||
services.xserver.displayManager.defaultSession = "plasma5";
|
services.xserver.displayManager.defaultSession = "plasma5";
|
||||||
services.xserver.desktopManager.plasma5.enable = true;
|
services.xserver.desktopManager.plasma5.enable = true;
|
||||||
services.xserver.displayManager.sddm.autoLogin = {
|
services.xserver.displayManager.autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "alice";
|
user = "alice";
|
||||||
};
|
};
|
||||||
|
|
|
@ -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")
|
||||||
|
'';
|
||||||
|
}
|
|
@ -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")
|
||||||
|
'';
|
||||||
|
}
|
|
@ -44,8 +44,8 @@ let
|
||||||
machine = { ... }: {
|
machine = { ... }: {
|
||||||
imports = [ ./common/user-account.nix ];
|
imports = [ ./common/user-account.nix ];
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
services.xserver.displayManager.sddm = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
sddm.enable = true;
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "alice";
|
user = "alice";
|
||||||
|
|
|
@ -1,16 +1,52 @@
|
||||||
import ./make-test-python.nix ({ lib, ... }:
|
import ./make-test-python.nix ({ lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
mungekey = "mungeverryweakkeybuteasytointegratoinatest";
|
|
||||||
|
|
||||||
slurmconfig = {
|
slurmconfig = {
|
||||||
controlMachine = "control";
|
services.slurm = {
|
||||||
nodeName = [ "node[1-3] CPUs=1 State=UNKNOWN" ];
|
controlMachine = "control";
|
||||||
partitionName = [ "debug Nodes=node[1-3] Default=YES MaxTime=INFINITE State=UP" ];
|
nodeName = [ "node[1-3] CPUs=1 State=UNKNOWN" ];
|
||||||
extraConfig = ''
|
partitionName = [ "debug Nodes=node[1-3] Default=YES MaxTime=INFINITE State=UP" ];
|
||||||
AccountingStorageHost=dbd
|
extraConfig = ''
|
||||||
AccountingStorageType=accounting_storage/slurmdbd
|
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 {
|
in {
|
||||||
name = "slurm";
|
name = "slurm";
|
||||||
|
|
||||||
|
@ -21,37 +57,40 @@ in {
|
||||||
computeNode =
|
computeNode =
|
||||||
{ ...}:
|
{ ...}:
|
||||||
{
|
{
|
||||||
|
imports = [ slurmconfig ];
|
||||||
# TODO slurmd port and slurmctld port should be configurations and
|
# TODO slurmd port and slurmctld port should be configurations and
|
||||||
# automatically allowed by the firewall.
|
# automatically allowed by the firewall.
|
||||||
networking.firewall.enable = false;
|
|
||||||
services.slurm = {
|
services.slurm = {
|
||||||
client.enable = true;
|
client.enable = true;
|
||||||
} // slurmconfig;
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
|
||||||
control =
|
control =
|
||||||
{ ...}:
|
{ ...}:
|
||||||
{
|
{
|
||||||
networking.firewall.enable = false;
|
imports = [ slurmconfig ];
|
||||||
services.slurm = {
|
services.slurm = {
|
||||||
server.enable = true;
|
server.enable = true;
|
||||||
} // slurmconfig;
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
submit =
|
submit =
|
||||||
{ ...}:
|
{ ...}:
|
||||||
{
|
{
|
||||||
networking.firewall.enable = false;
|
imports = [ slurmconfig ];
|
||||||
services.slurm = {
|
services.slurm = {
|
||||||
enableStools = true;
|
enableStools = true;
|
||||||
} // slurmconfig;
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
dbd =
|
dbd =
|
||||||
{ pkgs, ... } :
|
{ pkgs, ... } :
|
||||||
{
|
{
|
||||||
networking.firewall.enable = false;
|
networking.firewall.enable = false;
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"f /etc/munge/munge.key 0400 munge munge - mungeverryweakkeybuteasytointegratoinatest"
|
||||||
|
];
|
||||||
services.slurm.dbdserver = {
|
services.slurm.dbdserver = {
|
||||||
enable = true;
|
enable = true;
|
||||||
storagePass = "password123";
|
storagePass = "password123";
|
||||||
|
@ -87,24 +126,7 @@ in {
|
||||||
''
|
''
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
# Set up authentification across the cluster
|
# Make sure DBD is up after DB initialzation
|
||||||
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
|
|
||||||
with subtest("can_start_slurmdbd"):
|
with subtest("can_start_slurmdbd"):
|
||||||
dbd.succeed("systemctl restart slurmdbd")
|
dbd.succeed("systemctl restart slurmdbd")
|
||||||
dbd.wait_for_unit("slurmdbd.service")
|
dbd.wait_for_unit("slurmdbd.service")
|
||||||
|
@ -137,5 +159,8 @@ in {
|
||||||
# find the srun job from above in the database
|
# find the srun job from above in the database
|
||||||
control.succeed("sleep 5")
|
control.succeed("sleep 5")
|
||||||
control.succeed("sacct | grep hostname")
|
control.succeed("sacct | grep hostname")
|
||||||
|
|
||||||
|
with subtest("run_PMIx_mpitest"):
|
||||||
|
submit.succeed("srun -N 3 --mpi=pmix mpitest | grep size=3")
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
|
|
@ -11,6 +11,8 @@ let
|
||||||
virtualisation.useBootLoader = true;
|
virtualisation.useBootLoader = true;
|
||||||
virtualisation.useEFIBoot = true;
|
virtualisation.useEFIBoot = true;
|
||||||
boot.loader.systemd-boot.enable = true;
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
environment.systemPackages = [ pkgs.efibootmgr ];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
@ -31,6 +33,36 @@ in
|
||||||
machine.succeed(
|
machine.succeed(
|
||||||
"test -e /sys/firmware/efi/efivars/LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
|
"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"')
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ import ./make-test-python.nix (
|
||||||
services.xandikos.enable = true;
|
services.xandikos.enable = true;
|
||||||
services.xandikos.address = "localhost";
|
services.xandikos.address = "localhost";
|
||||||
services.xandikos.port = 8080;
|
services.xandikos.port = 8080;
|
||||||
services.xandikos.routePrefix = "/xandikos/";
|
services.xandikos.routePrefix = "/xandikos-prefix/";
|
||||||
services.xandikos.extraOptions = [
|
services.xandikos.extraOptions = [
|
||||||
"--defaults"
|
"--defaults"
|
||||||
];
|
];
|
||||||
|
@ -28,7 +28,7 @@ import ./make-test-python.nix (
|
||||||
serverName = "xandikos.local";
|
serverName = "xandikos.local";
|
||||||
basicAuth.xandikos = "snakeOilPassword";
|
basicAuth.xandikos = "snakeOilPassword";
|
||||||
locations."/xandikos/" = {
|
locations."/xandikos/" = {
|
||||||
proxyPass = "http://localhost:8080/";
|
proxyPass = "http://localhost:8080/xandikos-prefix/";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,8 +11,8 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||||
|
|
||||||
services.xserver.enable = true;
|
services.xserver.enable = true;
|
||||||
|
|
||||||
services.xserver.displayManager.lightdm = {
|
services.xserver.displayManager = {
|
||||||
enable = true;
|
lightdm.enable = true;
|
||||||
autoLogin = {
|
autoLogin = {
|
||||||
enable = true;
|
enable = true;
|
||||||
user = "alice";
|
user = "alice";
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "drumkv1";
|
pname = "drumkv1";
|
||||||
version = "0.9.14";
|
version = "0.9.15";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://sourceforge/drumkv1/${pname}-${version}.tar.gz";
|
url = "mirror://sourceforge/drumkv1/${pname}-${version}.tar.gz";
|
||||||
sha256 = "0fr7pkp55zvjxf7p22drs93fsjgvqhbd55vxi0srhp2s2wzz5qak";
|
sha256 = "108jk8p1sbm99plipf98ssij6dxaip1lmznibg8y2c4x0v2la6ab";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = [ libjack2 alsaLib libsndfile liblo lv2 qt5.qtbase qt5.qttools ];
|
buildInputs = [ libjack2 alsaLib libsndfile liblo lv2 qt5.qtbase qt5.qttools ];
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "GxPlugins.lv2";
|
pname = "GxPlugins.lv2";
|
||||||
version = "0.7";
|
version = "0.8";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "brummer10";
|
owner = "brummer10";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "0jqdqnkg7pg9plcbxy49p7gcs1aj6h0xf7y9gndmjmkw5yjn2940";
|
sha256 = "11iv7bwvvspm74pisqvcpsxpg9xi6b08hq4i8q67mri4mvy9hmal";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "jamulus";
|
pname = "jamulus";
|
||||||
version = "3.5.6";
|
version = "3.5.8";
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "corrados";
|
owner = "corrados";
|
||||||
repo = "jamulus";
|
repo = "jamulus";
|
||||||
rev = "r${stdenv.lib.replaceStrings [ "." ] [ "_" ] version}";
|
rev = "r${stdenv.lib.replaceStrings [ "." ] [ "_" ] version}";
|
||||||
sha256 = "00vd6kffsf3vqfwaxjvln63x3n0q32f385qc51fn5iyj54410x0f";
|
sha256 = "0mkrlfaw85pxlacrxfhb45731i4jnn67v411lzx5kb42ncar1586";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ pkg-config qmake ];
|
nativeBuildInputs = [ pkg-config qmake ];
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
python3.pkgs.buildPythonApplication rec {
|
python3.pkgs.buildPythonApplication rec {
|
||||||
pname = "lollypop";
|
pname = "lollypop";
|
||||||
version = "1.2.35";
|
version = "1.3.2";
|
||||||
|
|
||||||
format = "other";
|
format = "other";
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
@ -32,7 +32,7 @@ python3.pkgs.buildPythonApplication rec {
|
||||||
url = "https://gitlab.gnome.org/World/lollypop";
|
url = "https://gitlab.gnome.org/World/lollypop";
|
||||||
rev = "refs/tags/${version}";
|
rev = "refs/tags/${version}";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
sha256 = "19nw9qh17yyi9ih1nwngbbwjx1vr26haqhmzsdqf0yjgsgf9vldx";
|
sha256 = "14854j1dhq67s1vzs0lqy345vbl6f5w8nb36n4i33fmpva2flsk3";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
python3Packages.buildPythonApplication rec {
|
python3Packages.buildPythonApplication rec {
|
||||||
pname = "Mopidy-Iris";
|
pname = "Mopidy-Iris";
|
||||||
version = "3.49.0";
|
version = "3.50.0";
|
||||||
|
|
||||||
src = python3Packages.fetchPypi {
|
src = python3Packages.fetchPypi {
|
||||||
inherit pname version;
|
inherit pname version;
|
||||||
sha256 = "0zddm7286iwx437gjz47m4g28s8gdcxnm2hmly9w1dzi08aa4fas";
|
sha256 = "04miwf0dqb8jir9g7xkfnn3l62bdn74ap03kqzz2v3byg64f1p0g";
|
||||||
};
|
};
|
||||||
|
|
||||||
propagatedBuildInputs = [
|
propagatedBuildInputs = [
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "osmid";
|
pname = "osmid";
|
||||||
version = "0.6.8";
|
version = "0.8.0";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "llloret";
|
owner = "llloret";
|
||||||
repo = "osmid";
|
repo = "osmid";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "1yl25abf343yvd49nfsgxsz7jf956zrsi5n4xyqb5ldlp2hifk15";
|
sha256 = "1s1wsrp6g6wb0y61xzxvaj59mwycrgy52r4h456086zkz10ls6hw";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ cmake ];
|
nativeBuildInputs = [ cmake ];
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "padthv1";
|
pname = "padthv1";
|
||||||
version = "0.9.14";
|
version = "0.9.15";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://sourceforge/padthv1/${pname}-${version}.tar.gz";
|
url = "mirror://sourceforge/padthv1/${pname}-${version}.tar.gz";
|
||||||
sha256 = "079iwwlkl1gscyv70v9ambad8shxbs0ixdfp0vsl6dbh87b09qzh";
|
sha256 = "18ma429kamifcvjmsv0hysxk7qn2r9br4fia929bvfccapck98y1";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = [ libjack2 alsaLib libsndfile liblo lv2 qt5.qtbase qt5.qttools fftw ];
|
buildInputs = [ libjack2 alsaLib libsndfile liblo lv2 qt5.qtbase qt5.qttools fftw ];
|
||||||
|
|
|
@ -46,13 +46,13 @@ let
|
||||||
];
|
];
|
||||||
in stdenv.mkDerivation rec {
|
in stdenv.mkDerivation rec {
|
||||||
pname = "pulseeffects";
|
pname = "pulseeffects";
|
||||||
version = "4.7.2";
|
version = "4.7.3";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "wwmm";
|
owner = "wwmm";
|
||||||
repo = "pulseeffects";
|
repo = "pulseeffects";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "1yga25da5bpg12zkikp6dn4wqhn9f7r10awvjzfcz8s6w9xlz6rx";
|
sha256 = "1xsw3v9vapd8q1dxacdgy2wk0xf3adqwbmcqiimdkd34llbdv88f";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
, liblo, libsamplerate, libsndfile, lirc ? null, lrdf, qtbase }:
|
, liblo, libsamplerate, libsndfile, lirc ? null, lrdf, qtbase }:
|
||||||
|
|
||||||
stdenv.mkDerivation (rec {
|
stdenv.mkDerivation (rec {
|
||||||
version = "19.12";
|
version = "20.06";
|
||||||
pname = "rosegarden";
|
pname = "rosegarden";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://sourceforge/rosegarden/${pname}-${version}.tar.bz2";
|
url = "mirror://sourceforge/rosegarden/${pname}-${version}.tar.bz2";
|
||||||
sha256 = "1qcaxc6hdzva7kwxxhgl95437fagjbxzv4mihsgpr7y9qk08ppw1";
|
sha256 = "1i9x9rkqwwdrk77xl5ra8i48cjirbc7fbisnj0nnclccwaq0wk6r";
|
||||||
};
|
};
|
||||||
|
|
||||||
patchPhase = ''
|
patchPhase = ''
|
||||||
|
|
|
@ -23,17 +23,17 @@
|
||||||
|
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
pname = "shortwave";
|
pname = "shortwave";
|
||||||
version = "1.0.1";
|
version = "1.1.1";
|
||||||
|
|
||||||
src = fetchFromGitLab {
|
src = fetchFromGitLab {
|
||||||
domain = "gitlab.gnome.org";
|
domain = "gitlab.gnome.org";
|
||||||
owner = "World";
|
owner = "World";
|
||||||
repo = "Shortwave";
|
repo = "Shortwave";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "13lhlh75vw02vkcknl4nvy0yvpdf0qx811mmyja8bzs4rj1j9kr8";
|
sha256 = "1vlhp2ss06j41simjrrjg38alp85jddhqyvccy6bhfzm0gzynwld";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoSha256 = "0aph5z54a6i5p8ga5ghhx1c9hjc8zdw5pkv9inmanca0bq3hkdlh";
|
cargoSha256 = "181699rlpr5dszc18wg0kbss3gfskxaz9lpxpgsc4yfb6ip89qnk";
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
cargo
|
cargo
|
||||||
|
|
|
@ -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
|
, zlib, miniupnpc, qtbase ? null , qttools ? null, utillinux, protobuf, qrencode, libevent
|
||||||
, withGui }:
|
, withGui, python3, jemalloc, zeromq4 }:
|
||||||
|
|
||||||
with stdenv.lib;
|
with stdenv.lib;
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
|
|
||||||
name = "bitcoin" + (toString (optional (!withGui) "d")) + "-abc-" + version;
|
name = "bitcoin" + (toString (optional (!withGui) "d")) + "-abc-" + version;
|
||||||
version = "0.21.5";
|
version = "0.21.10";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "bitcoin-ABC";
|
owner = "bitcoin-ABC";
|
||||||
repo = "bitcoin-abc";
|
repo = "bitcoin-abc";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "1jx33n8dhn16iaxvmc56cxw0i5qk0ga5nf7qf9frwwq6zkglknga";
|
sha256 = "1m210g6db8f09m66v75ia1fdd1dlvs1srgk2jhd3wqbvnmjqa77f";
|
||||||
};
|
};
|
||||||
|
|
||||||
patches = [ ./fix-bitcoin-qt-build.patch ];
|
patches = [ ./fix-bitcoin-qt-build.patch ];
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgconfig autoreconfHook ];
|
nativeBuildInputs = [ pkgconfig cmake ];
|
||||||
buildInputs = [ openssl db53 boost zlib
|
buildInputs = [ openssl db53 boost zlib python3 jemalloc zeromq4
|
||||||
miniupnpc utillinux protobuf libevent ]
|
miniupnpc utillinux protobuf libevent ]
|
||||||
++ optionals withGui [ qtbase qttools qrencode ];
|
++ optionals withGui [ qtbase qttools qrencode ];
|
||||||
|
|
||||||
configureFlags = [ "--with-boost-libdir=${boost.out}/lib" ]
|
cmakeFlags = optionals (!withGui) [
|
||||||
++ optionals withGui [ "--with-gui=qt5" ];
|
"-DBUILD_BITCOIN_QT=OFF"
|
||||||
|
];
|
||||||
|
|
||||||
|
# many of the generated scripts lack execute permissions
|
||||||
|
postConfigure = ''
|
||||||
|
find ./. -type f -iname "*.sh" -exec chmod +x {} \;
|
||||||
|
'';
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
let
|
let
|
||||||
pname = "ledger-live-desktop";
|
pname = "ledger-live-desktop";
|
||||||
version = "2.6.0";
|
version = "2.8.0";
|
||||||
name = "${pname}-${version}";
|
name = "${pname}-${version}";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://github.com/LedgerHQ/${pname}/releases/download/v${version}/${pname}-${version}-linux-x86_64.AppImage";
|
url = "https://github.com/LedgerHQ/${pname}/releases/download/v${version}/${pname}-${version}-linux-x86_64.AppImage";
|
||||||
sha256 = "0c58bx6fgykz0fl2yjbpbg6h5bv31zmjwgd1m3qi8afqryf52m5w";
|
sha256 = "1nj7fjbf99zpmq82kci6wp9nzml8ij1bz96zc77gwzsi0dacjrv5";
|
||||||
};
|
};
|
||||||
|
|
||||||
appimageContents = appimageTools.extractType2 {
|
appimageContents = appimageTools.extractType2 {
|
||||||
|
|
|
@ -12,13 +12,13 @@ with stdenv.lib;
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "monero-gui";
|
pname = "monero-gui";
|
||||||
version = "0.16.0.0";
|
version = "0.16.0.2";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "monero-project";
|
owner = "monero-project";
|
||||||
repo = "monero-gui";
|
repo = "monero-gui";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "06vdrsj5y9k0zn32hspyxc7sw1kkyrvi3chzkdbnxk9jvyj8k4ld";
|
sha256 = "1b1m8vhs0hdh81ysm8s8vfwqskqsihylb51wz16kc98ba40r9gqg";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ qmake pkgconfig wrapQtAppsHook ];
|
nativeBuildInputs = [ qmake pkgconfig wrapQtAppsHook ];
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ fetchFromGitHub, stdenv, pkgconfig, autoreconfHook, wrapQtAppsHook ? null
|
{ 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
|
, qrencode, glib, protobuf, yasm, libevent
|
||||||
, utillinux, qtbase ? null, qttools ? null
|
, utillinux, qtbase ? null, qttools ? null
|
||||||
, enableUpnp ? false
|
, enableUpnp ? false
|
||||||
|
@ -10,17 +10,17 @@
|
||||||
with stdenv.lib;
|
with stdenv.lib;
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "pivx-${version}";
|
name = "pivx-${version}";
|
||||||
version = "4.0.2";
|
version = "4.1.1";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "PIVX-Project";
|
owner = "PIVX-Project";
|
||||||
repo= "PIVX";
|
repo= "PIVX";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "12lnp318k8dx1sar24zfmv2imnzs30srssnlpb31y7hcxhz0wpc5";
|
sha256 = "03ndk46h6093v8s18d5iffz48zhlshq7jrk6vgpjfs6z2iqgd2sy";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgconfig autoreconfHook ] ++ optionals withGui [ wrapQtAppsHook ];
|
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 ];
|
++ optionals withGui [ qtbase qttools qrencode ];
|
||||||
|
|
||||||
configureFlags = [ "--with-boost-libdir=${boost.out}/lib" ]
|
configureFlags = [ "--with-boost-libdir=${boost.out}/lib" ]
|
||||||
|
@ -28,7 +28,6 @@ stdenv.mkDerivation rec {
|
||||||
++ optional disableWallet "--disable-wallet"
|
++ optional disableWallet "--disable-wallet"
|
||||||
++ optional disableDaemon "--disable-daemon"
|
++ optional disableDaemon "--disable-daemon"
|
||||||
++ optionals withGui [ "--with-gui=yes"
|
++ optionals withGui [ "--with-gui=yes"
|
||||||
"--with-unsupported-ssl" # TODO remove this ASAP
|
|
||||||
"--with-qt-bindir=${qtbase.dev}/bin:${qttools.dev}/bin"
|
"--with-qt-bindir=${qtbase.dev}/bin:${qttools.dev}/bin"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -56,9 +55,5 @@ stdenv.mkDerivation rec {
|
||||||
homepage = "https://www.dash.org";
|
homepage = "https://www.dash.org";
|
||||||
maintainers = with maintainers; [ wucke13 ];
|
maintainers = with maintainers; [ wucke13 ];
|
||||||
platforms = platforms.unix;
|
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
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,11 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "gnome-builder";
|
pname = "gnome-builder";
|
||||||
version = "3.36.0";
|
version = "3.36.1";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://gnome/sources/${pname}/${stdenv.lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
|
url = "mirror://gnome/sources/${pname}/${stdenv.lib.versions.majorMinor version}/${pname}-${version}.tar.xz";
|
||||||
sha256 = "02ni81jyncycgfwslvaav0a62wzx3r9bi86xf0x7jvvk6plfaj8v";
|
sha256 = "17pvmd5jypar8dkr6w56hvf7jnq4l1wih2wwgkrv7sblr7rkkar2";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage rec {
|
||||||
pname = "gnvim-unwrapped";
|
pname = "gnvim-unwrapped";
|
||||||
version = "0.1.5";
|
version = "0.1.6";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "vhakulinen";
|
owner = "vhakulinen";
|
||||||
repo = "gnvim";
|
repo = "gnvim";
|
||||||
rev = version;
|
rev = "v${version}";
|
||||||
sha256 = "11gb59lhc1sp5dxj2fdm6072f4nxxay0war3kmchdwsk41nvxlrh";
|
sha256 = "1cc3yk04v9icdjr5cn58mqc3ba1wqmlzhf9ly7biy9m8yk30w9y0";
|
||||||
};
|
};
|
||||||
|
|
||||||
cargoSha256 = "0ay7hx5bzchp772ywgxzia12c44kbyarrshl689cmqh59wphsrx5";
|
cargoSha256 = "1fyn8nsabzrfl9ykf2gk2p8if0yjp6k0ybrmp0pw67pbwaxpb9ym";
|
||||||
|
|
||||||
buildInputs = [ gtk webkitgtk ];
|
buildInputs = [ gtk webkitgtk ];
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
, lib
|
, lib
|
||||||
, fetchurl
|
, fetchurl
|
||||||
, makeWrapper
|
, makeWrapper
|
||||||
, electron_5
|
, electron_8
|
||||||
, dpkg
|
, dpkg
|
||||||
, gtk3
|
, gtk3
|
||||||
, glib
|
, glib
|
||||||
|
@ -14,11 +14,11 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "typora";
|
pname = "typora";
|
||||||
version = "0.9.73";
|
version = "0.9.89";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://www.typora.io/linux/typora_${version}_amd64.deb";
|
url = "https://www.typora.io/linux/typora_${version}_amd64.deb";
|
||||||
sha256 = "1fgcb4bx5pw8ah5j30d38gw7qi1cmqarfhvgdns9f2n0d57bvvw3";
|
sha256 = "0gk8j13z1ymad34zzcy4vqwyjgd5khgyw5xjj9rbzm5v537kqmx6";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
@ -33,7 +33,8 @@ stdenv.mkDerivation rec {
|
||||||
gtk3
|
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;
|
dontWrapGApps = true;
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ stdenv.mkDerivation rec {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
postFixup = ''
|
postFixup = ''
|
||||||
makeWrapper ${electron_5}/bin/electron $out/bin/typora \
|
makeWrapper ${electron_8}/bin/electron $out/bin/typora \
|
||||||
--add-flags $out/share/typora \
|
--add-flags $out/share/typora \
|
||||||
"''${gappsWrapperArgs[@]}" \
|
"''${gappsWrapperArgs[@]}" \
|
||||||
${lib.optionalString withPandoc ''--prefix PATH : "${lib.makeBinPath [ pandoc ]}"''} \
|
${lib.optionalString withPandoc ''--prefix PATH : "${lib.makeBinPath [ pandoc ]}"''} \
|
||||||
|
|
|
@ -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
|
{ source ? "default", callPackage, stdenv, ncurses, pkgconfig, gettext
|
||||||
, writeText, config, glib, gtk2-x11, gtk3-x11, lua, python, perl, tcl, ruby
|
, writeText, config, glib, gtk2-x11, gtk3-x11, lua, python, perl, tcl, ruby
|
||||||
, libX11, libXext, libSM, libXpm, libXt, libXaw, libXau, libXmu
|
, libX11, libXext, libSM, libXpm, libXt, libXaw, libXau, libXmu
|
||||||
|
@ -156,7 +154,12 @@ in stdenv.mkDerivation rec {
|
||||||
'' + stdenv.lib.optionalString stdenv.isLinux ''
|
'' + stdenv.lib.optionalString stdenv.isLinux ''
|
||||||
patchelf --set-rpath \
|
patchelf --set-rpath \
|
||||||
"$(patchelf --print-rpath $out/bin/vim):${stdenv.lib.makeLibraryPath buildInputs}" \
|
"$(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
|
ln -sfn '${nixosRuntimepath}' "$out"/share/vim/vimrc
|
||||||
'' + stdenv.lib.optionalString wrapPythonDrv ''
|
'' + stdenv.lib.optionalString wrapPythonDrv ''
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "drawio";
|
pname = "drawio";
|
||||||
version = "13.3.5";
|
version = "13.3.9";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://github.com/jgraph/drawio-desktop/releases/download/v${version}/draw.io-x86_64-${version}.rpm";
|
url = "https://github.com/jgraph/drawio-desktop/releases/download/v${version}/draw.io-x86_64-${version}.rpm";
|
||||||
sha256 = "16pds6sip90davrlrk17a7ms5nh1bs8js5i0hbci1l8gsfyx22i7";
|
sha256 = "1i1idjy80x6a0w40lziivyhg8nnlbpri7xdqxikxy982vffgihwp";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
, lib
|
, lib
|
||||||
, fetchurl
|
, fetchurl
|
||||||
, substituteAll
|
, substituteAll
|
||||||
|
, autoreconfHook
|
||||||
, pkgconfig
|
, pkgconfig
|
||||||
, intltool
|
, intltool
|
||||||
, babl
|
, babl
|
||||||
|
@ -28,9 +29,10 @@
|
||||||
, ghostscript
|
, ghostscript
|
||||||
, aalib
|
, aalib
|
||||||
, shared-mime-info
|
, shared-mime-info
|
||||||
, python2Packages
|
, python2
|
||||||
, libexif
|
, libexif
|
||||||
, gettext
|
, gettext
|
||||||
|
, makeWrapper
|
||||||
, xorg
|
, xorg
|
||||||
, glib-networking
|
, glib-networking
|
||||||
, libmypaint
|
, libmypaint
|
||||||
|
@ -47,7 +49,7 @@
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (python2Packages) pygtk wrapPython python;
|
python = python2.withPackages (pp: [ pp.pygtk ]);
|
||||||
in stdenv.mkDerivation rec {
|
in stdenv.mkDerivation rec {
|
||||||
pname = "gimp";
|
pname = "gimp";
|
||||||
version = "2.10.20";
|
version = "2.10.20";
|
||||||
|
@ -59,11 +61,25 @@ in stdenv.mkDerivation rec {
|
||||||
sha256 = "4S+fh0saAHxCd7YKqB4LZzML5+YVPldJ6tg5uQL8ezw=";
|
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 = [
|
nativeBuildInputs = [
|
||||||
|
autoreconfHook # hardcode-plugin-interpreters.patch changes Makefile.am
|
||||||
pkgconfig
|
pkgconfig
|
||||||
intltool
|
intltool
|
||||||
gettext
|
gettext
|
||||||
wrapPython
|
makeWrapper
|
||||||
];
|
];
|
||||||
|
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
|
@ -97,7 +113,6 @@ in stdenv.mkDerivation rec {
|
||||||
libwebp
|
libwebp
|
||||||
libheif
|
libheif
|
||||||
python
|
python
|
||||||
pygtk
|
|
||||||
libexif
|
libexif
|
||||||
xorg.libXpm
|
xorg.libXpm
|
||||||
glib-networking
|
glib-networking
|
||||||
|
@ -116,8 +131,6 @@ in stdenv.mkDerivation rec {
|
||||||
gegl
|
gegl
|
||||||
];
|
];
|
||||||
|
|
||||||
pythonPath = [ pygtk ];
|
|
||||||
|
|
||||||
# Check if librsvg was built with --disable-pixbuf-loader.
|
# Check if librsvg was built with --disable-pixbuf-loader.
|
||||||
PKG_CONFIG_GDK_PIXBUF_2_0_GDK_PIXBUF_MODULEDIR = "${librsvg}/${gdk-pixbuf.moduleDir}";
|
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"
|
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 = ''
|
postFixup = ''
|
||||||
wrapPythonProgramsIn $out/lib/gimp/${passthru.majorVersion}/plug-ins/
|
|
||||||
wrapProgram $out/bin/gimp-${lib.versions.majorMinor version} \
|
wrapProgram $out/bin/gimp-${lib.versions.majorMinor version} \
|
||||||
--prefix PYTHONPATH : "$PYTHONPATH" \
|
|
||||||
--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE"
|
--set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_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
|
||||||
|
|
|
@ -10,11 +10,11 @@ with stdenv.lib;
|
||||||
|
|
||||||
perlPackages.buildPerlPackage rec {
|
perlPackages.buildPerlPackage rec {
|
||||||
pname = "gscan2pdf";
|
pname = "gscan2pdf";
|
||||||
version = "2.6.5";
|
version = "2.8.0";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://sourceforge/gscan2pdf/${version}/${pname}-${version}.tar.xz";
|
url = "mirror://sourceforge/gscan2pdf/${version}/${pname}-${version}.tar.xz";
|
||||||
sha256 = "0x8931i5zs4zl3iqjhlp7h8y6ssklxiqsddz5kh84nl3p0izbg0y";
|
sha256 = "0rqx41hkppil3lp1dhkxwlhv0kwp8w8fkgzlapryq1yd9pgkx6lw";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ wrapGAppsHook ];
|
nativeBuildInputs = [ wrapGAppsHook ];
|
||||||
|
@ -64,6 +64,7 @@ perlPackages.buildPerlPackage rec {
|
||||||
|
|
||||||
# Add runtime dependencies
|
# Add runtime dependencies
|
||||||
wrapProgram "$out/bin/gscan2pdf" \
|
wrapProgram "$out/bin/gscan2pdf" \
|
||||||
|
--prefix PATH : "${sane-backends}/bin" \
|
||||||
--prefix PATH : "${imagemagick}/bin" \
|
--prefix PATH : "${imagemagick}/bin" \
|
||||||
--prefix PATH : "${libtiff}/bin" \
|
--prefix PATH : "${libtiff}/bin" \
|
||||||
--prefix PATH : "${djvulibre}/bin" \
|
--prefix PATH : "${djvulibre}/bin" \
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "krita";
|
pname = "krita";
|
||||||
version = "4.2.9";
|
version = "4.3.0";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://download.kde.org/stable/${pname}/${version}/${pname}-${version}.tar.xz";
|
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
|
# *somtimes* fails with can't find ui_manager.h, also see https://github.com/NixOS/nixpkgs/issues/35359
|
||||||
|
|
|
@ -19,13 +19,13 @@ assert withOpenCL -> ocl-icd != null;
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "mandelbulber";
|
pname = "mandelbulber";
|
||||||
version = "2.21";
|
version = "2.22";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "buddhi1980";
|
owner = "buddhi1980";
|
||||||
repo = "mandelbulber2";
|
repo = "mandelbulber2";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "1bmk71vbxc1n8cnizlmzfqlvgxjb95cydbzxlvq1s5givxr2jwli";
|
sha256 = "011y2nl0jakf29cxprjmj1ifqc9iva61q5f4kk47b03gq7jw8sl4";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
, sane-backends, meson, ninja }:
|
, sane-backends, meson, ninja }:
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "sane-airscan";
|
pname = "sane-airscan";
|
||||||
version = "0.99.3";
|
version = "0.99.8";
|
||||||
|
|
||||||
nativeBuildInputs = [ meson ninja pkg-config ];
|
nativeBuildInputs = [ meson ninja pkg-config ];
|
||||||
buildInputs = [ avahi libsoup libjpeg libpng sane-backends ];
|
buildInputs = [ avahi libsoup libjpeg libpng sane-backends ];
|
||||||
|
@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
|
||||||
owner = "alexpevzner";
|
owner = "alexpevzner";
|
||||||
repo = pname;
|
repo = pname;
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "1sxp207vzjzi0ad5202n46acbha4dfmzcijl2v0b9j9lj4k42a8k";
|
sha256 = "0sdlnbzhnfn4i5mkqhc8zmjywbbjqkbnsiz2gpqhy6fypshryahz";
|
||||||
};
|
};
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ stdenv
|
{ stdenv
|
||||||
, pythonPackages
|
, python3Packages
|
||||||
, fetchurl
|
, fetchurl
|
||||||
, gettext
|
, gettext
|
||||||
, gobject-introspection
|
, gobject-introspection
|
||||||
|
@ -9,15 +9,15 @@
|
||||||
, libnotify
|
, libnotify
|
||||||
}:
|
}:
|
||||||
|
|
||||||
pythonPackages.buildPythonApplication rec {
|
python3Packages.buildPythonApplication rec {
|
||||||
pname = "bleachbit";
|
pname = "bleachbit";
|
||||||
version = "3.2.0";
|
version = "4.0.0";
|
||||||
|
|
||||||
format = "other";
|
format = "other";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.bz2";
|
url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.bz2";
|
||||||
sha256 = "1sszpn7ifiry0wwmkzdppzh61zvgrfypm9g7wk6q1ya20qhb5b51";
|
sha256 = "1dn3h6lr9ldbfpvgq9sdlk972sxhwalgj2f377qbqibm3yfxzpil";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
@ -32,7 +32,7 @@ pythonPackages.buildPythonApplication rec {
|
||||||
libnotify
|
libnotify
|
||||||
];
|
];
|
||||||
|
|
||||||
propagatedBuildInputs = with pythonPackages; [
|
propagatedBuildInputs = with python3Packages; [
|
||||||
chardet
|
chardet
|
||||||
pygobject3
|
pygobject3
|
||||||
requests
|
requests
|
||||||
|
@ -51,6 +51,12 @@ pythonPackages.buildPythonApplication rec {
|
||||||
"prefix=${placeholder "out"}"
|
"prefix=${placeholder "out"}"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
# prevent double wrapping from wrapGApps and wrapPythonProgram
|
||||||
|
dontWrapGApps = true;
|
||||||
|
makeWrapperArgs = [
|
||||||
|
''''${gappsWrapperArgs[@]}''
|
||||||
|
];
|
||||||
|
|
||||||
strictDeps = false;
|
strictDeps = false;
|
||||||
|
|
||||||
meta = with stdenv.lib; {
|
meta = with stdenv.lib; {
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "dbeaver-ce";
|
pname = "dbeaver-ce";
|
||||||
version = "7.1.1";
|
version = "7.1.2";
|
||||||
|
|
||||||
desktopItem = makeDesktopItem {
|
desktopItem = makeDesktopItem {
|
||||||
name = "dbeaver";
|
name = "dbeaver";
|
||||||
|
@ -30,7 +30,7 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://dbeaver.io/files/${version}/dbeaver-ce-${version}-linux.gtk.x86_64.tar.gz";
|
url = "https://dbeaver.io/files/${version}/dbeaver-ce-${version}-linux.gtk.x86_64.tar.gz";
|
||||||
sha256 = "11c9jvpjg72xkwnni4clwg3inig77s7jz3ik52gk52m6f09brxhs";
|
sha256 = "131v8y5la2pv3cqf2qknd816z24dvhf2c4f7js8vfzrfw5vwsqbq";
|
||||||
};
|
};
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "dmenu-wayland-unstable";
|
pname = "dmenu-wayland-unstable";
|
||||||
version = "2020-04-03";
|
version = "2020-07-06";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "nyyManni";
|
owner = "nyyManni";
|
||||||
repo = "dmenu-wayland";
|
repo = "dmenu-wayland";
|
||||||
rev = "550a7c39f3f925b803d51c616609c8cb6c0ea543";
|
rev = "304c8e917651ee02b16ebf0b7097a5c53fa2236b";
|
||||||
sha256 = "0az3w1csn4x6mjyacg6lf70kykdfqamic3hbr57mj83i5jjv0jlv";
|
sha256 = "0rkpmpk7xkcfbnv9vpg8n65423z5xpgp0hm2vg0rxf9354bjin7k";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = [ "out" "man" ];
|
outputs = [ "out" "man" ];
|
||||||
|
|
|
@ -11,7 +11,7 @@ stdenv.mkDerivation rec {
|
||||||
owner = "tud-zih-energy";
|
owner = "tud-zih-energy";
|
||||||
repo = "FIRESTARTER";
|
repo = "FIRESTARTER";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "161mg0h1hvp6bxfjdhyfqrljvphys896mfd36254rbgzxm38ibi7";
|
sha256 = "0zqfqb7hf48z39g1qhbl1iraf8rz4d629h1q6ikizckpzfq23kd0";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ python3 ];
|
nativeBuildInputs = [ python3 ];
|
||||||
|
@ -33,7 +33,7 @@ stdenv.mkDerivation rec {
|
||||||
homepage = "https://tu-dresden.de/zih/forschung/projekte/firestarter";
|
homepage = "https://tu-dresden.de/zih/forschung/projekte/firestarter";
|
||||||
description = "Processor Stress Test Utility";
|
description = "Processor Stress Test Utility";
|
||||||
platforms = platforms.linux;
|
platforms = platforms.linux;
|
||||||
maintainers = with maintainers; [ astro ];
|
maintainers = with maintainers; [ astro marenz ];
|
||||||
license = licenses.gpl3;
|
license = licenses.gpl3;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 rofi’s drun mode";
|
||||||
|
homepage = "https://codeberg.org/dnkl/fuzzel";
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = with maintainers; [ fionera ];
|
||||||
|
platforms = with platforms; linux;
|
||||||
|
};
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
, qttools
|
, qttools
|
||||||
, darwin
|
, darwin
|
||||||
|
|
||||||
|
, asciidoctor
|
||||||
, curl
|
, curl
|
||||||
, glibcLocales
|
, glibcLocales
|
||||||
, libXi
|
, libXi
|
||||||
|
@ -39,13 +40,13 @@ with stdenv.lib;
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
pname = "keepassxc";
|
pname = "keepassxc";
|
||||||
version = "2.5.4";
|
version = "2.6.0";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "keepassxreboot";
|
owner = "keepassxreboot";
|
||||||
repo = "keepassxc";
|
repo = "keepassxc";
|
||||||
rev = version;
|
rev = version;
|
||||||
sha256 = "1xih9q1pxszalc0l29fmjxwn1vrrrrbnhc8gmi8brw5sclhbs6bh";
|
sha256 = "0yi6kxnsrqirjn6hxhwym2krzf86qxf3kc6bfpkmiaggnd2kqpkp";
|
||||||
};
|
};
|
||||||
|
|
||||||
NIX_CFLAGS_COMPILE = stdenv.lib.optionalString stdenv.cc.isClang [
|
NIX_CFLAGS_COMPILE = stdenv.lib.optionalString stdenv.cc.isClang [
|
||||||
|
@ -63,11 +64,6 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
patches = [
|
patches = [
|
||||||
./darwin.patch
|
./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 = [
|
cmakeFlags = [
|
||||||
|
@ -97,6 +93,7 @@ stdenv.mkDerivation rec {
|
||||||
nativeBuildInputs = [ cmake wrapQtAppsHook qttools ];
|
nativeBuildInputs = [ cmake wrapQtAppsHook qttools ];
|
||||||
|
|
||||||
buildInputs = [
|
buildInputs = [
|
||||||
|
asciidoctor
|
||||||
curl
|
curl
|
||||||
glibcLocales
|
glibcLocales
|
||||||
libXi
|
libXi
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
, wine
|
, wine
|
||||||
, fluidsynth
|
, fluidsynth
|
||||||
, xorgserver
|
, xorgserver
|
||||||
|
, xorg
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -55,6 +56,8 @@ let
|
||||||
wine
|
wine
|
||||||
fluidsynth
|
fluidsynth
|
||||||
xorgserver
|
xorgserver
|
||||||
|
xorg.setxkbmap
|
||||||
|
xorg.xkbcomp
|
||||||
];
|
];
|
||||||
|
|
||||||
gstDeps = with gst_all_1; [
|
gstDeps = with gst_all_1; [
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
{ appimageTools, fetchurl, lib }:
|
{ appimageTools, fetchurl, lib, gsettings-desktop-schemas, gtk3 }:
|
||||||
|
|
||||||
let
|
let
|
||||||
pname = "marktext";
|
pname = "marktext";
|
||||||
version = "v0.16.0-rc.2";
|
version = "v0.16.2";
|
||||||
in
|
in
|
||||||
appimageTools.wrapType2 rec {
|
appimageTools.wrapType2 rec {
|
||||||
name = "${pname}-${version}-binary";
|
name = "${pname}-${version}-binary";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://github.com/marktext/marktext/releases/download/${version}/marktext-x86_64.AppImage";
|
url = "https://github.com/marktext/marktext/releases/download/${version}/marktext-x86_64.AppImage";
|
||||||
sha256 = "1w1mxa1j94zr36xhvlhzq8d77pi359vdxqb2j8mnz2bib9khxk9k";
|
sha256 = "0ivf9lvv2jk7dvxmqprzcsxgya3617xmx5bppjvik44z14b5x8r7";
|
||||||
};
|
};
|
||||||
|
|
||||||
profile = ''
|
profile = ''
|
||||||
export LC_ALL=C.UTF-8
|
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
|
multiPkgs = null; # no 32bit needed
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
|
|
||||||
mkDerivation rec {
|
mkDerivation rec {
|
||||||
pname = "megasync";
|
pname = "megasync";
|
||||||
version = "4.3.0.8";
|
version = "4.3.1.0";
|
||||||
|
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "meganz";
|
owner = "meganz";
|
||||||
repo = "MEGAsync";
|
repo = "MEGAsync";
|
||||||
rev = "v${version}_Linux";
|
rev = "v${version}_Linux";
|
||||||
sha256 = "1rhxkc6j3039rcsi8cxy3n00g6w7acir82ymnksbpsnp4yxqv5r3";
|
sha256 = "0b68wpif8a0wf1vfn1nr19dmz8f31dprb27jpldxrxhyfslc43yj";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
name = "netsurf-${libname}-${version}";
|
name = "netsurf-${libname}-${version}";
|
||||||
libname = "libnsbmp";
|
libname = "libnsbmp";
|
||||||
version = "0.1.5";
|
version = "0.1.6";
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "http://download.netsurf-browser.org/libs/releases/${libname}-${version}-src.tar.gz";
|
url = "http://download.netsurf-browser.org/libs/releases/${libname}-${version}-src.tar.gz";
|
||||||
sha256 = "0lib2m07d1i0k80m4blkwnj0g7rha4jbm5vrgd0wwbkyfa0hvk35";
|
sha256 = "0krjg69a2amxjsahdgm3wmy9ngnyr3gfs2a1zhdlbvb0z1jr7i3r";
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeBuildInputs = [ pkgconfig ];
|
nativeBuildInputs = [ pkgconfig ];
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue