Merge master into haskell-updates

This commit is contained in:
github-actions[bot]
2021-12-28 00:08:25 +00:00
committed by GitHub
87 changed files with 1507 additions and 917 deletions
@@ -14,7 +14,17 @@
</itemizedlist>
<section xml:id="sec-release-22.05-highlights">
<title>Highlights</title>
<itemizedlist spacing="compact">
<itemizedlist>
<listitem>
<para>
<literal>security.acme.defaults</literal> has been added to
simplify configuring settings for many certificates at once.
This also opens up the the option to use DNS-01 validation
when using <literal>enableACME</literal> on web server virtual
hosts (e.g.
<literal>services.nginx.virtualHosts.*.enableACME</literal>).
</para>
</listitem>
<listitem>
<para>
PHP 8.1 is now available
@@ -33,6 +43,14 @@
<link linkend="opt-services.aesmd.enable">services.aesmd</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://docs.docker.com/engine/security/rootless/">rootless
Docker</link>, a <literal>systemd --user</literal> Docker
service which runs without root permissions. Available as
<link xlink:href="options.html#opt-virtualisation.docker.rootless.enable">virtualisation.docker.rootless.enable</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html">filebeat</link>,
@@ -189,6 +207,20 @@
using this default will print a warning when rebuilt.
</para>
</listitem>
<listitem>
<para>
<literal>security.acme</literal> certificates will now
correctly check for CA revokation before reaching their
minimum age.
</para>
</listitem>
<listitem>
<para>
Removing domains from
<literal>security.acme.certs._name_.extraDomainNames</literal>
will now correctly remove those domains during rebuild/renew.
</para>
</listitem>
<listitem>
<para>
The option
@@ -6,11 +6,17 @@ In addition to numerous new and upgraded packages, this release has the followin
## Highlights {#sec-release-22.05-highlights}
- `security.acme.defaults` has been added to simplify configuring
settings for many certificates at once. This also opens up the
the option to use DNS-01 validation when using `enableACME` on
web server virtual hosts (e.g. `services.nginx.virtualHosts.*.enableACME`).
- PHP 8.1 is now available
## New Services {#sec-release-22.05-new-services}
- [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).
- [rootless Docker](https://docs.docker.com/engine/security/rootless/), a `systemd --user` Docker service which runs without root permissions. Available as [virtualisation.docker.rootless.enable](options.html#opt-virtualisation.docker.rootless.enable).
- [filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html), a lightweight shipper for forwarding and centralizing log data. Available as [services.filebeat](#opt-services.filebeat.enable).
@@ -75,6 +81,12 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `services.unifi.openPorts` option default value of `true` is now deprecated and will be changed to `false` in 22.11.
Configurations using this default will print a warning when rebuilt.
- `security.acme` certificates will now correctly check for CA
revokation before reaching their minimum age.
- Removing domains from `security.acme.certs._name_.extraDomainNames`
will now correctly remove those domains during rebuild/renew.
- The option
[services.ssh.enableAskPassword](#opt-services.ssh.enableAskPassword) was
added, decoupling the setting of `SSH_ASKPASS` from
+1
View File
@@ -1187,6 +1187,7 @@
./virtualisation/oci-containers.nix
./virtualisation/cri-o.nix
./virtualisation/docker.nix
./virtualisation/docker-rootless.nix
./virtualisation/ecs-agent.nix
./virtualisation/libvirtd.nix
./virtualisation/lxc.nix
+267 -221
View File
@@ -3,6 +3,7 @@ with lib;
let
cfg = config.security.acme;
opt = options.security.acme;
user = if cfg.useRoot then "root" else "acme";
# Used to calculate timer accuracy for coalescing
numCerts = length (builtins.attrNames cfg.certs);
@@ -23,7 +24,7 @@ let
# security.acme.certs.<cert>.group on some of the services.
commonServiceConfig = {
Type = "oneshot";
User = "acme";
User = user;
Group = mkDefault "acme";
UMask = 0022;
StateDirectoryMode = 750;
@@ -101,12 +102,12 @@ let
# is configurable on a per-cert basis.
userMigrationService = let
script = with builtins; ''
chown -R acme .lego/accounts
chown -R ${user} .lego/accounts
'' + (concatStringsSep "\n" (mapAttrsToList (cert: data: ''
for fixpath in ${escapeShellArg cert} .lego/${escapeShellArg cert}; do
if [ -d "$fixpath" ]; then
chmod -R u=rwX,g=rX,o= "$fixpath"
chown -R acme:${data.group} "$fixpath"
chown -R ${user}:${data.group} "$fixpath"
fi
done
'') certConfigs));
@@ -128,7 +129,7 @@ let
};
certToConfig = cert: data: let
acmeServer = if data.server != null then data.server else cfg.server;
acmeServer = data.server;
useDns = data.dnsProvider != null;
destPath = "/var/lib/acme/${cert}";
selfsignedDeps = optionals (cfg.preliminarySelfsigned) [ "acme-selfsigned-${cert}.service" ];
@@ -156,6 +157,7 @@ let
${toString data.ocspMustStaple} ${data.keyType}
'';
certDir = mkHash hashData;
# TODO remove domainHash usage entirely. Waiting on go-acme/lego#1532
domainHash = mkHash "${concatStringsSep " " extraDomains} ${data.domain}";
accountHash = (mkAccountHash acmeServer data);
accountDir = accountDirRoot + accountHash;
@@ -210,7 +212,7 @@ let
description = "Renew ACME Certificate for ${cert}";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.renewInterval;
OnCalendar = data.renewInterval;
Unit = "acme-${cert}.service";
Persistent = "yes";
@@ -267,7 +269,7 @@ let
cat key.pem fullchain.pem > full.pem
# Group might change between runs, re-apply it
chown 'acme:${data.group}' *
chown '${user}:${data.group}' *
# Default permissions make the files unreadable by group + anon
# Need to be readable by group
@@ -322,7 +324,7 @@ let
fi
'');
} // optionalAttrs (data.listenHTTP != null && toInt (elemAt (splitString ":" data.listenHTTP) 1) < 1024) {
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
};
# Working directory will be /tmp
@@ -355,7 +357,7 @@ let
expiration_s=$[expiration_date - now]
expiration_days=$[expiration_s / (3600 * 24)] # rounds down
[[ $expiration_days -gt ${toString cfg.validMinDays} ]]
[[ $expiration_days -gt ${toString data.validMinDays} ]]
}
${optionalString (data.webroot != null) ''
@@ -372,37 +374,40 @@ let
echo '${domainHash}' > domainhash.txt
# Check if we can renew
if [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' -a -n "$(ls -1 accounts)" ]; then
# Check if we can renew.
# We can only renew if the list of domains has not changed.
if cmp -s domainhash.txt certificates/domainhash.txt && [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' -a -n "$(ls -1 accounts)" ]; then
# When domains are updated, there's no need to do a full
# Lego run, but it's likely renew won't work if days is too low.
if [ -e certificates/domainhash.txt ] && cmp -s domainhash.txt certificates/domainhash.txt; then
# Even if a cert is not expired, it may be revoked by the CA.
# Try to renew, and silently fail if the cert is not expired.
# Avoids #85794 and resolves #129838
if ! lego ${renewOpts} --days ${toString data.validMinDays}; then
if is_expiration_skippable out/full.pem; then
echo 1>&2 "nixos-acme: skipping renewal because expiration isn't within the coming ${toString cfg.validMinDays} days"
echo 1>&2 "nixos-acme: Ignoring failed renewal because expiration isn't within the coming ${toString data.validMinDays} days"
else
echo 1>&2 "nixos-acme: renewing now, because certificate expires within the configured ${toString cfg.validMinDays} days"
lego ${renewOpts} --days ${toString cfg.validMinDays}
# High number to avoid Systemd reserved codes.
exit 11
fi
else
echo 1>&2 "certificate domain(s) have changed; will renew now"
# Any number > 90 works, but this one is over 9000 ;-)
lego ${renewOpts} --days 9001
fi
# Otherwise do a full run
else
lego ${runOpts}
elif ! lego ${runOpts}; then
# Produce a nice error for those doing their first nixos-rebuild with these certs
echo Failed to fetch certificates. \
This may mean your DNS records are set up incorrectly. \
${optionalString (cfg.preliminarySelfsigned) "Selfsigned certs are in place and dependant services will still start."}
# Exit 10 so that users can potentially amend SuccessExitStatus to ignore this error.
# High number to avoid Systemd reserved codes.
exit 10
fi
mv domainhash.txt certificates/
# Group might change between runs, re-apply it
chown 'acme:${data.group}' certificates/*
chown '${user}:${data.group}' certificates/*
# Copy all certs to the "real" certs directory
CERT='certificates/${keyName}.crt'
if [ -e "$CERT" ] && ! cmp -s "$CERT" out/fullchain.pem; then
if ! cmp -s 'certificates/${keyName}.crt' out/fullchain.pem; then
touch out/renewed
echo Installing new certificate
cp -vp 'certificates/${keyName}.crt' out/fullchain.pem
@@ -421,7 +426,194 @@ let
certConfigs = mapAttrs certToConfig cfg.certs;
certOpts = { name, ... }: {
# These options can be specified within
# security.acme.defaults or security.acme.certs.<name>
inheritableModule = isDefaults: { config, ... }: let
defaultAndText = name: default: {
# When ! isDefaults then this is the option declaration for the
# security.acme.certs.<name> path, which has the extra inheritDefaults
# option, which if disabled means that we can't inherit it
default = if isDefaults || ! config.inheritDefaults then default else cfg.defaults.${name};
# The docs however don't need to depend on inheritDefaults, they should
# stay constant. Though notably it wouldn't matter much, because to get
# the option information, a submodule with name `<name>` is evaluated
# without any definitions.
defaultText = if isDefaults then default else literalExpression "config.security.acme.defaults.${name}";
};
in {
options = {
validMinDays = mkOption {
type = types.int;
inherit (defaultAndText "validMinDays" 30) default defaultText;
description = "Minimum remaining validity before renewal in days.";
};
renewInterval = mkOption {
type = types.str;
inherit (defaultAndText "renewInterval" "daily") default defaultText;
description = ''
Systemd calendar expression when to check for renewal. See
<citerefentry><refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum></citerefentry>.
'';
};
enableDebugLogs = mkEnableOption "debug logging for this certificate" // {
inherit (defaultAndText "enableDebugLogs" true) default defaultText;
};
webroot = mkOption {
type = types.nullOr types.str;
inherit (defaultAndText "webroot" null) default defaultText;
example = "/var/lib/acme/acme-challenge";
description = ''
Where the webroot of the HTTP vhost is located.
<filename>.well-known/acme-challenge/</filename> directory
will be created below the webroot if it doesn't exist.
<literal>http://example.org/.well-known/acme-challenge/</literal> must also
be available (notice unencrypted HTTP).
'';
};
server = mkOption {
type = types.nullOr types.str;
inherit (defaultAndText "server" null) default defaultText;
description = ''
ACME Directory Resource URI. Defaults to Let's Encrypt's
production endpoint,
<link xlink:href="https://acme-v02.api.letsencrypt.org/directory"/>, if unset.
'';
};
email = mkOption {
type = types.str;
inherit (defaultAndText "email" null) default defaultText;
description = ''
Email address for account creation and correspondence from the CA.
It is recommended to use the same email for all certs to avoid account
creation limits.
'';
};
group = mkOption {
type = types.str;
inherit (defaultAndText "group" "acme") default defaultText;
description = "Group running the ACME client.";
};
reloadServices = mkOption {
type = types.listOf types.str;
inherit (defaultAndText "reloadServices" []) default defaultText;
description = ''
The list of systemd services to call <code>systemctl try-reload-or-restart</code>
on.
'';
};
postRun = mkOption {
type = types.lines;
inherit (defaultAndText "postRun" "") default defaultText;
example = "cp full.pem backup.pem";
description = ''
Commands to run after new certificates go live. Note that
these commands run as the root user.
Executed in the same directory with the new certificate.
'';
};
keyType = mkOption {
type = types.str;
inherit (defaultAndText "keyType" "ec256") default defaultText;
description = ''
Key type to use for private keys.
For an up to date list of supported values check the --key-type option
at <link xlink:href="https://go-acme.github.io/lego/usage/cli/#usage"/>.
'';
};
dnsProvider = mkOption {
type = types.nullOr types.str;
inherit (defaultAndText "dnsProvider" null) default defaultText;
example = "route53";
description = ''
DNS Challenge provider. For a list of supported providers, see the "code"
field of the DNS providers listed at <link xlink:href="https://go-acme.github.io/lego/dns/"/>.
'';
};
dnsResolver = mkOption {
type = types.nullOr types.str;
inherit (defaultAndText "dnsResolver" null) default defaultText;
example = "1.1.1.1:53";
description = ''
Set the resolver to use for performing recursive DNS queries. Supported:
host:port. The default is to use the system resolvers, or Google's DNS
resolvers if the system's cannot be determined.
'';
};
credentialsFile = mkOption {
type = types.path;
inherit (defaultAndText "credentialsFile" null) default defaultText;
description = ''
Path to an EnvironmentFile for the cert's service containing any required and
optional environment variables for your selected dnsProvider.
To find out what values you need to set, consult the documentation at
<link xlink:href="https://go-acme.github.io/lego/dns/"/> for the corresponding dnsProvider.
'';
example = "/var/src/secrets/example.org-route53-api-token";
};
dnsPropagationCheck = mkOption {
type = types.bool;
inherit (defaultAndText "dnsPropagationCheck" true) default defaultText;
description = ''
Toggles lego DNS propagation check, which is used alongside DNS-01
challenge to ensure the DNS entries required are available.
'';
};
ocspMustStaple = mkOption {
type = types.bool;
inherit (defaultAndText "ocspMustStaple" false) default defaultText;
description = ''
Turns on the OCSP Must-Staple TLS extension.
Make sure you know what you're doing! See:
<itemizedlist>
<listitem><para><link xlink:href="https://blog.apnic.net/2019/01/15/is-the-web-ready-for-ocsp-must-staple/" /></para></listitem>
<listitem><para><link xlink:href="https://blog.hboeck.de/archives/886-The-Problem-with-OCSP-Stapling-and-Must-Staple-and-why-Certificate-Revocation-is-still-broken.html" /></para></listitem>
</itemizedlist>
'';
};
extraLegoFlags = mkOption {
type = types.listOf types.str;
inherit (defaultAndText "extraLegoFlags" []) default defaultText;
description = ''
Additional global flags to pass to all lego commands.
'';
};
extraLegoRenewFlags = mkOption {
type = types.listOf types.str;
inherit (defaultAndText "extraLegoRenewFlags" []) default defaultText;
description = ''
Additional flags to pass to lego renew.
'';
};
extraLegoRunFlags = mkOption {
type = types.listOf types.str;
inherit (defaultAndText "extraLegoRunFlags" []) default defaultText;
description = ''
Additional flags to pass to lego run.
'';
};
};
};
certOpts = { name, config, ... }: {
options = {
# user option has been removed
user = mkOption {
@@ -441,40 +633,11 @@ let
default = "_mkMergedOptionModule";
};
enableDebugLogs = mkEnableOption "debug logging for this certificate" // { default = cfg.enableDebugLogs; };
webroot = mkOption {
type = types.nullOr types.str;
default = null;
example = "/var/lib/acme/acme-challenge";
description = ''
Where the webroot of the HTTP vhost is located.
<filename>.well-known/acme-challenge/</filename> directory
will be created below the webroot if it doesn't exist.
<literal>http://example.org/.well-known/acme-challenge/</literal> must also
be available (notice unencrypted HTTP).
'';
};
listenHTTP = mkOption {
type = types.nullOr types.str;
default = null;
example = ":1360";
description = ''
Interface and port to listen on to solve HTTP challenges
in the form [INTERFACE]:PORT.
If you use a port other than 80, you must proxy port 80 to this port.
'';
};
server = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
ACME Directory Resource URI. Defaults to Let's Encrypt's
production endpoint,
<link xlink:href="https://acme-v02.api.letsencrypt.org/directory"/>, if unset.
'';
directory = mkOption {
type = types.str;
readOnly = true;
default = "/var/lib/acme/${name}";
description = "Directory where certificate and other state is stored.";
};
domain = mkOption {
@@ -483,47 +646,6 @@ let
description = "Domain to fetch certificate for (defaults to the entry name).";
};
email = mkOption {
type = types.nullOr types.str;
default = cfg.email;
defaultText = literalExpression "config.${opt.email}";
description = "Contact email address for the CA to be able to reach you.";
};
group = mkOption {
type = types.str;
default = "acme";
description = "Group running the ACME client.";
};
reloadServices = mkOption {
type = types.listOf types.str;
default = [];
description = ''
The list of systemd services to call <code>systemctl try-reload-or-restart</code>
on.
'';
};
postRun = mkOption {
type = types.lines;
default = "";
example = "cp full.pem backup.pem";
description = ''
Commands to run after new certificates go live. Note that
these commands run as the root user.
Executed in the same directory with the new certificate.
'';
};
directory = mkOption {
type = types.str;
readOnly = true;
default = "/var/lib/acme/${name}";
description = "Directory where certificate and other state is stored.";
};
extraDomainNames = mkOption {
type = types.listOf types.str;
default = [];
@@ -538,92 +660,25 @@ let
'';
};
keyType = mkOption {
type = types.str;
default = "ec256";
description = ''
Key type to use for private keys.
For an up to date list of supported values check the --key-type option
at <link xlink:href="https://go-acme.github.io/lego/usage/cli/#usage"/>.
'';
};
dnsProvider = mkOption {
# This setting must be different for each configured certificate, otherwise
# two or more renewals may fail to bind to the address. Hence, it is not in
# the inheritableOpts.
listenHTTP = mkOption {
type = types.nullOr types.str;
default = null;
example = "route53";
example = ":1360";
description = ''
DNS Challenge provider. For a list of supported providers, see the "code"
field of the DNS providers listed at <link xlink:href="https://go-acme.github.io/lego/dns/"/>.
Interface and port to listen on to solve HTTP challenges
in the form [INTERFACE]:PORT.
If you use a port other than 80, you must proxy port 80 to this port.
'';
};
dnsResolver = mkOption {
type = types.nullOr types.str;
default = null;
example = "1.1.1.1:53";
description = ''
Set the resolver to use for performing recursive DNS queries. Supported:
host:port. The default is to use the system resolvers, or Google's DNS
resolvers if the system's cannot be determined.
'';
};
credentialsFile = mkOption {
type = types.path;
description = ''
Path to an EnvironmentFile for the cert's service containing any required and
optional environment variables for your selected dnsProvider.
To find out what values you need to set, consult the documentation at
<link xlink:href="https://go-acme.github.io/lego/dns/"/> for the corresponding dnsProvider.
'';
example = "/var/src/secrets/example.org-route53-api-token";
};
dnsPropagationCheck = mkOption {
type = types.bool;
inheritDefaults = mkOption {
default = true;
description = ''
Toggles lego DNS propagation check, which is used alongside DNS-01
challenge to ensure the DNS entries required are available.
'';
};
ocspMustStaple = mkOption {
type = types.bool;
default = false;
description = ''
Turns on the OCSP Must-Staple TLS extension.
Make sure you know what you're doing! See:
<itemizedlist>
<listitem><para><link xlink:href="https://blog.apnic.net/2019/01/15/is-the-web-ready-for-ocsp-must-staple/" /></para></listitem>
<listitem><para><link xlink:href="https://blog.hboeck.de/archives/886-The-Problem-with-OCSP-Stapling-and-Must-Staple-and-why-Certificate-Revocation-is-still-broken.html" /></para></listitem>
</itemizedlist>
'';
};
extraLegoFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Additional global flags to pass to all lego commands.
'';
};
extraLegoRenewFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Additional flags to pass to lego renew.
'';
};
extraLegoRunFlags = mkOption {
type = types.listOf types.str;
default = [];
description = ''
Additional flags to pass to lego run.
'';
example = true;
description = "Whether to inherit values set in `security.acme.defaults` or not.";
type = lib.types.bool;
};
};
};
@@ -632,41 +687,6 @@ in {
options = {
security.acme = {
enableDebugLogs = mkEnableOption "debug logging for all certificates by default" // { default = true; };
validMinDays = mkOption {
type = types.int;
default = 30;
description = "Minimum remaining validity before renewal in days.";
};
email = mkOption {
type = types.nullOr types.str;
default = null;
description = "Contact email address for the CA to be able to reach you.";
};
renewInterval = mkOption {
type = types.str;
default = "daily";
description = ''
Systemd calendar expression when to check for renewal. See
<citerefentry><refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum></citerefentry>.
'';
};
server = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
ACME Directory Resource URI. Defaults to Let's Encrypt's
production endpoint,
<link xlink:href="https://acme-v02.api.letsencrypt.org/directory"/>, if unset.
'';
};
preliminarySelfsigned = mkOption {
type = types.bool;
default = true;
@@ -689,9 +709,31 @@ in {
'';
};
useRoot = mkOption {
type = types.bool;
default = false;
description = ''
Whether to use the root user when generating certs. This is not recommended
for security + compatiblity reasons. If a service requires root owned certificates
consider following the guide on "Using ACME with services demanding root
owned certificates" in the NixOS manual, and only using this as a fallback
or for testing.
'';
};
defaults = mkOption {
type = types.submodule (inheritableModule true);
description = ''
Default values inheritable by all configured certs. You can
use this to define options shared by all your certs. These defaults
can also be ignored on a per-cert basis using the
`security.acme.certs.''${cert}.inheritDefaults' option.
'';
};
certs = mkOption {
default = { };
type = with types; attrsOf (submodule certOpts);
type = with types; attrsOf (submodule [ (inheritableModule false) certOpts ]);
description = ''
Attribute set of certificates to get signed and renewed. Creates
<literal>acme-''${cert}.{service,timer}</literal> systemd units for
@@ -722,12 +764,16 @@ in {
To use the let's encrypt staging server, use security.acme.server =
"https://acme-staging-v02.api.letsencrypt.org/directory".
''
)
'')
(mkRemovedOptionModule [ "security" "acme" "directory" ] "ACME Directory is now hardcoded to /var/lib/acme and its permisisons are managed by systemd. See https://github.com/NixOS/nixpkgs/issues/53852 for more info.")
(mkRemovedOptionModule [ "security" "acme" "preDelay" ] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
(mkRemovedOptionModule [ "security" "acme" "activationDelay" ] "This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service to the service you want to execute before the cert renewal")
(mkChangedOptionModule [ "security" "acme" "validMin" ] [ "security" "acme" "validMinDays" ] (config: config.security.acme.validMin / (24 * 3600)))
(mkChangedOptionModule [ "security" "acme" "validMin" ] [ "security" "acme" "defaults" "validMinDays" ] (config: config.security.acme.validMin / (24 * 3600)))
(mkChangedOptionModule [ "security" "acme" "validMinDays" ] [ "security" "acme" "defaults" "validMinDays" ] (config: config.security.acme.validMinDays))
(mkChangedOptionModule [ "security" "acme" "renewInterval" ] [ "security" "acme" "defaults" "renewInterval" ] (config: config.security.acme.renewInterval))
(mkChangedOptionModule [ "security" "acme" "email" ] [ "security" "acme" "defaults" "email" ] (config: config.security.acme.email))
(mkChangedOptionModule [ "security" "acme" "server" ] [ "security" "acme" "defaults" "server" ] (config: config.security.acme.server))
(mkChangedOptionModule [ "security" "acme" "enableDebugLogs" ] [ "security" "acme" "defaults" "enableDebugLogs" ] (config: config.security.acme.enableDebugLogs))
];
config = mkMerge [
@@ -842,8 +888,8 @@ in {
# Create some targets which can be depended on to be "active" after cert renewals
finishedTargets = mapAttrs' (cert: conf: nameValuePair "acme-finished-${cert}" {
wantedBy = [ "default.target" ];
requires = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
after = [ "acme-${cert}.service" ] ++ conf.selfsignedDeps;
requires = [ "acme-${cert}.service" ];
after = [ "acme-${cert}.service" ];
}) certConfigs;
# Create targets to limit the number of simultaneous account creations
+137 -22
View File
@@ -7,8 +7,9 @@
<para>
NixOS supports automatic domain validation &amp; certificate retrieval and
renewal using the ACME protocol. Any provider can be used, but by default
NixOS uses Let's Encrypt. The alternative ACME client <literal>lego</literal>
is used under the hood.
NixOS uses Let's Encrypt. The alternative ACME client
<link xlink:href="https://go-acme.github.io/lego/">lego</link> is used under
the hood.
</para>
<para>
Automatic cert validation and configuration for Apache and Nginx virtual
@@ -29,7 +30,7 @@
<para>
You must also set an email address to be used when creating accounts with
Let's Encrypt. You can set this for all certs with
<literal><xref linkend="opt-security.acme.email" /></literal>
<literal><xref linkend="opt-security.acme.defaults.email" /></literal>
and/or on a per-cert basis with
<literal><xref linkend="opt-security.acme.certs._name_.email" /></literal>.
This address is only used for registration and renewal reminders,
@@ -38,7 +39,7 @@
<para>
Alternatively, you can use a different ACME server by changing the
<literal><xref linkend="opt-security.acme.server" /></literal> option
<literal><xref linkend="opt-security.acme.defaults.server" /></literal> option
to a provider of your choosing, or just change the server for one cert with
<literal><xref linkend="opt-security.acme.certs._name_.server" /></literal>.
</para>
@@ -60,12 +61,12 @@
= true;</literal> in a virtualHost config. We first create self-signed
placeholder certificates in place of the real ACME certs. The placeholder
certs are overwritten when the ACME certs arrive. For
<literal>foo.example.com</literal> the config would look like.
<literal>foo.example.com</literal> the config would look like this:
</para>
<programlisting>
<xref linkend="opt-security.acme.acceptTerms" /> = true;
<xref linkend="opt-security.acme.email" /> = "admin+acme@example.com";
<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
services.nginx = {
<link linkend="opt-services.nginx.enable">enable</link> = true;
<link linkend="opt-services.nginx.virtualHosts">virtualHosts</link> = {
@@ -114,7 +115,7 @@ services.nginx = {
<programlisting>
<xref linkend="opt-security.acme.acceptTerms" /> = true;
<xref linkend="opt-security.acme.email" /> = "admin+acme@example.com";
<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
# /var/lib/acme/.challenges must be writable by the ACME user
# and readable by the Nginx user. The easiest way to achieve
@@ -218,7 +219,7 @@ services.bind = {
# Now we can configure ACME
<xref linkend="opt-security.acme.acceptTerms" /> = true;
<xref linkend="opt-security.acme.email" /> = "admin+acme@example.com";
<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
<xref linkend="opt-security.acme.certs" />."example.com" = {
<link linkend="opt-security.acme.certs._name_.domain">domain</link> = "*.example.com";
<link linkend="opt-security.acme.certs._name_.dnsProvider">dnsProvider</link> = "rfc2136";
@@ -231,25 +232,39 @@ services.bind = {
<para>
The <filename>dnskeys.conf</filename> and <filename>certs.secret</filename>
must be kept secure and thus you should not keep their contents in your
Nix config. Instead, generate them one time with these commands:
Nix config. Instead, generate them one time with a systemd service:
</para>
<programlisting>
mkdir -p /var/lib/secrets
tsig-keygen rfc2136key.example.com &gt; /var/lib/secrets/dnskeys.conf
chown named:root /var/lib/secrets/dnskeys.conf
chmod 400 /var/lib/secrets/dnskeys.conf
systemd.services.dns-rfc2136-conf = {
requiredBy = ["acme-example.com.service", "bind.service"];
before = ["acme-example.com.service", "bind.service"];
unitConfig = {
ConditionPathExists = "!/var/lib/secrets/dnskeys.conf";
};
serviceConfig = {
Type = "oneshot";
UMask = 0077;
};
path = [ pkgs.bind ];
script = ''
mkdir -p /var/lib/secrets
tsig-keygen rfc2136key.example.com &gt; /var/lib/secrets/dnskeys.conf
chown named:root /var/lib/secrets/dnskeys.conf
chmod 400 /var/lib/secrets/dnskeys.conf
# Copy the secret value from the dnskeys.conf, and put it in
# RFC2136_TSIG_SECRET below
# Copy the secret value from the dnskeys.conf, and put it in
# RFC2136_TSIG_SECRET below
cat &gt; /var/lib/secrets/certs.secret &lt;&lt; EOF
RFC2136_NAMESERVER='127.0.0.1:53'
RFC2136_TSIG_ALGORITHM='hmac-sha256.'
RFC2136_TSIG_KEY='rfc2136key.example.com'
RFC2136_TSIG_SECRET='your secret key'
EOF
chmod 400 /var/lib/secrets/certs.secret
cat &gt; /var/lib/secrets/certs.secret &lt;&lt; EOF
RFC2136_NAMESERVER='127.0.0.1:53'
RFC2136_TSIG_ALGORITHM='hmac-sha256.'
RFC2136_TSIG_KEY='rfc2136key.example.com'
RFC2136_TSIG_SECRET='your secret key'
EOF
chmod 400 /var/lib/secrets/certs.secret
'';
};
</programlisting>
<para>
@@ -258,6 +273,106 @@ chmod 400 /var/lib/secrets/certs.secret
journalctl -fu acme-example.com.service</literal> and watching its log output.
</para>
</section>
<section xml:id="module-security-acme-config-dns-with-vhosts">
<title>Using DNS validation with web server virtual hosts</title>
<para>
It is possible to use DNS-01 validation with all certificates,
including those automatically configured via the Nginx/Apache
<literal><link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link></literal>
option. This configuration pattern is fully
supported and part of the module's test suite for Nginx + Apache.
</para>
<para>
You must follow the guide above on configuring DNS-01 validation
first, however instead of setting the options for one certificate
(e.g. <xref linkend="opt-security.acme.certs._name_.dnsProvider" />)
you will set them as defaults
(e.g. <xref linkend="opt-security.acme.defaults.dnsProvider" />).
</para>
<programlisting>
# Configure ACME appropriately
<xref linkend="opt-security.acme.acceptTerms" /> = true;
<xref linkend="opt-security.acme.defaults.email" /> = "admin+acme@example.com";
<xref linkend="opt-security.acme.defaults" /> = {
<link linkend="opt-security.acme.defaults.dnsProvider">dnsProvider</link> = "rfc2136";
<link linkend="opt-security.acme.defaults.credentialsFile">credentialsFile</link> = "/var/lib/secrets/certs.secret";
# We don't need to wait for propagation since this is a local DNS server
<link linkend="opt-security.acme.defaults.dnsPropagationCheck">dnsPropagationCheck</link> = false;
};
# For each virtual host you would like to use DNS-01 validation with,
# set acmeRoot = null
services.nginx = {
<link linkend="opt-services.nginx.enable">enable</link> = true;
<link linkend="opt-services.nginx.virtualHosts">virtualHosts</link> = {
"foo.example.com" = {
<link linkend="opt-services.nginx.virtualHosts._name_.enableACME">enableACME</link> = true;
<link linkend="opt-services.nginx.virtualHosts._name_.acmeRoot">acmeRoot</link> = null;
};
};
}
</programlisting>
<para>
And that's it! Next time your configuration is rebuilt, or when
you add a new virtualHost, it will be DNS-01 validated.
</para>
</section>
<section xml:id="module-security-acme-root-owned">
<title>Using ACME with services demanding root owned certificates</title>
<para>
Some services refuse to start if the configured certificate files
are not owned by root. PostgreSQL and OpenSMTPD are examples of these.
There is no way to change the user the ACME module uses (it will always be
<literal>acme</literal>), however you can use systemd's
<literal>LoadCredential</literal> feature to resolve this elegantly.
Below is an example configuration for OpenSMTPD, but this pattern
can be applied to any service.
</para>
<programlisting>
# Configure ACME however you like (DNS or HTTP validation), adding
# the following configuration for the relevant certificate.
# Note: You cannot use `systemctl reload` here as that would mean
# the LoadCredential configuration below would be skipped and
# the service would continue to use old certificates.
security.acme.certs."mail.example.com".postRun = ''
systemctl restart opensmtpd
'';
# Now you must augment OpenSMTPD's systemd service to load
# the certificate files.
<link linkend="opt-systemd.services._name_.requires">systemd.services.opensmtpd.requires</link> = ["acme-finished-mail.example.com.target"];
<link linkend="opt-systemd.services._name_.serviceConfig">systemd.services.opensmtpd.serviceConfig.LoadCredential</link> = let
certDir = config.security.acme.certs."mail.example.com".directory;
in [
"cert.pem:${certDir}/cert.pem"
"key.pem:${certDir}/key.pem"
];
# Finally, configure OpenSMTPD to use these certs.
services.opensmtpd = let
credsDir = "/run/credentials/opensmtpd.service";
in {
enable = true;
setSendmail = false;
serverConfiguration = ''
pki mail.example.com cert "${credsDir}/cert.pem"
pki mail.example.com key "${credsDir}/key.pem"
listen on localhost tls pki mail.example.com
action act1 relay host smtp://127.0.0.1:10027
match for local action act1
'';
};
</programlisting>
</section>
<section xml:id="module-security-acme-regenerate">
<title>Regenerating certificates</title>
+15 -2
View File
@@ -1,5 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
let
format = pkgs.formats.json { };
cfg = config.services.influxdb2;
@@ -9,12 +11,14 @@ in
options = {
services.influxdb2 = {
enable = mkEnableOption "the influxdb2 server";
package = mkOption {
default = pkgs.influxdb2-server;
defaultText = literalExpression "pkgs.influxdb2";
description = "influxdb2 derivation to use.";
type = types.package;
};
settings = mkOption {
default = { };
description = ''configuration options for influxdb2, see <link xlink:href="https://docs.influxdata.com/influxdb/v2.0/reference/config-options"/> for details.'';
@@ -28,18 +32,20 @@ in
assertion = !(builtins.hasAttr "bolt-path" cfg.settings) && !(builtins.hasAttr "engine-path" cfg.settings);
message = "services.influxdb2.config: bolt-path and engine-path should not be set as they are managed by systemd";
}];
systemd.services.influxdb2 = {
description = "InfluxDB is an open-source, distributed, time series database";
documentation = [ "https://docs.influxdata.com/influxdb/" ];
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = {
INFLUXD_CONFIG_PATH = "${configFile}";
INFLUXD_CONFIG_PATH = configFile;
};
serviceConfig = {
ExecStart = "${cfg.package}/bin/influxd --bolt-path \${STATE_DIRECTORY}/influxd.bolt --engine-path \${STATE_DIRECTORY}/engine";
StateDirectory = "influxdb2";
DynamicUser = true;
User = "influxdb2";
Group = "influxdb2";
CapabilityBoundingSet = "";
SystemCallFilter = "@system-service";
LimitNOFILE = 65536;
@@ -47,6 +53,13 @@ in
Restart = "on-failure";
};
};
users.extraUsers.influxdb2 = {
isSystemUser = true;
group = "influxdb2";
};
users.extraGroups.influxdb2 = {};
};
meta.maintainers = with lib.maintainers; [ nickcao ];
+44 -49
View File
@@ -28,38 +28,45 @@ let
}
'';
dhcpdService = postfix: cfg: optionalAttrs cfg.enable {
"dhcpd${postfix}" = {
description = "DHCPv${postfix} server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
dhcpdService = postfix: cfg:
let
configFile =
if cfg.configFile != null
then cfg.configFile
else writeConfig cfg;
leaseFile = "/var/lib/dhcpd${postfix}/dhcpd.leases";
args = [
"@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
"-pf" "/run/dhcpd${postfix}/dhcpd.pid"
"-cf" configFile
"-lf" leaseFile
] ++ cfg.extraFlags
++ cfg.interfaces;
in
optionalAttrs cfg.enable {
"dhcpd${postfix}" = {
description = "DHCPv${postfix} server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
preStart = ''
mkdir -m 755 -p ${cfg.stateDir}
chown dhcpd:nogroup ${cfg.stateDir}
touch ${cfg.stateDir}/dhcpd.leases
'';
serviceConfig =
let
configFile = if cfg.configFile != null then cfg.configFile else writeConfig cfg;
args = [ "@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
"-pf" "/run/dhcpd${postfix}/dhcpd.pid"
"-cf" "${configFile}"
"-lf" "${cfg.stateDir}/dhcpd.leases"
"-user" "dhcpd" "-group" "nogroup"
] ++ cfg.extraFlags
++ cfg.interfaces;
in {
ExecStart = concatMapStringsSep " " escapeShellArg args;
Type = "forking";
Restart = "always";
RuntimeDirectory = [ "dhcpd${postfix}" ];
PIDFile = "/run/dhcpd${postfix}/dhcpd.pid";
preStart = "touch ${leaseFile}";
serviceConfig = {
ExecStart = concatMapStringsSep " " escapeShellArg args;
Type = "forking";
Restart = "always";
DynamicUser = true;
User = "dhcpd";
Group = "dhcpd";
AmbientCapabilities = [
"CAP_NET_RAW" # to send ICMP messages
"CAP_NET_BIND_SERVICE" # to bind on DHCP port (67)
];
StateDirectory = "dhcpd${postfix}";
RuntimeDirectory = "dhcpd${postfix}";
PIDFile = "/run/dhcpd${postfix}/dhcpd.pid";
};
};
};
};
};
machineOpts = { ... }: {
@@ -102,15 +109,6 @@ let
'';
};
stateDir = mkOption {
type = types.path;
# We use /var/lib/dhcp for DHCPv4 to save backwards compatibility.
default = "/var/lib/dhcp${if postfix == "4" then "" else postfix}";
description = ''
State directory for the DHCP server.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
@@ -194,7 +192,13 @@ in
imports = [
(mkRenamedOptionModule [ "services" "dhcpd" ] [ "services" "dhcpd4" ])
];
] ++ flip map [ "4" "6" ] (postfix:
mkRemovedOptionModule [ "services" "dhcpd${postfix}" "stateDir" ] ''
The DHCP server state directory is now managed with the systemd's DynamicUser mechanism.
This means the directory is named after the service (dhcpd${postfix}), created under
/var/lib/private/ and symlinked to /var/lib/.
''
);
###### interface
@@ -210,15 +214,6 @@ in
config = mkIf (cfg4.enable || cfg6.enable) {
users = {
users.dhcpd = {
isSystemUser = true;
group = "dhcpd";
description = "DHCP daemon user";
};
groups.dhcpd = {};
};
systemd.services = dhcpdService "4" cfg4 // dhcpdService "6" cfg6;
};
+5 -1
View File
@@ -236,6 +236,7 @@ in
environment = {
KEA_PIDFILE_DIR = "/run/kea";
KEA_LOCKFILE_DIR = "/run/kea";
};
restartTriggers = [
@@ -271,6 +272,7 @@ in
environment = {
KEA_PIDFILE_DIR = "/run/kea";
KEA_LOCKFILE_DIR = "/run/kea";
};
restartTriggers = [
@@ -313,6 +315,7 @@ in
environment = {
KEA_PIDFILE_DIR = "/run/kea";
KEA_LOCKFILE_DIR = "/run/kea";
};
restartTriggers = [
@@ -353,6 +356,7 @@ in
environment = {
KEA_PIDFILE_DIR = "/run/kea";
KEA_LOCKFILE_DIR = "/run/kea";
};
restartTriggers = [
@@ -361,7 +365,7 @@ in
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp-ddns -c /etc/kea/dhcp-ddns.conf ${lib.escapeShellArgs cfg.dhcp-ddns.extraArgs}";
AmbientCapabilites = [
AmbientCapabilities = [
"CAP_NET_BIND_SERVICE"
];
CapabilityBoundingSet = [
@@ -72,7 +72,7 @@ services.prosody = {
a TLS certificate for the three endponits:
<programlisting>
security.acme = {
<link linkend="opt-security.acme.email">email</link> = "root@example.org";
<link linkend="opt-security.acme.defaults.email">email</link> = "root@example.org";
<link linkend="opt-security.acme.acceptTerms">acceptTerms</link> = true;
<link linkend="opt-security.acme.certs">certs</link> = {
"example.org" = {
@@ -25,7 +25,7 @@ services.discourse = {
};
<link linkend="opt-services.discourse.secretKeyBaseFile">secretKeyBaseFile</link> = "/path/to/secret_key_base_file";
};
<link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com";
<link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com";
<link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true;
</programlisting>
</para>
@@ -20,7 +20,7 @@
};
<link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true;
<link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ];
<link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com";
<link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com";
<link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true;
}</programlisting>
</para>
@@ -46,7 +46,7 @@
};
<link linkend="opt-services.jitsi-videobridge.openFirewall">services.jitsi-videobridge.openFirewall</link> = true;
<link linkend="opt-networking.firewall.allowedTCPPorts">networking.firewall.allowedTCPPorts</link> = [ 80 443 ];
<link linkend="opt-security.acme.email">security.acme.email</link> = "me@example.com";
<link linkend="opt-security.acme.defaults.email">security.acme.email</link> = "me@example.com";
<link linkend="opt-security.acme.acceptTerms">security.acme.acceptTerms</link> = true;
}</programlisting>
</para>
@@ -154,7 +154,7 @@ let
sslServerKey = if useACME then "${sslCertDir}/key.pem" else hostOpts.sslServerKey;
sslServerChain = if useACME then "${sslCertDir}/chain.pem" else hostOpts.sslServerChain;
acmeChallenge = optionalString useACME ''
acmeChallenge = optionalString (useACME && hostOpts.acmeRoot != null) ''
Alias /.well-known/acme-challenge/ "${hostOpts.acmeRoot}/.well-known/acme-challenge/"
<Directory "${hostOpts.acmeRoot}">
AllowOverride None
@@ -677,9 +677,16 @@ in
};
security.acme.certs = let
acmePairs = map (hostOpts: nameValuePair hostOpts.hostName {
acmePairs = map (hostOpts: let
hasRoot = hostOpts.acmeRoot != null;
in nameValuePair hostOpts.hostName {
group = mkDefault cfg.group;
webroot = hostOpts.acmeRoot;
# if acmeRoot is null inherit config.security.acme
# Since config.security.acme.certs.<cert>.webroot's own default value
# should take precedence set priority higher than mkOptionDefault
webroot = mkOverride (if hasRoot then 1000 else 2000) hostOpts.acmeRoot;
# Also nudge dnsProvider to null in case it is inherited
dnsProvider = mkOverride (if hasRoot then 1000 else 2000) null;
extraDomainNames = hostOpts.serverAliases;
# Use the vhost-specific email address if provided, otherwise let
# security.acme.email or security.acme.certs.<cert>.email be used.
@@ -128,9 +128,12 @@ in
};
acmeRoot = mkOption {
type = types.str;
type = types.nullOr types.str;
default = "/var/lib/acme/acme-challenge";
description = "Directory for the acme challenge which is PUBLIC, don't put certs or keys in here";
description = ''
Directory for the acme challenge which is PUBLIC, don't put certs or keys in here.
Set to null to inherit from config.security.acme.
'';
};
sslServerCert = mkOption {
@@ -278,7 +278,7 @@ let
acmeLocation = optionalString (vhost.enableACME || vhost.useACMEHost != null) ''
location /.well-known/acme-challenge {
${optionalString (vhost.acmeFallbackHost != null) "try_files $uri @acme-fallback;"}
root ${vhost.acmeRoot};
${optionalString (vhost.acmeRoot != null) "root ${vhost.acmeRoot};"}
auth_basic off;
}
${optionalString (vhost.acmeFallbackHost != null) ''
@@ -948,9 +948,16 @@ in
};
security.acme.certs = let
acmePairs = map (vhostConfig: nameValuePair vhostConfig.serverName {
acmePairs = map (vhostConfig: let
hasRoot = vhostConfig.acmeRoot != null;
in nameValuePair vhostConfig.serverName {
group = mkDefault cfg.group;
webroot = vhostConfig.acmeRoot;
# if acmeRoot is null inherit config.security.acme
# Since config.security.acme.certs.<cert>.webroot's own default value
# should take precedence set priority higher than mkOptionDefault
webroot = mkOverride (if hasRoot then 1000 else 2000) vhostConfig.acmeRoot;
# Also nudge dnsProvider to null in case it is inherited
dnsProvider = mkOverride (if hasRoot then 1000 else 2000) null;
extraDomainNames = vhostConfig.serverAliases;
# Filter for enableACME-only vhosts. Don't want to create dud certs
}) (filter (vhostConfig: vhostConfig.useACMEHost == null) acmeEnabledVhosts);
@@ -3,7 +3,7 @@
# has additional options that affect the web server as a whole, like
# the user/group to run under.)
{ lib, ... }:
{ config, lib, ... }:
with lib;
{
@@ -85,9 +85,12 @@ with lib;
};
acmeRoot = mkOption {
type = types.str;
type = types.nullOr types.str;
default = "/var/lib/acme/acme-challenge";
description = "Directory for the acme challenge which is PUBLIC, don't put certs or keys in here";
description = ''
Directory for the acme challenge which is PUBLIC, don't put certs or keys in here.
Set to null to inherit from config.security.acme.
'';
};
acmeFallbackHost = mkOption {
@@ -0,0 +1,98 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.virtualisation.docker.rootless;
proxy_env = config.networking.proxy.envVars;
settingsFormat = pkgs.formats.json {};
daemonSettingsFile = settingsFormat.generate "daemon.json" cfg.daemon.settings;
in
{
###### interface
options.virtualisation.docker.rootless = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
This option enables docker in a rootless mode, a daemon that manages
linux containers. To interact with the daemon, one needs to set
<command>DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock</command>.
'';
};
setSocketVariable = mkOption {
type = types.bool;
default = false;
description = ''
Point <command>DOCKER_HOST</command> to rootless Docker instance for
normal users by default.
'';
};
daemon.settings = mkOption {
type = settingsFormat.type;
default = { };
example = {
ipv6 = true;
"fixed-cidr-v6" = "fd00::/80";
};
description = ''
Configuration for docker daemon. The attributes are serialized to JSON used as daemon.conf.
See https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
'';
};
package = mkOption {
default = pkgs.docker;
defaultText = literalExpression "pkgs.docker";
type = types.package;
example = literalExpression "pkgs.docker-edge";
description = ''
Docker package to be used in the module.
'';
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.extraInit = optionalString cfg.setSocketVariable ''
if [ -z "$DOCKER_HOST" -a -n "$XDG_RUNTIME_DIR" ]; then
export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"
fi
'';
# Taken from https://github.com/moby/moby/blob/master/contrib/dockerd-rootless-setuptool.sh
systemd.user.services.docker = {
wantedBy = [ "default.target" ];
description = "Docker Application Container Engine (Rootless)";
# needs newuidmap from pkgs.shadow
path = [ "/run/wrappers" ];
environment = proxy_env;
unitConfig.StartLimitInterval = "60s";
serviceConfig = {
Type = "notify";
ExecStart = "${cfg.package}/bin/dockerd-rootless --config-file=${daemonSettingsFile}";
ExecReload = "${pkgs.procps}/bin/kill -s HUP $MAINPID";
TimeoutSec = 0;
RestartSec = 2;
Restart = "always";
StartLimitBurst = 3;
LimitNOFILE = "infinity";
LimitNPROC = "infinity";
LimitCORE = "infinity";
Delegate = true;
NotifyAccess = "all";
KillMode = "mixed";
};
};
};
}
+366 -210
View File
@@ -1,9 +1,9 @@
let
import ./make-test-python.nix ({ pkgs, lib, ... }: let
commonConfig = ./common/acme/client;
dnsServerIP = nodes: nodes.dnsserver.config.networking.primaryIPAddress;
dnsScript = {pkgs, nodes}: let
dnsScript = nodes: let
dnsAddress = dnsServerIP nodes;
in pkgs.writeShellScript "dns-hook.sh" ''
set -euo pipefail
@@ -15,30 +15,137 @@ let
fi
'';
documentRoot = pkgs: pkgs.runCommand "docroot" {} ''
dnsConfig = nodes: {
dnsProvider = "exec";
dnsPropagationCheck = false;
credentialsFile = pkgs.writeText "wildcard.env" ''
EXEC_PATH=${dnsScript nodes}
EXEC_POLLING_INTERVAL=1
EXEC_PROPAGATION_TIMEOUT=1
EXEC_SEQUENCE_INTERVAL=1
'';
};
documentRoot = pkgs.runCommand "docroot" {} ''
mkdir -p "$out"
echo hello world > "$out/index.html"
'';
vhostBase = pkgs: {
vhostBase = {
forceSSL = true;
locations."/".root = documentRoot pkgs;
locations."/".root = documentRoot;
};
in import ./make-test-python.nix ({ lib, ... }: {
vhostBaseHttpd = {
forceSSL = true;
inherit documentRoot;
};
# Base specialisation config for testing general ACME features
webserverBasicConfig = {
services.nginx.enable = true;
services.nginx.virtualHosts."a.example.test" = vhostBase // {
enableACME = true;
};
};
# Generate specialisations for testing a web server
mkServerConfigs = { server, group, vhostBaseData, extraConfig ? {} }: let
baseConfig = { nodes, config, specialConfig ? {} }: lib.mkMerge [
{
security.acme = {
defaults = (dnsConfig nodes) // {
inherit group;
};
# One manual wildcard cert
certs."example.test" = {
domain = "*.example.test";
};
};
services."${server}" = {
enable = true;
virtualHosts = {
# Run-of-the-mill vhost using HTTP-01 validation
"${server}-http.example.test" = vhostBaseData // {
serverAliases = [ "${server}-http-alias.example.test" ];
enableACME = true;
};
# Another which inherits the DNS-01 config
"${server}-dns.example.test" = vhostBaseData // {
serverAliases = [ "${server}-dns-alias.example.test" ];
enableACME = true;
# Set acmeRoot to null instead of using the default of "/var/lib/acme/acme-challenge"
# webroot + dnsProvider are mutually exclusive.
acmeRoot = null;
};
# One using the wildcard certificate
"${server}-wildcard.example.test" = vhostBaseData // {
serverAliases = [ "${server}-wildcard-alias.example.test" ];
useACMEHost = "example.test";
};
};
};
# Used to determine if service reload was triggered
systemd.targets."test-renew-${server}" = {
wants = [ "acme-${server}-http.example.test.service" ];
after = [ "acme-${server}-http.example.test.service" "${server}-config-reload.service" ];
};
}
specialConfig
extraConfig
];
in {
"${server}".configuration = { nodes, config, ... }: baseConfig {
inherit nodes config;
};
# Test that server reloads when an alias is removed (and subsequently test removal works in acme)
"${server}-remove-alias".configuration = { nodes, config, ... }: baseConfig {
inherit nodes config;
specialConfig = {
# Remove an alias, but create a standalone vhost in its place for testing.
# This configuration results in certificate errors as useACMEHost does not imply
# append extraDomains, and thus we can validate the SAN is removed.
services."${server}" = {
virtualHosts."${server}-http.example.test".serverAliases = lib.mkForce [];
virtualHosts."${server}-http-alias.example.test" = vhostBaseData // {
useACMEHost = "${server}-http.example.test";
};
};
};
};
# Test that the server reloads when only the acme configuration is changed.
"${server}-change-acme-conf".configuration = { nodes, config, ... }: baseConfig {
inherit nodes config;
specialConfig = {
security.acme.certs."${server}-http.example.test" = {
keyType = "ec384";
# Also test that postRun is exec'd as root
postRun = "id | grep root";
};
};
};
};
in {
name = "acme";
meta.maintainers = lib.teams.acme.members;
nodes = {
# The fake ACME server which will respond to client requests
acme = { nodes, lib, ... }: {
acme = { nodes, ... }: {
imports = [ ./common/acme/server ];
networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ];
};
# A fake DNS server which can be configured with records as desired
# Used to test DNS-01 challenge
dnsserver = { nodes, pkgs, ... }: {
dnsserver = { nodes, ... }: {
networking.firewall.allowedTCPPorts = [ 8055 53 ];
networking.firewall.allowedUDPPorts = [ 53 ];
systemd.services.pebble-challtestsrv = {
@@ -54,7 +161,7 @@ in import ./make-test-python.nix ({ lib, ... }: {
};
# A web server which will be the node requesting certs
webserver = { pkgs, nodes, lib, config, ... }: {
webserver = { nodes, config, ... }: {
imports = [ commonConfig ];
networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
@@ -63,130 +170,142 @@ in import ./make-test-python.nix ({ lib, ... }: {
environment.systemPackages = [ pkgs.openssl ];
# Set log level to info so that we can see when the service is reloaded
services.nginx.enable = true;
services.nginx.logError = "stderr info";
# First tests configure a basic cert and run a bunch of openssl checks
services.nginx.virtualHosts."a.example.test" = (vhostBase pkgs) // {
enableACME = true;
};
specialisation = {
# First derivation used to test general ACME features
general.configuration = { ... }: let
caDomain = nodes.acme.config.test-support.acme.caDomain;
email = config.security.acme.defaults.email;
# Exit 99 to make it easier to track if this is the reason a renew failed
accountCreateTester = ''
test -e accounts/${caDomain}/${email}/account.json || exit 99
'';
in lib.mkMerge [
webserverBasicConfig
{
# Used to test that account creation is collated into one service.
# These should not run until after acme-finished-a.example.test.target
systemd.services."b.example.test".preStart = accountCreateTester;
systemd.services."c.example.test".preStart = accountCreateTester;
# Used to determine if service reload was triggered
systemd.targets.test-renew-nginx = {
wants = [ "acme-a.example.test.service" ];
after = [ "acme-a.example.test.service" "nginx-config-reload.service" ];
};
services.nginx.virtualHosts."b.example.test" = vhostBase // {
enableACME = true;
};
services.nginx.virtualHosts."c.example.test" = vhostBase // {
enableACME = true;
};
}
];
# Test that account creation is collated into one service
specialisation.account-creation.configuration = { nodes, pkgs, lib, ... }: let
email = "newhostmaster@example.test";
caDomain = nodes.acme.config.test-support.acme.caDomain;
# Exit 99 to make it easier to track if this is the reason a renew failed
testScript = ''
test -e accounts/${caDomain}/${email}/account.json || exit 99
'';
# Test OCSP Stapling
ocsp-stapling.configuration = { ... }: lib.mkMerge [
webserverBasicConfig
{
security.acme.certs."a.example.test".ocspMustStaple = true;
services.nginx.virtualHosts."a.example.test" = {
extraConfig = ''
ssl_stapling on;
ssl_stapling_verify on;
'';
};
}
];
# Validate service relationships by adding a slow start service to nginx' wants.
# Reproducer for https://github.com/NixOS/nixpkgs/issues/81842
slow-startup.configuration = { ... }: lib.mkMerge [
webserverBasicConfig
{
systemd.services.my-slow-service = {
wantedBy = [ "multi-user.target" "nginx.service" ];
before = [ "nginx.service" ];
preStart = "sleep 5";
script = "${pkgs.python3}/bin/python -m http.server";
};
services.nginx.virtualHosts."slow.example.test" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://localhost:8000";
};
}
];
# Test lego internal server (listenHTTP option)
# Also tests useRoot option
lego-server.configuration = { ... }: {
security.acme.useRoot = true;
security.acme.certs."lego.example.test" = {
listenHTTP = ":80";
group = "nginx";
};
services.nginx.enable = true;
services.nginx.virtualHosts."lego.example.test" = {
useACMEHost = "lego.example.test";
onlySSL = true;
};
};
# Test compatiblity with Caddy
# It only supports useACMEHost, hence not using mkServerConfigs
} // (let
baseCaddyConfig = { nodes, config, ... }: {
security.acme = {
defaults = (dnsConfig nodes) // {
group = config.services.caddy.group;
};
# One manual wildcard cert
certs."example.test" = {
domain = "*.example.test";
};
};
services.caddy = {
enable = true;
virtualHosts."a.exmaple.test" = {
useACMEHost = "example.test";
extraConfig = ''
root * ${documentRoot}
'';
};
};
};
in {
security.acme.email = lib.mkForce email;
systemd.services."b.example.test".preStart = testScript;
systemd.services."c.example.test".preStart = testScript;
caddy.configuration = baseCaddyConfig;
services.nginx.virtualHosts."b.example.test" = (vhostBase pkgs) // {
enableACME = true;
};
services.nginx.virtualHosts."c.example.test" = (vhostBase pkgs) // {
enableACME = true;
};
};
# Test that the server reloads when only the acme configuration is changed.
"caddy-change-acme-conf".configuration = { nodes, config, ... }: lib.mkMerge [
(baseCaddyConfig {
inherit nodes config;
})
{
security.acme.certs."example.test" = {
keyType = "ec384";
};
}
];
# Cert config changes will not cause the nginx configuration to change.
# This tests that the reload service is correctly triggered.
# It also tests that postRun is exec'd as root
specialisation.cert-change.configuration = { pkgs, ... }: {
security.acme.certs."a.example.test".keyType = "ec384";
security.acme.certs."a.example.test".postRun = ''
set -euo pipefail
touch /home/test
chown root:root /home/test
echo testing > /home/test
'';
};
# Test compatibility with Nginx
}) // (mkServerConfigs {
server = "nginx";
group = "nginx";
vhostBaseData = vhostBase;
})
# Now adding an alias to ensure that the certs are updated
specialisation.nginx-aliases.configuration = { pkgs, ... }: {
services.nginx.virtualHosts."a.example.test" = {
serverAliases = [ "b.example.test" ];
};
};
# Test OCSP Stapling
specialisation.ocsp-stapling.configuration = { pkgs, ... }: {
security.acme.certs."a.example.test" = {
ocspMustStaple = true;
};
services.nginx.virtualHosts."a.example.com" = {
extraConfig = ''
ssl_stapling on;
ssl_stapling_verify on;
'';
};
};
# Test using Apache HTTPD
specialisation.httpd-aliases.configuration = { pkgs, config, lib, ... }: {
services.nginx.enable = lib.mkForce false;
services.httpd.enable = true;
services.httpd.adminAddr = config.security.acme.email;
services.httpd.virtualHosts."c.example.test" = {
serverAliases = [ "d.example.test" ];
forceSSL = true;
enableACME = true;
documentRoot = documentRoot pkgs;
};
# Used to determine if service reload was triggered
systemd.targets.test-renew-httpd = {
wants = [ "acme-c.example.test.service" ];
after = [ "acme-c.example.test.service" "httpd-config-reload.service" ];
};
};
# Validation via DNS-01 challenge
specialisation.dns-01.configuration = { pkgs, config, nodes, ... }: {
security.acme.certs."example.test" = {
domain = "*.example.test";
group = config.services.nginx.group;
dnsProvider = "exec";
dnsPropagationCheck = false;
credentialsFile = pkgs.writeText "wildcard.env" ''
EXEC_PATH=${dnsScript { inherit pkgs nodes; }}
'';
};
services.nginx.virtualHosts."dns.example.test" = (vhostBase pkgs) // {
useACMEHost = "example.test";
};
};
# Validate service relationships by adding a slow start service to nginx' wants.
# Reproducer for https://github.com/NixOS/nixpkgs/issues/81842
specialisation.slow-startup.configuration = { pkgs, config, nodes, lib, ... }: {
systemd.services.my-slow-service = {
wantedBy = [ "multi-user.target" "nginx.service" ];
before = [ "nginx.service" ];
preStart = "sleep 5";
script = "${pkgs.python3}/bin/python -m http.server";
};
services.nginx.virtualHosts."slow.example.com" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://localhost:8000";
};
};
# Test compatibility with Apache HTTPD
// (mkServerConfigs {
server = "httpd";
group = "wwwrun";
vhostBaseData = vhostBaseHttpd;
extraConfig = {
services.httpd.adminAddr = config.security.acme.defaults.email;
};
});
};
# The client will be used to curl the webserver to validate configuration
client = {nodes, lib, pkgs, ...}: {
client = { nodes, ... }: {
imports = [ commonConfig ];
networking.nameservers = lib.mkForce [ (dnsServerIP nodes) ];
@@ -195,7 +314,7 @@ in import ./make-test-python.nix ({ lib, ... }: {
};
};
testScript = {nodes, ...}:
testScript = { nodes, ... }:
let
caDomain = nodes.acme.config.test-support.acme.caDomain;
newServerSystem = nodes.webserver.config.system.build.toplevel;
@@ -204,23 +323,26 @@ in import ./make-test-python.nix ({ lib, ... }: {
# Note, wait_for_unit does not work for oneshot services that do not have RemainAfterExit=true,
# this is because a oneshot goes from inactive => activating => inactive, and never
# reaches the active state. Targets do not have this issue.
''
import time
has_switched = False
def switch_to(node, name):
global has_switched
if has_switched:
node.succeed(
"${switchToNewServer}"
)
has_switched = True
# On first switch, this will create a symlink to the current system so that we can
# quickly switch between derivations
root_specs = "/tmp/specialisation"
node.execute(
f"test -e {root_specs}"
f" || ln -s $(readlink /run/current-system)/specialisation {root_specs}"
)
switcher_path = f"/run/current-system/specialisation/{name}/bin/switch-to-configuration"
rc, _ = node.execute(f"test -e '{switcher_path}'")
if rc > 0:
switcher_path = f"/tmp/specialisation/{name}/bin/switch-to-configuration"
node.succeed(
f"/run/current-system/specialisation/{name}/bin/switch-to-configuration test"
f"{switcher_path} test"
)
@@ -310,8 +432,7 @@ in import ./make-test-python.nix ({ lib, ... }: {
return download_ca_certs(node, retries - 1)
client.start()
dnsserver.start()
start_all()
dnsserver.wait_for_unit("pebble-challtestsrv.service")
client.wait_for_unit("default.target")
@@ -320,19 +441,30 @@ in import ./make-test-python.nix ({ lib, ... }: {
'curl --data \'{"host": "${caDomain}", "addresses": ["${nodes.acme.config.networking.primaryIPAddress}"]}\' http://${dnsServerIP nodes}:8055/add-a'
)
acme.start()
webserver.start()
acme.wait_for_unit("network-online.target")
acme.wait_for_unit("pebble.service")
download_ca_certs(client)
with subtest("Can request certificate with HTTPS-01 challenge"):
# Perform general tests first
switch_to(webserver, "general")
with subtest("Can request certificate with HTTP-01 challenge"):
webserver.wait_for_unit("acme-finished-a.example.test.target")
check_fullchain(webserver, "a.example.test")
check_issuer(webserver, "a.example.test", "pebble")
webserver.wait_for_unit("nginx.service")
check_connection(client, "a.example.test")
with subtest("Runs 1 cert for account creation before others"):
webserver.wait_for_unit("acme-finished-b.example.test.target")
webserver.wait_for_unit("acme-finished-c.example.test.target")
check_connection(client, "b.example.test")
check_connection(client, "c.example.test")
with subtest("Certificates and accounts have safe + valid permissions"):
group = "${nodes.webserver.config.security.acme.certs."a.example.test".group}"
# Nginx will set the group appropriately when enableACME is used
group = "nginx"
webserver.succeed(
f"test $(stat -L -c '%a %U %G' /var/lib/acme/a.example.test/*.pem | tee /dev/stderr | grep '640 acme {group}' | wc -l) -eq 5"
)
@@ -346,12 +478,6 @@ in import ./make-test-python.nix ({ lib, ... }: {
f"test $(find /var/lib/acme/accounts -type f -exec stat -L -c '%a %U %G' {{}} \\; | tee /dev/stderr | grep -v '600 acme {group}' | wc -l) -eq 0"
)
with subtest("Certs are accepted by web server"):
webserver.succeed("systemctl start nginx.service")
check_fullchain(webserver, "a.example.test")
check_issuer(webserver, "a.example.test", "pebble")
check_connection(client, "a.example.test")
# Selfsigned certs tests happen late so we aren't fighting the system init triggering cert renewal
with subtest("Can generate valid selfsigned certs"):
webserver.succeed("systemctl clean acme-a.example.test.service --what=state")
@@ -365,77 +491,107 @@ in import ./make-test-python.nix ({ lib, ... }: {
# Will succeed if nginx can load the certs
webserver.succeed("systemctl start nginx-config-reload.service")
with subtest("Can reload nginx when timer triggers renewal"):
webserver.succeed("systemctl start test-renew-nginx.target")
check_issuer(webserver, "a.example.test", "pebble")
check_connection(client, "a.example.test")
with subtest("Runs 1 cert for account creation before others"):
switch_to(webserver, "account-creation")
webserver.wait_for_unit("acme-finished-a.example.test.target")
check_connection(client, "a.example.test")
webserver.wait_for_unit("acme-finished-b.example.test.target")
webserver.wait_for_unit("acme-finished-c.example.test.target")
check_connection(client, "b.example.test")
check_connection(client, "c.example.test")
with subtest("Can reload web server when cert configuration changes"):
switch_to(webserver, "cert-change")
webserver.wait_for_unit("acme-finished-a.example.test.target")
check_connection_key_bits(client, "a.example.test", "384")
webserver.succeed("grep testing /home/test")
# Clean to remove the testing file (and anything else messy we did)
webserver.succeed("systemctl clean acme-a.example.test.service --what=state")
with subtest("Correctly implements OCSP stapling"):
switch_to(webserver, "ocsp-stapling")
webserver.wait_for_unit("acme-finished-a.example.test.target")
check_stapling(client, "a.example.test")
with subtest("Can request certificate with HTTPS-01 when nginx startup is delayed"):
switch_to(webserver, "slow-startup")
webserver.wait_for_unit("acme-finished-slow.example.com.target")
check_issuer(webserver, "slow.example.com", "pebble")
check_connection(client, "slow.example.com")
with subtest("Can request certificate for vhost + aliases (nginx)"):
# Check the key hash before and after adding an alias. It should not change.
# The previous test reverts the ed384 change
webserver.wait_for_unit("acme-finished-a.example.test.target")
switch_to(webserver, "nginx-aliases")
webserver.wait_for_unit("acme-finished-a.example.test.target")
check_issuer(webserver, "a.example.test", "pebble")
with subtest("Can request certificate with HTTP-01 using lego's internal web server"):
switch_to(webserver, "lego-server")
webserver.wait_for_unit("acme-finished-lego.example.test.target")
webserver.wait_for_unit("nginx.service")
webserver.succeed("echo HENLO && systemctl cat nginx.service")
webserver.succeed("test \"$(stat -c '%U' /var/lib/acme/* | uniq)\" = \"root\"")
check_connection(client, "a.example.test")
check_connection(client, "b.example.test")
check_connection(client, "lego.example.test")
with subtest("Can request certificates for vhost + aliases (apache-httpd)"):
try:
switch_to(webserver, "httpd-aliases")
webserver.wait_for_unit("acme-finished-c.example.test.target")
except Exception as err:
_, output = webserver.execute(
"cat /var/log/httpd/*.log && ls -al /var/lib/acme/acme-challenge"
)
print(output)
raise err
check_issuer(webserver, "c.example.test", "pebble")
check_connection(client, "c.example.test")
check_connection(client, "d.example.test")
with subtest("Can request certificate with HTTP-01 when nginx startup is delayed"):
webserver.execute("systemctl stop nginx")
switch_to(webserver, "slow-startup")
webserver.wait_for_unit("acme-finished-slow.example.test.target")
check_issuer(webserver, "slow.example.test", "pebble")
webserver.wait_for_unit("nginx.service")
check_connection(client, "slow.example.test")
with subtest("Can reload httpd when timer triggers renewal"):
# Switch to selfsigned first
webserver.succeed("systemctl clean acme-c.example.test.service --what=state")
webserver.succeed("systemctl start acme-selfsigned-c.example.test.service")
check_issuer(webserver, "c.example.test", "minica")
webserver.succeed("systemctl start httpd-config-reload.service")
webserver.succeed("systemctl start test-renew-httpd.target")
check_issuer(webserver, "c.example.test", "pebble")
check_connection(client, "c.example.test")
with subtest("Can request wildcard certificates using DNS-01 challenge"):
switch_to(webserver, "dns-01")
with subtest("Works with caddy"):
switch_to(webserver, "caddy")
webserver.wait_for_unit("acme-finished-example.test.target")
check_issuer(webserver, "example.test", "pebble")
check_connection(client, "dns.example.test")
webserver.wait_for_unit("caddy.service")
# FIXME reloading caddy is not sufficient to load new certs.
# Restart it manually until this is fixed.
webserver.succeed("systemctl restart caddy.service")
check_connection(client, "a.example.test")
with subtest("security.acme changes reflect on caddy"):
switch_to(webserver, "caddy-change-acme-conf")
webserver.wait_for_unit("acme-finished-example.test.target")
webserver.wait_for_unit("caddy.service")
# FIXME reloading caddy is not sufficient to load new certs.
# Restart it manually until this is fixed.
webserver.succeed("systemctl restart caddy.service")
check_connection_key_bits(client, "a.example.test", "384")
domains = ["http", "dns", "wildcard"]
for server, logsrc in [
("nginx", "journalctl -n 30 -u nginx.service"),
("httpd", "tail -n 30 /var/log/httpd/*.log"),
]:
wait_for_server = lambda: webserver.wait_for_unit(f"{server}.service")
with subtest(f"Works with {server}"):
try:
switch_to(webserver, server)
# Skip wildcard domain for this check ([:-1])
for domain in domains[:-1]:
webserver.wait_for_unit(
f"acme-finished-{server}-{domain}.example.test.target"
)
except Exception as err:
_, output = webserver.execute(
f"{logsrc} && ls -al /var/lib/acme/acme-challenge"
)
print(output)
raise err
wait_for_server()
for domain in domains[:-1]:
check_issuer(webserver, f"{server}-{domain}.example.test", "pebble")
for domain in domains:
check_connection(client, f"{server}-{domain}.example.test")
check_connection(client, f"{server}-{domain}-alias.example.test")
test_domain = f"{server}-{domains[0]}.example.test"
with subtest(f"Can reload {server} when timer triggers renewal"):
# Switch to selfsigned first
webserver.succeed(f"systemctl clean acme-{test_domain}.service --what=state")
webserver.succeed(f"systemctl start acme-selfsigned-{test_domain}.service")
check_issuer(webserver, test_domain, "minica")
webserver.succeed(f"systemctl start {server}-config-reload.service")
webserver.succeed(f"systemctl start test-renew-{server}.target")
check_issuer(webserver, test_domain, "pebble")
check_connection(client, test_domain)
with subtest("Can remove an alias from a domain + cert is updated"):
test_alias = f"{server}-{domains[0]}-alias.example.test"
switch_to(webserver, f"{server}-remove-alias")
webserver.wait_for_unit(f"acme-finished-{test_domain}.target")
wait_for_server()
check_connection(client, test_domain)
rc, _ = client.execute(
f"openssl s_client -CAfile /tmp/ca.crt -connect {test_alias}:443"
" </dev/null 2>/dev/null | openssl x509 -noout -text"
f" | grep DNS: | grep {test_alias}"
)
assert rc > 0, "Removed extraDomainName was not removed from the cert"
with subtest("security.acme changes reflect on web server"):
# Switch back to normal server config first, reset everything.
switch_to(webserver, server)
wait_for_server()
switch_to(webserver, f"{server}-change-acme-conf")
webserver.wait_for_unit(f"acme-finished-{test_domain}.target")
wait_for_server()
check_connection_key_bits(client, test_domain, "384")
'';
})
+1
View File
@@ -105,6 +105,7 @@ in
dnscrypt-wrapper = handleTestOn ["x86_64-linux"] ./dnscrypt-wrapper {};
doas = handleTest ./doas.nix {};
docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
docker-rootless = handleTestOn ["x86_64-linux"] ./docker-rootless.nix {};
docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {};
docker-registry = handleTest ./docker-registry.nix {};
docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {};
+4 -2
View File
@@ -5,9 +5,11 @@ let
in {
security.acme = {
server = "https://${caDomain}/dir";
email = "hostmaster@example.test";
acceptTerms = true;
defaults = {
server = "https://${caDomain}/dir";
email = "hostmaster@example.test";
};
};
security.pki.certificateFiles = [ caCert ];
@@ -120,6 +120,11 @@ in {
enable = true;
description = "Pebble ACME server";
wantedBy = [ "network.target" ];
environment = {
# We're not testing lego, we're just testing our configuration.
# No need to sleep.
PEBBLE_VA_NOSLEEP = "1";
};
serviceConfig = {
RuntimeDirectory = "pebble";
+41
View File
@@ -0,0 +1,41 @@
# This test runs docker and checks if simple container starts
import ./make-test-python.nix ({ lib, pkgs, ...} : {
name = "docker-rootless";
meta = with pkgs.lib.maintainers; {
maintainers = [ abbradar ];
};
nodes = {
machine = { pkgs, ... }: {
virtualisation.docker.rootless.enable = true;
users.users.alice = {
uid = 1000;
isNormalUser = true;
};
};
};
testScript = { nodes, ... }:
let
user = nodes.machine.config.users.users.alice;
sudo = lib.concatStringsSep " " [
"XDG_RUNTIME_DIR=/run/user/${toString user.uid}"
"DOCKER_HOST=unix:///run/user/${toString user.uid}/docker.sock"
"sudo" "--preserve-env=XDG_RUNTIME_DIR,DOCKER_HOST" "-u" "alice"
];
in ''
machine.wait_for_unit("multi-user.target")
machine.succeed("loginctl enable-linger alice")
machine.wait_until_succeeds("${sudo} systemctl --user is-active docker.service")
machine.succeed("tar cv --files-from /dev/null | ${sudo} docker import - scratchimg")
machine.succeed(
"${sudo} docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
)
machine.succeed("${sudo} docker ps | grep sleeping")
machine.succeed("${sudo} docker stop sleeping")
'';
})
@@ -9,6 +9,8 @@ lib.makeScope newScope (self: with self; {
mopidy-iris = callPackage ./iris.nix { };
mopidy-jellyfin = callPackage ./jellyfin.nix { };
mopidy-local = callPackage ./local.nix { };
mopidy-moped = callPackage ./moped.nix { };
@@ -0,0 +1,25 @@
{ lib, python3Packages, mopidy }:
python3Packages.buildPythonApplication rec {
pname = "mopidy-jellyfin";
version = "1.0.2";
src = python3Packages.fetchPypi {
inherit version;
pname = "Mopidy-Jellyfin";
sha256 = "0j7v5xx3c401r5dw1sqm1n2263chjga1d3ml85rg79hjhhhacy75";
};
propagatedBuildInputs = [ mopidy python3Packages.unidecode python3Packages.websocket-client ];
# no tests implemented
doCheck = false;
pythonImportsCheck = [ "mopidy_jellyfin" ];
meta = with lib; {
homepage = "https://github.com/jellyfin/mopidy-jellyfin";
description = "Mopidy extension for playing audio files from Jellyfin";
license = licenses.asl20;
maintainers = [ maintainers.pstn ];
};
}
@@ -26,6 +26,7 @@
, siteStart ? ./site-start.el
, nativeComp ? false
, withPgtk ? false
, withXinput2 ? false
, withImageMagick ? lib.versionOlder version "27" && (withX || withNS)
, toolkit ? (
if withGTK2 then "gtk2"
@@ -152,6 +153,7 @@ let emacs = stdenv.mkDerivation (lib.optionalAttrs nativeComp {
++ lib.optional nativeComp "--with-native-compilation"
++ lib.optional withImageMagick "--with-imagemagick"
++ lib.optional withPgtk "--with-pgtk"
++ lib.optional withXinput2 "--with-xinput2"
;
installTargets = [ "tags" "install" ];
@@ -35,7 +35,6 @@
, swig
, python
, wxPython
, opencascade
, opencascade-occt
, libngspice
, valgrind
@@ -44,22 +43,16 @@
, baseName
, kicadSrc
, kicadVersion
, i18n
, withOCE
, withOCC
, withNgspice
, withScripting
, withI18n
, withPCM
, debug
, sanitizeAddress
, sanitizeThreads
, withI18n
}:
assert lib.asserts.assertMsg (!(withOCE && stdenv.isAarch64)) "OCE fails a test on Aarch64";
assert lib.asserts.assertMsg (!(withOCC && withOCE))
"Only one of OCC and OCE may be enabled";
assert lib.assertMsg (!(stable && (sanitizeAddress || sanitizeThreads)))
"Only kicad-unstable(-small) supports address/thread sanitation";
assert lib.assertMsg (!(sanitizeAddress && sanitizeThreads))
"'sanitizeAddress' and 'sanitizeThreads' are mutually exclusive, use one.";
@@ -75,6 +68,7 @@ stdenv.mkDerivation rec {
# tagged releases don't have "unknown"
# kicad nightlies use git describe --dirty
# nix removes .git, so its approximated here
# "6.99.0" doesn't have "-unknown", yet; so leaving this in case it returns
postPatch = ''
substituteInPlace CMakeModules/KiCadVersion.cmake \
--replace "unknown" "${builtins.substring 0 10 src.rev}" \
@@ -82,23 +76,14 @@ stdenv.mkDerivation rec {
makeFlags = optionals (debug) [ "CFLAGS+=-Og" "CFLAGS+=-ggdb" ];
cmakeFlags = optionals (stable && withScripting) [
"-DKICAD_SCRIPTING=ON"
"-DKICAD_SCRIPTING_MODULES=ON"
"-DKICAD_SCRIPTING_PYTHON3=ON"
"-DKICAD_SCRIPTING_WXPYTHON_PHOENIX=ON"
cmakeFlags = optionals (withScripting) [
"-DKICAD_SCRIPTING_WXPYTHON=ON"
]
++ optionals (!withScripting) [
"-DKICAD_SCRIPTING=OFF"
"-DKICAD_SCRIPTING_WXPYTHON=OFF"
]
++ optional (withNgspice) "-DKICAD_SPICE=ON"
++ optional (!withOCE) "-DKICAD_USE_OCE=OFF"
++ optional (!withNgspice) "-DKICAD_SPICE=OFF"
++ optional (!withOCC) "-DKICAD_USE_OCC=OFF"
++ optionals (withOCE) [
"-DKICAD_USE_OCE=ON"
"-DOCE_DIR=${opencascade}"
]
++ optionals (withOCC) [
"-DKICAD_USE_OCC=ON"
"-DOCC_INCLUDE_DIR=${opencascade-occt}/include/opencascade"
@@ -108,11 +93,20 @@ stdenv.mkDerivation rec {
"-DKICAD_STDLIB_DEBUG=ON"
"-DKICAD_USE_VALGRIND=ON"
]
++ optionals (!doInstallCheck) [
"-DKICAD_BUILD_QA_TESTS=OFF"
]
++ optionals (sanitizeAddress) [
"-DKICAD_SANITIZE_ADDRESS=ON"
]
++ optionals (sanitizeThreads) [
"-DKICAD_SANITIZE_THREADS=ON"
]
++ optionals (withI18n) [
"-DKICAD_BUILD_I18N=ON"
]
++ optionals (!withPCM) [
"-DKICAD_PCM=OFF"
];
nativeBuildInputs = [
@@ -154,34 +148,27 @@ stdenv.mkDerivation rec {
curl
openssl
boost
swig
python
]
# unstable requires swig and python
# wxPython still optional
++ optionals (withScripting || (!stable)) [ swig python ]
++ optional (withScripting) wxPython
++ optional (withNgspice) libngspice
++ optional (withOCE) opencascade
++ optional (withOCC) opencascade-occt
++ optional (debug) valgrind
;
# debug builds fail all but the python test
# 5.1.x fails the eeschema test
doInstallCheck = !debug && !stable;
#doInstallCheck = !debug;
# temporarily disabled until upstream issue 9888 is resolved
doInstallCheck = false;
installCheckTarget = "test";
dontStrip = debug;
postInstall = optionalString (withI18n) ''
mkdir -p $out/share
lndir ${i18n}/share $out/share
'';
meta = {
description = "Just the built source without the libraries";
longDescription = ''
Just the build products, optionally with the i18n linked in
the libraries are passed via an env var in the wrapper, default.nix
Just the build products, the libraries are passed via an env var in the wrapper, default.nix
'';
homepage = "https://www.kicad.org/";
license = lib.licenses.agpl3;
@@ -2,8 +2,7 @@
, fetchFromGitLab
, gnome
, dconf
, wxGTK30
, wxGTK31
, wxGTK31-gtk3
, makeWrapper
, gsettings-desktop-schemas
, hicolor-icon-theme
@@ -14,42 +13,36 @@
, pname ? "kicad"
, stable ? true
, oceSupport ? false
, withOCE ? false
, withOCCT ? false
, withOCC ? true
, ngspiceSupport ? false
, withNgspice ? true
, libngspice
, scriptingSupport ? false
, withScripting ? true
, python3
, debug ? false
, sanitizeAddress ? false
, sanitizeThreads ? false
, with3d ? true
, withI18n ? true
, withI18n ? false
, withPCM ? true # Plugin and Content Manager
, srcs ? { }
}:
# The `srcs` parameter can be used to override the kicad source code
# and all libraries (including i18n), which are otherwise inaccessible
# and all libraries, which are otherwise inaccessible
# to overlays since most of the kicad build expression has been
# refactored into base.nix, most of the library build expressions have
# been refactored into libraries.nix, and most the i18n build
# expression has been refactored into i18n.nix. Overrides are only
# applied when building `kicad-unstable`. The `srcs` parameter has no
# effect for stable `kicad`. `srcs` takes an attribute set in which
# been refactored into libraries.nix. Overrides are only applied when
# building `kicad-unstable`. The `srcs` parameter has
# no effect for stable `kicad`. `srcs` takes an attribute set in which
# any of the following attributes are meaningful (though none are
# mandatory): "kicad", "kicadVersion", "i18n", "symbols", "templates",
# mandatory): "kicad", "kicadVersion", "symbols", "templates",
# "footprints", "packages3d", and "libVersion". "kicadVersion" and
# "libVersion" should be set to a string with the desired value for
# the version attribute in kicad's `mkDerivation` and the version
# attribute in any of the library's or i18n's `mkDerivation`,
# respectively. "kicad", "i18n", "symbols", "templates", "footprints",
# and "packages3d" should be set to an appropriate fetcher (e.g.,
# `fetchFromGitLab`). So, for example, a possible overlay for kicad
# is:
# attribute in any of the library's `mkDerivation`, respectively.
# "kicad", "symbols", "templates", "footprints", and "packages3d"
# should be set to an appropriate fetcher (e.g. `fetchFromGitLab`).
# So, for example, a possible overlay for kicad is:
#
# final: prev:
@@ -68,15 +61,6 @@
# });
# }
assert withNgspice -> libngspice != null;
assert lib.assertMsg (!ngspiceSupport)
"`nspiceSupport` was renamed to `withNgspice` for the sake of consistency with other kicad nix arguments.";
assert lib.assertMsg (!oceSupport)
"`oceSupport` was renamed to `withOCE` for the sake of consistency with other kicad nix arguments.";
assert lib.assertMsg (!scriptingSupport)
"`scriptingSupport` was renamed to `withScripting` for the sake of consistency with other kicad nix arguments.";
assert lib.assertMsg (!withOCCT)
"`withOCCT` was renamed to `withOCC` for the sake of consistency with upstream cmake options.";
let
baseName = if (stable) then "kicad" else "kicad-unstable";
versionsImport = import ./versions.nix;
@@ -91,14 +75,6 @@ let
sha256 = versionsImport.${baseName}.kicadVersion.src.sha256;
};
i18nSrcFetch = fetchFromGitLab {
group = "kicad";
owner = "code";
repo = "kicad-i18n";
rev = versionsImport.${baseName}.libVersion.libSources.i18n.rev;
sha256 = versionsImport.${baseName}.libVersion.libSources.i18n.sha256;
};
libSrcFetch = name: fetchFromGitLab {
group = "kicad";
owner = "libraries";
@@ -121,36 +97,15 @@ let
if srcOverridep "kicadVersion" then srcs.kicadVersion
else versionsImport.${baseName}.kicadVersion.version;
i18nSrc = if srcOverridep "i18n" then srcs.i18n else i18nSrcFetch;
i18nVersion =
if srcOverridep "i18nVersion" then srcs.i18nVersion
else versionsImport.${baseName}.libVersion.version;
libSrc = name: if srcOverridep name then srcs.${name} else libSrcFetch name;
# TODO does it make sense to only have one version for all libs?
libVersion =
if srcOverridep "libVersion" then srcs.libVersion
else versionsImport.${baseName}.libVersion.version;
wxGTK =
if (stable)
# wxGTK3x may default to withGtk2 = false, see #73145
then
wxGTK30.override
{
withGtk2 = false;
}
# wxGTK31 currently introduces an issue with opening the python interpreter in pcbnew
# but brings high DPI support?
else
wxGTK31.override {
withGtk2 = false;
};
wxGTK = wxGTK31-gtk3;
python = python3;
wxPython = if (stable)
then python.pkgs.wxPython_4_0
else python.pkgs.wxPython_4_1;
wxPython = python.pkgs.wxPython_4_1;
inherit (lib) concatStringsSep flatten optionalString optionals;
in
@@ -158,13 +113,11 @@ stdenv.mkDerivation rec {
# Common libraries, referenced during runtime, via the wrapper.
passthru.libraries = callPackages ./libraries.nix { inherit libSrc; };
passthru.i18n = callPackage ./i18n.nix { src = i18nSrc; };
base = callPackage ./base.nix {
inherit stable baseName;
inherit kicadSrc kicadVersion;
inherit (passthru) i18n;
inherit wxGTK python wxPython;
inherit withI18n withOCC withOCE withNgspice withScripting;
inherit withOCC withNgspice withScripting withI18n withPCM;
inherit debug sanitizeAddress sanitizeThreads;
};
@@ -197,27 +150,14 @@ stdenv.mkDerivation rec {
"--prefix GIO_EXTRA_MODULES : ${dconf}/lib/gio/modules"
# required to open a bug report link in firefox-wayland
"--set-default MOZ_DBUS_REMOTE 1"
]
++ optionals (stable)
[
"--set-default KISYSMOD ${footprints}/share/kicad/modules"
"--set-default KICAD_SYMBOL_DIR ${symbols}/share/kicad/library"
"--set-default KICAD_TEMPLATE_DIR ${templates}/share/kicad/template"
"--prefix KICAD_TEMPLATE_DIR : ${symbols}/share/kicad/template"
"--prefix KICAD_TEMPLATE_DIR : ${footprints}/share/kicad/template"
]
++ optionals (stable && with3d) [ "--set-default KISYS3DMOD ${packages3d}/share/kicad/modules/packages3d" ]
++ optionals (!stable)
[
"--set-default KICAD6_FOOTPRINT_DIR ${footprints}/share/kicad/footprints"
"--set-default KICAD6_SYMBOL_DIR ${symbols}/share/kicad/symbols"
"--set-default KICAD6_TEMPLATE_DIR ${templates}/share/kicad/template"
"--prefix KICAD6_TEMPLATE_DIR : ${symbols}/share/kicad/template"
"--prefix KICAD6_TEMPLATE_DIR : ${footprints}/share/kicad/template"
]
++ optionals (!stable && with3d)
++ optionals (with3d)
[
"--set-default KISYS3DMOD ${packages3d}/share/kicad/3dmodels"
"--set-default KICAD6_3DMODEL_DIR ${packages3d}/share/kicad/3dmodels"
]
++ optionals (withNgspice) [ "--prefix LD_LIBRARY_PATH : ${libngspice}/lib" ]
@@ -259,9 +199,6 @@ stdenv.mkDerivation rec {
ln -s ${base}/share/applications $out/share/applications
ln -s ${base}/share/icons $out/share/icons
ln -s ${base}/share/mime $out/share/mime
'' + optionalString (stable) ''
ln -s ${base}/share/appdata $out/share/appdata
'' + optionalString (!stable) ''
ln -s ${base}/share/metainfo $out/share/metainfo
'';
@@ -1,18 +0,0 @@
{ lib, stdenv
, cmake
, gettext
, src
}:
stdenv.mkDerivation {
inherit src;
pname = "kicad-i18n";
version = builtins.substring 0 10 src.rev;
nativeBuildInputs = [ cmake gettext ];
meta = with lib; {
license = licenses.gpl2; # https://github.com/KiCad/kicad-i18n/issues/3
platforms = platforms.all;
};
}
@@ -1,7 +1,9 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p coreutils git nix curl
# shellcheck shell=bash enable=all
set -e
shopt -s inherit_errexit
# this script will generate versions.nix in the right location
# this should contain the versions' revs and hashes
@@ -25,10 +27,12 @@ export TMPDIR=/tmp
# remove items left in /nix/store?
# get the latest tag that isn't an RC or *.99
latest_tag="$(git ls-remote --tags --sort -version:refname \
https://gitlab.com/kicad/code/kicad.git \
| grep -o 'refs/tags/[0-9]*\.[0-9]*\.[0-9]*$' \
| grep -v ".99" | head -n 1 | cut -d '/' -f 3)"
latest_tags="$(git ls-remote --tags --sort -version:refname https://gitlab.com/kicad/code/kicad.git)"
# using a scratch variable to ensure command failures get caught (SC2312)
scratch="$(grep -o 'refs/tags/[0-9]*\.[0-9]*\.[0-9]*$' <<< "${latest_tags}")"
scratch="$(grep -ve '\.99' -e '\.9\.9' <<< "${scratch}")"
scratch="$(head -n 1 <<< "${scratch}")"
latest_tag="$(cut -d '/' -f 3 <<< "${scratch}")"
all_versions=( "${latest_tag}" master )
@@ -60,15 +64,15 @@ tmp="${here}/,versions.nix.${RANDOM}"
libs=( symbols templates footprints packages3d )
get_rev="git ls-remote --heads --tags"
get_rev() {
git ls-remote --heads --tags "$@"
}
gitlab="https://gitlab.com/kicad"
# append commit hash or tag
gitlab_pre="https://gitlab.com/api/v4/projects/kicad%2Fcode%2Fkicad/repository/archive.tar.gz?sha="
# not a lib, but separate and already moved to gitlab
i18n="${gitlab}/code/kicad-i18n.git"
i18n_pre="https://gitlab.com/api/v4/projects/kicad%2Fcode%2Fkicad-i18n/repository/archive.tar.gz?sha="
src_pre="https://gitlab.com/api/v4/projects/kicad%2Fcode%2Fkicad/repository/archive.tar.gz?sha="
lib_pre="https://gitlab.com/api/v4/projects/kicad%2Flibraries%2Fkicad-"
lib_mid="/repository/archive.tar.gz?sha="
count=0
@@ -108,16 +112,19 @@ for version in "${all_versions[@]}"; do
printf "%6ssrc = {\n" ""
echo "Checking src" >&2
src_rev="$(${get_rev} "${gitlab}"/code/kicad.git "${version}" | cut -f1)"
scratch="$(get_rev "${gitlab}"/code/kicad.git "${version}")"
src_rev="$(cut -f1 <<< "${scratch}")"
has_rev="$(grep -sm 1 "\"${pname}\"" -A 4 "${file}" | grep -sm 1 "${src_rev}" || true)"
has_hash="$(grep -sm 1 "\"${pname}\"" -A 5 "${file}" | grep -sm 1 "sha256" || true)"
if [[ -n ${has_rev} && -n ${has_hash} && -z ${clean} ]]; then
echo "Reusing old ${pname}.src.sha256, already latest .rev" >&2
grep -sm 1 "\"${pname}\"" -A 5 "${file}" | grep -sm 1 "rev" -A 1
scratch=$(grep -sm 1 "\"${pname}\"" -A 5 "${file}")
grep -sm 1 "rev" -A 1 <<< "${scratch}"
else
prefetched="$(${prefetch} "${src_pre}${src_rev}")"
printf "%8srev =\t\t\t\"%s\";\n" "" "${src_rev}"
printf "%8ssha256 =\t\t\"%s\";\n" \
"" "$(${prefetch} "${gitlab_pre}${src_rev}")"
printf "%8ssha256 =\t\t\"%s\";\n" "" "${prefetched}"
count=$((count+1))
fi
printf "%6s};\n" ""
@@ -127,37 +134,26 @@ for version in "${all_versions[@]}"; do
printf "%6sversion =\t\t\t\"%s\";\n" "" "${today}"
printf "%6slibSources = {\n" ""
echo "Checking i18n" >&2
i18n_rev="$(${get_rev} "${i18n}" "${version}" | cut -f1)"
has_rev="$(grep -sm 1 "\"${pname}\"" -A 11 "${file}" | grep -sm 1 "${i18n_rev}" || true)"
has_hash="$(grep -sm 1 "\"${pname}\"" -A 12 "${file}" | grep -sm 1 "i18n.sha256" || true)"
if [[ -n ${has_rev} && -n ${has_hash} && -z ${clean} ]]; then
echo "Reusing old kicad-i18n-${today}.src.sha256, already latest .rev" >&2
grep -sm 1 "\"${pname}\"" -A 12 "${file}" | grep -sm 1 "i18n" -A 1
else
printf "%8si18n.rev =\t\t\"%s\";\n" "" "${i18n_rev}"
printf "%8si18n.sha256 =\t\t\"%s\";\n" "" \
"$(${prefetch} "${i18n_pre}${i18n_rev}")"
count=$((count+1))
fi
for lib in "${libs[@]}"; do
echo "Checking ${lib}" >&2
url="${gitlab}/libraries/kicad-${lib}.git"
lib_rev="$(${get_rev} "${url}" "${version}" | cut -f1 | tail -n1)"
scratch="$(get_rev "${url}" "${version}")"
scratch="$(cut -f1 <<< "${scratch}")"
lib_rev="$(tail -n1 <<< "${scratch}")"
has_rev="$(grep -sm 1 "\"${pname}\"" -A 19 "${file}" | grep -sm 1 "${lib_rev}" || true)"
has_hash="$(grep -sm 1 "\"${pname}\"" -A 20 "${file}" | grep -sm 1 "${lib}.sha256" || true)"
if [[ -n ${has_rev} && -n ${has_hash} && -z ${clean} ]]; then
echo "Reusing old kicad-${lib}-${today}.src.sha256, already latest .rev" >&2
grep -sm 1 "\"${pname}\"" -A 20 "${file}" | grep -sm 1 "${lib}" -A 1
scratch="$(grep -sm 1 "\"${pname}\"" -A 20 "${file}")"
grep -sm 1 "${lib}" -A 1 <<< "${scratch}"
else
prefetched="$(${prefetch} "${lib_pre}${lib}${lib_mid}${lib_rev}")"
printf "%8s%s.rev =\t" "" "${lib}"
case "${lib}" in
symbols|templates) printf "\t" ;; *) ;;
esac
printf "\"%s\";\n" "${lib_rev}"
printf "%8s%s.sha256 =\t\"%s\";\n" "" \
"${lib}" "$(${prefetch} "https://gitlab.com/api/v4/projects/kicad%2Flibraries%2Fkicad-${lib}/repository/archive.tar.gz?sha=${lib_rev}")"
printf "%8s%s.sha256 =\t\"%s\";\n" "" "${lib}" "${prefetched}"
count=$((count+1))
fi
done
@@ -166,7 +162,7 @@ for version in "${all_versions[@]}"; do
printf "%2s};\n" ""
else
printf "\nReusing old %s\n" "${pname}" >&2
grep -sm 1 "\"${pname}\"" -A 23 "${file}"
grep -sm 1 "\"${pname}\"" -A 21 "${file}"
fi
done
printf "}\n"
@@ -3,47 +3,43 @@
{
"kicad" = {
kicadVersion = {
version = "5.1.12";
version = "6.0.0";
src = {
rev = "84ad8e8a86f13c0697f5cbed8c17977b6545ddc9";
sha256 = "0kgikchqxds3mp71nkg307mr4c1dgv8akbmksz4w9x8jg4i1mfqq";
rev = "d3dd2cf0fa975548d027db88d19b8a88866866d8";
sha256 = "1jrfwyi4zs0rpcpsj01z6687a433nnr56cxbnz12jfg2yafpxk23";
};
};
libVersion = {
version = "5.1.12";
version = "6.0.0";
libSources = {
i18n.rev = "0ad3d7e469e31c8868ad83f90e22a9c18f16aa1f";
i18n.sha256 = "0y51l0r62cnxkvpc21732p3cx7pjvaqjih8193502hlv9kv1j9p6";
symbols.rev = "97c0bfdd2f5ebe952bc90c60f080a8e41da60615";
symbols.sha256 = "1zdajim409570xzis53kmrbdcf7000v2vmc90f49h214lrx2zhr2";
templates.rev = "eca0f632eb76c8f49de4d5a590c83543090d0b7d";
templates.sha256 = "1fbhn1l3j2rwc29aida9b408wif55i23bp9ddcs7dvf83smjm05g";
footprints.rev = "b65732f8ebd7ab894fd638f3f2bf4a4e9b24f653";
footprints.sha256 = "0qpii55dgv2gxqg1qq0dngdnbb9din790qi5qv0l6qqrzx843h5s";
packages3d.rev = "0ddd588650fede09766b704feb15d30bcb6e144f";
packages3d.sha256 = "12w7m5nbk9kcnlnlg4sk1sd7xgb9i2kxfi0jcbd0phs89qyl7wjr";
symbols.rev = "275f22eb9eecd5b6deabdefd82c9a826254d9f23";
symbols.sha256 = "0wjk464l60xknvgc9d870901lqnx296dw7amlh3wg0wf78izarfr";
templates.rev = "3a422b5b0928f3fd31579769d4dee2b009a85a11";
templates.sha256 = "0vbjy1v5923942ma0rqcp1dhylhxk1m4vyfxjxw13sizkrpmlwr1";
footprints.rev = "3ea7895b0817abecaa34276346749a711b0c69f6";
footprints.sha256 = "0jv2plwzhhkfx7a2zankkjkbfzjxv43ab8rqpxzqfq2fnx83q6r5";
packages3d.rev = "e607286d4a48ddf654585b37b45d74416a9a70c7";
packages3d.sha256 = "0vwcbzq42hzjl4f0zjaswmiff1x59hv64g5n00mx1gl0gwngnyla";
};
};
};
"kicad-unstable" = {
kicadVersion = {
version = "6.0.0-rc1";
version = "2021-12-23";
src = {
rev = "9fb05440b3ef3073613ecdeba6112aeb6b26c4df";
sha256 = "1j0hd6bpmd80dyvy9mz4n4rr8f849bdwdd4vs8vfbsswf0gxj734";
rev = "21eb92821866d558acd9e737b643b300a8b18202";
sha256 = "01hg0byp60xzgz0xxfwvyq1hbvbllsys6lx9yfj27d3qjc3bdk42";
};
};
libVersion = {
version = "6.0.0-rc1";
version = "2021-12-25";
libSources = {
i18n.rev = "e89d9a89bec59199c1ade56ee2556591412ab7b0";
i18n.sha256 = "04zaqyhj3qr4ymyd3k5vjpcna64j8klpsygcgjcv29s3rdi8glfl";
symbols.rev = "27b627393a7f2733e965ed82a5533a757789cbb2";
symbols.sha256 = "0p1qay6h6ibkhcz1b8xszsihi432ddi8jgnan2xr5rl4539c4ydp";
symbols.rev = "125a2e736504e776e4c6fb7f5131efad75edf245";
symbols.sha256 = "0wjk464l60xknvgc9d870901lqnx296dw7amlh3wg0wf78izarfr";
templates.rev = "8c9ff3dadb9c75cf2932f11c09a46c0c9d84784b";
templates.sha256 = "0vbjy1v5923942ma0rqcp1dhylhxk1m4vyfxjxw13sizkrpmlwr1";
footprints.rev = "4ce2242095912e491f1690210d9cb2328363b268";
footprints.sha256 = "1zx13rrpiamxyv7y27mr5xsdz0d09hpwfgc2j496p3q41q2crlq0";
footprints.rev = "ac8de318d8ef7b3eb64c78c6c2650b7b085f3271";
footprints.sha256 = "0jv2plwzhhkfx7a2zankkjkbfzjxv43ab8rqpxzqfq2fnx83q6r5";
packages3d.rev = "1080b6e565e56bae9be46db2278a1542092d7a2d";
packages3d.sha256 = "0vwcbzq42hzjl4f0zjaswmiff1x59hv64g5n00mx1gl0gwngnyla";
};
@@ -15,7 +15,7 @@ rec {
, go-md2man, go, containerd_1_4, runc, docker-proxy, tini, libtool
, sqlite, iproute2, lvm2, systemd, docker-buildx, docker-compose_2
, btrfs-progs, iptables, e2fsprogs, xz, util-linux, xfsprogs, git
, procps, libseccomp
, procps, libseccomp, rootlesskit, slirp4netns, fuse-overlayfs
, nixosTests
, clientOnly ? !stdenv.isLinux, symlinkJoin
}:
@@ -77,6 +77,8 @@ rec {
extraPath = optionals (stdenv.isLinux) (makeBinPath [ iproute2 iptables e2fsprogs xz xfsprogs procps util-linux git ]);
extraUserPath = optionals (stdenv.isLinux && !clientOnly) (makeBinPath [ rootlesskit slirp4netns fuse-overlayfs ]);
postPatch = ''
patchShebangs hack/make.sh hack/make/
'';
@@ -109,6 +111,11 @@ rec {
install -Dm644 ./contrib/init/systemd/docker.service $out/etc/systemd/system/docker.service
substituteInPlace $out/etc/systemd/system/docker.service --replace /usr/bin/dockerd $out/bin/dockerd
install -Dm644 ./contrib/init/systemd/docker.socket $out/etc/systemd/system/docker.socket
# rootless Docker
install -Dm755 ./contrib/dockerd-rootless.sh $out/libexec/docker/dockerd-rootless.sh
makeWrapper $out/libexec/docker/dockerd-rootless.sh $out/bin/dockerd-rootless \
--prefix PATH : "$out/libexec/docker:$extraPath:$extraUserPath"
'';
DOCKER_BUILDTAGS = []
@@ -184,6 +191,7 @@ rec {
'' + optionalString (!clientOnly) ''
# symlink docker daemon to docker cli derivation
ln -s ${moby}/bin/dockerd $out/bin/dockerd
ln -s ${moby}/bin/dockerd-rootless $out/bin/dockerd-rootless
# systemd
mkdir -p $out/etc/systemd/system
@@ -2,11 +2,11 @@
buildGraalvmNativeImage rec {
pname = "babashka";
version = "0.6.8";
version = "0.7.0";
src = fetchurl {
url = "https://github.com/babashka/${pname}/releases/download/v${version}/${pname}-${version}-standalone.jar";
sha256 = "sha256-GIJXXWJZ77n2FBOLKqRSlueo63JMxo0a49dDhneO6oo=";
sha256 = "sha256-zSjiHacetJ68U0GciIbuGET9I/51EM8JnPPUGemDfEI=";
};
executable = "bb";
@@ -2,19 +2,21 @@
, buildPythonPackage
, fetchPypi
, aiohttp
, asyncio-throttle
}:
buildPythonPackage rec {
pname = "aiohue";
version = "3.0.7";
version = "3.0.10";
src = fetchPypi {
inherit pname version;
sha256 = "sha256-Q01giQZytOQ+Ko7kvL0OfdDPysfvtKhW7fYmHmAv5Go=";
sha256 = "sha256-LwtE9F5ic0aZ9/q3dSWn20O27yW/QD/Yi1NPdFmiP10=";
};
propagatedBuildInputs = [
aiohttp
asyncio-throttle
];
pythonImportsCheck = [
@@ -15,7 +15,7 @@
buildPythonPackage rec {
pname = "aiopvpc";
version = "2.2.4";
version = "3.0.0";
format = "pyproject";
disabled = pythonOlder "3.8";
@@ -24,7 +24,7 @@ buildPythonPackage rec {
owner = "azogue";
repo = pname;
rev = "v${version}";
sha256 = "sha256-39cGDbaBS5we+WbqvABe6tKwTmbgd+NYLssKQCOuBsc=";
sha256 = "sha256-eTCQddoZIaCs7iKGNBC8aSq6ek4vwYXgIXx35UlME/k=";
};
nativeBuildInputs = [
@@ -13,7 +13,7 @@
buildPythonPackage rec {
pname = "bimmer-connected";
version = "0.8.5";
version = "0.8.7";
format = "setuptools";
disabled = pythonOlder "3.6";
@@ -22,7 +22,7 @@ buildPythonPackage rec {
owner = "bimmerconnected";
repo = "bimmer_connected";
rev = version;
hash = "sha256-twVI84YCW+t9ar2vHN1OEiY5tT4/pHP29GnpWprdeHs=";
hash = "sha256-nLZdaV341mULXIngkEqiLQeg4G2NDFGNg/AUozgJe74=";
};
nativeBuildInputs = [
@@ -4,7 +4,6 @@
, pythonOlder
, icalendar
, lxml
, mock
, nose
, pytz
, requests
@@ -15,23 +14,27 @@
buildPythonPackage rec {
pname = "caldav";
version = "0.8.0";
version = "0.8.2";
src = fetchFromGitHub {
owner = "python-caldav";
repo = pname;
rev = "v${version}";
sha256 = "11q3svns3a2ywfci739krxbh67cx691qja772wq22606blyygyjy";
hash = "sha256-2mpE1aLipps4X/3EF0oKHXDcrgUh78/fxY6y1B1V2IU=";
};
nativeBuildInputs = lib.optionals (pythonOlder "3.5") [ mock ];
propagatedBuildInputs = [ six requests vobject lxml ]
++ lib.optionals (pythonOlder "3.6") [ pytz tzlocal ];
propagatedBuildInputs = [
vobject
lxml
requests
six
];
checkInputs = [
icalendar
nose
tzlocal
pytz
];
checkPhase = ''
@@ -41,7 +44,7 @@ buildPythonPackage rec {
# xandikos and radicale is only a optional test dependency, not available for python3
postPatch = ''
substituteInPlace setup.py \
--replace ", 'xandikos'" "" \
--replace ", 'xandikos<0.2.4'" "" \
--replace ", 'radicale'" ""
'';
@@ -51,7 +54,6 @@ buildPythonPackage rec {
description = "This project is a CalDAV (RFC4791) client library for Python.";
homepage = "https://github.com/python-caldav/caldav";
license = licenses.asl20;
maintainers = with maintainers; [ marenz ];
#broken = true; # requires radicale which is not packaged yet
maintainers = with maintainers; [ marenz dotlambda ];
};
}
@@ -2,11 +2,11 @@
buildPythonPackage rec {
pname = "deep-translator";
version = "1.5.5";
version = "1.6.0";
src = fetchPypi {
inherit pname version;
sha256 = "sha256-XARhzRsquvKcdhPcooGIEmhGN7QJOCubcvOrZB0nhxU=";
sha256 = "sha256-B/SnLSaCRVhQvSU2hmdKPswM2N73nHAzQfVNBMgCofI=";
};
propagatedBuildInputs = [
@@ -3,11 +3,11 @@
buildPythonPackage rec {
pname = "django_compressor";
version = "2.4.1";
version = "3.1";
src = fetchPypi {
inherit pname version;
sha256 = "3358077605c146fdcca5f9eaffb50aa5dbe15f238f8854679115ebf31c0415e0";
sha256 = "c4a87bf65f9a534cfaf1c321a000a229c24e50c6d62ba6ab089482db42e819d9";
};
postPatch = ''
substituteInPlace setup.py \
@@ -16,14 +16,14 @@
buildPythonPackage rec {
pname = "faraday-plugins";
version = "1.5.8";
version = "1.5.9";
format = "setuptools";
src = fetchFromGitHub {
owner = "infobyte";
repo = "faraday_plugins";
rev = "v${version}";
sha256 = "1r415g2f0cid8nr3y27ipx9hvwzh70l5wp0d7nv25qblc7g38mms";
sha256 = "sha256-rU7BF1lXLgJYLed5FVKXroivxKpmmNE5woGCpAcKAwg=";
};
propagatedBuildInputs = [
@@ -8,7 +8,7 @@
buildPythonPackage rec {
pname = "flux-led";
version = "0.27.13";
version = "0.27.19";
format = "setuptools";
disabled = pythonOlder "3.7";
@@ -17,7 +17,7 @@ buildPythonPackage rec {
owner = "Danielhiversen";
repo = "flux_led";
rev = version;
sha256 = "sha256-lOfEEMHuhTfti7NYeZpXc+jeYQMJd/EnvT1oHByaCbw=";
sha256 = "sha256-QJCRBwsfQQzXQ7DDvzb9NKnZS2LqrQUygdzJ+ccjWt4=";
};
propagatedBuildInputs = [
@@ -7,11 +7,11 @@
buildPythonPackage rec {
pname = "isodate";
version = "0.6.0";
version = "0.6.1";
src = fetchPypi {
inherit pname version;
sha256 = "2e364a3d5759479cdb2d37cce6b9376ea504db2ff90252a2e5b7cc89cc9ff2d8";
sha256 = "SMWIHefosKDWSMsCTIBi3ITnuEDtgehkx2FP08Envek=";
};
propagatedBuildInputs = [ six ];
@@ -10,12 +10,12 @@
buildPythonPackage rec {
pname = "jupyterlab";
version = "3.2.4";
version = "3.2.5";
disabled = pythonOlder "3.5";
src = fetchPypi {
inherit pname version;
sha256 = "f692e0d95338d60f72dde660f16f3955a087775c59ec541ddb25952e3f97e9b1";
sha256 = "31b28f473b0f5826d2020583973c385526f0559b5b26efac6b8035ac1562874a";
};
nativeBuildInputs = [ jupyter-packaging ];
@@ -0,0 +1,45 @@
{ lib
, buildPythonPackage
, fetchPypi
, pythonOlder
, h5py
, nibabel
, numpy
, setuptools-scm
, toml
}:
buildPythonPackage rec {
pname = "nitransforms";
version = "21.0.0";
disabled = pythonOlder "3.7";
src = fetchPypi {
inherit pname version;
sha256 = "njJqHqXVxldyGfmdM8GmgKdgIT4kMYLzcM5+ayR2EDo=";
};
buildInputs = [ setuptools-scm toml ];
propagatedBuildInputs = [ h5py nibabel numpy ];
doCheck = false;
# relies on data repo (https://github.com/nipreps-data/nitransforms-tests);
# probably too heavy
pythonImportsCheck = [
"nitransforms"
"nitransforms.base"
"nitransforms.io"
"nitransforms.io.base"
"nitransforms.linear"
"nitransforms.manip"
"nitransforms.nonlinear"
"nitransforms.patched"
];
meta = with lib; {
homepage = "https://nitransforms.readthedocs.io";
description = "Geometric transformations for images and surfaces";
license = licenses.mit;
maintainers = with maintainers; [ bcdarwin ];
};
}
@@ -27,7 +27,7 @@
buildPythonPackage rec {
pname = "ocrmypdf";
version = "13.1.1";
version = "13.2.0";
src = fetchFromGitHub {
owner = "jbarlow83";
@@ -39,7 +39,7 @@ buildPythonPackage rec {
extraPostFetch = ''
rm "$out/.git_archival.txt"
'';
sha256 = "sha256-NIh7eTsXQPNhrNWrTMFG7v4SFsicj1B4szEXcp5fXB4=";
sha256 = "sha256-mVPKcxTKoRgttwJdsY7r0kF7W1+G45iCc+mFctDipSM=";
};
SETUPTOOLS_SCM_PRETEND_VERSION = version;
@@ -17,7 +17,7 @@
buildPythonPackage rec {
pname = "openai";
version = "0.11.4";
version = "0.11.5";
disabled = pythonOlder "3.7.1";
@@ -26,7 +26,7 @@ buildPythonPackage rec {
owner = "openai";
repo = "openai-python";
rev = "v${version}";
sha256 = "O2O4+GkyMyAxJqMNgiyPKoSXeJk0HGAst02QV6c9mJs=";
sha256 = "sha256-6eL3/vDWyIOVjRQo4OO3OgyUG3t8dKPtxzMMTxPCglM=";
};
propagatedBuildInputs = [
@@ -17,7 +17,7 @@ let
in
buildPythonPackage rec {
pname = "panel";
version = "0.12.5";
version = "0.12.6";
# Don't forget to also update the node packages
# 1. retrieve the package.json file
@@ -25,7 +25,7 @@ buildPythonPackage rec {
# 3. node2nix
src = fetchPypi {
inherit pname version;
sha256 = "351481f2a2176359b28effa64c9d9fce487d6758514109cab96f9ed84787ae99";
sha256 = "97e158e8eb941f88d71929407f9455c903b5e18d89969db8ce8af66036f46b53";
};
# Since 0.10.0 panel attempts to fetch from the web.
@@ -6,12 +6,12 @@
buildPythonPackage rec {
pname = "phonenumbers";
version = "8.12.39";
version = "8.12.40";
format = "setuptools";
src = fetchPypi {
inherit pname version;
sha256 = "0f7745e1f108654db347d885e814cbb5f225b8c5f5ce336024b193c79291ddaa";
sha256 = "00f2955a456b458f9b6ab0d24329049c3e7358c44dfc1979fe4908ced40f1eb8";
};
checkInputs = [
@@ -11,7 +11,7 @@
buildPythonPackage rec {
pname = "pycarwings2";
version = "2.12";
version = "2.13";
format = "setuptools";
disabled = pythonOlder "3.5";
@@ -20,8 +20,8 @@ buildPythonPackage rec {
owner = "filcole";
repo = pname;
# release not tagged: https://github.com/filcole/pycarwings2/issues/33
rev = "0dc9e7e74cb119614c72c7f955801a366f303c56";
sha256 = "sha256-3lyAgLuaNrCDvRT2yYkgaDiLPKW9Hbg05cQlMIBUs6o=";
rev = "v${version}";
sha256 = "04k1la7wix6sp668nqpwdhd3057b2bzcz7h2b9a57cxlifl8pjxf";
};
propagatedBuildInputs = [
@@ -13,7 +13,7 @@
buildPythonPackage rec {
pname = "pytile";
version = "2021.10.0";
version = "2021.12.0";
format = "pyproject";
disabled = pythonOlder "3.7";
@@ -22,7 +22,7 @@ buildPythonPackage rec {
owner = "bachya";
repo = pname;
rev = version;
sha256 = "sha256-9FbcGhRmXULJgfJOmy6mhiZwQUDNmvxZI/WxjJIbnc8=";
sha256 = "sha256-a76Qzk8ZsoV6HUOcDjMdnFVZJu/iKFbShoC9OZ0caDc=";
};
nativeBuildInputs = [
@@ -24,12 +24,12 @@
buildPythonPackage rec {
pname = "snowflake-connector-python";
version = "2.7.1";
version = "2.7.2";
disabled = pythonOlder "3.6";
src = fetchPypi {
inherit pname version;
sha256 = "81175ff9fe0355a7e9007a087458dddc0816985ec10dc122e690de03549afbff";
sha256 = "b2f8f360750eefa98be09ff53c130381646f8dfc8c6e4a705387676210ff8578";
};
propagatedBuildInputs = [
@@ -2,11 +2,11 @@
buildPythonPackage rec {
pname = "stripe";
version = "2.63.0";
version = "2.64.0";
src = fetchPypi {
inherit pname version;
sha256 = "816c935e31d82737a9e4362c662e8702bdf9000ea1bd36882cd4cbd23eb81ae1";
sha256 = "2f4b2175046104e4fcd8a2689a68bb9828a857814126d2ed13772cf2554fb93e";
};
propagatedBuildInputs = [ requests ];
@@ -11,7 +11,7 @@
buildPythonPackage rec {
pname = "xknx";
version = "0.18.14";
version = "0.18.15";
format = "setuptools";
disabled = pythonOlder "3.8";
@@ -20,7 +20,7 @@ buildPythonPackage rec {
owner = "XKNX";
repo = pname;
rev = version;
sha256 = "sha256-PWBUG9sa9530cfXqpJ+0UVxOx+FxNfz4ZLazpUILvww=";
sha256 = "sha256-k/fLUuBjXScTvlvoBLZIVPEqNGIPI04FBeTBadp5uiY=";
};
propagatedBuildInputs = [
@@ -1,34 +1,53 @@
{ lib, buildPythonPackage, fetchFromGitHub, pytestCheckHook, pytest-xdist
, pythonOlder, click, ruyaml }:
{ lib
, buildPythonPackage
, click
, fetchFromGitHub
, pytest-xdist
, pytestCheckHook
, pythonOlder
, ruyaml
}:
buildPythonPackage rec {
pname = "yamlfix";
version = "0.7.2";
version = "0.8.0";
format = "setuptools";
disabled = pythonOlder "3.7";
src = fetchFromGitHub {
owner = "lyz-code";
repo = pname;
rev = version;
sha256 = "sha256-qlA6TyLkOuTXCdMnpfkyN/HDIRfB6+0pQ7f0GCsIjL4=";
sha256 = "sha256-Gkq80YMeiPy7xxLauA/nloW4znMV2tfE+e24HyZgUaQ=";
};
propagatedBuildInputs = [ click ruyaml ];
propagatedBuildInputs = [
click
ruyaml
];
checkInputs = [ pytestCheckHook pytest-xdist ];
checkInputs = [
pytest-xdist
pytestCheckHook
];
postPatch = ''
substituteInPlace pyproject.toml \
--replace 'python_paths = "."' ""
'';
pytestFlagsArray = [ "-n" "$NIX_BUILD_CORES" ];
pytestFlagsArray = [
"-n"
"$NIX_BUILD_CORES"
];
pythonImportsCheck = [ "yamlfix" ];
pythonImportsCheck = [
"yamlfix"
];
meta = with lib; {
description =
"A simple opinionated yaml formatter that keeps your comments!";
description = "Python YAML formatter that keeps your comments";
homepage = "https://github.com/lyz-code/yamlfix";
license = licenses.gpl3Plus;
maintainers = with maintainers; [ koozz ];
+38 -28
View File
@@ -3,21 +3,23 @@
, fetchFromGitHub
, cmake
, wrapQtAppsHook
, SDL2
, qtbase
, qtmultimedia
, boost17x
, libpulseaudio
, pkg-config
, libusb1
, zstd
, libressl
, alsa-lib
, rapidjson
, aacHleDecoding ? true
, fdk_aac
, ffmpeg-full
, enableSdl2 ? true, SDL2
, enableQt ? true, qtbase, qtmultimedia
, enableQtTranslation ? enableQt, qttools
, enableWebService ? true
, enableCubeb ? true, libpulseaudio
, enableFfmpegAudioDecoder ? true
, enableFfmpegVideoDumper ? true
, ffmpeg
, useDiscordRichPresence ? true, rapidjson
, enableFdk ? false, fdk_aac
}:
assert lib.assertMsg (!enableFfmpegAudioDecoder || !enableFdk) "Can't enable both enableFfmpegAudioDecoder and enableFdk";
stdenv.mkDerivation {
pname = "citra";
@@ -31,36 +33,43 @@ stdenv.mkDerivation {
fetchSubmodules = true;
};
nativeBuildInputs = [ cmake wrapQtAppsHook pkg-config ];
nativeBuildInputs = [
cmake
pkg-config
]
++ lib.optionals enableQt [ wrapQtAppsHook ];
buildInputs = [
SDL2
qtbase
qtmultimedia
libpulseaudio
boost17x
libusb1
alsa-lib
rapidjson # for discord-rpc
] ++ lib.optional aacHleDecoding [ fdk_aac ffmpeg-full ];
]
++ lib.optionals enableSdl2 [ SDL2 ]
++ lib.optionals enableQt [ qtbase qtmultimedia ]
++ lib.optionals enableQtTranslation [ qttools ]
++ lib.optionals enableCubeb [ libpulseaudio ]
++ lib.optionals (enableFfmpegAudioDecoder || enableFfmpegVideoDumper) [ ffmpeg ]
++ lib.optionals useDiscordRichPresence [ rapidjson ]
++ lib.optionals enableFdk [ fdk_aac ];
cmakeFlags = [
"-DUSE_SYSTEM_BOOST=ON"
"-DUSE_DISCORD_PRESENCE=ON"
] ++ lib.optionals aacHleDecoding [
"-DENABLE_FFMPEG_AUDIO_DECODER=ON"
"-DCITRA_USE_BUNDLED_FFMPEG=OFF"
];
]
++ lib.optionals (!enableSdl2) [ "-DENABLE_SDL2=OFF" ]
++ lib.optionals (!enableQt) [ "-DENABLE_QT=OFF" ]
++ lib.optionals enableQtTranslation [ "-DENABLE_QT_TRANSLATION=ON" ]
++ lib.optionals (!enableWebService) [ "-DENABLE_WEB_SERVICE=OFF" ]
++ lib.optionals (!enableCubeb) [ "-DENABLE_CUBEB=OFF" ]
++ lib.optionals enableFfmpegAudioDecoder [ "-DENABLE_FFMPEG_AUDIO_DECODER=ON"]
++ lib.optionals enableFfmpegVideoDumper [ "-DENABLE_FFMPEG_VIDEO_DUMPER=ON" ]
++ lib.optionals useDiscordRichPresence [ "-DUSE_DISCORD_PRESENCE=ON" ]
++ lib.optionals enableFdk [ "-DENABLE_FDK=ON" ];
postPatch = ''
# we already know the submodules are present
# We already know the submodules are present
substituteInPlace CMakeLists.txt \
--replace "check_submodules_present()" ""
# Trick configure system.
sed -n 's,^ *path = \(.*\),\1,p' .gitmodules | while read path; do
mkdir "$path/.git"
done
# Devendoring
rm -rf externals/zstd externals/libressl
cp -r ${zstd.src} externals/zstd
tar xf ${libressl.src} -C externals/
@@ -69,6 +78,7 @@ stdenv.mkDerivation {
'';
# Todo: cubeb audio backend (the default one) doesn't work on the SDL interface.
# This seems to be a problem with libpulseaudio, other applications have similar problems (e.g Duckstation).
# Note that the two interfaces have two separate configuration files.
meta = with lib; {
+12
View File
@@ -2818,6 +2818,18 @@ final: prev:
meta.homepage = "https://github.com/JuliaEditorSupport/julia-vim/";
};
kanagawa-nvim = buildVimPluginFrom2Nix {
pname = "kanagawa.nvim";
version = "2021-12-25";
src = fetchFromGitHub {
owner = "rebelot";
repo = "kanagawa.nvim";
rev = "10bccb5e8e8530725c8059df2e6852fb01842d1c";
sha256 = "15jji03qvpbyfk1bpc9b31rbkklfzdnhmnld4cr5ydjmz1fd5fzb";
};
meta.homepage = "https://github.com/rebelot/kanagawa.nvim/";
};
kommentary = buildVimPluginFrom2Nix {
pname = "kommentary";
version = "2021-12-03";
+1
View File
@@ -642,6 +642,7 @@ rbong/vim-flog
rcarriga/nvim-dap-ui
rcarriga/nvim-notify
rcarriga/vim-ultest
rebelot/kanagawa.nvim
rhysd/clever-f.vim
rhysd/committia.vim
rhysd/conflict-marker.vim
@@ -8,6 +8,8 @@
, esbuild
, pkg-config
, libsecret
, stdenv
, darwin
, setDefaultServerPath ? true
}:
@@ -40,6 +42,9 @@ let
jq moreutils esbuild
# Required by `keytar`, which is a dependency of `vsce`.
pkg-config libsecret
] ++ lib.optionals stdenv.isDarwin [
darwin.apple_sdk.frameworks.AppKit
darwin.apple_sdk.frameworks.Security
];
# Follows https://github.com/rust-analyzer/rust-analyzer/blob/41949748a6123fd6061eb984a47f4fe780525e63/xtask/src/dist.rs#L39-L65
@@ -2,7 +2,7 @@
# Do not edit!
{
version = "2021.12.4";
version = "2021.12.5";
components = {
"abode" = ps: with ps; [ abodepy ];
"accuweather" = ps: with ps; [ accuweather ];
@@ -180,7 +180,7 @@
"devolo_home_network" = ps: with ps; [ devolo-plc-api ];
"dexcom" = ps: with ps; [ pydexcom ];
"dhcp" = ps: with ps; [ aiodiscover scapy ];
"dht" = ps: with ps; [ ]; # missing inputs: adafruit-circuitpython-dht
"dht" = ps: with ps; [ ]; # missing inputs: RPi.GPIO adafruit-circuitpython-dht
"dialogflow" = ps: with ps; [ aiohttp-cors ];
"digital_ocean" = ps: with ps; [ digital-ocean ];
"digitalloggers" = ps: with ps; [ ]; # missing inputs: dlipower
@@ -706,7 +706,7 @@
"remote" = ps: with ps; [ ];
"remote_rpi_gpio" = ps: with ps; [ ]; # missing inputs: gpiozero
"renault" = ps: with ps; [ renault-api ];
"repetier" = ps: with ps; [ ]; # missing inputs: pyrepetier
"repetier" = ps: with ps; [ ]; # missing inputs: pyrepetierng
"rest" = ps: with ps; [ jsonpath xmltodict ];
"rest_command" = ps: with ps; [ ];
"rflink" = ps: with ps; [ rflink ];
+15 -2
View File
@@ -219,6 +219,19 @@ let
});
})
# Remove with 2021.12.6 as the requirement will be 1.1.16 (at least)
(self: super: {
yalexs = super.yalexs.overridePythonAttrs (oldAttrs: rec {
version = "1.1.13";
src = fetchFromGitHub {
owner = "bdraco";
repo = "yalexs";
rev = "v${version}";
sha256 = "sha256-lnx8+VyDyO7Wg+QW+CC0FUg77Ndfjar6PLsDYwEpaCQ=";
};
});
})
# home-assistant-frontend does not exist in python3.pkgs
(self: super: {
home-assistant-frontend = self.callPackage ./frontend.nix { };
@@ -252,7 +265,7 @@ let
extraBuildInputs = extraPackages py.pkgs;
# Don't forget to run parse-requirements.py after updating
hassVersion = "2021.12.4";
hassVersion = "2021.12.5";
in with py.pkgs; buildPythonApplication rec {
pname = "homeassistant";
@@ -269,7 +282,7 @@ in with py.pkgs; buildPythonApplication rec {
owner = "home-assistant";
repo = "core";
rev = version;
hash = "sha256:NZPv6Zyy9brdArRsyGA6EMkYEY1wCf6osjek4lEsr1c=";
hash = "sha256:116qklmzvqh3hn3i6i7lvsnqydd2qclk612rwlxs3v56kzpks62n";
};
# leave this in, so users don't have to constantly update their downstream patch handling
+3 -3
View File
@@ -2,13 +2,13 @@
python3.pkgs.buildPythonApplication rec {
pname = "radicale";
version = "3.0.6";
version = "3.1.0";
src = fetchFromGitHub {
owner = "Kozea";
repo = "Radicale";
rev = version;
sha256 = "1xlsvrmx6jhi71j6j8z9sli5vwxasivzjyqf8zq8r0l5p7350clf";
rev = "v${version}";
hash = "sha256-LtPv+3FQMGC2YP2+1cSPZVUIzrUhteJTl58+JdvGcQg=";
};
postPatch = ''
+7 -2
View File
@@ -8,13 +8,14 @@
, icu66
, krb5
, lib
, libtasn1
, makeWrapper
, stdenv
, openssl
}:
stdenv.mkDerivation rec {
pname = "roon-server";
version = "1.8-850";
version = "1.8-880";
src =
let
@@ -22,13 +23,17 @@ stdenv.mkDerivation rec {
in
fetchurl {
url = "http://download.roonlabs.com/builds/RoonServer_linuxx64_${urlVersion}.tar.bz2";
sha256 = "sha256-NSNaL0ERYTSYn9ETjWcQiuI4hY+w/lWVOz3n9lt6O+4=";
sha256 = "sha256-Td3iRYGmTg8Vx9c4e4ugIIbAqhDFPax9vR2BsCIQCZA=";
};
dontConfigure = true;
dontBuild = true;
buildInputs = [
alsa-lib
freetype
krb5
libtasn1
stdenv.cc.cc.lib
];
+7 -3
View File
@@ -10,13 +10,13 @@
}@args:
let
version = "2.8.0.beta9";
version = "2.8.0.beta10";
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse";
rev = "v${version}";
sha256 = "sha256-cTedMbf0N50ysRQqA9Fm1WQmI5J5hsqDSi2JZIa49jg=";
sha256 = "sha256-mlTOsHR8p0mTdhZHBESyDAa1XtMJ4uIht0VUcGD6Ses=";
};
runtimeDeps = [
@@ -313,7 +313,11 @@ let
enabledPlugins = plugins;
plugins = callPackage ./plugins/all-plugins.nix { inherit mkDiscoursePlugin; };
ruby = rubyEnv.wrappedRuby;
tests = import ../../../../nixos/tests/discourse.nix { package = pkgs.discourse.override args; };
tests = import ../../../../nixos/tests/discourse.nix {
inherit (stdenv) system;
inherit pkgs;
package = pkgs.discourse.override args;
};
};
};
in discourse
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-assign";
rev = "91d0712b0440b6bb0c2fedbf6c31191cdeb991fe";
sha256 = "sha256-ATWLu0vJZFquRcAUpFKaU8mqjjVOv3PziAsHR3aemWk=";
rev = "920503f5fc2cbec1b3ba4d431cffda2281e12509";
sha256 = "sha256-qMUlJwETu99Qmbh4sn/1Vn7Xgaj3Jhi+/E8ecIbnVH8=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-docs";
@@ -1,21 +1,19 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.1.4.1)
activesupport (7.0.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
concurrent-ruby (1.1.9)
i18n (1.8.11)
concurrent-ruby (~> 1.0)
minitest (5.14.4)
minitest (5.15.0)
rrule (0.4.2)
activesupport (>= 4.1)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
zeitwerk (2.5.1)
PLATFORMS
ruby
@@ -6,8 +6,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-calendar";
rev = "fbc617a5fa9f3a22bcc72bc2b32ea3cbdf6087c5";
sha256 = "sha256-qBtq8IvxdKYIFNL9DwdRqZceMMO/qgd6jTr3kk3so3Y=";
rev = "9c5516ff039225be04b1302c5c67837ce64fba9c";
sha256 = "sha256-tfQWhkQvHrIUl0+tIv8X65MvoUhUnKD7KHwQbBm3p7U=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-calendar";
@@ -1,14 +1,14 @@
{
activesupport = {
dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo" "zeitwerk"];
dependencies = ["concurrent-ruby" "i18n" "minitest" "tzinfo"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "19gx1jcq46x9d1pi1w8xq0bgvvfw239y4lalr8asm291gj3q3ds4";
sha256 = "04bsr3420wb8y5pagg3s0rkx44fix47wrjvfby2d205l9bq6azyk";
type = "gem";
};
version = "6.1.4.1";
version = "7.0.0";
};
concurrent-ruby = {
groups = ["default"];
@@ -36,10 +36,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "19z7wkhg59y8abginfrm2wzplz7py3va8fyngiigngqvsws6cwgl";
sha256 = "06xf558gid4w8lwx13jwfdafsch9maz8m0g85wnfymqj63x5nbbd";
type = "gem";
};
version = "5.14.4";
version = "5.15.0";
};
rrule = {
dependencies = ["activesupport"];
@@ -63,14 +63,4 @@
};
version = "2.0.4";
};
zeitwerk = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "18l4r6layck0d80ydc692mv1lxak5xbf6w2paj1x7m2ggbggzxgj";
type = "gem";
};
version = "2.5.1";
};
}
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-canned-replies";
rev = "1bb77ebbe0577f257bc16783dc8b7bbf2d915092";
sha256 = "0qvx8k9jsxjllqsqpf4k0j4niv1k2sggy6ak067wigs8ha3dkcr0";
rev = "dbbb8740287e44b5e9f0d8c968e3d237154e1f3c";
sha256 = "sha256-o4yZaXiQpt7Bb29kVKJOiIdNgcSEOnSiFAIhZtiX6ys=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-canned-replies";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-chat-integration";
rev = "ae0389ca89f26401a6c4cffaaae6adcf14af0e15";
sha256 = "sha256-wT9S2mMz2MOpWpYv/FrHYhZibStRIGC4P2Vrqs04bkA=";
rev = "46b2c05cbd00dbc49bff87d78f8e1ec4fdd43735";
sha256 = "sha256-G17obAc03FR3Qzn/IR++Y5Z1TkpP6lY5UDJsm4Lmj0M=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-chat-integration";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-checklist";
rev = "d8012abd3d6dccb72eec83e6a96ef4809dcad681";
sha256 = "1ngjql65939c571gyaqj8ydcxy5kkril2qlkxqf579vvwzpvxw13";
rev = "b4e14bdac40131bd70a698015b35a111a18c9f88";
sha256 = "sha256-okxcLu6gXvEY37ylnhit5B+LwCdV5gMKBpC/m/PaGtc=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-checklist";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-data-explorer";
rev = "3ce778ec6d96a300a06ffe0581f4681fbed8df7f";
sha256 = "1555k1anrijfbm0qfraby3ivh6h76177d541nxhnarj85mjx0hjb";
rev = "f77f5999069dbe98c49302566c82e5f77bb72db2";
sha256 = "sha256-N9LmFnza1pA3JRBE9bT9b/NhdYMKoF5GOUpq9XYdokY=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-data-explorer";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-docs";
rev = "d3eee7008b7a703774331808e302e36f2f8b4eae";
sha256 = "1p3aqfpv207pvlbis43znwgw56yqsn41320yaw1gdcaakf5s2rsx";
rev = "e56816eb502b5ea37606f65a8df188e233f77240";
sha256 = "sha256-qvuoFsVXKa2IZgjVeqCca7X9jfohEBaoieZRsSFJCto=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-docs";
@@ -6,8 +6,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-github";
rev = "8cd8c0703991c16cb2fa8cb1fd22a9c3849c7ae2";
sha256 = "17ga31a10sm3fqjpf40mz7fk62vynyng2a243pia9fjdq9py8slx";
rev = "9fae5e365c1330bc25265e3bb2a06d29adb38266";
sha256 = "sha256-0HUrhO78XbTr6ygNFT+Uh70n2z9dFpimawh4u8fpNjg=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-github";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-math";
rev = "cacbd04bb239db3c772ff5a37c19fe39d127ff3d";
sha256 = "1bhs7wslb4rdf2b6h6klw1mpjf9pjpfpf2zg2mj8vg0acyaqvv9d";
rev = "3de98fc75b7d06d06651edc48449b1bb71d2171b";
sha256 = "sha256-HDhy6uvfmBxJq9UobLhAUdFcYULFvPZbb5vT1Sg7ung=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-math";
@@ -6,8 +6,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-openid-connect";
rev = "0e1511fcec2bbb26ef08e453920e955d4140df42";
sha256 = "02knx3z0ycz83cdarld2hmmpl6f9nkd2snp0qsbk9mjvbfvpfkni";
rev = "aa6a628687edc041bd6f46eb2a38e9a71644bdda";
sha256 = "sha256-VdaeueESr7X4gB1pW9e//nDLz62GTaZEPyFIvvCfg18=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-openid-connect";
@@ -6,8 +6,8 @@
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-prometheus";
rev = "08138ae4f89da76dd577781a2116b2ab66f8f547";
sha256 = "1x4awgx9fj0a6drsix3mi39ynj56rca3km0fz2xb3g6vxgc7d2z1";
rev = "aaaf3eda30e5fc03c880c056c1f2388739569fb0";
sha256 = "sha256-8bfjPCcwDjEC7Tu0Jr9VZRpaDlP2nlIOWBH8pUQakxo=";
};
patches = [
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-saved-searches";
rev = "b59e0b60afdd5133e60c5cc6169f42f1edd746be";
sha256 = "0yhr7gx35q2nshvfxkplplkq73l7sgqlm8r3g1apniqicpk5flqy";
rev = "0c14b9080306c2e35abf32f8211076286fdfbd2f";
sha256 = "sha256-ahNw2WL5J4qAyUBgpYWTiS4G+QmQa+gloG2Vu67qXR8=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-saved-searches";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-solved";
rev = "40277e50d43e4bdaab99efab44f59f6e33d74740";
sha256 = "02n266swdslws8r26xf99l3ghpqd3dryd0qfp7kiqk3ksy8hh5n2";
rev = "6f50e2633545e160c01188bdfa9e57adf1d18adc";
sha256 = "sha256-+L4GzJrt15vYY29iYxVpPZFYhLygZJK4I5fqvhdI/HI=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-solved";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-spoiler-alert";
rev = "790380d9d321f9368c7a16d8ed87718fc6047bf2";
sha256 = "079w4x2wlbsx164wv0zb373r8552wb5fvrb9pqzmrfvy0ybwf328";
rev = "f9545afaa557829f8f0c17a856e028a5be7407cf";
sha256 = "sha256-VhA7tK+uE2r6E66yn5FbT+Mdp9Ckj92xCF3Q9Wp60T8=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-spoiler-alert";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-voting";
rev = "36a41c2969c1ddfd8980e3f766b730b849726a08";
sha256 = "0ns2i8liwpd29kbn44wzx9yb0jfpyz70h0hmrs71hz6fdalzm4ph";
rev = "c2d8b9456834796e90f2e13e7d11a08f389531e1";
sha256 = "sha256-z6JBsuq4nj1eqfU/xoU4xWcVNphuyr3C3iKO0chcSz4=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-voting";
@@ -5,8 +5,8 @@ mkDiscoursePlugin {
src = fetchFromGitHub {
owner = "discourse";
repo = "discourse-yearly-review";
rev = "683327574ea1a67c9c4182c887d6ba85171ca02b";
sha256 = "0y0hvb2ir9254ilpf7mnbn9xvv9anyqj4qwh97cw7jly7n2mga4m";
rev = "e42f48a576b753cb1e042e9693af35214333bb0f";
sha256 = "sha256-8+pwiQE0Ytva0t80bRDs+7mTZ82fPpmwb7Nk9boPFt8=";
};
meta = with lib; {
homepage = "https://github.com/discourse/discourse-yearly-review";
@@ -83,7 +83,7 @@ GEM
bootsnap (1.9.3)
msgpack (~> 1.0)
builder (3.2.4)
bullet (6.1.5)
bullet (7.0.0)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
@@ -101,7 +101,7 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
css_parser (1.10.0)
css_parser (1.11.0)
addressable
debug_inspector (1.1.0)
diff-lcs (1.4.4)
@@ -129,10 +129,10 @@ GEM
sprockets (>= 3.3, < 4.1)
ember-source (2.18.2)
erubi (1.10.0)
excon (0.88.0)
excon (0.89.0)
execjs (2.8.1)
exifr (1.3.9)
fabrication (2.22.0)
fabrication (2.23.1)
faker (2.19.0)
i18n (>= 1.6, < 2)
fakeweb (1.3.0)
@@ -157,7 +157,7 @@ GEM
faraday-rack (1.0.0)
fast_blank (1.0.1)
fast_xs (0.8.0)
fastimage (2.2.5)
fastimage (2.2.6)
ffi (1.15.4)
fspath (3.1.2)
gc_tracer (1.5.1)
@@ -198,7 +198,6 @@ GEM
jwt (2.3.0)
kgio (2.11.4)
libv8-node (16.10.0.0)
libv8-node (16.10.0.0-aarch64-linux)
listen (3.7.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
@@ -211,15 +210,15 @@ GEM
logstash-event (1.2.02)
logstash-logger (0.26.1)
logstash-event (~> 1.2)
logster (2.10.0)
loofah (2.12.0)
logster (2.10.1)
loofah (2.13.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
lz4-ruby (0.3.3)
maxminddb (0.1.22)
memory_profiler (1.0.0)
message_bus (3.3.6)
message_bus (3.3.8)
rack (>= 1.1.3)
method_source (1.0.0)
mini_mime (1.1.2)
@@ -229,9 +228,9 @@ GEM
mini_scheduler (0.13.0)
sidekiq (>= 4.2.3)
mini_sql (1.1.3)
mini_suffix (0.3.2)
mini_suffix (0.3.3)
ffi (~> 1.9)
minitest (5.14.4)
minitest (5.15.0)
mocha (1.13.0)
mock_redis (0.29.0)
ruby2_keywords
@@ -282,7 +281,7 @@ GEM
parallel (1.21.0)
parallel_tests (3.7.3)
parallel
parser (3.0.3.1)
parser (3.0.3.2)
ast (~> 2.4.1)
pg (1.2.3)
progress (3.6.0)
@@ -325,7 +324,7 @@ GEM
rake (>= 0.13)
thor (~> 1.0)
rainbow (3.0.0)
raindrops (0.19.2)
raindrops (0.20.0)
rake (13.0.6)
rb-fsevent (0.11.0)
rb-inotify (0.10.1)
@@ -338,7 +337,7 @@ GEM
redis (4.5.1)
redis-namespace (1.8.1)
redis (>= 3.0.4)
regexp_parser (2.1.1)
regexp_parser (2.2.0)
request_store (1.5.0)
rack (>= 1.4)
rexml (3.2.5)
@@ -388,9 +387,9 @@ GEM
rubocop-ast (>= 1.12.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.13.0)
rubocop-ast (1.15.0)
parser (>= 3.0.1.1)
rubocop-discourse (2.4.2)
rubocop-discourse (2.5.0)
rubocop (>= 1.1.0)
rubocop-rspec (>= 2.0.0)
rubocop-rspec (2.6.0)
@@ -432,7 +431,7 @@ GEM
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.1)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
@@ -466,7 +465,6 @@ GEM
zeitwerk (2.5.1)
PLATFORMS
aarch64-linux
ruby
DEPENDENCIES
@@ -273,10 +273,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "01xachwsyykmp153514vz2khanbsz1n27j09za5gcxj54srh5l4p";
sha256 = "0w3jk595azcc9fvklrk2klkljwhgzjhnns7l5iqhnafvr8q60xnr";
type = "gem";
};
version = "6.1.5";
version = "7.0.0";
};
byebug = {
groups = ["development" "test"];
@@ -414,10 +414,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1q8gj3wkc2mbzsqw5zcsr3kyzrrb2pda03pi769rjbvqr94g3bm5";
sha256 = "1qbdgp36dhcyljhmfxrvbgp1ha9yqxhxgyg3sdm48y9m371jd2an";
type = "gem";
};
version = "1.10.0";
version = "1.11.0";
};
debug_inspector = {
groups = ["default" "development"];
@@ -573,10 +573,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "15yrwawhvkjvfg0dsf8z81876ddj6161q0wh5s7pw4sim8z8pspr";
sha256 = "0153rr745g48h48vaplgmx7xkfjbc79acpq5jsl7agdrk4yf75ih";
type = "gem";
};
version = "0.88.0";
version = "0.89.0";
};
execjs = {
groups = ["assets" "default"];
@@ -603,10 +603,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1a1zv94hcss44n1b04w0rg0swg8npigrj3nva9h0y2f1iflj124k";
sha256 = "1i4pcqmf8q0gkjzhndcbzgg8bg4rkvbpp2gapnqxc8j8gcxzi1fi";
type = "gem";
};
version = "2.22.0";
version = "2.23.1";
};
faker = {
dependencies = ["i18n"];
@@ -757,10 +757,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "05i1fgqy4l40niwm9y56d04f876sm0cvc7q3w2rpddf8gya4lcs9";
sha256 = "0nnggg20za5vamdpkgrxxa32z33d8hf0g2bciswkhqnc6amb3yjr";
type = "gem";
};
version = "2.2.5";
version = "2.2.6";
};
ffi = {
groups = ["default" "development" "test"];
@@ -1090,10 +1090,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "13k73ap18p09bxwgw24xc1lb5bxnky8p0xpx7yrlk74xlffasw30";
sha256 = "09l4rdq5gsnhr7ma7i5ddg8sagkqn122kz8cb244q4hyk9rwmd2w";
type = "gem";
};
version = "2.10.0";
version = "2.10.1";
};
loofah = {
dependencies = ["crass" "nokogiri"];
@@ -1101,10 +1101,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1nqcya57x2n58y1dify60i0dpla40n4yir928khp4nj5jrn9mgmw";
sha256 = "17rvbrqcci1579d7dpbsfmz1f9g7msk82lyh9ip5h29dkrnixcgg";
type = "gem";
};
version = "2.12.0";
version = "2.13.0";
};
lru_redux = {
groups = ["default"];
@@ -1175,10 +1175,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1d0cdx4cszsa0wgnch1b5dcyalg6x9niyydik8yyampnpjghwfnk";
sha256 = "0xf3r47qpigg661krwa8z7k4f0z0rx9r5g2mgahrrwgjn67d332l";
type = "gem";
};
version = "3.3.6";
version = "3.3.8";
};
method_source = {
groups = ["default" "development" "test"];
@@ -1248,20 +1248,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1r6pwyv1vpyza0rn1pyxls4qdw5jd3vg4k5dp1iaqa57n6fiqrvi";
sha256 = "1rr2nx1kixd7ccxqdnswjnflg46s6lr1f9vxkdy298k95zwk67cd";
type = "gem";
};
version = "0.3.2";
version = "0.3.3";
};
minitest = {
groups = ["default" "development" "test"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "19z7wkhg59y8abginfrm2wzplz7py3va8fyngiigngqvsws6cwgl";
sha256 = "06xf558gid4w8lwx13jwfdafsch9maz8m0g85wnfymqj63x5nbbd";
type = "gem";
};
version = "5.14.4";
version = "5.15.0";
};
mocha = {
groups = ["development" "test"];
@@ -1530,10 +1530,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1skkdjawwigi9vs5zkp03jkpx2f11drfjz483g1xw2dnjdsq22c3";
sha256 = "0sszdl9mpzqzn9kxrp28sqmg47mjxcwypr4d60vbajqba4v885di";
type = "gem";
};
version = "3.0.3.1";
version = "3.0.3.2";
};
pg = {
groups = ["default"];
@@ -1752,10 +1752,10 @@
}];
source = {
remotes = ["https://rubygems.org"];
sha256 = "07nikrdnsf6g55225njnzs1lm9s0lnbv2krvqd2gldwl49l7vl9x";
sha256 = "0wb2x51parf6v78w0cic90m33bdc92y5h8rj4wqs75dhw1b69hc7";
type = "gem";
};
version = "0.19.2";
version = "0.20.0";
};
rake = {
groups = ["default" "development" "test"];
@@ -1839,10 +1839,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0vg7imjnfcqjx7kw94ccj5r78j4g190cqzi1i59sh4a0l940b9cr";
sha256 = "008yn8j44414qxhn1c0nxp4a70rq0bqhz70hnjpgx8cjh2g0makp";
type = "gem";
};
version = "2.1.1";
version = "2.2.0";
};
request_store = {
dependencies = ["rack"];
@@ -2031,10 +2031,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "06krbzlj49gjfmxpjwadfwqsqg5bgcp9k1fahyxxk3f6idqhkjbv";
sha256 = "0bj8ppl4143f7pkcwm4l5wcahid6yzracdlzh1w2fpss89pic2rf";
type = "gem";
};
version = "1.13.0";
version = "1.15.0";
};
rubocop-discourse = {
dependencies = ["rubocop" "rubocop-rspec"];
@@ -2042,10 +2042,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1agjjqdzajlssw2lxpchz5gr2sll9lh5yldccgmghxh39l01cr0a";
sha256 = "01f4y7am9cq276zl8vsgv64w8wfmhpbzg7vzsifhgnnh92g6s04g";
type = "gem";
};
version = "2.4.2";
version = "2.5.0";
};
rubocop-rspec = {
dependencies = ["rubocop"];
@@ -2227,10 +2227,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0pjz4lbv2v0p9fa5nsrxy5lphsixb9a69gq2rxp0h5sr61m18mdq";
sha256 = "1b9i14qb27zs56hlcc2hf139l0ghbqnjpmfi0054dxycaxvk5min";
type = "gem";
};
version = "3.4.1";
version = "3.4.2";
};
sshkey = {
groups = ["default"];
+1 -1
View File
@@ -164,7 +164,7 @@ def _diff_file(filepath: str, old_version: DiscourseVersion, new_version: Discou
def _remove_platforms(rubyenv_dir: Path):
for platform in ['arm64-darwin-20', 'x86_64-darwin-18',
'x86_64-darwin-19', 'x86_64-darwin-20',
'x86_64-linux']:
'x86_64-linux', 'aarch64-linux']:
with open(rubyenv_dir / 'Gemfile.lock', 'r') as f:
for line in f:
if platform in line:
@@ -5,13 +5,13 @@
python3.pkgs.buildPythonApplication rec {
pname = "calendar-cli";
version = "0.12.0";
version = "0.13.0";
src = fetchFromGitHub {
owner = "tobixen";
repo = "calendar-cli";
rev = "v${version}";
sha256 = "0qjld2m7hl3dx90491pqbjcja82c1f5gwx274kss4lkb8aw0kmlv";
hash = "sha256-wGigrBl5PJL+fVfnFnHDJ5zyB+Rq3Fm+q9vMvLuBBys=";
};
propagatedBuildInputs = with python3.pkgs; [
+2 -2
View File
@@ -14,11 +14,11 @@
stdenv.mkDerivation rec {
pname = "crowdin-cli";
version = "3.7.2";
version = "3.7.4";
src = fetchurl {
url = "https://github.com/crowdin/${pname}/releases/download/${version}/${pname}.zip";
sha256 = "sha256-7p+Di4GcztwzybJTcFXlun15NFYbJN8eGmJ0y9bify0=";
sha256 = "sha256-zsd95dkKzuhqtWFwc84tjZ05MnzE25UvfF459gfp+lA=";
};
nativeBuildInputs = [ installShellFiles makeWrapper unzip ];
+1
View File
@@ -27154,6 +27154,7 @@ with pkgs;
inherit (mopidyPackages)
mopidy
mopidy-iris
mopidy-jellyfin
mopidy-local
mopidy-moped
mopidy-mopify
+7
View File
@@ -6312,6 +6312,13 @@ let
url = "mirror://cpan/authors/id/R/RI/RIBASUSHI/DBIx-Class-0.082842.tar.gz";
sha256 = "1rh7idjjbibc1zmiaaarask434lh0lx7f2xyfwmy37k9fa0xcpmh";
};
patches = [
# https://github.com/Perl5/DBIx-Class/pull/141
(fetchpatch {
url = "https://github.com/Perl5/DBIx-Class/commit/fb896701d23fa4da622b5b1b2afbbba3da2dd8f3.patch";
sha256 = "sha256-MSbV9UfHu90NCdC5IFwuy/vpSDw4atfellYh7Ydvkm4=";
})
];
buildInputs = [ DBDSQLite TestDeep TestException TestWarn ];
propagatedBuildInputs = [ ClassAccessorGrouped ClassC3Componentised ConfigAny ContextPreserve DBI DataDumperConcise DataPage DevelGlobalDestruction ModuleFind PathClass SQLAbstractClassic ScopeGuard SubName namespaceclean ];
meta = {
+2
View File
@@ -5296,6 +5296,8 @@ in {
nitpick = callPackage ../applications/version-management/nitpick { };
nitransforms = callPackage ../development/python-modules/nitransforms { };
nix-kernel = callPackage ../development/python-modules/nix-kernel {
inherit (pkgs) nix;
};