Merge remote-tracking branch 'origin/master' into staging-next
This commit is contained in:
@@ -61,3 +61,17 @@ This results in a key with the following semantics:
|
||||
```
|
||||
<running-workflow>-<triggering-workflow>-<triggered-event>-<pull-request/fallback>
|
||||
```
|
||||
|
||||
## Required Status Checks
|
||||
|
||||
The "Required Status Checks" branch ruleset is implemented in two top-level workflows: `pr.yml` and `merge-group.yml`.
|
||||
|
||||
The PR workflow defines all checks that need to succeed to add a Pull Request to the Merge Queue.
|
||||
If no Merge Queue is set up for a branch, the PR workflow defines the checks required to merge into the target branch.
|
||||
|
||||
The Merge Group workflow defines all checks that are run as part of the Merge Queue.
|
||||
Only when these pass, a Pull Request is finally merged into the target branch.
|
||||
They don't apply when no Merge Queue is set up.
|
||||
|
||||
Both workflows work with the same `no PR failures` status check.
|
||||
This name can never be changed, because it's used in the branch ruleset for these rules.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
name: Merge Group
|
||||
|
||||
on:
|
||||
merge_group:
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
uses: ./.github/workflows/lint.yml
|
||||
with:
|
||||
mergedSha: ${{ github.event.merge_group.head_sha }}
|
||||
targetSha: ${{ github.event.merge_group.base_sha }}
|
||||
|
||||
# This job's only purpose is to serve as a target for the "Required Status Checks" branch ruleset.
|
||||
# It "needs" all the jobs that should block the Merge Queue.
|
||||
# If they pass, it is skipped — which counts as "success" for purposes of the branch ruleset.
|
||||
# However, if any of them fail, this job will also fail — thus blocking the branch ruleset.
|
||||
no-pr-failures:
|
||||
# Modify this list to add or remove jobs from required status checks.
|
||||
needs:
|
||||
- lint
|
||||
# WARNING:
|
||||
# Do NOT change the name of this job, otherwise the rule will not catch it anymore.
|
||||
# This would prevent all PRs from passing the merge queue.
|
||||
name: no PR failures
|
||||
if: ${{ failure() }}
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- run: exit 1
|
||||
@@ -2123,12 +2123,8 @@ The following rules are desired to be respected:
|
||||
It does not need to be set explicitly unless the package requires a specific platform.
|
||||
* The file is formatted with `nixfmt-rfc-style`.
|
||||
* Commit names of Python libraries must reflect that they are Python
|
||||
libraries (e.g. `python313Packages.numpy: 1.11 -> 1.12` rather than `numpy: 1.11 -> 1.12`).
|
||||
* The current default version of python should be included
|
||||
in commit messages to enable automatic builds by ofborg.
|
||||
For example `python313Packages.numpy: 1.11 -> 1.12` should be used rather
|
||||
than `python3Packages.numpy: 1.11 -> 1.12`.
|
||||
Note that `pythonPackages` is an alias for `python27Packages`.
|
||||
libraries (e.g. `python3Packages.numpy: 1.11 -> 1.12` rather than `numpy: 1.11 -> 1.12`).
|
||||
See also [`pkgs/README.md`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/README.md#commit-conventions).
|
||||
* Attribute names in `python-packages.nix` as well as `pname`s should match the
|
||||
library's name on PyPI, but be normalized according to [PEP
|
||||
0503](https://www.python.org/dev/peps/pep-0503/#normalized-names). This means
|
||||
|
||||
@@ -1468,6 +1468,9 @@
|
||||
"module-security-acme-fix-jws": [
|
||||
"index.html#module-security-acme-fix-jws"
|
||||
],
|
||||
"module-security-acme-reload-dependencies": [
|
||||
"index.html#module-security-acme-reload-dependencies"
|
||||
],
|
||||
"module-programs-zsh-ohmyzsh": [
|
||||
"index.html#module-programs-zsh-ohmyzsh"
|
||||
],
|
||||
|
||||
@@ -173,6 +173,21 @@
|
||||
|
||||
- `services.gitea` supports sending notifications with sendmail again. To do this, activate the parameter `services.gitea.mailerUseSendmail` and configure SMTP server.
|
||||
|
||||
- Revamp of the ACME certificate acquisication and renewal process to help scale systems with lots (100+) of certificates.
|
||||
|
||||
Units and targets have been reshaped to better support more specific dependency propagation and avoid
|
||||
superfluously triggering unchanged units:
|
||||
|
||||
If a service requires a syntactically valid certificate to start it should now depend on the `acme-{certname}.service` unit.
|
||||
|
||||
We now always generate initial self-signed certificates as this drastically simplifies the dependency structure. As a result, the option `security.acme.preliminarySelfsigned` has been removed.
|
||||
|
||||
Instead of the previous `acme-finished-{certname}.target`s there are now `acme-order-renew-{certname}.service`s that will be activated
|
||||
in a delayed fashion to ensure that bootstrapping with servers like nginx that take part in the acquisition/renewal process works
|
||||
smoothly. Dependencies on `acme-finished` units should move to `acme-order-renew`.
|
||||
|
||||
Note that system activation will complete before all certificates may have been renewed or acquired.
|
||||
|
||||
- `libvirt` now supports using `nftables` backend.
|
||||
- The `virtualisation.libvirtd.firewallBackend` option can be used to configure the firewall backend used by libvirtd.
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ let
|
||||
inherit (config.sdImage) storePaths;
|
||||
compressImage = config.sdImage.compressImage;
|
||||
populateImageCommands = config.sdImage.populateRootCommands;
|
||||
volumeLabel = "NIXOS_SD";
|
||||
volumeLabel = config.sdImage.rootVolumeLabel;
|
||||
}
|
||||
// optionalAttrs (config.sdImage.rootPartitionUUID != null) {
|
||||
uuid = config.sdImage.rootPartitionUUID;
|
||||
@@ -117,6 +117,17 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
rootVolumeLabel = mkOption {
|
||||
type = types.str;
|
||||
default = "NIXOS_SD";
|
||||
example = "NIXOS_PENDRIVE";
|
||||
description = ''
|
||||
Label for the NixOS root volume.
|
||||
Usually used when creating a recovery NixOS media installation
|
||||
that avoids conflicting with previous instalation label.
|
||||
'';
|
||||
};
|
||||
|
||||
firmwareSize = mkOption {
|
||||
type = types.int;
|
||||
# As of 2019-08-18 the Raspberry pi firmware + u-boot takes ~18MiB
|
||||
@@ -197,7 +208,7 @@ in
|
||||
];
|
||||
};
|
||||
"/" = {
|
||||
device = "/dev/disk/by-label/NIXOS_SD";
|
||||
device = "/dev/disk/by-label/${config.sdImage.rootVolumeLabel}";
|
||||
fsType = "ext4";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -318,7 +318,7 @@ can be applied to any service.
|
||||
|
||||
# Now you must augment OpenSMTPD's systemd service to load
|
||||
# the certificate files.
|
||||
systemd.services.opensmtpd.requires = [ "acme-finished-mail.example.com.target" ];
|
||||
systemd.services.opensmtpd.requires = [ "acme-mail.example.com.service" ];
|
||||
systemd.services.opensmtpd.serviceConfig.LoadCredential =
|
||||
let
|
||||
certDir = config.security.acme.certs."mail.example.com".directory;
|
||||
@@ -376,3 +376,11 @@ systemd-tmpfiles --create
|
||||
# Note: Do this for all certs that share the same account email address
|
||||
systemctl start acme-example.com.service
|
||||
```
|
||||
|
||||
## Ensuring dependencies for services that need to be reloaded when a certificate challenges {#module-security-acme-reload-dependencies}
|
||||
|
||||
Services that depend on ACME certificates and need to be reloaded can use one of two approaches to reload upon successfull certificate acquisition or renewal:
|
||||
|
||||
1. **Using the `security.acme.certs.<name>.reloadServices` option**: This will cause `systemctl try-reload-or-restart` to be run for the listed services.
|
||||
|
||||
2. **Using a separate reload unit**: if you need perform more complex actions you can implement a separate reload unit but need to ensure that it lists the `acme-renew-<name>.service` unit both as `wantedBy` AND `after`. See the nginx module implementation with its `nginx-config-reload` service.
|
||||
|
||||
@@ -24,56 +24,32 @@ let
|
||||
# Since that service is a oneshot with RemainAfterExit,
|
||||
# the folder will exist during all renewal services.
|
||||
lockdir = "/run/acme/";
|
||||
concurrencyLockfiles = map (n: "${toString n}.lock") (lib.range 1 cfg.maxConcurrentRenewals);
|
||||
# Assign elements of `baseList` to each element of `needAssignmentList`, until the latter is exhausted.
|
||||
# returns: [{fst = "element of baseList"; snd = "element of needAssignmentList"}]
|
||||
roundRobinAssign =
|
||||
baseList: needAssignmentList:
|
||||
if baseList == [ ] then [ ] else _rrCycler baseList baseList needAssignmentList;
|
||||
_rrCycler =
|
||||
with builtins;
|
||||
origBaseList: workingBaseList: needAssignmentList:
|
||||
if (workingBaseList == [ ] || needAssignmentList == [ ]) then
|
||||
[ ]
|
||||
else
|
||||
[
|
||||
{
|
||||
fst = head workingBaseList;
|
||||
snd = head needAssignmentList;
|
||||
}
|
||||
]
|
||||
++ _rrCycler origBaseList (
|
||||
if (tail workingBaseList == [ ]) then origBaseList else tail workingBaseList
|
||||
) (tail needAssignmentList);
|
||||
attrsToList = lib.mapAttrsToList (
|
||||
attrname: attrval: {
|
||||
name = attrname;
|
||||
value = attrval;
|
||||
}
|
||||
);
|
||||
# for an AttrSet `funcsAttrs` having functions as values, apply single arguments from
|
||||
# `argsList` to them in a round-robin manner.
|
||||
# Returns an attribute set with the applied functions as values.
|
||||
roundRobinApplyAttrs =
|
||||
funcsAttrs: argsList:
|
||||
lib.listToAttrs (
|
||||
map (x: {
|
||||
inherit (x.snd) name;
|
||||
value = x.snd.value x.fst;
|
||||
}) (roundRobinAssign argsList (attrsToList funcsAttrs))
|
||||
);
|
||||
|
||||
wrapInFlock =
|
||||
lockfilePath: script:
|
||||
script:
|
||||
# explainer: https://stackoverflow.com/a/60896531
|
||||
''
|
||||
exec {LOCKFD}> ${lockfilePath}
|
||||
echo "Waiting to acquire lock ${lockfilePath}"
|
||||
${pkgs.flock}/bin/flock ''${LOCKFD} || exit 1
|
||||
echo "Acquired lock ${lockfilePath}"
|
||||
maxConcurrentRenewals=${toString cfg.maxConcurrentRenewals}
|
||||
|
||||
acquireLock() {
|
||||
echo "Waiting to acquire lock in ${lockdir}"
|
||||
while true; do
|
||||
for i in $(seq 1 $maxConcurrentRenewals); do
|
||||
exec {LOCKFD}> "${lockdir}/$i.lock"
|
||||
if ${pkgs.flock}/bin/flock -n ''${LOCKFD}; then
|
||||
return 0
|
||||
fi
|
||||
exec {LOCKFD}>&-
|
||||
done
|
||||
sleep 1;
|
||||
done
|
||||
}
|
||||
|
||||
if [ "$maxConcurrentRenewals" -gt "0" ]; then
|
||||
acquireLock
|
||||
fi
|
||||
''
|
||||
+ script
|
||||
+ "\n"
|
||||
+ ''echo "Releasing lock ${lockfilePath}" # only released after process exit'';
|
||||
+ script;
|
||||
|
||||
# There are many services required to make cert renewals work.
|
||||
# They all follow a common structure:
|
||||
@@ -160,58 +136,49 @@ let
|
||||
);
|
||||
|
||||
# This is defined with lib.mkMerge so that we can separate the config per function.
|
||||
setupService = lib.mkMerge [
|
||||
{
|
||||
description = "Set up the ACME certificate renewal infrastructure";
|
||||
script = lib.mkBefore ''
|
||||
${lib.optionalString cfg.defaults.enableDebugLogs "set -x"}
|
||||
set -euo pipefail
|
||||
'';
|
||||
serviceConfig = commonServiceConfig // {
|
||||
# This script runs with elevated privileges, denoted by the +
|
||||
# ExecStartPre is used instead of ExecStart so that the `script` continues to work.
|
||||
ExecStartPre = "+${lib.getExe privilegedSetupScript}";
|
||||
setupService = {
|
||||
description = "Set up the ACME certificate renewal infrastructure";
|
||||
path = [ pkgs.minica ];
|
||||
|
||||
# We don't want this to run every time a renewal happens
|
||||
RemainAfterExit = true;
|
||||
script = lib.mkBefore ''
|
||||
${lib.optionalString cfg.defaults.enableDebugLogs "set -x"}
|
||||
set -euo pipefail
|
||||
test -e ca/key.pem || minica \
|
||||
--ca-key ca/key.pem \
|
||||
--ca-cert ca/cert.pem \
|
||||
--domains selfsigned.local
|
||||
'';
|
||||
|
||||
# StateDirectory entries are a cleaner, service-level mechanism
|
||||
# for dealing with persistent service data
|
||||
StateDirectory = [
|
||||
"acme"
|
||||
"acme/.lego"
|
||||
"acme/.lego/accounts"
|
||||
];
|
||||
StateDirectoryMode = "0755";
|
||||
serviceConfig = commonServiceConfig // {
|
||||
# This script runs with elevated privileges, denoted by the +
|
||||
# ExecStartPre is used instead of ExecStart so that the `script` continues to work.
|
||||
ExecStartPre = "+${lib.getExe privilegedSetupScript}";
|
||||
|
||||
# Creates ${lockdir}. Earlier RemainAfterExit=true means
|
||||
# it does not get deleted immediately.
|
||||
RuntimeDirectory = "acme";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
# We don't want this to run every time a renewal happens
|
||||
RemainAfterExit = true;
|
||||
|
||||
# Generally, we don't write anything that should be group accessible.
|
||||
# Group varies for most ACME units, and setup files are only used
|
||||
# under the acme user.
|
||||
UMask = "0077";
|
||||
};
|
||||
}
|
||||
# StateDirectory entries are a cleaner, service-level mechanism
|
||||
# for dealing with persistent service data
|
||||
StateDirectory = [
|
||||
"acme"
|
||||
"acme/.lego"
|
||||
"acme/.lego/accounts"
|
||||
"acme/.minica"
|
||||
];
|
||||
BindPaths = "/var/lib/acme/.minica:/tmp/ca";
|
||||
StateDirectoryMode = "0755";
|
||||
|
||||
# Avoid race conditions creating the CA for selfsigned certs
|
||||
(lib.mkIf cfg.preliminarySelfsigned {
|
||||
path = [ pkgs.minica ];
|
||||
# Working directory will be /tmp
|
||||
script = ''
|
||||
test -e ca/key.pem || minica \
|
||||
--ca-key ca/key.pem \
|
||||
--ca-cert ca/cert.pem \
|
||||
--domains selfsigned.local
|
||||
'';
|
||||
serviceConfig = {
|
||||
StateDirectory = [ "acme/.minica" ];
|
||||
BindPaths = "/var/lib/acme/.minica:/tmp/ca";
|
||||
};
|
||||
})
|
||||
];
|
||||
# Creates ${lockdir}. Earlier RemainAfterExit=true means
|
||||
# it does not get deleted immediately.
|
||||
RuntimeDirectory = "acme";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
|
||||
# Generally, we don't write anything that should be group accessible.
|
||||
# Group varies for most ACME units, and setup files are only used
|
||||
# under the acme user.
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
|
||||
certToConfig =
|
||||
cert: data:
|
||||
@@ -219,7 +186,6 @@ let
|
||||
acmeServer = data.server;
|
||||
useDns = data.dnsProvider != null;
|
||||
destPath = "/var/lib/acme/${cert}";
|
||||
selfsignedDeps = lib.optionals (cfg.preliminarySelfsigned) [ "acme-selfsigned-${cert}.service" ];
|
||||
|
||||
# Minica and lego have a "feature" which replaces * with _. We need
|
||||
# to make this substitution to reference the output files from both programs.
|
||||
@@ -339,16 +305,18 @@ let
|
||||
certificateKey = if data.csrKey != null then "${data.csrKey}" else "certificates/${keyName}.key";
|
||||
in
|
||||
{
|
||||
inherit accountHash cert selfsignedDeps;
|
||||
inherit accountHash cert;
|
||||
|
||||
group = data.group;
|
||||
|
||||
renewTimer = {
|
||||
description = "Renew ACME Certificate for ${cert}";
|
||||
wantedBy = [ "timers.target" ];
|
||||
# Avoid triggering certificate renewals accidentally when running s-t-c.
|
||||
unitConfig."X-OnlyManualStart" = true;
|
||||
timerConfig = {
|
||||
OnCalendar = data.renewInterval;
|
||||
Unit = "acme-${cert}.service";
|
||||
Unit = "acme-order-renew-${cert}.service";
|
||||
Persistent = "yes";
|
||||
|
||||
# Allow systemd to pick a convenient time within the day
|
||||
@@ -364,15 +332,29 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
selfsignService = lockfileName: {
|
||||
description = "Generate self-signed certificate for ${cert}";
|
||||
baseService = {
|
||||
description = "Ensure certificate for ${cert}";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
after = [ "acme-setup.service" ];
|
||||
requires = [ "acme-setup.service" ];
|
||||
|
||||
# Whenever this service starts (on boot, through dependencies, through
|
||||
# changes) we trigger the acme-order-renew service to give it a chance
|
||||
# to catch up with the potentially changed config.
|
||||
wants = [
|
||||
"acme-setup.service"
|
||||
"acme-order-renew-${cert}.service"
|
||||
];
|
||||
before = [ "acme-order-renew-${cert}.service" ];
|
||||
|
||||
restartTriggers = [
|
||||
config.systemd.services."acme-order-renew-${cert}".script
|
||||
];
|
||||
|
||||
path = [ pkgs.minica ];
|
||||
|
||||
unitConfig = {
|
||||
ConditionPathExists = "!/var/lib/acme/${cert}/key.pem";
|
||||
StartLimitIntervalSec = 0;
|
||||
};
|
||||
|
||||
@@ -380,52 +362,83 @@ let
|
||||
Group = data.group;
|
||||
UMask = "0027";
|
||||
|
||||
RemainAfterExit = true;
|
||||
|
||||
StateDirectory = "acme/${cert}";
|
||||
|
||||
BindPaths = [
|
||||
"/var/lib/acme/.minica:/tmp/ca"
|
||||
"/var/lib/acme/${cert}:/tmp/${keyName}"
|
||||
"/var/lib/acme/${cert}:/tmp/out"
|
||||
];
|
||||
};
|
||||
|
||||
# Working directory will be /tmp
|
||||
# minica will output to a folder sharing the name of the first domain
|
||||
# in the list, which will be ${data.domain}
|
||||
script = (if (lockfileName == null) then lib.id else wrapInFlock "${lockdir}${lockfileName}") ''
|
||||
script = wrapInFlock ''
|
||||
set -ex
|
||||
|
||||
# Regenerate self-signed certificates (in case the SANs change) until we
|
||||
# have seen a succesfull ACME certificate at least once.
|
||||
if [ -e out/acme-success ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
minica \
|
||||
--ca-key ca/key.pem \
|
||||
--ca-cert ca/cert.pem \
|
||||
--domains ${lib.escapeShellArg (builtins.concatStringsSep "," ([ data.domain ] ++ extraDomains))}
|
||||
|
||||
# Create files to match directory layout for real certificates
|
||||
cd '${keyName}'
|
||||
cp ../ca/cert.pem chain.pem
|
||||
cat cert.pem chain.pem > fullchain.pem
|
||||
cat key.pem fullchain.pem > full.pem
|
||||
(
|
||||
cd '${keyName}'
|
||||
cp -vp cert.pem ../out/cert.pem
|
||||
cp -vp key.pem ../out/key.pem
|
||||
)
|
||||
cat out/cert.pem ca/cert.pem > out/fullchain.pem
|
||||
cp ca/cert.pem out/chain.pem
|
||||
cat out/key.pem out/fullchain.pem > out/full.pem
|
||||
|
||||
# Group might change between runs, re-apply it
|
||||
chown '${user}:${data.group}' -- *
|
||||
# Fix up the output files to adhere to the group and
|
||||
# have consistent permissions. This needs to be kept
|
||||
# consistent with the acme-setup script above.
|
||||
for fixpath in out certificates; do
|
||||
if [ -d "$fixpath" ]; then
|
||||
chmod -R u=rwX,g=rX,o= "$fixpath"
|
||||
chown -R ${user}:${data.group} "$fixpath"
|
||||
fi
|
||||
done
|
||||
|
||||
# Default permissions make the files unreadable by group + anon
|
||||
# Need to be readable by group
|
||||
chmod 640 -- *
|
||||
${lib.optionalString (data.webroot != null) ''
|
||||
# Ensure the webroot exists. Fixing group is required in case configuration was changed between runs.
|
||||
# Lego will fail if the webroot does not exist at all.
|
||||
(
|
||||
mkdir -p '${data.webroot}/.well-known/acme-challenge' \
|
||||
&& chgrp '${data.group}' ${data.webroot}/.well-known/acme-challenge
|
||||
) || (
|
||||
echo 'Please ensure ${data.webroot}/.well-known/acme-challenge exists and is writable by acme:${data.group}' \
|
||||
&& exit 1
|
||||
)
|
||||
''}
|
||||
'';
|
||||
};
|
||||
|
||||
renewService = lockfileName: {
|
||||
description = "Renew ACME certificate for ${cert}";
|
||||
orderRenewService = {
|
||||
description = "Order (and renew) ACME certificate for ${cert}";
|
||||
after = [
|
||||
"network.target"
|
||||
"network-online.target"
|
||||
"acme-setup.service"
|
||||
"nss-lookup.target"
|
||||
]
|
||||
++ selfsignedDeps;
|
||||
wants = [ "network-online.target" ] ++ selfsignedDeps;
|
||||
requires = [ "acme-setup.service" ];
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/pull/81371#issuecomment-605526099
|
||||
wantedBy = lib.optionals (!config.boot.isContainer) [ "multi-user.target" ];
|
||||
"acme-${cert}.service"
|
||||
];
|
||||
wants = [
|
||||
"network-online.target"
|
||||
"acme-setup.service"
|
||||
"acme-${cert}.service"
|
||||
];
|
||||
# Ensure that certificates are generated if people use `security.acme.certs`
|
||||
# without having/declaring other systemd units that depend on the cert.
|
||||
|
||||
path = with pkgs; [
|
||||
lego
|
||||
@@ -491,7 +504,7 @@ let
|
||||
};
|
||||
|
||||
# Working directory will be /tmp
|
||||
script = (if (lockfileName == null) then lib.id else wrapInFlock "${lockdir}${lockfileName}") ''
|
||||
script = wrapInFlock ''
|
||||
${lib.optionalString data.enableDebugLogs "set -x"}
|
||||
set -euo pipefail
|
||||
|
||||
@@ -523,25 +536,12 @@ let
|
||||
[[ $expiration_days -gt ${toString data.validMinDays} ]]
|
||||
}
|
||||
|
||||
${lib.optionalString (data.webroot != null) ''
|
||||
# Ensure the webroot exists. Fixing group is required in case configuration was changed between runs.
|
||||
# Lego will fail if the webroot does not exist at all.
|
||||
(
|
||||
mkdir -p '${data.webroot}/.well-known/acme-challenge' \
|
||||
&& chgrp '${data.group}' ${data.webroot}/.well-known/acme-challenge
|
||||
) || (
|
||||
echo 'Please ensure ${data.webroot}/.well-known/acme-challenge exists and is writable by acme:${data.group}' \
|
||||
&& exit 1
|
||||
)
|
||||
''}
|
||||
|
||||
echo '${domainHash}' > domainhash.txt
|
||||
|
||||
# Check if we can renew.
|
||||
# Check if a new order is needed
|
||||
# We can only renew if the list of domains has not changed.
|
||||
# We also need an account key. Avoids #190493
|
||||
if cmp -s domainhash.txt certificates/domainhash.txt && [ -e '${certificateKey}' ] && [ -e 'certificates/${keyName}.crt' ] && [ -n "$(find accounts -name '${data.email}.key')" ]; 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
|
||||
@@ -553,13 +553,12 @@ let
|
||||
exit 11
|
||||
fi
|
||||
fi
|
||||
|
||||
# Otherwise do a full run
|
||||
# Do a full run
|
||||
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. \
|
||||
${lib.optionalString (cfg.preliminarySelfsigned) "Selfsigned certs are in place and dependant services will still start."}
|
||||
Self-signed 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
|
||||
@@ -567,10 +566,12 @@ let
|
||||
|
||||
mv domainhash.txt certificates/
|
||||
|
||||
# Group might change between runs, re-apply it
|
||||
chown '${user}:${data.group}' certificates/*
|
||||
touch out/acme-success
|
||||
|
||||
# Copy all certs to the "real" certs directory
|
||||
# lego has only an interesting subset of files available,
|
||||
# construct reasonably compatible files that clients can consume
|
||||
# as expected.
|
||||
if ! cmp -s 'certificates/${keyName}.crt' out/fullchain.pem; then
|
||||
touch out/renewed
|
||||
echo Installing new certificate
|
||||
@@ -581,10 +582,13 @@ let
|
||||
cat out/key.pem out/fullchain.pem > out/full.pem
|
||||
fi
|
||||
|
||||
# By default group will have no access to the cert files.
|
||||
# This chmod will fix that.
|
||||
chmod 640 out/*
|
||||
|
||||
# Keep permissions consistent. Needs to be in sync with the other scripts.
|
||||
for fixpath in out certificates; do
|
||||
if [ -d "$fixpath" ]; then
|
||||
chmod -R u=rwX,g=rX,o= "$fixpath"
|
||||
chown -R ${user}:${data.group} "$fixpath"
|
||||
fi
|
||||
done
|
||||
# Also ensure safer permissions on the account directory.
|
||||
chmod -R u=rwX,g=,o= accounts/.
|
||||
'';
|
||||
@@ -905,19 +909,6 @@ in
|
||||
|
||||
options = {
|
||||
security.acme = {
|
||||
preliminarySelfsigned = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether a preliminary self-signed certificate should be generated before
|
||||
doing ACME requests. This can be useful when certificates are required in
|
||||
a webserver, but ACME needs the webserver to make its requests.
|
||||
|
||||
With preliminary self-signed certificate the webserver can be started and
|
||||
can later reload the correct ACME certificates.
|
||||
'';
|
||||
};
|
||||
|
||||
acceptTerms = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
@@ -1003,10 +994,13 @@ in
|
||||
"ACME Directory is now hardcoded to /var/lib/acme and its permissions are managed by systemd. See https://github.com/NixOS/nixpkgs/issues/53852 for more info."
|
||||
)
|
||||
(lib.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"
|
||||
"This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service and Before=acme-\${cert}.service to the service you want to execute before the cert renewal"
|
||||
)
|
||||
(lib.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"
|
||||
"This option has been removed. If you want to make sure that something executes before certificates are provisioned, add a RequiredBy=acme-\${cert}.service and Before=acme-\${cert}.service to the service you want to execute before the cert renewal"
|
||||
)
|
||||
(lib.mkRemovedOptionModule [ "security" "acme" "preliminarySelfsigned" ]
|
||||
"This option has been removed. Preliminary self-signed certificates are now always generated to simplify the dependency structure."
|
||||
)
|
||||
(lib.mkChangedOptionModule
|
||||
[ "security" "acme" "validMin" ]
|
||||
@@ -1161,45 +1155,25 @@ in
|
||||
|
||||
systemd.services =
|
||||
let
|
||||
renewServiceFunctions = lib.mapAttrs' (
|
||||
cert: conf: lib.nameValuePair "acme-${cert}" conf.renewService
|
||||
orderRenewServices = lib.mapAttrs' (
|
||||
cert: conf: lib.nameValuePair "acme-order-renew-${cert}" conf.orderRenewService
|
||||
) certConfigs;
|
||||
renewServices =
|
||||
if cfg.maxConcurrentRenewals > 0 then
|
||||
roundRobinApplyAttrs renewServiceFunctions concurrencyLockfiles
|
||||
else
|
||||
lib.mapAttrs (_: f: f null) renewServiceFunctions;
|
||||
selfsignServiceFunctions = lib.mapAttrs' (
|
||||
cert: conf: lib.nameValuePair "acme-selfsigned-${cert}" conf.selfsignService
|
||||
baseServices = lib.mapAttrs' (
|
||||
cert: conf: lib.nameValuePair "acme-${cert}" conf.baseService
|
||||
) certConfigs;
|
||||
selfsignServices =
|
||||
if cfg.maxConcurrentRenewals > 0 then
|
||||
roundRobinApplyAttrs selfsignServiceFunctions concurrencyLockfiles
|
||||
else
|
||||
lib.mapAttrs (_: f: f null) selfsignServiceFunctions;
|
||||
in
|
||||
{
|
||||
acme-setup = setupService;
|
||||
}
|
||||
// renewServices
|
||||
// lib.optionalAttrs cfg.preliminarySelfsigned selfsignServices;
|
||||
// baseServices
|
||||
// orderRenewServices;
|
||||
|
||||
systemd.timers = lib.mapAttrs' (
|
||||
cert: conf: lib.nameValuePair "acme-${cert}" conf.renewTimer
|
||||
cert: conf: lib.nameValuePair "acme-renew-${cert}" conf.renewTimer
|
||||
) certConfigs;
|
||||
|
||||
systemd.targets =
|
||||
let
|
||||
# Create some targets which can be depended on to be "active" after cert renewals
|
||||
finishedTargets = lib.mapAttrs' (
|
||||
cert: conf:
|
||||
lib.nameValuePair "acme-finished-${cert}" {
|
||||
wantedBy = [ "default.target" ];
|
||||
requires = [ "acme-${cert}.service" ];
|
||||
after = [ "acme-${cert}.service" ];
|
||||
}
|
||||
) certConfigs;
|
||||
|
||||
# Create targets to limit the number of simultaneous account creations
|
||||
# How it works:
|
||||
# - Pick a "leader" cert service, which will be in charge of creating the account,
|
||||
@@ -1214,8 +1188,8 @@ in
|
||||
let
|
||||
dnsConfs = builtins.filter (conf: cfg.certs.${conf.cert}.dnsProvider != null) confs;
|
||||
leaderConf = if dnsConfs != [ ] then builtins.head dnsConfs else builtins.head confs;
|
||||
leader = "acme-${leaderConf.cert}.service";
|
||||
followers = map (conf: "acme-${conf.cert}.service") (
|
||||
leader = "acme-order-renew-${leaderConf.cert}.service";
|
||||
followers = map (conf: "acme-order-renew-${conf.cert}.service") (
|
||||
builtins.filter (conf: conf != leaderConf) confs
|
||||
);
|
||||
in
|
||||
@@ -1224,10 +1198,11 @@ in
|
||||
before = followers;
|
||||
requires = [ leader ];
|
||||
after = [ leader ];
|
||||
unitConfig.RefuseManualStart = true;
|
||||
}
|
||||
) (lib.groupBy (conf: conf.accountHash) (lib.attrValues certConfigs));
|
||||
in
|
||||
finishedTargets // accountTargets;
|
||||
accountTargets;
|
||||
})
|
||||
];
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ in
|
||||
"network.target"
|
||||
]
|
||||
++ lib.optional (cfg.useACMEHost != null) "acme-${cfg.useACMEHost}.service";
|
||||
wants = lib.optional (cfg.useACMEHost != null) "acme-finished-${cfg.useACMEHost}.target";
|
||||
wants = lib.optional (cfg.useACMEHost != null) "acme-${cfg.useACMEHost}.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
|
||||
|
||||
@@ -87,9 +87,8 @@ with lib;
|
||||
|
||||
ppp-pptpd-wrapped = pkgs.stdenv.mkDerivation {
|
||||
name = "ppp-pptpd-wrapped";
|
||||
phases = [ "installPhase" ];
|
||||
nativeBuildInputs = with pkgs; [ makeWrapper ];
|
||||
installPhase = ''
|
||||
buildCommand = ''
|
||||
mkdir -p $out/bin
|
||||
makeWrapper ${pkgs.ppp}/bin/pppd $out/bin/pppd \
|
||||
--set LD_PRELOAD "${pkgs.libredirect}/lib/libredirect.so" \
|
||||
|
||||
@@ -89,9 +89,8 @@ with lib;
|
||||
|
||||
xl2tpd-ppp-wrapped = pkgs.stdenv.mkDerivation {
|
||||
name = "xl2tpd-ppp-wrapped";
|
||||
phases = [ "installPhase" ];
|
||||
nativeBuildInputs = with pkgs; [ makeWrapper ];
|
||||
installPhase = ''
|
||||
buildCommand = ''
|
||||
mkdir -p $out/bin
|
||||
|
||||
makeWrapper ${pkgs.ppp}/sbin/pppd $out/bin/pppd \
|
||||
|
||||
@@ -201,7 +201,7 @@ let
|
||||
echo "Tried for at least 30 seconds, giving up..."
|
||||
exit 1
|
||||
fi
|
||||
count=$((count++))
|
||||
count=$((++count))
|
||||
done
|
||||
|
||||
${recoverIdmAdmin}
|
||||
|
||||
@@ -145,7 +145,7 @@ in
|
||||
'';
|
||||
"~* ^(\\/cache\\/files.*)(\\/.*)".extraConfig = ''
|
||||
alias /var/lib/onlyoffice/documentserver/App_Data$1;
|
||||
add_header Content-Disposition "attachment; filename*=UTF-8''$arg_filename";
|
||||
more_set_headers Content-Disposition "attachment; filename*=UTF-8''$arg_filename";
|
||||
|
||||
set $secure_link_secret verysecretstring;
|
||||
secure_link $arg_md5,$arg_expires;
|
||||
|
||||
@@ -48,8 +48,6 @@ let
|
||||
) (filter (hostOpts: hostOpts.enableACME || hostOpts.useACMEHost != null) vhosts);
|
||||
|
||||
vhostCertNames = unique (map (hostOpts: hostOpts.certName) acmeEnabledVhosts);
|
||||
dependentCertNames = filter (cert: certs.${cert}.dnsProvider == null) vhostCertNames; # those that might depend on the HTTP server
|
||||
independentCertNames = filter (cert: certs.${cert}.dnsProvider != null) vhostCertNames; # those that don't depend on the HTTP server
|
||||
|
||||
mkListenInfo =
|
||||
hostOpts:
|
||||
@@ -914,13 +912,14 @@ in
|
||||
systemd.services.httpd = {
|
||||
description = "Apache HTTPD";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = concatLists (map (certName: [ "acme-finished-${certName}.target" ]) vhostCertNames);
|
||||
wants = concatLists (map (certName: [ "acme-${certName}.service" ]) vhostCertNames);
|
||||
after = [
|
||||
"network.target"
|
||||
]
|
||||
++ map (certName: "acme-selfsigned-${certName}.service") vhostCertNames
|
||||
++ map (certName: "acme-${certName}.service") independentCertNames; # avoid loading self-signed key w/ real cert, or vice-versa
|
||||
before = map (certName: "acme-${certName}.service") dependentCertNames;
|
||||
# Ensure httpd runs with baseline certificates in place.
|
||||
++ map (certName: "acme-${certName}.service") vhostCertNames;
|
||||
# Ensure httpd runs (with current config) before the actual ACME jobs run
|
||||
before = map (certName: "acme-order-renew-${certName}.service") vhostCertNames;
|
||||
restartTriggers = [ cfg.configFile ];
|
||||
|
||||
path = [
|
||||
@@ -960,19 +959,17 @@ in
|
||||
|
||||
# postRun hooks on cert renew can't be used to restart Apache since renewal
|
||||
# runs as the unprivileged acme user. sslTargets are added to wantedBy + before
|
||||
# which allows the acme-finished-$cert.target to signify the successful updating
|
||||
# which allows the acme-order-renew-$cert.service to signify the successful updating
|
||||
# of certs end-to-end.
|
||||
systemd.services.httpd-config-reload =
|
||||
let
|
||||
sslServices = map (certName: "acme-${certName}.service") vhostCertNames;
|
||||
sslTargets = map (certName: "acme-finished-${certName}.target") vhostCertNames;
|
||||
sslServices = map (certName: "acme-order-renew-${certName}.service") vhostCertNames;
|
||||
in
|
||||
mkIf (vhostCertNames != [ ]) {
|
||||
wantedBy = sslServices ++ [ "multi-user.target" ];
|
||||
# Before the finished targets, after the renew services.
|
||||
# This service might be needed for HTTP-01 challenges, but we only want to confirm
|
||||
# certs are updated _after_ config has been reloaded.
|
||||
before = sslTargets;
|
||||
after = sslServices;
|
||||
restartTriggers = [ cfg.configFile ];
|
||||
# Block reloading if not all certs exist yet.
|
||||
|
||||
@@ -14,13 +14,11 @@ let
|
||||
virtualHosts = attrValues cfg.virtualHosts;
|
||||
acmeEnabledVhosts = filter (hostOpts: hostOpts.useACMEHost != null) virtualHosts;
|
||||
vhostCertNames = unique (map (hostOpts: hostOpts.useACMEHost) acmeEnabledVhosts);
|
||||
dependentCertNames = filter (cert: certs.${cert}.dnsProvider == null) vhostCertNames; # those that might depend on the HTTP server
|
||||
independentCertNames = filter (cert: certs.${cert}.dnsProvider != null) vhostCertNames; # those that don't depend on the HTTP server
|
||||
|
||||
mkVHostConf =
|
||||
hostOpts:
|
||||
let
|
||||
sslCertDir = config.security.acme.certs.${hostOpts.useACMEHost}.directory;
|
||||
sslCertDir = certs.${hostOpts.useACMEHost}.directory;
|
||||
in
|
||||
''
|
||||
${hostOpts.hostName} ${concatStringsSep " " hostOpts.serverAliases} {
|
||||
@@ -392,7 +390,7 @@ in
|
||||
++ map (
|
||||
name:
|
||||
mkCertOwnershipAssertion {
|
||||
cert = config.security.acme.certs.${name};
|
||||
cert = certs.${name};
|
||||
groups = config.users.groups;
|
||||
services = [ config.systemd.services.caddy ];
|
||||
}
|
||||
@@ -412,11 +410,8 @@ in
|
||||
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd.services.caddy = {
|
||||
wants = map (certName: "acme-finished-${certName}.target") vhostCertNames;
|
||||
after =
|
||||
map (certName: "acme-selfsigned-${certName}.service") vhostCertNames
|
||||
++ map (certName: "acme-${certName}.service") independentCertNames; # avoid loading self-signed key w/ real cert, or vice-versa
|
||||
before = map (certName: "acme-${certName}.service") dependentCertNames;
|
||||
wants = map (certName: "acme-${certName}.service") vhostCertNames;
|
||||
after = map (certName: "acme-${certName}.service") vhostCertNames;
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
startLimitIntervalSec = 14400;
|
||||
|
||||
@@ -434,14 +434,13 @@ in
|
||||
systemd.services.h2o = {
|
||||
description = "H2O HTTP server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = lib.concatLists (map (certName: [ "acme-finished-${certName}.target" ]) acmeCertNames.all);
|
||||
wants = lib.concatLists (map (certName: [ "acme-${certName}.service" ]) acmeCertNames.all);
|
||||
# Since H2O will be hosting the challenges, H2O must be started
|
||||
before = builtins.map (certName: "acme-${certName}.service") acmeCertNames.dependent;
|
||||
before = builtins.map (certName: "acme-order-renew-${certName}.service") acmeCertNames.all;
|
||||
after = [
|
||||
"network.target"
|
||||
]
|
||||
++ builtins.map (certName: "acme-selfsigned-${certName}.service") acmeCertNames.all
|
||||
++ builtins.map (certName: "acme-${certName}.service") acmeCertNames.independent; # avoid loading self-signed key w/ real cert, or vice-versa
|
||||
++ builtins.map (certName: "acme-${certName}.service") acmeCertNames.all;
|
||||
|
||||
serviceConfig = {
|
||||
ExecStart = "${h2oExe} --mode 'master'";
|
||||
@@ -490,16 +489,14 @@ in
|
||||
|
||||
# This service waits for all certificates to be available before reloading
|
||||
# H2O configuration. `tlsTargets` are added to `wantedBy` + `before` which
|
||||
# allows the `acme-finished-$cert.target` to signify the successful updating
|
||||
# allows the `acme-order-renew-$cert.service` to signify the successful updating
|
||||
# of certs end-to-end.
|
||||
systemd.services.h2o-config-reload =
|
||||
let
|
||||
tlsTargets = map (certName: "acme-${certName}.target") acmeCertNames.all;
|
||||
tlsServices = map (certName: "acme-${certName}.service") acmeCertNames.all;
|
||||
tlsServices = map (certName: "acme-order-renew-${certName}.service") acmeCertNames.all;
|
||||
in
|
||||
mkIf (acmeCertNames.all != [ ]) {
|
||||
wantedBy = tlsServices ++ [ "multi-user.target" ];
|
||||
before = tlsTargets;
|
||||
after = tlsServices;
|
||||
unitConfig = {
|
||||
ConditionPathExists = map (
|
||||
|
||||
@@ -15,8 +15,6 @@ let
|
||||
vhostConfig: vhostConfig.enableACME || vhostConfig.useACMEHost != null
|
||||
) vhostsConfigs;
|
||||
vhostCertNames = unique (map (hostOpts: hostOpts.certName) acmeEnabledVhosts);
|
||||
dependentCertNames = filter (cert: certs.${cert}.dnsProvider == null) vhostCertNames; # those that might depend on the HTTP server
|
||||
independentCertNames = filter (cert: certs.${cert}.dnsProvider != null) vhostCertNames; # those that don't depend on the HTTP server
|
||||
virtualHosts = mapAttrs (
|
||||
vhostName: vhostConfig:
|
||||
let
|
||||
@@ -442,6 +440,7 @@ let
|
||||
auth_basic off;
|
||||
auth_request off;
|
||||
proxy_pass http://${vhost.acmeFallbackHost};
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
''}
|
||||
'';
|
||||
@@ -1481,16 +1480,14 @@ in
|
||||
systemd.services.nginx = {
|
||||
description = "Nginx Web Server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = concatLists (map (certName: [ "acme-finished-${certName}.target" ]) vhostCertNames);
|
||||
wants = concatLists (map (certName: [ "acme-${certName}.service" ]) vhostCertNames);
|
||||
after = [
|
||||
"network.target"
|
||||
]
|
||||
++ map (certName: "acme-selfsigned-${certName}.service") vhostCertNames
|
||||
++ map (certName: "acme-${certName}.service") independentCertNames; # avoid loading self-signed key w/ real cert, or vice-versa
|
||||
# Nginx needs to be started in order to be able to request certificates
|
||||
# (it's hosting the acme challenge after all)
|
||||
# This fixes https://github.com/NixOS/nixpkgs/issues/81842
|
||||
before = map (certName: "acme-${certName}.service") dependentCertNames;
|
||||
# Ensure nginx runs with baseline certificates in place.
|
||||
++ map (certName: "acme-${certName}.service") vhostCertNames;
|
||||
# Ensure nginx runs (with current config) before the actual ACME jobs run
|
||||
before = map (certName: "acme-order-renew-${certName}.service") vhostCertNames;
|
||||
stopIfChanged = false;
|
||||
preStart = ''
|
||||
${cfg.preStart}
|
||||
@@ -1585,26 +1582,24 @@ in
|
||||
# This service waits for all certificates to be available
|
||||
# before reloading nginx configuration.
|
||||
# sslTargets are added to wantedBy + before
|
||||
# which allows the acme-finished-$cert.target to signify the successful updating
|
||||
# which allows the acme-order-renew-$cert.service to signify the successful updating
|
||||
# of certs end-to-end.
|
||||
systemd.services.nginx-config-reload =
|
||||
let
|
||||
sslServices = map (certName: "acme-${certName}.service") vhostCertNames;
|
||||
sslTargets = map (certName: "acme-finished-${certName}.target") vhostCertNames;
|
||||
sslOrderRenewServices = map (certName: "acme-order-renew-${certName}.service") vhostCertNames;
|
||||
in
|
||||
mkIf (cfg.enableReload || vhostCertNames != [ ]) {
|
||||
wants = optionals cfg.enableReload [ "nginx.service" ];
|
||||
wantedBy = sslServices ++ [ "multi-user.target" ];
|
||||
# Before the finished targets, after the renew services.
|
||||
wantedBy = sslOrderRenewServices ++ [ "multi-user.target" ];
|
||||
# XXX Before the finished targets, after the renew services.
|
||||
# This service might be needed for HTTP-01 challenges, but we only want to confirm
|
||||
# certs are updated _after_ config has been reloaded.
|
||||
before = sslTargets;
|
||||
after = sslServices;
|
||||
after = sslOrderRenewServices;
|
||||
restartTriggers = optionals cfg.enableReload [ configFile ];
|
||||
# Block reloading if not all certs exist yet.
|
||||
# Happens when config changes add new vhosts/certs.
|
||||
unitConfig = {
|
||||
ConditionPathExists = optionals (sslServices != [ ]) (
|
||||
ConditionPathExists = optionals (vhostCertNames != [ ]) (
|
||||
map (certName: certs.${certName}.directory + "/fullchain.pem") vhostCertNames
|
||||
);
|
||||
# Disable rate limiting for this, because it may be triggered quickly a bunch of times
|
||||
|
||||
@@ -72,11 +72,11 @@ in
|
||||
wants = [
|
||||
"network.target"
|
||||
]
|
||||
++ (optional (cfg.useACMEHost != null) "acme-finished-${cfg.useACMEHost}.target");
|
||||
++ (optional (cfg.useACMEHost != null) "acme-${cfg.useACMEHost}.service");
|
||||
after = [
|
||||
"network.target"
|
||||
]
|
||||
++ (optional (cfg.useACMEHost != null) "acme-finished-${cfg.useACMEHost}.target");
|
||||
++ (optional (cfg.useACMEHost != null) "acme-${cfg.useACMEHost}.service");
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = optionalAttrs (cfg.useACMEHost != null) {
|
||||
CERTIFICATE_FILE = "fullchain.pem";
|
||||
@@ -127,18 +127,16 @@ in
|
||||
|
||||
# postRun hooks on cert renew can't be used to restart Nginx since renewal
|
||||
# runs as the unprivileged acme user. sslTargets are added to wantedBy + before
|
||||
# which allows the acme-finished-$cert.target to signify the successful updating
|
||||
# which allows the acme-order-renew-$cert.target to signify the successful updating
|
||||
# of certs end-to-end.
|
||||
systemd.services.pomerium-config-reload = mkIf (cfg.useACMEHost != null) {
|
||||
# TODO(lukegb): figure out how to make config reloading work with credentials.
|
||||
|
||||
wantedBy = [
|
||||
"acme-finished-${cfg.useACMEHost}.target"
|
||||
"acme-order-renew-${cfg.useACMEHost}.service"
|
||||
"multi-user.target"
|
||||
];
|
||||
# Before the finished targets, after the renew services.
|
||||
before = [ "acme-finished-${cfg.useACMEHost}.target" ];
|
||||
after = [ "acme-${cfg.useACMEHost}.service" ];
|
||||
after = [ "acme-order-renew-${cfg.useACMEHost}.service" ];
|
||||
# Block reloading if not all certs exist yet.
|
||||
unitConfig.ConditionPathExists = [
|
||||
"${config.security.acme.certs.${cfg.useACMEHost}.directory}/fullchain.pem"
|
||||
|
||||
@@ -85,33 +85,24 @@ in
|
||||
ca_domain = "${nodes.acme.test-support.acme.caDomain}"
|
||||
fqdn = "${nodes.caddy.networking.fqdn}"
|
||||
|
||||
with subtest("Boot and start with selfsigned certificates"):
|
||||
caddy.start()
|
||||
caddy.wait_for_unit("caddy.service")
|
||||
check_issuer(caddy, fqdn, "minica")
|
||||
# Check that the web server has picked up the selfsigned cert
|
||||
check_connection(caddy, fqdn, minica=True)
|
||||
|
||||
acme.start()
|
||||
wait_for_running(acme)
|
||||
acme.wait_for_open_port(443)
|
||||
|
||||
with subtest("Boot and acquire a new cert"):
|
||||
caddy.start()
|
||||
wait_for_running(caddy)
|
||||
|
||||
with subtest("Acquire a new cert"):
|
||||
caddy.succeed(f"systemctl restart acme-{fqdn}.service")
|
||||
check_issuer(caddy, fqdn, "pebble")
|
||||
check_domain(caddy, fqdn, fqdn)
|
||||
|
||||
download_ca_certs(caddy, ca_domain)
|
||||
check_connection(caddy, fqdn)
|
||||
|
||||
with subtest("Can run on selfsigned certificates"):
|
||||
# Switch to selfsigned first
|
||||
caddy.succeed(f"systemctl clean acme-{fqdn}.service --what=state")
|
||||
caddy.succeed(f"systemctl start acme-selfsigned-{fqdn}.service")
|
||||
check_issuer(caddy, fqdn, "minica")
|
||||
caddy.succeed("systemctl restart caddy.service")
|
||||
# Check that the web server has picked up the selfsigned cert
|
||||
check_connection(caddy, fqdn, minica=True)
|
||||
caddy.succeed(f"systemctl start acme-{fqdn}.service")
|
||||
# This may fail a couple of times before caddy is restarted
|
||||
check_issuer(caddy, fqdn, "pebble")
|
||||
check_connection(caddy, fqdn)
|
||||
|
||||
with subtest("security.acme changes reflect on caddy"):
|
||||
check_connection(caddy, f"caddy-alt.{domain}", fail=True)
|
||||
switch_to(caddy, "add_domain")
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
{ runTest }:
|
||||
let
|
||||
domain = "example.test";
|
||||
in
|
||||
{
|
||||
http01-builtin = runTest ./http01-builtin.nix;
|
||||
dns01 = runTest ./dns01.nix;
|
||||
caddy = runTest ./caddy.nix;
|
||||
nginx = runTest (
|
||||
import ./webserver.nix {
|
||||
inherit domain;
|
||||
serverName = "nginx";
|
||||
group = "nginx";
|
||||
baseModule = {
|
||||
@@ -22,17 +26,17 @@
|
||||
addSSL = true;
|
||||
useACMEHost = "proxied.example.test";
|
||||
acmeFallbackHost = "localhost:8080";
|
||||
# lego will refuse the request if the host header is not correct
|
||||
extraConfig = ''
|
||||
proxy_set_header Host $host;
|
||||
'';
|
||||
};
|
||||
};
|
||||
specialisation.nullroot.configuration = {
|
||||
services.nginx.virtualHosts."nullroot.${domain}".acmeFallbackHost = "localhost:8081";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
httpd = runTest (
|
||||
import ./webserver.nix {
|
||||
inherit domain;
|
||||
serverName = "httpd";
|
||||
group = "wwwrun";
|
||||
baseModule = {
|
||||
@@ -50,6 +54,16 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
specialisation.nullroot.configuration = {
|
||||
services.httpd.virtualHosts."nullroot.${domain}" = {
|
||||
locations."/.well-known/acme-challenge" = {
|
||||
proxyPass = "http://localhost:8081/.well-known/acme-challenge";
|
||||
extraConfig = ''
|
||||
ProxyPreserveHost On
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -37,6 +37,12 @@ in
|
||||
listenHTTP = ":80";
|
||||
};
|
||||
|
||||
systemd.targets."renew-triggered" = {
|
||||
wantedBy = [ "acme-order-renew-${config.networking.fqdn}.service" ];
|
||||
after = [ "acme-order-renew-${config.networking.fqdn}.service" ];
|
||||
unitConfig.RefuseManualStart = true;
|
||||
};
|
||||
|
||||
specialisation = {
|
||||
renew.configuration = {
|
||||
# Pebble provides 5 year long certs,
|
||||
@@ -177,17 +183,29 @@ in
|
||||
# old_hash will be used in the preservation tests later
|
||||
old_hash = hash
|
||||
builtin.succeed(f"systemctl start acme-{cert}.service")
|
||||
builtin.succeed(f"systemctl start acme-order-renew-{cert}.service")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
hash_after = builtin.succeed(f"sha256sum /var/lib/acme/{cert}/cert.pem")
|
||||
assert hash == hash_after, "Certificate was unexpectedly changed"
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "renew")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_issuer(builtin, cert, "pebble")
|
||||
hash_after = builtin.succeed(f"sha256sum /var/lib/acme/{cert}/cert.pem | tee /dev/stderr")
|
||||
assert hash != hash_after, "Certificate was not renewed"
|
||||
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Handles email change correctly"):
|
||||
hash = builtin.succeed(f"sha256sum /var/lib/acme/{cert}/cert.pem")
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "accountchange")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_issuer(builtin, cert, "pebble")
|
||||
# Check that there are now 2 account directories
|
||||
builtin.succeed("test $(ls -1 /var/lib/acme/.lego/accounts | tee /dev/stderr | wc -l) -eq 2")
|
||||
@@ -202,58 +220,101 @@ in
|
||||
# old_hash will be used in the preservation tests later
|
||||
old_hash = hash_after
|
||||
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Correctly implements OCSP stapling"):
|
||||
check_stapling(builtin, cert, "${caDomain}", fail=True)
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "ocsp_stapling")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_stapling(builtin, cert, "${caDomain}")
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Handles keyType change correctly"):
|
||||
check_key_bits(builtin, cert, 256)
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "keytype")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_key_bits(builtin, cert, 384)
|
||||
# keyType is part of the accountHash, thus a new account will be created
|
||||
builtin.succeed("test $(ls -1 /var/lib/acme/.lego/accounts | tee /dev/stderr | wc -l) -eq 2")
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Reuses generated, valid certs from previous configurations"):
|
||||
# Right now, the hash should not match due to the previous test
|
||||
hash = builtin.succeed(f"sha256sum /var/lib/acme/{cert}/cert.pem | tee /dev/stderr")
|
||||
assert hash != old_hash, "Expected certificate to differ"
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "preservation")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
hash = builtin.succeed(f"sha256sum /var/lib/acme/{cert}/cert.pem | tee /dev/stderr")
|
||||
assert hash == old_hash, "Expected certificate to match from older configuration"
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Add a new cert, extend existing cert domains"):
|
||||
check_domain(builtin, cert, f"builtin-alt.{domain}", fail=True)
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "add_cert_and_domain")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_issuer(builtin, cert, "pebble")
|
||||
check_domain(builtin, cert, f"builtin-alt.{domain}")
|
||||
check_issuer(builtin, cert2, "pebble")
|
||||
check_domain(builtin, cert2, cert2)
|
||||
# There should not be a new account folder created
|
||||
builtin.succeed("test $(ls -1 /var/lib/acme/.lego/accounts | tee /dev/stderr | wc -l) -eq 2")
|
||||
check_permissions(builtin, cert, "acme")
|
||||
check_permissions(builtin, cert2, "acme")
|
||||
|
||||
with subtest("Check account hashing compatibility with pre-24.05 settings"):
|
||||
switch_to(builtin, "legacy_account_hash", fail=True)
|
||||
builtin.succeed(f"stat {legacy_account_dir} > /dev/stderr && rm -rf {legacy_account_dir}")
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "legacy_account_hash"
|
||||
)
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
with subtest("Ensure Concurrency limits work"):
|
||||
builtin.succeed(f"stat {legacy_account_dir} > /dev/stderr && rm -rf {legacy_account_dir}")
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Ensure concurrency limits work"):
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "concurrency")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_issuer(builtin, cert3, "pebble")
|
||||
check_domain(builtin, cert3, cert3)
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Can renew using a CSR"):
|
||||
builtin.succeed(f"systemctl stop acme-{cert}.service")
|
||||
builtin.succeed(f"systemctl clean acme-{cert}.service --what=state")
|
||||
|
||||
builtin.succeed("systemctl stop renew-triggered.target")
|
||||
switch_to(builtin, "csr")
|
||||
builtin.wait_for_unit("renew-triggered.target")
|
||||
|
||||
check_issuer(builtin, cert, "pebble")
|
||||
|
||||
with subtest("Generate self-signed certs"):
|
||||
acme.shutdown()
|
||||
|
||||
check_issuer(builtin, cert, "pebble")
|
||||
|
||||
builtin.succeed(f"systemctl stop acme-{cert}.service")
|
||||
builtin.succeed(f"systemctl clean acme-{cert}.service --what=state")
|
||||
builtin.succeed(f"systemctl start acme-selfsigned-{cert}.service")
|
||||
builtin.succeed(f"systemctl start acme-{cert}.service")
|
||||
|
||||
check_issuer(builtin, cert, "minica")
|
||||
check_domain(builtin, cert, cert)
|
||||
|
||||
with subtest("Validate permissions (self-signed)"):
|
||||
check_permissions(builtin, cert, "acme")
|
||||
|
||||
with subtest("Can renew using a CSR"):
|
||||
builtin.succeed(f"systemctl clean acme-{cert}.service --what=state")
|
||||
switch_to(builtin, "csr")
|
||||
check_issuer(builtin, cert, "pebble")
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -3,6 +3,36 @@ import time
|
||||
|
||||
TOTAL_RETRIES = 20
|
||||
|
||||
# BackoffTracker provides a robust system for handling test retries
|
||||
class BackoffTracker:
|
||||
delay = 1
|
||||
increment = 1
|
||||
|
||||
def handle_fail(self, retries, message) -> int:
|
||||
assert retries < TOTAL_RETRIES, message
|
||||
|
||||
print(f"Retrying in {self.delay}s, {retries + 1}/{TOTAL_RETRIES}")
|
||||
time.sleep(self.delay)
|
||||
|
||||
# Only increment after the first try
|
||||
if retries == 0:
|
||||
self.delay += self.increment
|
||||
self.increment *= 2
|
||||
|
||||
return retries + 1
|
||||
|
||||
def protect(self, func):
|
||||
def wrapper(*args, retries: int = 0, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as err:
|
||||
retries = self.handle_fail(retries, err.args)
|
||||
return wrapper(*args, retries=retries, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
backoff = BackoffTracker()
|
||||
|
||||
def run(node, cmd, fail=False):
|
||||
if fail:
|
||||
@@ -39,6 +69,7 @@ def switch_to(node, name, fail=False) -> None:
|
||||
# and matches the issuer we expect it to be.
|
||||
# It's a good validation to ensure the cert.pem and fullchain.pem
|
||||
# are not still selfsigned after verification
|
||||
@backoff.protect
|
||||
def check_issuer(node, cert_name, issuer) -> None:
|
||||
for fname in ("cert.pem", "fullchain.pem"):
|
||||
actual_issuer = node.succeed(
|
||||
@@ -102,9 +133,10 @@ def check_permissions(node, cert_name, group):
|
||||
f"test $({stat} /var/lib/acme/{cert_name}/*.pem"
|
||||
f" | tee /dev/stderr | grep -v '640 acme {group}' | wc -l) -eq 0"
|
||||
)
|
||||
node.execute(f"ls -lahR /var/lib/acme/.lego/{cert_name}/* > /dev/stderr")
|
||||
node.succeed(
|
||||
f"test $({stat} /var/lib/acme/.lego/{cert_name}/*/{cert_name}*"
|
||||
f" | tee /dev/stderr | grep -v '600 acme {group}' | wc -l) -eq 0"
|
||||
f" | tee /dev/stderr | grep -v '640 acme {group}' | wc -l) -eq 0"
|
||||
)
|
||||
node.succeed(
|
||||
f"test $({stat} /var/lib/acme/{cert_name}"
|
||||
@@ -115,37 +147,6 @@ def check_permissions(node, cert_name, group):
|
||||
f" | tee /dev/stderr | grep -v '600 acme {group}' | wc -l) -eq 0"
|
||||
)
|
||||
|
||||
# BackoffTracker provides a robust system for handling test retries
|
||||
class BackoffTracker:
|
||||
delay = 1
|
||||
increment = 1
|
||||
|
||||
def handle_fail(self, retries, message) -> int:
|
||||
assert retries < TOTAL_RETRIES, message
|
||||
|
||||
print(f"Retrying in {self.delay}s, {retries + 1}/{TOTAL_RETRIES}")
|
||||
time.sleep(self.delay)
|
||||
|
||||
# Only increment after the first try
|
||||
if retries == 0:
|
||||
self.delay += self.increment
|
||||
self.increment *= 2
|
||||
|
||||
return retries + 1
|
||||
|
||||
def protect(self, func):
|
||||
def wrapper(*args, retries: int = 0, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as err:
|
||||
retries = self.handle_fail(retries, err.args)
|
||||
return wrapper(*args, retries=retries, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
backoff = BackoffTracker()
|
||||
|
||||
|
||||
@backoff.protect
|
||||
def download_ca_certs(node, ca_domain):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
serverName,
|
||||
group,
|
||||
baseModule,
|
||||
domain ? "example.test",
|
||||
domain,
|
||||
}:
|
||||
{
|
||||
config,
|
||||
@@ -18,6 +18,8 @@
|
||||
timeout = 300;
|
||||
};
|
||||
|
||||
interactive.sshBackdoor.enable = true;
|
||||
|
||||
nodes = {
|
||||
# The fake ACME server which will respond to client requests
|
||||
acme =
|
||||
@@ -45,6 +47,7 @@
|
||||
"certchange.${domain}"
|
||||
"zeroconf.${domain}"
|
||||
"zeroconf2.${domain}"
|
||||
"zeroconf3.${domain}"
|
||||
"nullroot.${domain}"
|
||||
];
|
||||
|
||||
@@ -57,6 +60,7 @@
|
||||
systemd.targets."renew-triggered" = {
|
||||
wantedBy = [ "${serverName}-config-reload.service" ];
|
||||
after = [ "${serverName}-config-reload.service" ];
|
||||
unitConfig.RefuseManualStart = true;
|
||||
};
|
||||
|
||||
security.acme.certs."proxied.${domain}" = {
|
||||
@@ -101,13 +105,42 @@
|
||||
# Test that "acmeRoot = null" still results in
|
||||
# valid cert generation by inheriting defaults.
|
||||
nullroot.configuration = {
|
||||
security.acme.defaults.listenHTTP = ":8080";
|
||||
# The default.nix has the server-type dependent config statements
|
||||
# to properly set up the proxying. We need a separate port here to
|
||||
# avoid hostname issues with the proxy already running on :8080
|
||||
security.acme.defaults.listenHTTP = ":8081";
|
||||
services.${serverName}.virtualHosts."nullroot.${domain}" = {
|
||||
onlySSL = true;
|
||||
addSSL = true;
|
||||
enableACME = true;
|
||||
acmeRoot = null;
|
||||
};
|
||||
};
|
||||
|
||||
# Test that a adding a second virtual host will not trigger
|
||||
# other units (account and renewal service for first)
|
||||
zeroconf3.configuration = {
|
||||
services.${serverName}.virtualHosts = {
|
||||
"zeroconf.${domain}" = {
|
||||
addSSL = true;
|
||||
enableACME = true;
|
||||
serverAliases = [ "zeroconf2.${domain}" ];
|
||||
};
|
||||
"zeroconf3.${domain}" = {
|
||||
addSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
# We're doing something risky with the combination of the service unit being persistent
|
||||
# that could end up that the timers do not trigger properly. Show that timers have the
|
||||
# desired effect.
|
||||
systemd.timers."acme-renew-zeroconf3.${domain}".timerConfig = {
|
||||
OnCalendar = lib.mkForce "*-*-* *:*:0/5";
|
||||
AccuracySec = lib.mkForce 0;
|
||||
# Skew randomly within the day, per https://letsencrypt.org/docs/integration-guide/.
|
||||
RandomizedDelaySec = lib.mkForce 0;
|
||||
FixedRandomDelay = lib.mkForce 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -121,30 +154,24 @@
|
||||
ca_domain = "${nodes.acme.test-support.acme.caDomain}"
|
||||
fqdn = f"proxied.{domain}"
|
||||
|
||||
webserver.start()
|
||||
webserver.wait_for_unit("${serverName}.service")
|
||||
|
||||
with subtest("Can run on self-signed certificates"):
|
||||
check_issuer(webserver, fqdn, "minica")
|
||||
# Check that the web server has picked up the selfsigned cert
|
||||
check_connection(webserver, fqdn, minica=True)
|
||||
|
||||
acme.start()
|
||||
wait_for_running(acme)
|
||||
acme.wait_for_open_port(443)
|
||||
|
||||
with subtest("Acquire a cert through a proxied lego"):
|
||||
webserver.start()
|
||||
webserver.succeed("systemctl is-system-running --wait")
|
||||
wait_for_running(webserver)
|
||||
download_ca_certs(webserver, ca_domain)
|
||||
check_connection(webserver, fqdn)
|
||||
|
||||
with subtest("Can run on selfsigned certificates"):
|
||||
# Switch to selfsigned first
|
||||
webserver.succeed(f"systemctl clean acme-{fqdn}.service --what=state")
|
||||
webserver.succeed(f"systemctl start acme-selfsigned-{fqdn}.service")
|
||||
check_issuer(webserver, fqdn, "minica")
|
||||
webserver.succeed("systemctl restart ${serverName}-config-reload.service")
|
||||
# Check that the web server has picked up the selfsigned cert
|
||||
check_connection(webserver, fqdn, minica=True)
|
||||
webserver.succeed("systemctl stop renew-triggered.target")
|
||||
webserver.succeed(f"systemctl start acme-{fqdn}.service")
|
||||
webserver.wait_for_unit("renew-triggered.target")
|
||||
check_issuer(webserver, fqdn, "pebble")
|
||||
check_connection(webserver, fqdn)
|
||||
webserver.succeed(f"systemctl start acme-order-renew-{fqdn}.service")
|
||||
webserver.wait_for_unit("renew-triggered.target")
|
||||
download_ca_certs(webserver, ca_domain)
|
||||
check_issuer(webserver, fqdn, "pebble")
|
||||
check_connection(webserver, fqdn)
|
||||
|
||||
with subtest("security.acme changes reflect on web server part 1"):
|
||||
check_connection(webserver, f"certchange.{domain}", fail=True)
|
||||
@@ -181,5 +208,23 @@
|
||||
switch_to(webserver, "nullroot")
|
||||
webserver.wait_for_unit("renew-triggered.target")
|
||||
check_connection(webserver, f"nullroot.{domain}")
|
||||
|
||||
with subtest("Ensure that adding a second vhost does not trigger first vhost acme units"):
|
||||
switch_to(webserver, "zeroconf")
|
||||
webserver.wait_for_unit("renew-triggered.target")
|
||||
webserver.succeed("journalctl --cursor-file=/tmp/cursor | grep acme")
|
||||
switch_to(webserver, "zeroconf3")
|
||||
webserver.wait_for_unit("renew-triggered.target")
|
||||
output = webserver.succeed("journalctl --cursor-file=/tmp/cursor | grep acme")
|
||||
# The new certificate unit gets triggered:
|
||||
t.assertIn(f"acme-zeroconf3.{domain}-start", output)
|
||||
# The account generation should not be triggered again:
|
||||
t.assertNotIn("acme-account-d590213ed52603e9128d.target", output)
|
||||
# The other certificates should also not be triggered:
|
||||
t.assertNotIn(f"acme-zeroconf.{domain}-start", output)
|
||||
t.assertNotIn(f"acme-proxied.{domain}-start", output)
|
||||
# Ensure the timer works, due to our shenanigans with
|
||||
# RemainAfterExit=true
|
||||
webserver.wait_until_succeeds(f"journalctl --cursor-file=/tmp/cursor | grep 'Starting Order (and renew) ACME certificate for zeroconf3.{domain}...'")
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -137,17 +137,18 @@ import ./make-test-python.nix (
|
||||
caserver.wait_for_unit("step-ca.service")
|
||||
caserver.wait_until_succeeds("journalctl -o cat -u step-ca.service | grep '${pkgs.step-ca.version}'")
|
||||
|
||||
caclient.wait_for_unit("acme-finished-caclient.target")
|
||||
catester.succeed("curl https://caclient/ | grep \"Welcome to nginx!\"")
|
||||
caclient.wait_for_unit("acme-caclient.service")
|
||||
# The order is run asynchonously, keep trying.
|
||||
catester.wait_until_succeeds("curl https://caclient/ | grep \"Welcome to nginx!\"")
|
||||
|
||||
caclientcaddy.wait_for_unit("caddy.service")
|
||||
# It’s hard to know when Caddy has finished the ACME dance with
|
||||
# step-ca, so we keep trying cURL until success.
|
||||
catester.wait_until_succeeds("curl https://caclientcaddy/ | grep \"Welcome to Caddy!\"")
|
||||
|
||||
caclienth2o.wait_for_unit("acme-finished-caclienth2o.target")
|
||||
caclienth2o.wait_for_unit("acme-caclienth2o.service")
|
||||
caclienth2o.wait_for_unit("h2o.service")
|
||||
catester.succeed("curl https://caclienth2o/ | grep \"Welcome to H2O!\"")
|
||||
catester.wait_until_succeeds("curl https://caclienth2o/ | grep \"Welcome to H2O!\"")
|
||||
'';
|
||||
}
|
||||
)
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "okteta";
|
||||
version = "0.26.22";
|
||||
version = "0.26.23";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://kde/stable/okteta/${version}/src/${pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-vi7XhMj/PaMeK4V6FxU7Yi7XyWMaOBUenafZPpaP+n0=";
|
||||
sha256 = "sha256-sExQmI6sJsUHaKtb1A9bNaNIxE1uDmqNVgVjzw6xo7E=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -4968,6 +4968,19 @@ final: prev: {
|
||||
meta.hydraPlatforms = [ ];
|
||||
};
|
||||
|
||||
fine-cmdline-nvim = buildVimPlugin {
|
||||
pname = "fine-cmdline.nvim";
|
||||
version = "2025-06-15";
|
||||
src = fetchFromGitHub {
|
||||
owner = "VonHeikemen";
|
||||
repo = "fine-cmdline.nvim";
|
||||
rev = "7db181d1cb294581b12a036eadffffde762a118f";
|
||||
sha256 = "0991l33f37vpc5plw3c5rwm92sn08gfrlzqy8y1cn06f4p6ll78b";
|
||||
};
|
||||
meta.homepage = "https://github.com/VonHeikemen/fine-cmdline.nvim/";
|
||||
meta.hydraPlatforms = [ ];
|
||||
};
|
||||
|
||||
firenvim = buildVimPlugin {
|
||||
pname = "firenvim";
|
||||
version = "2025-07-22";
|
||||
|
||||
@@ -380,6 +380,7 @@ https://github.com/bakpakin/fennel.vim/,,
|
||||
https://github.com/wincent/ferret/,,
|
||||
https://github.com/bogado/file-line/,,
|
||||
https://github.com/lewis6991/fileline.nvim/,,
|
||||
https://github.com/VonHeikemen/fine-cmdline.nvim/,HEAD,
|
||||
https://github.com/glacambre/firenvim/,HEAD,
|
||||
https://github.com/andviro/flake8-vim/,,
|
||||
https://github.com/folke/flash.nvim/,HEAD,
|
||||
|
||||
@@ -89,8 +89,8 @@ let
|
||||
mktplcRef = {
|
||||
publisher = "42Crunch";
|
||||
name = "vscode-openapi";
|
||||
version = "4.37.2";
|
||||
hash = "sha256-XUD5lXybUdUavbiqCqv561NAPAbZ0Q9oLsQkrSRUmsU=";
|
||||
version = "4.38.0";
|
||||
hash = "sha256-J9hZhPrHkJEFkiyD8eACiJwbsPfYGMK42FkcwkTQ0RE=";
|
||||
};
|
||||
meta = {
|
||||
changelog = "https://marketplace.visualstudio.com/items/42Crunch.vscode-openapi/changelog";
|
||||
@@ -4853,8 +4853,8 @@ let
|
||||
mktplcRef = {
|
||||
name = "emacs-mcx";
|
||||
publisher = "tuttieee";
|
||||
version = "0.82.0";
|
||||
hash = "sha256-JpqHwQksZ/NsgiZ7EqHxT1FG9DLeInhDg6B+UWOFkeM=";
|
||||
version = "0.88.10";
|
||||
hash = "sha256-Umfe+V3BzHsEow6nOvtvg9EN1T0O6SbVwt5g2YHkaSU=";
|
||||
};
|
||||
meta = {
|
||||
changelog = "https://github.com/whitphx/vscode-emacs-mcx/blob/main/CHANGELOG.md";
|
||||
|
||||
@@ -10,8 +10,8 @@ vscode-utils.buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
publisher = "ms-azuretools";
|
||||
name = "vscode-bicep";
|
||||
version = "0.36.1";
|
||||
hash = "sha256-yrSIHTGHZ1m6fLGrtVlT4UHyWpKuzGKdywBDsMepd4g=";
|
||||
version = "0.37.4";
|
||||
hash = "sha256-RBoScMaYWKfA9SONCLkFEcGwj8ffQ3ZlAOiyQY9LtVw=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
}:
|
||||
mkLibretroCore {
|
||||
core = "mednafen-psx" + lib.optionalString withHw "-hw";
|
||||
version = "0-unstable-2025-08-01";
|
||||
version = "0-unstable-2025-08-06";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "libretro";
|
||||
repo = "beetle-psx-libretro";
|
||||
rev = "6eafe85d672ace484bd6b29eeb94eb84f0b41ee1";
|
||||
hash = "sha256-+gja4vMD+o78BxCR1SY4wLks6zOjKfU7M3a7cYg+2lc=";
|
||||
rev = "1e42a9076ab1ec5756d3f72e6d61923080fb2128";
|
||||
hash = "sha256-3k2qgAgyo3o/qwNQZsc0J1dKueZqM7jYvm9gzNkEShw=";
|
||||
};
|
||||
|
||||
extraBuildInputs = lib.optionals withHw [
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "pdfsam-basic";
|
||||
version = "5.3.1";
|
||||
version = "5.3.2";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/torakiki/pdfsam/releases/download/v${version}/pdfsam-basic_${version}-1_amd64.deb";
|
||||
hash = "sha256-Fhj/MJnnm8nsuJmSb6PigJT6Qm+CkGg8lV0NaUMfur0=";
|
||||
hash = "sha256-Y0Q9uT6cyxIYTX0JxoS0r3TamPT1iLXr94Zex30AeWo=";
|
||||
};
|
||||
|
||||
unpackPhase = ''
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "kubernetes-helm";
|
||||
version = "3.18.4";
|
||||
version = "3.18.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "helm";
|
||||
repo = "helm";
|
||||
rev = "v${finalAttrs.version}";
|
||||
sha256 = "sha256-2xOrTguenFzX7rvwm1ojSqV6ARCUSPUs07y3ut9Teec=";
|
||||
sha256 = "sha256-SVaNuTIBnM9TFk+xy7yvUXX+8BEbfQdbHPTWUuimVw4=";
|
||||
};
|
||||
vendorHash = "sha256-Z3OAbuoeAtChd9Sk4bbzgwIxmFrw+/1c4zyxpNP0xXg=";
|
||||
vendorHash = "sha256-Gn2h7a4bu9nWPEiqW9uN8SnKSZ7NRfchfRoFfpp49+M=";
|
||||
|
||||
subPackages = [ "cmd/helm" ];
|
||||
ldflags = [
|
||||
|
||||
@@ -3,23 +3,23 @@
|
||||
{
|
||||
"kicad" = {
|
||||
kicadVersion = {
|
||||
version = "9.0.2";
|
||||
version = "9.0.3";
|
||||
src = {
|
||||
rev = "bf9b9242aea7832d140dc25ff897fe01e2f36e41";
|
||||
sha256 = "1v3nvp5ifa36hx3iw3whlp3j7hiy91fzihc0jc1daw0hnps7qy24";
|
||||
rev = "08e2e9df692929a2087bbf1340a915aa2365c622";
|
||||
sha256 = "19rij2hz79rsmikdbygxzll2l7im5qi3i6phz4sdiagkc5k8b3rb";
|
||||
};
|
||||
};
|
||||
libVersion = {
|
||||
version = "9.0.2";
|
||||
version = "9.0.3";
|
||||
libSources = {
|
||||
symbols.rev = "9eab1c9c90a8aa84b0f7eec73076329d91764583";
|
||||
symbols.sha256 = "134x4d5w89aahl4k9zai6vwcazibz17gsgzy04l9xn4zcf6v11qp";
|
||||
templates.rev = "f93acff0f8c8c8e215ea125db060c86bf4b1f5d3";
|
||||
symbols.rev = "77ee421d180de82fce2d8c00f1b13a9456b43526";
|
||||
symbols.sha256 = "0r9aimyrv7p4ykqnwb9ac3fd0dv11zmv2ll6qkmm5s875s35hhfl";
|
||||
templates.rev = "6e651a795134380ac0dc3df1417d11cfab228033";
|
||||
templates.sha256 = "0zs29zn8qjgxv0w1vyr8yxmj02m8752zagn4vcraqgik46dwg2id";
|
||||
footprints.rev = "855079c1514bbdf38565fedcacee7fb05ffad5aa";
|
||||
footprints.sha256 = "0w44b7dzx6d3xw2vbw37k34zxy25bq46rsnv21x10227313vr2wm";
|
||||
packages3d.rev = "26e8886b3049a07e8b2b0bed82634ff755783352";
|
||||
packages3d.sha256 = "18cxlp5grvv5m63c3sb6m9l9cmijqqcjmxrkdzg63d5jp7w73smn";
|
||||
footprints.rev = "3ef8a3e0691599c633864118a3241e1cbeb873f1";
|
||||
footprints.sha256 = "1ysnj0973y05nn016hxrghccfv65cas772i369xflay0sns8anqf";
|
||||
packages3d.rev = "4c91925fde1402cc6da61d97cfb30a3de08d5bb6";
|
||||
packages3d.sha256 = "0njv4y31k62qhcx0xxcl94p34jgna8z4bs3hwjwzjfmp7ddl2dyx";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -5,9 +5,9 @@ let
|
||||
in
|
||||
{
|
||||
sublime-merge = common {
|
||||
buildVersion = "2102";
|
||||
aarch64sha256 = "E//XrWlfvMeRWYfBXVTSSUPlDFY/rzSynJ4aP1WyZ0Y=";
|
||||
x64sha256 = "Odb3ZvJCo4HTvJ7z31J/5wlyhSUpZRFBXP3f/Wkb7tU=";
|
||||
buildVersion = "2110";
|
||||
aarch64sha256 = "lG95VgRsicSRjve7ESTamU9dp/xBjR6yyLL+1wh6BXg=";
|
||||
x64sha256 = "v5CFqS+bB0Oe0fZ+vP0zxrJ2SUctNXKqODmB8M9XMIY=";
|
||||
} { };
|
||||
|
||||
sublime-merge-dev = common {
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "tartube";
|
||||
version = "2.5.156";
|
||||
version = "2.5.164";
|
||||
format = "setuptools";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "axcore";
|
||||
repo = "tartube";
|
||||
tag = "v${version}";
|
||||
sha256 = "sha256-4M1tYq8nVC1/+SQMtt0D0YfLW1uYWPcGx7XjuvbBxFw=";
|
||||
sha256 = "sha256-PPvbdxxGUYUKL+5exO5+iO5ObJgjzFejZIIDA17hvYo=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "3cpio";
|
||||
version = "0.8.0";
|
||||
version = "0.10.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bdrung";
|
||||
repo = "3cpio";
|
||||
tag = version;
|
||||
hash = "sha256-1kdJSwe9v7ojdukj04/G/RDeEk0NVCXmiNoVaelqt4Y=";
|
||||
hash = "sha256-UtXyJ4PDzi4BJ0nd9w/hygcJVfNd3H5WAIV+f23dtpk=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-axPghG1T5NZYzGRZBwtdBJ5tQh+h8/vep/EmL5ADCjE=";
|
||||
cargoHash = "sha256-XGTa5Ui4yPHmuC4tTWGMTKN/erHSaiJVmxHglbt+udg=";
|
||||
|
||||
# Tests attempt to access arbitrary filepaths
|
||||
doCheck = false;
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "abiword";
|
||||
version = "3.0.6";
|
||||
version = "3.0.7";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
domain = "gitlab.gnome.org";
|
||||
owner = "World";
|
||||
repo = "AbiWord";
|
||||
rev = "refs/tags/release-${version}";
|
||||
hash = "sha256-PPK4O+NKXdl7DKPOgGlVyCFTol8hhmtq0wdTTtwKQ/4=";
|
||||
hash = "sha256-dYbJ726Zuxs7+VTTCWHYQLsVZ/86hRUBQRac6toO4UI=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -37,12 +37,12 @@ in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = binName;
|
||||
|
||||
version = "0.23.2";
|
||||
version = "0.24.0";
|
||||
src = fetchFromGitHub {
|
||||
owner = "toeverything";
|
||||
repo = "AFFiNE";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-4WPnS+ZaiNgtib70ii/XfWkn2tNg2OsSAglD+mpnDvg=";
|
||||
hash = "sha256-vI4lCucwNdrbmst78NUkHXtluZvrc7aHymzm1Zbls78=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoVendor {
|
||||
@@ -92,7 +92,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
'';
|
||||
dontInstall = true;
|
||||
outputHashMode = "recursive";
|
||||
outputHash = "sha256-tpn+TlSrGIABmSM9B3iQc39nZmGEf5MliKyaKOsM7yM=";
|
||||
outputHash = "sha256-wSEAxOSLS0ul5vQDTj/bVXH8ViqDFsq6jHTaXJFAm/U=";
|
||||
};
|
||||
|
||||
buildInputs = lib.optionals hostPlatform.isDarwin [
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "afterburn";
|
||||
version = "5.8.2";
|
||||
version = "5.9.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "coreos";
|
||||
repo = "afterburn";
|
||||
tag = "v${version}";
|
||||
sha256 = "sha256-hlcUtEc0uWFolCt+mZd7f68PJPa+i/mv+2aJh4Vhmsw=";
|
||||
sha256 = "sha256-kMq3yoqIp2j5DRQFarEK9kss9DoVgAEkjUYJX5Ogu0g=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-Wn4Np1rwHh2sL1sqKalJrIDgMffxJgD1C2QOAR8bDRo=";
|
||||
cargoHash = "sha256-pWt2+SptdTiP4/oROw38qc6ekfbVWOf86BR18QC+ZPU=";
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ openssl ];
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
}:
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "app2unit";
|
||||
version = "1.0.0";
|
||||
version = "1.0.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Vladimir-csp";
|
||||
repo = "app2unit";
|
||||
tag = "v${version}";
|
||||
sha256 = "sha256-xHqPCA9ycPcImmyMrJZEfnfrFZ3sKfP/mhJ86CHLTQ8=";
|
||||
sha256 = "sha256-7eEVjgs+8k+/NLteSBKgn4gPaPLHC+3Uzlmz6XB0930=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ scdoc ];
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
}:
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "arkenfox-userjs";
|
||||
version = "133.0";
|
||||
version = "140.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://raw.githubusercontent.com/arkenfox/user.js/${finalAttrs.version}/user.js";
|
||||
hash = "sha256-rPcH24YqEBOzoPB9yxMlke/3tqpi9L7GVMsZ3MUP8WY=";
|
||||
hash = "sha256-/cz0dnQXKa3c/DqUTAEwBV0I9Tc3x6uzU6rtYijg3Zo=";
|
||||
};
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
|
||||
let
|
||||
source = {
|
||||
version = "2.27.0";
|
||||
hash = "sha256-FKWK/yYMNBrGgfWtdUC9DpQ2y8mBn3/5G+buQNzzot4=";
|
||||
npmDepsHash = "sha256-FpRO7lhgQNZ5wHQwHFIxkrYfmivgTopXKFcrQ48B20w=";
|
||||
clientNpmDepsHash = "sha256-GHN49bo7m9pzvwNvkVtA0cwTv+rWSAKpBHG7jqXm/vo=";
|
||||
version = "2.28.0";
|
||||
hash = "sha256-bbsiaSGIaD5oFnhk3e+SWzYxv4dsRXrgMVbe1lsj4pw=";
|
||||
npmDepsHash = "sha256-JC2uOXV+EwS6CGwyOUTXcymFwLSz/KUqIoB4ccSGgbw=";
|
||||
clientNpmDepsHash = "sha256-6l8apOd3R259+SlcD6P6rx1FkRnB80keoBGcfbQNhGU=";
|
||||
};
|
||||
|
||||
src = fetchFromGitHub {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p curl gnused gawk nix-prefetch common-updater-scripts jq prefetch-npm-deps
|
||||
#!nix-shell -i bash -p curl gnused gawk nix-prefetch nix-prefetch-git common-updater-scripts jq prefetch-npm-deps
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -13,16 +13,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "bootc";
|
||||
version = "1.5.1";
|
||||
version = "1.6.0";
|
||||
|
||||
cargoHash = "sha256-+FxydTK0Dmcj+doHMSoTgiues7Rrwxv/D+BOq4siKCk=";
|
||||
cargoHash = "sha256-KGwXQ6+/w3uHuPqSADsqJSip+SMdC104dfW7tNxGwnc=";
|
||||
doInstallCheck = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bootc-dev";
|
||||
repo = "bootc";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-LmhgCiVFbhrePV/A/FaNjD7VytUZqSm9VDU+1z0O98U=";
|
||||
hash = "sha256-TztsiC+DwD9yEAmjTuiuOi+Kf8WEYMsOVVnMKpSM3/g=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "calibre";
|
||||
version = "8.6.0";
|
||||
version = "8.7.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://download.calibre-ebook.com/${finalAttrs.version}/calibre-${finalAttrs.version}.tar.xz";
|
||||
hash = "sha256-FYWeUS78jvFV9nj/9RSRxPFYKYxSF04dIXZINSbn7WA=";
|
||||
hash = "sha256-LP5Yfjdz2GB/6LvvvNd7XPuBYSTKyJ5JE1PeuPL6kyQ=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
||||
@@ -34,6 +34,10 @@ rustPlatform.buildRustPackage rec {
|
||||
# requires internet access
|
||||
"--skip=detects_target_dependencies"
|
||||
"--skip=query::tests_lints::feature_missing"
|
||||
# platform specific snapshots
|
||||
"--skip=query::tests_lints::trait_method_target_feature_removed"
|
||||
"--skip=query::tests_lints::unsafe_trait_method_requires_more_target_features"
|
||||
"--skip=query::tests_lints::unsafe_trait_method_target_feature_added"
|
||||
];
|
||||
|
||||
preCheck = ''
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "cdogs-sdl";
|
||||
version = "2.3.0";
|
||||
version = "2.3.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
repo = "cdogs-sdl";
|
||||
owner = "cxong";
|
||||
rev = version;
|
||||
sha256 = "sha256-I4v13CPdA2KYwhlIJjz+qgKe2EoXUtV6iWeadrg4Usc=";
|
||||
sha256 = "sha256-jdrmtI/FADZ0vJDtX4Kq0A9RJ1ELjsQZjO2nMDf/fT8=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "chirpstack-concentratord";
|
||||
version = "4.5.0";
|
||||
version = "4.5.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "chirpstack";
|
||||
repo = "chirpstack-concentratord";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-UlliScDD1OEH4hLzKVr0z74iI48TTQTDfSsTwHzk8kw=";
|
||||
hash = "sha256-sqAroYaiDbVbl0Yqdc+Yl1rhYLjUv/Go+//nX4t7S0U=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-NkP3sMSw/iEkzqdX7rR6qMRq7MyZNyF9HcjrVuVRBEk=";
|
||||
cargoHash = "sha256-cg/icdN0ntbVdnEs6I0AJWVYkawsyV1gPYjDMhzzDBY=";
|
||||
|
||||
buildInputs = [
|
||||
libloragw-2g4
|
||||
|
||||
@@ -24,18 +24,18 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "clapgrep";
|
||||
version = "25.05+1";
|
||||
version = "25.07";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "luleyleo";
|
||||
repo = "clapgrep";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-DL3voYSsNGjPb1CnPuJGg+7UgWYZO7cH5T2Z37BuDSE=";
|
||||
hash = "sha256-XH0ei0x4QeCaVLDpRrHFgI6ExR5CSX7Pzg1PCrTyBec=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoVendor {
|
||||
inherit (finalAttrs) src;
|
||||
hash = "sha256-hTejIaXIAi8opZdE2X3vEi+VYoSti8RNB41ikVOWGPk=";
|
||||
hash = "sha256-tKC3YgLECV3EMMzBLBPj0GntHk2oavXGpTwWG9EjH1U=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
+4
-4
@@ -6,13 +6,13 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-code": "^1.0.74"
|
||||
"@anthropic-ai/claude-code": "^1.0.80"
|
||||
}
|
||||
},
|
||||
"node_modules/@anthropic-ai/claude-code": {
|
||||
"version": "1.0.74",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.74.tgz",
|
||||
"integrity": "sha512-Iahs887b3Zdk6xWkb+qDgz178nOWqfse35Ten2l+oOQqeS1A7Ct14BPZuQmLiWtkoSZxqFAsee3Gp+ITfPicrw==",
|
||||
"version": "1.0.80",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.80.tgz",
|
||||
"integrity": "sha512-OpJb8LZBYuQ21lmT71c65NwUKGtQiva8dyKmCIPWnRIXHDaZ/31zzpDqcxgONUKUiZrnHqoMXwEwWyPyhD0+dA==",
|
||||
"license": "SEE LICENSE IN README.md",
|
||||
"bin": {
|
||||
"claude": "cli.js"
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
buildNpmPackage rec {
|
||||
pname = "claude-code";
|
||||
version = "1.0.74";
|
||||
version = "1.0.80";
|
||||
|
||||
nodejs = nodejs_20; # required for sandboxed Nix builds on Darwin
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-${version}.tgz";
|
||||
hash = "sha256-cjiW39n74BV+s1ZKf/kgZVAg02XGWsoVfdzwPxuwe3g=";
|
||||
hash = "sha256-o7fG0LnTR7fGxq4VP5393tcQZi0JtPOF8Gb2cUAsevA=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-z+ZU8rT0rKcWxG4fZut7rA2rChVdyOyCw62+CNNObZU=";
|
||||
npmDepsHash = "sha256-9eVpQfcdiLyL6LWcBuVrd6XHQC5caZS9m8sNy9kaRyQ=";
|
||||
|
||||
postPatch = ''
|
||||
cp ${./package-lock.json} package-lock.json
|
||||
|
||||
@@ -1,31 +1,38 @@
|
||||
{
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
buildGo123Module,
|
||||
buildGoModule,
|
||||
}:
|
||||
|
||||
buildGo123Module rec {
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "clusternet";
|
||||
version = "0.17.3";
|
||||
version = "0.18.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "clusternet";
|
||||
repo = "clusternet";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-uhRnJyUR7lbJvVxd3YNVxmTSTDksQsVcM5G8ZKO7Xbk=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-MtiQM2msHv2gLaVpYoSrzJMZWwA0vMBIklwAQi+lG4g=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-hY4bgQXwKjL4UT3omDYuxy9xN9XOr00mMvGssKOSsG4=";
|
||||
vendorHash = "sha256-vG+k9ttXp/QqhbVKgwn2uo5kEk8OD+LBvJi5lBQfUk4=";
|
||||
|
||||
ldFlags = [
|
||||
"-s"
|
||||
"-w"
|
||||
];
|
||||
|
||||
# Clusternet hub is disabled due to panic: inlined function github.com/clusternet/clusternet/pkg/hub/apiserver/shadow.(*crdHandler).addStorage.func9.1 missing func info
|
||||
subPackages = [
|
||||
"cmd/clusternet-agent"
|
||||
"cmd/clusternet-controller-manager"
|
||||
"cmd/clusternet-scheduler"
|
||||
];
|
||||
|
||||
meta = {
|
||||
description = "CNCF Sandbox Project for managing your Kubernetes clusters";
|
||||
homepage = "https://github.com/clusternet/clusternet";
|
||||
license = lib.licenses.asl20;
|
||||
maintainers = with lib.maintainers; [ genga898 ];
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "codeql";
|
||||
version = "2.22.2";
|
||||
version = "2.22.3";
|
||||
|
||||
dontConfigure = true;
|
||||
dontBuild = true;
|
||||
@@ -19,7 +19,7 @@ stdenv.mkDerivation rec {
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://github.com/github/codeql-cli-binaries/releases/download/v${version}/codeql.zip";
|
||||
hash = "sha256-4GbvOtRm9YG0lqKnFv859UEsGb6cCkzjfx7Xazs5two=";
|
||||
hash = "sha256-75ayL/TftTM1nfwIFsVOhfqFi//ts6o8GeK/mYez04k=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "conmon-rs";
|
||||
version = "0.7.1";
|
||||
version = "0.7.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "containers";
|
||||
repo = "conmon-rs";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-NydA6IiIGX2Pc/49bstEGeA/X+zRIVNGbxhDfPwrWgM=";
|
||||
hash = "sha256-FZwX9xihg2mKpHT11FCASyoJ5nDUkAa4Cqk5zRQOfeY=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -23,7 +23,7 @@ rustPlatform.buildRustPackage rec {
|
||||
];
|
||||
doCheck = false;
|
||||
|
||||
cargoHash = "sha256-qP4AIPST1s6fiGq6FM2aXpEfkm4G/cOSYJyhtqF2k1E=";
|
||||
cargoHash = "sha256-JVUckmOAJj4zNBe4yq/JzrPw+IqfhiZRB6s03ZxXFV4=";
|
||||
|
||||
meta = with lib; {
|
||||
description = "OCI container runtime monitor written in Rust";
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "corsix-th";
|
||||
version = "0.69.0";
|
||||
version = "0.69.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "CorsixTH";
|
||||
repo = "CorsixTH";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-U8rl24EBjSRJrK2VmCI3YKeEM7U8ynaufEghgVfqrp0=";
|
||||
hash = "sha256-Jrf3PhgnJUBGy+ZcSPjU5tQFyuTmnn5+8P6LujsoSAg=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "cosmic-protocols";
|
||||
version = "0-unstable-2025-08-04";
|
||||
version = "0-unstable-2025-08-12";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "pop-os";
|
||||
repo = "cosmic-protocols";
|
||||
rev = "5035f8c810bf734401e21e0a9625c7b7e0c73325";
|
||||
hash = "sha256-FYfSVg7v7S8G1gHZ5puAqb2yZES81HK+KMu0819cQ8w=";
|
||||
rev = "8e84152fedf350d2756a2c1c90e07313acb9cdf6";
|
||||
hash = "sha256-rFoSSc2wBNiW8wK3AIKxyv28FNTEiGk6UWjp5dQVxe8=";
|
||||
};
|
||||
|
||||
makeFlags = [ "PREFIX=${placeholder "out"}" ];
|
||||
|
||||
@@ -12,13 +12,13 @@ let
|
||||
in
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "cozette";
|
||||
version = "1.29.0";
|
||||
version = "1.30.0";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://github.com/slavfox/Cozette/releases/download/v.${version}/CozetteFonts-v-${
|
||||
builtins.replaceStrings [ "." ] [ "-" ] version
|
||||
}.zip";
|
||||
hash = "sha256-DHUnCzp6c3d57cfkO2kH+czXRiqRWn6DBTo9NVTghQ0=";
|
||||
hash = "sha256-Njh6V5wTBKM/1QKmPwG1qiOYyAJSVQXLTBLN03V6DaE=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ bdf2psf ];
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "dmenu";
|
||||
version = "5.3";
|
||||
version = "5.4";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://dl.suckless.org/tools/dmenu-${finalAttrs.version}.tar.gz";
|
||||
hash = "sha256-3lRLa3NIg+7bUSDnef/rVL3XwvWWHTIPQ8mcVaq/SVI=";
|
||||
hash = "sha256-6bFq3Pj3cuZqLR0pkoJyfx3CDWmmSqkDoEVptMfej7g=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "doomretro";
|
||||
version = "5.7.1";
|
||||
version = "5.7.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bradharding";
|
||||
repo = "doomretro";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-yBc7TLY0wAPMXeUo0u6EcidoJpdkw5XijyWDB6FsTgg=";
|
||||
hash = "sha256-ShzZMmUwPB8IHhaA/7U4CEE7qcEjxfQDXVZkAVuEgtw=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "doublecmd";
|
||||
version = "1.1.26";
|
||||
version = "1.1.27";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "doublecmd";
|
||||
repo = "doublecmd";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-1rUAyI+Qe4I6F1T9KxMxHxedcARav6CE8W5qvWLu8Y0=";
|
||||
hash = "sha256-YHaxynBIxoirFDKvGEECKIAJezuex3DBoU8snEdbhhg=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "dpdk";
|
||||
version = "25.03";
|
||||
version = "25.07";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://fast.dpdk.org/rel/dpdk-${version}.tar.xz";
|
||||
sha256 = "sha256-akCnMTKChuvXloWxj/pZkua3cME4Q9Zf0NEVfPzP9j0=";
|
||||
sha256 = "sha256-aIbL7cNQu4y+80fRA2fWJZ42Q1Yn+7J9V4rb3A07QQ0=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
let
|
||||
themeName = "Dracula";
|
||||
version = "4.0.0-unstable-2025-07-17";
|
||||
version = "4.0.0-unstable-2025-08-04";
|
||||
in
|
||||
stdenvNoCC.mkDerivation {
|
||||
pname = "dracula-theme";
|
||||
@@ -17,8 +17,8 @@ stdenvNoCC.mkDerivation {
|
||||
src = fetchFromGitHub {
|
||||
owner = "dracula";
|
||||
repo = "gtk";
|
||||
rev = "96948976d1d9013a4cba30c3879e7cc09e51d77c";
|
||||
hash = "sha256-MrlyZpZH6CajGuzQMD3HQX/58LRrVHNnbumDofa6GNs=";
|
||||
rev = "646918e419c98747f4e6f8305c0ecaf6bbc860c6";
|
||||
hash = "sha256-8p9IS5aMZGP/VCuFTjQU+D3wfFIwfT/lcY7ujUv3SRc=";
|
||||
};
|
||||
|
||||
propagatedUserEnvPkgs = [
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
|
||||
python3Packages.buildPythonPackage {
|
||||
pname = "edl";
|
||||
version = "3.52.1-unstable-2025-07-28";
|
||||
version = "3.52.1-unstable-2025-07-31";
|
||||
format = "setuptools";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bkerler";
|
||||
repo = "edl";
|
||||
rev = "a474b79f6456123e4ff30ce0c5f0d362c2c283ba";
|
||||
rev = "502db9c439b0d748ca38b86e02765290cae9873e";
|
||||
fetchSubmodules = true;
|
||||
hash = "sha256-wTd+P0xLTffKAwepUmT2nSQ9R34OkB7ENgbwpysAlRE=";
|
||||
hash = "sha256-C4/cYGopg+d/gAT3k79Xu5tmkBiUO2Za0pE921wV+k4=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with python3Packages; [
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
}:
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "etesync-dav";
|
||||
version = "0.35.0";
|
||||
version = "0.35.1";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "etesync";
|
||||
repo = "etesync-dav";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-CD02nuA9GD/oe7mjExUHIftkPxM1pZQKyDalXSoOhXY=";
|
||||
hash = "sha256-y4BhU2kSn+RWqc5+pJQFhbwfat9cMWD0ED0EXJp25cY=";
|
||||
};
|
||||
|
||||
build-system = with python3Packages; [ setuptools ];
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "fly";
|
||||
version = "7.13.2";
|
||||
version = "7.14.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "concourse";
|
||||
repo = "concourse";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-onowKvN8YLDWRRn3rGEMoMxc6XaAcBKJcFOHSVh9Yy8=";
|
||||
hash = "sha256-7CXxaqfwFfxq6v0IKxkK08WkICBTLGf7ME1WuZzrG8w=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-WC4uzTgvW15IumwmsWXXeiF5qagbeb5XWRaSjd1XLvA=";
|
||||
vendorHash = "sha256-2busKAFaQYE82XKCAx8BGOMjjs8WzqIxdpz+J45maoc=";
|
||||
|
||||
subPackages = [ "fly" ];
|
||||
|
||||
|
||||
@@ -41,17 +41,17 @@ let
|
||||
in
|
||||
buildGoModule rec {
|
||||
pname = "forgejo-runner";
|
||||
version = "9.0.2";
|
||||
version = "9.0.3";
|
||||
|
||||
src = fetchFromGitea {
|
||||
domain = "code.forgejo.org";
|
||||
owner = "forgejo";
|
||||
repo = "runner";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-UjYi7+UAKvdz5FuElYGLfTYQD/E0vS1TJkUyPfUq7YA=";
|
||||
hash = "sha256-Zanx6Hg05+mvxdga8zQoCv13/kdAMnyCBMfuihvQv3M=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-7R42Aa04wCba90xLTX2p6oNX58OpfDDKegqwDw3Ycbk=";
|
||||
vendorHash = "sha256-PvqG4ogIiFeDN7gwM+cECXFjo9FBkdzglf+nuLqAZhE=";
|
||||
|
||||
# See upstream Makefile
|
||||
# https://code.forgejo.org/forgejo/runner/src/branch/main/Makefile
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "newt";
|
||||
version = "1.4.0";
|
||||
version = "1.4.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "fosrl";
|
||||
repo = "newt";
|
||||
tag = version;
|
||||
hash = "sha256-t1MqcrbYa5vojMOyn+iyExsUDQ1FQYlmZBFqyOkotyw=";
|
||||
hash = "sha256-rRieo1olWwTSx5p7HpDE0eMY4d2/GcU0o0wIFyXetzI=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-V8sq7XD/HJFKjhggrDWPdEEq3hjz0IHzpybQXA8Z/pg=";
|
||||
vendorHash = "sha256-PENsCO2yFxLVZNPgx2OP+gWVNfjJAfXkwWS7tzlm490=";
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace main.go \
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "olm";
|
||||
version = "1.0.0";
|
||||
version = "1.1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "fosrl";
|
||||
repo = "olm";
|
||||
tag = version;
|
||||
hash = "sha256-a0gkEo5EuJpHpZ5fKAPBXSTRvZaQo6KOJu4Abi1EztU=";
|
||||
hash = "sha256-/sDWsWOMgDcBYerBbxKWMfWlOUaeQeKQ+OIcE7LJg00=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-Ms8tLFKIa8GqmyFI7o+sQEpsZghNPIpq8BRCoY89Org=";
|
||||
vendorHash = "sha256-DqZU64jwg2AHmze1oWOmDgltB+k1mLSHQyAxnovLaVo=";
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "galene";
|
||||
version = "0.96.3";
|
||||
version = "1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jech";
|
||||
repo = "galene";
|
||||
tag = "galene-${finalAttrs.version}";
|
||||
hash = "sha256-loAiPfwTyPi4BKn4TNgVVde2mO119h443A+HwlLvi4g=";
|
||||
hash = "sha256-+ERoH2DsEMJNs3eGTBr4I+2+EdEKBfWnVRFKZ8igA6g=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-LDLKjD4qYn/Aae6GUX6gZ57+MUfKc058H+YHM0bNZV0=";
|
||||
vendorHash = "sha256-r9W/2Uead/EHKWnnJLL9bdA/MazLbe1UsgVXkPNFnxM=";
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "ghost-cli";
|
||||
version = "1.28.1";
|
||||
version = "1.28.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "TryGhost";
|
||||
repo = "Ghost-CLI";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-gpOaoR/UB8ermQCXlYgoVA3h+OdUGvP6ofjlFlMHA58=";
|
||||
hash = "sha256-hmLEkYivIH3uNOz6umEYU+A843a7d1M31OE5RCQ9WRQ=";
|
||||
};
|
||||
|
||||
yarnOfflineCache = fetchYarnDeps {
|
||||
yarnLock = finalAttrs.src + "/yarn.lock";
|
||||
hash = "sha256-4GJ6I0Iynu+/lmiKat3p/MIivVjcyxxhpXKPSOheBls=";
|
||||
hash = "sha256-ncZ5ULF1nE0vl+WISfEGZKtABT+pkJtWjHMkT1BjPCE=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "git-town";
|
||||
version = "21.3.0";
|
||||
version = "21.4.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "git-town";
|
||||
repo = "git-town";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-G1xeMOKZ1EKCZXqC2fJEUa5PeWUGknv0zew7rjAXqkM=";
|
||||
hash = "sha256-IBBnqwXx7q6QBk0Z5cHugXVeJHq85lCX7Y5U1tCXZmA=";
|
||||
};
|
||||
|
||||
vendorHash = null;
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "golangci-lint";
|
||||
version = "2.3.1";
|
||||
version = "2.4.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "golangci";
|
||||
repo = "golangci-lint";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-TuMIDKs8g1oYT4nQoUjwW0wEMaGxN+3YyWsbWTGy+tE=";
|
||||
hash = "sha256-JMFSYT9aiBdr/lOy+GYigbpMHETTQAomGZ7ehyr8U/M=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-1jnunHTVtqeDoljOC6JVq1pOxtZ/njqIRyQHRzctxgI=";
|
||||
vendorHash = "sha256-o01naYSkPpsXSvFlphGqJR14j3IBmTGBHpsu7DUE1Xg=";
|
||||
|
||||
subPackages = [ "cmd/golangci-lint" ];
|
||||
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "gost";
|
||||
version = "3.2.0";
|
||||
version = "3.2.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "go-gost";
|
||||
repo = "gost";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-pdDCBknAXHIFD7vNkinsoq7Uec6g3VJsNNoE1lvKkW4=";
|
||||
hash = "sha256-B2ffIGS0tURZI7uVALih7YM9thBWAjihdIdSHhQFnE8=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-6oRw2tCiQFExWhF1l+vvbL1uoJNx+rzPz+LX2J5r4no=";
|
||||
vendorHash = "sha256-WvCNvmH/KpFivKMBqBMgKi9VieOegGIrh463YC9WwAg=";
|
||||
|
||||
# Based on ldflags in upstream's .goreleaser.yaml
|
||||
ldflags = [
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "gruvbox-plus-icons";
|
||||
version = "6.2.0";
|
||||
version = "6.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "SylEleuth";
|
||||
repo = "gruvbox-plus-icon-pack";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-MCof2CFQfh/ChFNlsxw9BmrFf1A804HzWoHJdNsrW74=";
|
||||
hash = "sha256-4UJOiDdw5BxtOjLQjCpkQnUwQRs49GZTShpcElWjAU8=";
|
||||
};
|
||||
|
||||
patches = [ ./folder-color.patch ];
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
nodejs,
|
||||
pnpm_9,
|
||||
fetchFromGitHub,
|
||||
buildGoModule,
|
||||
wails,
|
||||
webkitgtk_4_0,
|
||||
pkg-config,
|
||||
libsoup_3,
|
||||
fetchFromGitHub,
|
||||
autoPatchelfHook,
|
||||
makeDesktopItem,
|
||||
copyDesktopItems,
|
||||
nodejs,
|
||||
pkg-config,
|
||||
pnpm_10,
|
||||
wails,
|
||||
webkitgtk_4_1,
|
||||
makeDesktopItem,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
let
|
||||
pname = "gui-for-clash";
|
||||
version = "1.9.7";
|
||||
version = "1.9.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "GUI-for-Cores";
|
||||
repo = "GUI.for.Clash";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-Ij9zyBzYpAfDEjJXqOiPxun+5e1T5j3juYudpvraBcQ=";
|
||||
hash = "sha256-YwolOIN4pQ9ykXruKAetUDMFkNnQppkzioDNlrPefL8=";
|
||||
};
|
||||
|
||||
metaCommon = {
|
||||
@@ -35,20 +34,24 @@ let
|
||||
frontend = stdenv.mkDerivation (finalAttrs: {
|
||||
inherit pname version src;
|
||||
|
||||
sourceRoot = "${finalAttrs.src.name}/frontend";
|
||||
|
||||
nativeBuildInputs = [
|
||||
nodejs
|
||||
pnpm_9.configHook
|
||||
pnpm_10.configHook
|
||||
];
|
||||
|
||||
pnpmDeps = pnpm_9.fetchDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
sourceRoot = "${finalAttrs.src.name}/frontend";
|
||||
fetcherVersion = 1;
|
||||
hash = "sha256-5tz1FItH9AvZhJjka8i5Kz22yf/tEmRPkDhz6iswZzc=";
|
||||
pnpmDeps = pnpm_10.fetchDeps {
|
||||
inherit (finalAttrs)
|
||||
pname
|
||||
version
|
||||
src
|
||||
sourceRoot
|
||||
;
|
||||
fetcherVersion = 2;
|
||||
hash = "sha256-iVD/9uTK3cUzKE20pJk67uk53UCtfj/YCpgwgxmmg8k=";
|
||||
};
|
||||
|
||||
sourceRoot = "${finalAttrs.src.name}/frontend";
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
@@ -74,27 +77,24 @@ in
|
||||
buildGoModule {
|
||||
inherit pname version src;
|
||||
|
||||
patches = [ ./bridge.patch ];
|
||||
patches = [ ./xdg-path-and-restart-patch.patch ];
|
||||
|
||||
# As we need the $out reference, we can't use `replaceVars` here.
|
||||
postPatch = ''
|
||||
# As we need the $out reference, we can't use `replaceVars` here.
|
||||
substituteInPlace bridge/bridge.go \
|
||||
--replace-fail '@basepath@' "$out"
|
||||
--subst-var out
|
||||
'';
|
||||
|
||||
vendorHash = "sha256-Coq8GtaIS7ClmOTFw6PSgGDFW/CpGpKPvXgNw8qz3Hs=";
|
||||
vendorHash = "sha256-7pFjfUFkpXyYEVjiXbfFUC7FQSlZubKJJ5MI8WY0IVA=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
wails
|
||||
pkg-config
|
||||
autoPatchelfHook
|
||||
copyDesktopItems
|
||||
pkg-config
|
||||
wails
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
webkitgtk_4_0
|
||||
libsoup_3
|
||||
];
|
||||
buildInputs = [ webkitgtk_4_1 ];
|
||||
|
||||
preBuild = ''
|
||||
cp -r ${frontend} frontend/dist
|
||||
@@ -103,7 +103,7 @@ buildGoModule {
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
wails build -m -s -trimpath -skipbindings -devtools -tags webkit2_40 -o GUI.for.Clash
|
||||
wails build -m -s -trimpath -skipbindings -devtools -tags webkit2_41 -o GUI.for.Clash
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
@@ -124,7 +124,7 @@ buildGoModule {
|
||||
runHook preInstall
|
||||
|
||||
install -Dm 0755 build/bin/GUI.for.Clash $out/bin/GUI.for.Clash
|
||||
install -Dm 0644 build/appicon.png $out/share/pixmaps/gui-for-clash.png
|
||||
install -Dm 0644 build/appicon.png $out/share/icons/hicolor/256x256/apps/gui-for-clash.png
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
--- a/bridge/bridge.go 2024-12-25 20:53:45.504021585 +0000
|
||||
+++ b/bridge/bridge.go 2024-12-25 21:02:20.318422528 +0000
|
||||
--- a/bridge/bridge.go
|
||||
+++ b/bridge/bridge.go
|
||||
@@ -41,13 +41,13 @@
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
func (a *App) RestartApp() FlagResult {
|
||||
- exePath := Env.BasePath + "/" + Env.AppName
|
||||
+ exePath := "@basepath@/bin" + "/" + Env.AppName
|
||||
+ exePath := "@out@/bin" + "/" + Env.AppName
|
||||
|
||||
cmd := exec.Command(exePath)
|
||||
SetCmdWindowHidden(cmd)
|
||||
SetCmdWindowHidden(cmd)
|
||||
@@ -13,16 +13,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "habitat";
|
||||
version = "1.6.1243";
|
||||
version = "1.6.1244";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "habitat-sh";
|
||||
repo = "habitat";
|
||||
rev = version;
|
||||
hash = "sha256-+5If4veDOGTTIhYxhAiq1cC4Sy6vAmjX5hrmUmpGlFU=";
|
||||
hash = "sha256-BNrBhDNR8sIafC9mgfL+1Q8c6BbjpFgLBElusydY/2o=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-AI7Ij9F/K/chjxQUC0SnBsQQPLlVS6esa5LJAGRS9YI=";
|
||||
cargoHash = "sha256-U4m3KzlU7XambNdwsdFuI5QPv2Fkm7Dwe264SRdHLak=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
}:
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "handheld-daemon";
|
||||
version = "3.17.6";
|
||||
version = "3.18.2";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "hhd-dev";
|
||||
repo = "hhd";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-JDTYqVzkdtMwMyMUyc+MABxzEKVsdRuQce9pMS2JnAE=";
|
||||
hash = "sha256-tU5xDwqmeYFT+2byq2Qo/k29TncPfTQgYZF0JZUe/Iw=";
|
||||
};
|
||||
|
||||
# Handheld-daemon runs some selinux-related utils which are not in nixpkgs.
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "hcxdumptool";
|
||||
version = "6.3.5";
|
||||
version = "7.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ZerBea";
|
||||
repo = "hcxdumptool";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-PA4nbjg4ybWvZZ7wbsh+OR/wEEVm5qu5OfM9EO3HBYs=";
|
||||
hash = "sha256-emSIUSE8r0PX1qhkuIQcyh9+rBB+jBA6pmt+n4WugWk=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "hcxtools";
|
||||
version = "6.3.5";
|
||||
version = "7.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ZerBea";
|
||||
repo = "hcxtools";
|
||||
rev = version;
|
||||
sha256 = "sha256-8VfGiIXl/F2wgCMuS3+lt9sT/re9YgoRKwzgSHCir04=";
|
||||
sha256 = "sha256-gL1OnNtd6cqW0kM3w2wHc0UU3JvC6H2kQg1aBDaN11U=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
@@ -8,22 +8,22 @@
|
||||
|
||||
let
|
||||
pname = "hoppscotch";
|
||||
version = "25.7.0-0";
|
||||
version = "25.7.1-0";
|
||||
|
||||
src =
|
||||
fetchurl
|
||||
{
|
||||
aarch64-darwin = {
|
||||
url = "https://github.com/hoppscotch/releases/releases/download/v${version}/Hoppscotch_mac_aarch64.dmg";
|
||||
hash = "sha256-oM/Gpl7Z8tlgPsujQc0RUlN8anWoiQfg+bSxg+oK2AE=";
|
||||
hash = "sha256-Qr7xv3XyneA9RzvO7MqtblBF+oO4auYi5DX/F0n/I0c=";
|
||||
};
|
||||
x86_64-darwin = {
|
||||
url = "https://github.com/hoppscotch/releases/releases/download/v${version}/Hoppscotch_mac_x64.dmg";
|
||||
hash = "sha256-yFzMMpJpBlMcV1NMqG2L8XOSyC2cT4+WMZwdphYPFF4=";
|
||||
hash = "sha256-/5++4ifR2xcCmU7jg+qm4zsi8swSXTbU7Hdz80p+UCM=";
|
||||
};
|
||||
x86_64-linux = {
|
||||
url = "https://github.com/hoppscotch/releases/releases/download/v${version}/Hoppscotch_linux_x64.AppImage";
|
||||
hash = "sha256-req782QlPw2ZDo5eqNAWVPoTPvBODTnAhvLYewd0b2E=";
|
||||
hash = "sha256-EToScp/zKv4KAuVPJmhKmBtx3WeM+CH38jXinhnT0tE=";
|
||||
};
|
||||
}
|
||||
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
callPackage,
|
||||
fetchFromGitHub,
|
||||
pkg-config,
|
||||
libftdi1,
|
||||
@@ -18,48 +19,50 @@
|
||||
usePyPy ? stdenv.hostPlatform.system == "x86_64-linux",
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "icestorm";
|
||||
version = "2020.12.04";
|
||||
version = "0-unstable-2025-06-03";
|
||||
|
||||
passthru = rec {
|
||||
pythonPkg = if (false && usePyPy) then pypy3 else python3;
|
||||
pythonInterp = pythonPkg.interpreter;
|
||||
|
||||
tests.examples = callPackage ./tests.nix {
|
||||
inherit (finalAttrs) pname src;
|
||||
icestorm = finalAttrs.finalPackage;
|
||||
};
|
||||
};
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "YosysHQ";
|
||||
repo = "icestorm";
|
||||
rev = "7afc64b480212c9ac2ce7cb1622731a69a7d212c";
|
||||
sha256 = "0vxhqs2fampglg3xlfwb35229iv96kvlwp1gyxrdrmlpznhkqdrk";
|
||||
rev = "f31c39cc2eadd0ab7f29f34becba1348ae9f8721";
|
||||
hash = "sha256-SLSxqgVsYMUxv8YjY1iRLnVFiIAhk/GKmZr4Ido0A3o=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [
|
||||
passthru.pythonPkg
|
||||
finalAttrs.passthru.pythonPkg
|
||||
libftdi1
|
||||
];
|
||||
makeFlags = [ "PREFIX=$(out)" ];
|
||||
makeFlags = [
|
||||
"PREFIX=$(out)"
|
||||
"PYTHON3=${finalAttrs.passthru.pythonInterp}"
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
# fix icebox_vlog chipdb path. icestorm issue:
|
||||
# https://github.com/cliffordwolf/icestorm/issues/125
|
||||
#
|
||||
# also, fix up the path to the chosen Python interpreter. for pypy-compatible
|
||||
# fix up the path to the chosen Python interpreter. for pypy-compatible
|
||||
# platforms, it offers significant performance improvements.
|
||||
patchPhase = ''
|
||||
substituteInPlace ./icebox/icebox_vlog.py \
|
||||
--replace /usr/local/share "$out/share"
|
||||
|
||||
for x in icefuzz/Makefile icebox/Makefile icetime/Makefile; do
|
||||
substituteInPlace "$x" --replace python3 "${passthru.pythonInterp}"
|
||||
done
|
||||
|
||||
for x in $(find . -type f -iname '*.py'); do
|
||||
for x in $(find . -type f -iname '*.py' -executable); do
|
||||
substituteInPlace "$x" \
|
||||
--replace '/usr/bin/env python3' '${passthru.pythonInterp}'
|
||||
--replace-fail '/usr/bin/env python3' '${finalAttrs.passthru.pythonInterp}'
|
||||
done
|
||||
|
||||
# We use GNU sed on Darwin, while icebox/Makefile assumed BSD sed (which
|
||||
# requires a (potentially empty) argument for the -i flag).
|
||||
substituteInPlace icebox/Makefile --replace-fail "sed -i '''" "sed -i"
|
||||
'';
|
||||
|
||||
meta = {
|
||||
@@ -78,4 +81,4 @@ stdenv.mkDerivation rec {
|
||||
];
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# Run the examples from $src/examples/ as simple integration tests. They require
|
||||
# yosys and nextpnr (which itself depends on this package), so they cannot be
|
||||
# ran during the check phase.
|
||||
{
|
||||
runCommand,
|
||||
icestorm,
|
||||
nextpnr,
|
||||
yosys,
|
||||
|
||||
pname,
|
||||
src,
|
||||
}:
|
||||
|
||||
runCommand "${pname}-test-examples"
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
icestorm
|
||||
nextpnr
|
||||
yosys
|
||||
];
|
||||
}
|
||||
''
|
||||
cp -r ${src}/examples .
|
||||
chmod -R +w examples
|
||||
for example in examples/*; do
|
||||
make -C $example
|
||||
done
|
||||
touch $out
|
||||
''
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
let
|
||||
pname = "Jan";
|
||||
version = "0.6.5";
|
||||
version = "0.6.6";
|
||||
src = fetchurl {
|
||||
url = "https://github.com/janhq/jan/releases/download/v${version}/Jan_${version}_amd64.AppImage";
|
||||
hash = "sha256-0JRaefi8mUGoy63BbPa2C8EE/7/TGSsP1VmmWh7Lsko=";
|
||||
hash = "sha256-KTU7jSouFCv4ER6cOzNYQJxRpgGTV5AnLs4i0Ne4GYQ=";
|
||||
};
|
||||
|
||||
appimageContents = appimageTools.extractType2 { inherit pname version src; };
|
||||
|
||||
@@ -8,17 +8,17 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "jfrog-cli";
|
||||
version = "2.78.2";
|
||||
version = "2.78.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jfrog";
|
||||
repo = "jfrog-cli";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-E6UjHtLJ8wgAM9CPtFLsBOKaIaF+exjegBBnP0aBcvA=";
|
||||
hash = "sha256-sV8cj+H9l/Rm/INRmfMvTMYehYVmQhZHH7KxWGcEMXs=";
|
||||
};
|
||||
|
||||
proxyVendor = true;
|
||||
vendorHash = "sha256-8Aaxwysbuzo2n2w4OPn7jooqrjEGwrZAlgec3j/pN2A=";
|
||||
vendorHash = "sha256-SriBFQXKLYPDTqDmC4cXfV1fjwvUCUuujq5hb4w5Fgg=";
|
||||
|
||||
checkFlags = "-skip=^TestReleaseBundle";
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
let
|
||||
pname = "jicofo";
|
||||
version = "1.0-1138";
|
||||
version = "1.0-1153";
|
||||
src = fetchurl {
|
||||
url = "https://download.jitsi.org/stable/${pname}_${version}-1_all.deb";
|
||||
sha256 = "YLzWyeeWWgsqfGAKXPIKIkfIq3McFEjcZGYLhi2Otew=";
|
||||
sha256 = "tBvaXyRqNg8VeIy3aI1HbrZNlelsYowLOVlsXyap+gA=";
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
|
||||
let
|
||||
pname = "jitsi-videobridge2";
|
||||
version = "2.3-236-g95ef6210";
|
||||
version = "2.3-249-g9a2123ad4";
|
||||
src = fetchurl {
|
||||
url = "https://download.jitsi.org/stable/${pname}_${version}-1_all.deb";
|
||||
sha256 = "GUihengE21ISqXozFwTsdiQurDi0ft/btj+DcbGH/Rg=";
|
||||
sha256 = "b8hYuDyweRLAagaehHMzC2/XjZHNlxMchM8za8zPtj4=";
|
||||
};
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
|
||||
Generated
+1166
-944
File diff suppressed because it is too large
Load Diff
@@ -19,13 +19,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "keyguard";
|
||||
version = "1.12.3";
|
||||
version = "1.13.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "AChep";
|
||||
repo = "keyguard-app";
|
||||
tag = "r20250530";
|
||||
hash = "sha256-FTDZ4ztFv+pcyupI+tHr+VLrENSN6hqs13i1KJmreAM=";
|
||||
tag = "r20250705";
|
||||
hash = "sha256-9UT75HntRswpf1G04x07DfxNfR3PsMv0Ee/NRVrJS3Y=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "kics";
|
||||
version = "2.1.11";
|
||||
version = "2.1.12";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Checkmarx";
|
||||
repo = "kics";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-WtqP+6mMzVT/boKuMVWJadUNQanIQDrh50RqrdMM/FM=";
|
||||
hash = "sha256-InoH/BzRJtJaFGL1OjLpRoz72Gkrf03WRZQUDyxnFDM=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-5Am4iJpAKdU00hP5BBrd57ULXs/h/Ja9sm29HmYVOYw=";
|
||||
vendorHash = "sha256-kKK3kSWjork6KZdPzKySsiHR0bOLKlzltP/u6ZQioqM=";
|
||||
|
||||
subPackages = [ "cmd/console" ];
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "lexbor";
|
||||
version = "2.4.0";
|
||||
version = "2.5.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "lexbor";
|
||||
repo = "lexbor";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-wsm+2L2ar+3LGyBXl39Vp9l1l5JONWvO0QbI87TDfWM=";
|
||||
hash = "sha256-QmD8p6dySLEeHjCmDSTplXwsy2Z7yHKYlXmPCKwaBfU=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -15,13 +15,13 @@ assert !lapack.isILP64;
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "libMBD";
|
||||
version = "0.12.8";
|
||||
version = "0.13.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "libmbd";
|
||||
repo = "libMBD";
|
||||
rev = version;
|
||||
hash = "sha256-ctUaBLPaZHoV1rU3u1idvPLGbvC9Z17YBxYKCaL7EMk=";
|
||||
hash = "sha256-mSKD/pNluumKP3SCubD68uak2Vya/1tyIh42UxRgSXY=";
|
||||
};
|
||||
|
||||
preConfigure = ''
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "libnvme";
|
||||
version = "1.11.1";
|
||||
version = "1.15";
|
||||
|
||||
outputs = [ "out" ] ++ lib.optionals withDocs [ "man" ];
|
||||
|
||||
@@ -27,7 +27,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
owner = "linux-nvme";
|
||||
repo = "libnvme";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-CEGr7PDOVRi210XvICH8iLYDKn8S9bGruBO4tycvsT8=";
|
||||
hash = "sha256-PdSlynwOjC9SkUh3H6doEgHwwBry5Ti5XjRoS2bc5a0=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
pkgconf,
|
||||
libsodium,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "liboprf";
|
||||
version = "0.7.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "stef";
|
||||
repo = "liboprf";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-auC6iVTMbLktKCPY8VgOdx2dMI2KDzNgtY1zyNXjM1A=";
|
||||
};
|
||||
|
||||
sourceRoot = "${finalAttrs.src.name}/src";
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
nativeBuildInputs = [ pkgconf ];
|
||||
|
||||
buildInputs = [ libsodium ];
|
||||
|
||||
makeFlags = [ "PREFIX=$(out)" ];
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Library providing OPRF and Threshold OPRF based on libsodium";
|
||||
homepage = "https://github.com/stef/liboprf";
|
||||
changelog = "https://github.com/stef/liboprf/releases/tag/v${finalAttrs.version}";
|
||||
license = lib.licenses.lgpl3Plus;
|
||||
teams = [ lib.teams.ngi ];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
})
|
||||
@@ -7,7 +7,7 @@
|
||||
}:
|
||||
let
|
||||
# This package should be updated together with libphidget22extra
|
||||
version = "1.22.20250324";
|
||||
version = "1.22.20250714";
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "libphidget22";
|
||||
@@ -15,7 +15,7 @@ stdenv.mkDerivation {
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://www.phidgets.com/downloads/phidget22/libraries/linux/libphidget22/libphidget22-${version}.tar.gz";
|
||||
hash = "sha256-FR/+b4z73LtGQdT4gypre9SZmZSiWzP/Q+00uia1lhA=";
|
||||
hash = "sha256-QsdNyShJkKtRHNtezO9jF2ZUilrTaqZBMTp+UcWNkhA=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ automake ];
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "livi";
|
||||
version = "0.3.1";
|
||||
version = "0.3.2";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "guidog";
|
||||
repo = "livi";
|
||||
domain = "gitlab.gnome.org";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-cPnmKepXPeA3h0VYHypEPHAOclhVseokL1NsCKxGJ78=";
|
||||
hash = "sha256-cLvSK50RnXCYoXwpp+unTVnxqCkPa3Zr4dZT0TpYFpE=";
|
||||
};
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
|
||||
@@ -34,13 +34,13 @@
|
||||
}:
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "megasync";
|
||||
version = "5.12.0.1";
|
||||
version = "5.14.0.2";
|
||||
|
||||
src = fetchFromGitHub rec {
|
||||
owner = "meganz";
|
||||
repo = "MEGAsync";
|
||||
tag = "v${finalAttrs.version}_Linux";
|
||||
hash = "sha256-dIva/Xmk7enmRbczfuy1VLAcAMPQ27HUaHEQSTsldaY=";
|
||||
hash = "sha256-iYAyk8UCIuYaacdviPSuWmwx6hgzHveW9oyftISZo7s=";
|
||||
fetchSubmodules = false; # DesignTokensImporter cannot be fetched, see #1010 in github:meganz/megasync
|
||||
leaveDotGit = true;
|
||||
postFetch = ''
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "mihomo-party";
|
||||
version = "1.7.6";
|
||||
version = "1.8.3";
|
||||
|
||||
src =
|
||||
let
|
||||
@@ -31,8 +31,8 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
fetchurl {
|
||||
url = "https://github.com/mihomo-party-org/mihomo-party/releases/download/v${finalAttrs.version}/mihomo-party-linux-${finalAttrs.version}-${arch}.deb";
|
||||
hash = selectSystem {
|
||||
x86_64-linux = "sha256-83RajPreGieOYBAkoR6FsFREnOGDDuMK6+Qg+R/koac=";
|
||||
aarch64-linux = "sha256-oWOXLUYWRKRgPtNv9ZvM1ODd44dhymVTKHJBK/xxOOs=";
|
||||
x86_64-linux = "sha256-3x6xueQS81IWutY0BH52wRdb8Fh2kTQF7QgwZACE6kk=";
|
||||
aarch64-linux = "sha256-SBPFnY/0CAUhEpZe+wav+HY2kmZ45+gzoXrUn7jUrts=";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
lib,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
pkg-config,
|
||||
dbus,
|
||||
openssl,
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "mprisence";
|
||||
version = "1.2.4";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "lazykern";
|
||||
repo = "mprisence";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-eUUUHjR6wnbaPb1QD9luEVvu5qSAxG5c4TuMjnzRV40=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-BnzDMvwqQ56VFc7AuzsfyZ002qcmRaAOMfipynZ1/Mc=";
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
buildInputs = [
|
||||
dbus
|
||||
openssl
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Highly customizable Discord Rich Presence for MPRIS media players on Linux";
|
||||
homepage = "https://github.com/lazykern/mprisence";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ toasteruwu ];
|
||||
sourceProvenance = with sourceTypes; [ fromSource ];
|
||||
mainProgram = "mprisence";
|
||||
};
|
||||
})
|
||||
@@ -22,13 +22,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "nestopia";
|
||||
version = "1.53.1";
|
||||
version = "1.53.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "0ldsk00l";
|
||||
repo = "nestopia";
|
||||
rev = finalAttrs.version;
|
||||
hash = "sha256-6r6o/2GDp1Rcp+OWaQVgIQGC6NAxtmx4lxDWWpwv8aQ=";
|
||||
hash = "sha256-sKemwbmEr637KL951wsmDxLFDvWh+0K+exdDd0+Iq1c=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user