mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-09-16 12:20:10 +00:00
Merge ee11c0fef4 into haskell-updates
This commit is contained in:
14
.github/workflows/README.md
vendored
14
.github/workflows/README.md
vendored
@@ -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.
|
||||
|
||||
6
.github/workflows/check.yml
vendored
6
.github/workflows/check.yml
vendored
@@ -38,13 +38,13 @@ jobs:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-24.04-arm
|
||||
timeout-minutes: 10
|
||||
timeout-minutes: 3
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
filter: tree:0
|
||||
path: trusted
|
||||
sparse-checkout: |
|
||||
ci/github-script
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install bottleneck
|
||||
|
||||
31
.github/workflows/merge-group.yml
vendored
Normal file
31
.github/workflows/merge-group.yml
vendored
Normal file
@@ -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
|
||||
@@ -79,7 +79,7 @@ You can donate to the NixOS foundation through [SEPA bank transfers](https://nix
|
||||
|
||||
Nixpkgs is licensed under the [MIT License](COPYING).
|
||||
|
||||
Note:
|
||||
MIT license does not apply to the packages built by Nixpkgs, merely to the files in this repository (the Nix expressions, build scripts, NixOS modules, etc.).
|
||||
> [!Note]
|
||||
> MIT license does not apply to the packages built by Nixpkgs, merely to the files in this repository (the Nix expressions, build scripts, NixOS modules, etc.).
|
||||
It also might not apply to patches included in Nixpkgs, which may be derivative works of the packages to which they apply.
|
||||
The aforementioned artifacts are all covered by the licenses of the respective packages.
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
This report is automatically generated by the `PR / Check / cherry-pick` CI workflow.
|
||||
|
||||
Some of the commits in this PR require the author's and reviewer's attention.
|
||||
|
||||
Please follow the [backporting guidelines](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#how-to-backport-pull-requests) and cherry-pick with the `-x` flag.
|
||||
This requires changes to the unstable `master` and `staging` branches first, before backporting them.
|
||||
|
||||
Occasionally, it is not possible to cherry-pick exactly the same patch.
|
||||
This most frequently happens when resolving merge conflicts or when updating minor versions of packages which have already advanced to the next major on unstable.
|
||||
If you need to merge this PR despite the warnings, please [dismiss](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/dismissing-a-pull-request-review) this review shortly before merging.
|
||||
@@ -22,22 +22,36 @@ module.exports = async function ({ github, context, core, dry }) {
|
||||
'?pr=' +
|
||||
pull_number
|
||||
|
||||
async function handle({ sha, commit }) {
|
||||
async function extract({ sha, commit }) {
|
||||
const noCherryPick = Array.from(
|
||||
commit.message.matchAll(/^Not-cherry-picked-because: (.*)$/g)
|
||||
).at(0)
|
||||
|
||||
if (noCherryPick)
|
||||
return {
|
||||
sha,
|
||||
commit,
|
||||
severity: 'important',
|
||||
message: `${sha} is not a cherry-pick, because: ${noCherryPick[1]}. Please review this commit manually.`,
|
||||
type: 'no-cherry-pick',
|
||||
}
|
||||
|
||||
// Using the last line with "cherry" + hash, because a chained backport
|
||||
// can result in multiple of those lines. Only the last one counts.
|
||||
const match = Array.from(
|
||||
const cherry = Array.from(
|
||||
commit.message.matchAll(/cherry.*([0-9a-f]{40})/g),
|
||||
).at(-1)
|
||||
|
||||
if (!match)
|
||||
if (!cherry)
|
||||
return {
|
||||
sha,
|
||||
commit,
|
||||
severity: 'warning',
|
||||
message: `Couldn't locate original commit hash in message of ${sha}.`,
|
||||
type: 'no-commit-hash',
|
||||
}
|
||||
|
||||
const original_sha = match[1]
|
||||
const original_sha = cherry[1]
|
||||
|
||||
let branches
|
||||
try {
|
||||
@@ -68,6 +82,14 @@ module.exports = async function ({ github, context, core, dry }) {
|
||||
message: `${original_sha} given in ${sha} not found in any pickable branch.`,
|
||||
}
|
||||
|
||||
return {
|
||||
sha,
|
||||
commit,
|
||||
original_sha,
|
||||
}
|
||||
}
|
||||
|
||||
function diff({ sha, commit, original_sha }) {
|
||||
const diff = execFileSync('git', [
|
||||
'-C',
|
||||
__dirname,
|
||||
@@ -113,6 +135,7 @@ module.exports = async function ({ github, context, core, dry }) {
|
||||
colored_diff,
|
||||
severity: 'warning',
|
||||
message: `Difference between ${sha} and original ${original_sha} may warrant inspection.`,
|
||||
type: 'diff',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +144,26 @@ module.exports = async function ({ github, context, core, dry }) {
|
||||
pull_number,
|
||||
})
|
||||
|
||||
const results = await Promise.all(commits.map(handle))
|
||||
const extracted = await Promise.all(commits.map(extract))
|
||||
|
||||
const fetch = extracted
|
||||
.filter(({ severity }) => !severity)
|
||||
.map(({ sha, original_sha }) => [ sha, original_sha ])
|
||||
.flat()
|
||||
|
||||
if (fetch.length > 0) {
|
||||
// Fetching all commits we need for diff at once is much faster than any other method.
|
||||
execFileSync('git', [
|
||||
'-C',
|
||||
__dirname,
|
||||
'fetch',
|
||||
'--depth=2',
|
||||
'origin',
|
||||
...fetch,
|
||||
])
|
||||
}
|
||||
|
||||
const results = extracted.map(result => result.severity ? result : diff(result))
|
||||
|
||||
// Log all results without truncation, with better highlighting and all whitespace changes to the job log.
|
||||
results.forEach(({ sha, commit, severity, message, colored_diff }) => {
|
||||
@@ -175,10 +217,29 @@ module.exports = async function ({ github, context, core, dry }) {
|
||||
if (results.some(({ severity }) => severity == 'error'))
|
||||
process.exitCode = 1
|
||||
|
||||
core.summary.addRaw(
|
||||
await readFile(join(__dirname, 'check-cherry-picks.md'), 'utf-8'),
|
||||
true,
|
||||
)
|
||||
core.summary.addRaw('This report is automatically generated by the `PR / Check / cherry-pick` CI workflow.', true)
|
||||
core.summary.addEOL()
|
||||
core.summary.addRaw("Some of the commits in this PR require the author's and reviewer's attention.", true)
|
||||
core.summary.addEOL()
|
||||
|
||||
if (results.some(({ type }) => type === 'no-commit-hash')) {
|
||||
core.summary.addRaw('Please follow the [backporting guidelines](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md#how-to-backport-pull-requests) and cherry-pick with the `-x` flag.', true)
|
||||
core.summary.addRaw('This requires changes to the unstable `master` and `staging` branches first, before backporting them.', true)
|
||||
core.summary.addEOL()
|
||||
core.summary.addRaw('Occasionally, commits are not cherry-picked at all, for example when updating minor versions of packages which have already advanced to the next major on unstable.', true)
|
||||
core.summary.addRaw('These commits can optionally be marked with a `Not-cherry-picked-because: <reason>` footer.', true)
|
||||
core.summary.addEOL()
|
||||
}
|
||||
|
||||
if (results.some(({ type }) => type === 'diff')) {
|
||||
core.summary.addRaw('Sometimes it is not possible to cherry-pick exactly the same patch.', true)
|
||||
core.summary.addRaw('This most frequently happens when resolving merge conflicts.', true)
|
||||
core.summary.addRaw('The range-diff will help to review the resolution of conflicts.', true)
|
||||
core.summary.addEOL()
|
||||
}
|
||||
|
||||
core.summary.addRaw('If you need to merge this PR despite the warnings, please [dismiss](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/dismissing-a-pull-request-review) this review shortly before merging.', true)
|
||||
|
||||
results.forEach(({ severity, message, diff }) => {
|
||||
if (severity == 'info') return
|
||||
|
||||
@@ -195,7 +256,7 @@ module.exports = async function ({ github, context, core, dry }) {
|
||||
// Whether this is intended or just an implementation detail is unclear.
|
||||
core.summary.addRaw('<blockquote>')
|
||||
core.summary.addRaw(
|
||||
`\n\n[!${severity == 'warning' ? 'WARNING' : 'CAUTION'}]`,
|
||||
`\n\n[!${({ important: 'IMPORTANT', warning: 'WARNING', error: 'CAUTION' })[severity]}]`,
|
||||
true,
|
||||
)
|
||||
core.summary.addRaw(`${message}`, true)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
|
||||
- `fetchgit`: Add `rootDir` argument to limit the resulting source to one subdirectory of the whole Git repository. Corresponding `--root-dir` option added to `nix-prefetch-git`.
|
||||
|
||||
- The `clickhouse` package now track the stable upstream version per [upstream's
|
||||
recommendation](https://clickhouse.com/docs/faq/operations/production). Users
|
||||
can continue to use the `clickhouse-lts` package if desired.
|
||||
|
||||
## Nixpkgs Library {#sec-nixpkgs-release-25.11-lib}
|
||||
|
||||
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Throws an error if any of our lib tests fail.
|
||||
|
||||
let
|
||||
tests = [
|
||||
"misc"
|
||||
"systems"
|
||||
];
|
||||
all = builtins.concatLists (map (f: import (./. + "/${f}.nix")) tests);
|
||||
in
|
||||
if all == [ ] then null else throw (builtins.toJSON all)
|
||||
@@ -145,6 +145,11 @@ let
|
||||
inherit expected;
|
||||
};
|
||||
|
||||
dummyDerivation = derivation {
|
||||
name = "name";
|
||||
builder = "builder";
|
||||
system = "system";
|
||||
};
|
||||
in
|
||||
|
||||
runTests {
|
||||
@@ -757,18 +762,8 @@ runTests {
|
||||
};
|
||||
|
||||
testSplitStringsDerivation = {
|
||||
expr = take 3 (
|
||||
strings.splitString "/" (derivation {
|
||||
name = "name";
|
||||
builder = "builder";
|
||||
system = "system";
|
||||
})
|
||||
);
|
||||
expected = [
|
||||
""
|
||||
"nix"
|
||||
"store"
|
||||
];
|
||||
expr = lib.dropEnd 1 (strings.splitString "/" dummyDerivation);
|
||||
expected = strings.splitString "/" builtins.storeDir;
|
||||
};
|
||||
|
||||
testSplitVersionSingle = {
|
||||
@@ -816,7 +811,7 @@ runTests {
|
||||
in
|
||||
{
|
||||
storePath = isStorePath goodPath;
|
||||
storePathDerivation = isStorePath (import ../.. { system = "x86_64-linux"; }).hello;
|
||||
storePathDerivation = isStorePath dummyDerivation;
|
||||
storePathAppendix = isStorePath "${goodPath}/bin/python";
|
||||
nonAbsolute = isStorePath (concatStrings (tail (stringToCharacters goodPath)));
|
||||
asPath = isStorePath (/. + goodPath);
|
||||
@@ -901,7 +896,7 @@ runTests {
|
||||
};
|
||||
|
||||
testHasInfixDerivation = {
|
||||
expr = hasInfix "hello" (import ../.. { system = "x86_64-linux"; }).hello;
|
||||
expr = hasInfix "name" dummyDerivation;
|
||||
expected = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
pkgs.runCommand "nixpkgs-lib-tests-nix-${nix.version}"
|
||||
{
|
||||
buildInputs = [
|
||||
(import ./check-eval.nix)
|
||||
(import ./fetchers.nix)
|
||||
(import ../path/tests {
|
||||
inherit pkgs;
|
||||
})
|
||||
@@ -71,6 +69,12 @@ pkgs.runCommand "nixpkgs-lib-tests-nix-${nix.version}"
|
||||
echo "Running lib/tests/systems.nix"
|
||||
[[ $(nix-instantiate --eval --strict lib/tests/systems.nix | tee /dev/stderr) == '[ ]' ]];
|
||||
|
||||
echo "Running lib/tests/misc.nix"
|
||||
[[ $(nix-instantiate --eval --strict lib/tests/misc.nix | tee /dev/stderr) == '[ ]' ]];
|
||||
|
||||
echo "Running lib/tests/fetchers.nix"
|
||||
[[ $(nix-instantiate --eval --strict lib/tests/fetchers.nix | tee /dev/stderr) == '[ ]' ]];
|
||||
|
||||
mkdir $out
|
||||
echo success > $out/${nix.version}
|
||||
''
|
||||
|
||||
@@ -2737,6 +2737,12 @@
|
||||
githubId = 31864305;
|
||||
name = "William Hai";
|
||||
};
|
||||
bahrom04 = {
|
||||
name = "Baxrom Raxmatov";
|
||||
email = "magdiyevbahrom@gmail.com";
|
||||
github = "bahrom04";
|
||||
githubId = 116780481;
|
||||
};
|
||||
baileylu = {
|
||||
name = "Luke Bailey";
|
||||
email = "baileylu@tcd.ie";
|
||||
@@ -3034,6 +3040,12 @@
|
||||
githubId = 32039602;
|
||||
keys = [ { fingerprint = "2B46 58FF 887A 8366 F88B BE92 CF83 0BB3 B973 9A6A"; } ];
|
||||
};
|
||||
bemeritus = {
|
||||
name = "Shohrux Rasulov";
|
||||
email = "bemerituss@gmail.com";
|
||||
github = "bemeritus";
|
||||
githubId = 175357618;
|
||||
};
|
||||
ben9986 = {
|
||||
name = "Ben Carmichael";
|
||||
email = "ben9986.unvmn@passinbox.com";
|
||||
@@ -6258,13 +6270,6 @@
|
||||
githubId = 17111639;
|
||||
name = "Devin Singh";
|
||||
};
|
||||
devpikachu = {
|
||||
email = "andrei.hava@proton.me";
|
||||
matrix = "@andrei:matrix.detpikachu.dev";
|
||||
github = "devpikachu";
|
||||
githubId = 30475873;
|
||||
name = "Andrei Hava";
|
||||
};
|
||||
devplayer0 = {
|
||||
email = "dev@nul.ie";
|
||||
github = "devplayer0";
|
||||
@@ -26189,6 +26194,11 @@
|
||||
githubId = 1215104;
|
||||
keys = [ { fingerprint = "B1FD 4E2A 84B2 2379 F4BF 2EF5 FE33 A228 2371 E831"; } ];
|
||||
};
|
||||
txkyel = {
|
||||
github = "txkyel";
|
||||
githubId = 56144092;
|
||||
name = "Kyle Xiao";
|
||||
};
|
||||
tyberius-prime = {
|
||||
name = "Tyberius Prime";
|
||||
github = "TyberiusPrime";
|
||||
|
||||
@@ -1252,6 +1252,16 @@ with lib.maintainers;
|
||||
shortName = "coqui-ai TTS";
|
||||
};
|
||||
|
||||
uzinfocom = {
|
||||
members = [
|
||||
orzklv
|
||||
bahrom04
|
||||
bemeritus
|
||||
];
|
||||
scope = "Maintain Uzbek Linux state & community packages and modules.";
|
||||
shortName = "Uzinfocom Open Source";
|
||||
};
|
||||
|
||||
windows = {
|
||||
members = [
|
||||
RossSmyth
|
||||
|
||||
@@ -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"
|
||||
],
|
||||
|
||||
@@ -171,6 +171,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 \
|
||||
|
||||
@@ -46,5 +46,5 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ orzklv ];
|
||||
meta.maintainers = lib.teams.uzinfocom.members;
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ let
|
||||
echo "Tried for at least 30 seconds, giving up..."
|
||||
exit 1
|
||||
fi
|
||||
count=$((count++))
|
||||
count=$((++count))
|
||||
done
|
||||
|
||||
${recoverIdmAdmin}
|
||||
|
||||
@@ -23,7 +23,7 @@ in
|
||||
};
|
||||
|
||||
openFirewall = lib.mkEnableOption "" // {
|
||||
description = "Open ports in the firewall for the Radarr web interface.";
|
||||
description = "Open ports in the firewall for LANraragi's web interface.";
|
||||
};
|
||||
|
||||
passwordFile = lib.mkOption {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -294,6 +294,45 @@ in
|
||||
);
|
||||
};
|
||||
|
||||
discordAuthentication = lib.mkOption {
|
||||
description = ''
|
||||
To configure Discord auth, you'll need to create an application at
|
||||
https://discord.com/developers/applications/
|
||||
|
||||
See https://docs.getoutline.com/s/hosting/doc/discord-g4JdWFFub6
|
||||
for details on setting up your Discord app.
|
||||
'';
|
||||
default = null;
|
||||
type = lib.types.nullOr (
|
||||
lib.types.submodule {
|
||||
options = {
|
||||
clientId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Authentication client identifier.";
|
||||
};
|
||||
clientSecretFile = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "File path containing the authentication secret.";
|
||||
};
|
||||
serverId = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
Restrict logins to a specific server (optional, but recommended).
|
||||
You can find a Discord server's ID by right-clicking the server icon,
|
||||
and select “Copy Server ID”.
|
||||
'';
|
||||
};
|
||||
serverRoles = lib.mkOption {
|
||||
type = lib.types.commas;
|
||||
default = "";
|
||||
description = "Optionally restrict logins to a comma-separated list of role IDs";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
oidcAuthentication = lib.mkOption {
|
||||
description = ''
|
||||
To configure generic OIDC auth, you'll need some kind of identity
|
||||
@@ -721,6 +760,12 @@ in
|
||||
SLACK_MESSAGE_ACTIONS = builtins.toString cfg.slackIntegration.messageActions;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.discordAuthentication != null) {
|
||||
DISCORD_CLIENT_ID = cfg.discordAuthentication.clientId;
|
||||
DISCORD_SERVER_ID = cfg.discordAuthentication.serverId;
|
||||
DISCORD_SERVER_ROLES = cfg.discordAuthentication.serverRoles;
|
||||
})
|
||||
|
||||
(lib.mkIf (cfg.smtp != null) {
|
||||
SMTP_HOST = cfg.smtp.host;
|
||||
SMTP_PORT = builtins.toString cfg.smtp.port;
|
||||
@@ -760,6 +805,9 @@ in
|
||||
${lib.optionalString (cfg.oidcAuthentication != null) ''
|
||||
export OIDC_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.oidcAuthentication.clientSecretFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.discordAuthentication != null) ''
|
||||
export DISCORD_CLIENT_SECRET="$(head -n1 ${lib.escapeShellArg cfg.discordAuthentication.clientSecretFile})"
|
||||
''}
|
||||
${lib.optionalString (cfg.sslKeyFile != null) ''
|
||||
export SSL_KEY="$(head -n1 ${lib.escapeShellArg cfg.sslKeyFile})"
|
||||
''}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
pkgs,
|
||||
utils,
|
||||
...
|
||||
}:
|
||||
|
||||
@@ -12,6 +13,7 @@ let
|
||||
e = pkgs.enlightenment;
|
||||
xcfg = config.services.xserver;
|
||||
cfg = xcfg.desktopManager.enlightenment;
|
||||
|
||||
GST_PLUGIN_PATH = lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" [
|
||||
pkgs.gst_all_1.gst-plugins-base
|
||||
pkgs.gst_all_1.gst-plugins-good
|
||||
@@ -41,11 +43,17 @@ in
|
||||
description = "Enable the Enlightenment desktop environment.";
|
||||
};
|
||||
|
||||
environment.enlightenment.excludePackages = mkOption {
|
||||
default = [ ];
|
||||
example = literalExpression "[ pkgs.enlightenment.ephoto ]";
|
||||
type = types.listOf types.package;
|
||||
description = "Which packages Enlightenment should exclude from the default environment";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
environment.systemPackages = utils.removePackagesByName (with pkgs; [
|
||||
enlightenment.econnman
|
||||
enlightenment.efl
|
||||
enlightenment.enlightenment
|
||||
@@ -54,7 +62,7 @@ in
|
||||
enlightenment.rage
|
||||
enlightenment.terminology
|
||||
xorg.xcursorthemes
|
||||
];
|
||||
]) config.environment.enlightenment.excludePackages;
|
||||
|
||||
environment.pathsToLink = [
|
||||
"/etc/enlightenment"
|
||||
|
||||
@@ -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}...'")
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -333,7 +333,14 @@ in
|
||||
cinnamon-wayland = runTest ./cinnamon-wayland.nix;
|
||||
cjdns = runTest ./cjdns.nix;
|
||||
clatd = runTest ./clatd.nix;
|
||||
clickhouse = import ./clickhouse { inherit runTest; };
|
||||
clickhouse = import ./clickhouse {
|
||||
inherit runTest;
|
||||
package = pkgs.clickhouse;
|
||||
};
|
||||
clickhouse-lts = import ./clickhouse {
|
||||
inherit runTest;
|
||||
package = pkgs.clickhouse-lts;
|
||||
};
|
||||
cloud-init = runTest ./cloud-init.nix;
|
||||
cloud-init-hostname = runTest ./cloud-init-hostname.nix;
|
||||
cloudlog = runTest ./cloudlog.nix;
|
||||
@@ -1485,7 +1492,7 @@ in
|
||||
teleports = runTest ./teleports.nix;
|
||||
thelounge = handleTest ./thelounge.nix { };
|
||||
terminal-emulators = handleTest ./terminal-emulators.nix { };
|
||||
thanos = handleTest ./thanos.nix { };
|
||||
thanos = runTest ./thanos.nix;
|
||||
tiddlywiki = runTest ./tiddlywiki.nix;
|
||||
tigervnc = handleTest ./tigervnc.nix { };
|
||||
tika = runTest ./tika.nix;
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
{ pkgs, ... }:
|
||||
{ pkgs, package, ... }:
|
||||
{
|
||||
name = "clickhouse";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ jpds ];
|
||||
meta.maintainers = with pkgs.lib.maintainers; [
|
||||
jpds
|
||||
thevar1able
|
||||
];
|
||||
|
||||
nodes.machine = {
|
||||
services.clickhouse.enable = true;
|
||||
services.clickhouse = {
|
||||
enable = true;
|
||||
inherit package;
|
||||
};
|
||||
virtualisation.memorySize = 4096;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,31 @@
|
||||
{ runTest }:
|
||||
{
|
||||
runTest,
|
||||
package,
|
||||
}:
|
||||
|
||||
{
|
||||
base = runTest ./base.nix;
|
||||
kafka = runTest ./kafka.nix;
|
||||
keeper = runTest ./keeper.nix;
|
||||
s3 = runTest ./s3.nix;
|
||||
base = runTest {
|
||||
imports = [ ./base.nix ];
|
||||
_module.args = {
|
||||
inherit package;
|
||||
};
|
||||
};
|
||||
kafka = runTest {
|
||||
imports = [ ./kafka.nix ];
|
||||
_module.args = {
|
||||
inherit package;
|
||||
};
|
||||
};
|
||||
keeper = runTest {
|
||||
imports = [ ./keeper.nix ];
|
||||
_module.args = {
|
||||
inherit package;
|
||||
};
|
||||
};
|
||||
s3 = runTest {
|
||||
imports = [ ./s3.nix ];
|
||||
_module.args = {
|
||||
inherit package;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{ pkgs, package, ... }:
|
||||
|
||||
let
|
||||
kafkaNamedCollectionConfig = ''
|
||||
@@ -28,7 +28,10 @@ let
|
||||
in
|
||||
{
|
||||
name = "clickhouse-kafka";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ jpds ];
|
||||
meta.maintainers = with pkgs.lib.maintainers; [
|
||||
jpds
|
||||
thevar1able
|
||||
];
|
||||
|
||||
nodes = {
|
||||
clickhouse = {
|
||||
@@ -38,7 +41,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
services.clickhouse.enable = true;
|
||||
services.clickhouse = {
|
||||
enable = true;
|
||||
inherit package;
|
||||
};
|
||||
virtualisation.memorySize = 4096;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
{ lib, pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
package,
|
||||
...
|
||||
}:
|
||||
rec {
|
||||
name = "clickhouse-keeper";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ jpds ];
|
||||
meta.maintainers = with pkgs.lib.maintainers; [
|
||||
jpds
|
||||
thevar1able
|
||||
];
|
||||
|
||||
nodes =
|
||||
let
|
||||
@@ -94,7 +102,10 @@ rec {
|
||||
9444
|
||||
];
|
||||
|
||||
services.clickhouse.enable = true;
|
||||
services.clickhouse = {
|
||||
enable = true;
|
||||
inherit package;
|
||||
};
|
||||
|
||||
systemd.services.clickhouse = {
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{ pkgs, package, ... }:
|
||||
|
||||
let
|
||||
s3 = {
|
||||
@@ -40,7 +40,10 @@ let
|
||||
in
|
||||
{
|
||||
name = "clickhouse-s3";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ jpds ];
|
||||
meta.maintainers = with pkgs.lib.maintainers; [
|
||||
jpds
|
||||
thevar1able
|
||||
];
|
||||
|
||||
nodes = {
|
||||
clickhouse = {
|
||||
@@ -50,7 +53,10 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
services.clickhouse.enable = true;
|
||||
services.clickhouse = {
|
||||
enable = true;
|
||||
inherit package;
|
||||
};
|
||||
virtualisation.diskSize = 15 * 1024;
|
||||
virtualisation.memorySize = 4 * 1024;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
{ pkgs, ... }:
|
||||
|
||||
let
|
||||
inherit (import ./ssh-keys.nix pkgs)
|
||||
snakeOilEd25519PrivateKey
|
||||
snakeOilEd25519PublicKey
|
||||
;
|
||||
|
||||
remoteRepository = "/root/restic-backup";
|
||||
remoteFromFileRepository = "/root/restic-backup-from-file";
|
||||
remoteInhibitTestRepository = "/root/restic-backup-inhibit-test";
|
||||
remoteNoInitRepository = "/root/restic-backup-no-init";
|
||||
rcloneRepository = "rclone:local:/root/restic-rclone-backup";
|
||||
sftpRepository = "sftp:alice@sftp:backups/test";
|
||||
|
||||
backupPrepareCommand = ''
|
||||
touch /root/backupPrepareCommand
|
||||
@@ -51,7 +57,34 @@ in
|
||||
};
|
||||
|
||||
nodes = {
|
||||
server =
|
||||
sftp =
|
||||
# Copied from openssh.nix
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
extraConfig = ''
|
||||
Match Group sftponly
|
||||
ChrootDirectory /srv/sftp
|
||||
ForceCommand internal-sftp
|
||||
'';
|
||||
};
|
||||
|
||||
users.groups = {
|
||||
sftponly = { };
|
||||
};
|
||||
users.users = {
|
||||
alice = {
|
||||
isNormalUser = true;
|
||||
createHome = false;
|
||||
group = "sftponly";
|
||||
shell = "/run/current-system/sw/bin/nologin";
|
||||
openssh.authorizedKeys.keys = [ snakeOilEd25519PublicKey ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
restic =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.restic.backups = {
|
||||
@@ -68,6 +101,20 @@ in
|
||||
initialize = true;
|
||||
timerConfig = null; # has no effect here, just checking that it doesn't break the service
|
||||
};
|
||||
remote-sftp = {
|
||||
inherit
|
||||
passwordFile
|
||||
paths
|
||||
exclude
|
||||
pruneOpts
|
||||
;
|
||||
repository = sftpRepository;
|
||||
initialize = true;
|
||||
timerConfig = null; # has no effect here, just checking that it doesn't break the service
|
||||
extraOptions = [
|
||||
"sftp.command='ssh alice@sftp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -s sftp'"
|
||||
];
|
||||
};
|
||||
remote-from-file-backup = {
|
||||
inherit passwordFile exclude pruneOpts;
|
||||
initialize = true;
|
||||
@@ -143,28 +190,55 @@ in
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
server.start()
|
||||
server.wait_for_unit("dbus.socket")
|
||||
server.fail(
|
||||
restic.start()
|
||||
sftp.start()
|
||||
restic.wait_for_unit("dbus.socket")
|
||||
sftp.wait_for_unit("sshd.service")
|
||||
|
||||
restic.systemctl("start network-online.target")
|
||||
restic.wait_for_unit("network-online.target")
|
||||
|
||||
sftp.succeed(
|
||||
"mkdir -p /srv/sftp/backups",
|
||||
"chown alice:sftponly /srv/sftp/backups",
|
||||
"chmod 0755 /srv/sftp/backups",
|
||||
)
|
||||
|
||||
restic.succeed(
|
||||
"mkdir -p /root/.ssh/",
|
||||
"cat ${snakeOilEd25519PrivateKey} > /root/.ssh/id_ed25519",
|
||||
"chmod 0600 /root/.ssh/id_ed25519",
|
||||
)
|
||||
|
||||
restic.fail(
|
||||
"restic-remotebackup snapshots",
|
||||
"restic-remote-sftp snapshots",
|
||||
'restic-remote-from-file-backup snapshots"',
|
||||
"restic-rclonebackup snapshots",
|
||||
"grep 'backup.* /opt' /root/fake-restic.log",
|
||||
)
|
||||
server.succeed(
|
||||
restic.succeed(
|
||||
# set up
|
||||
"cp -rT ${testDir} /opt",
|
||||
"touch /opt/excluded_file_1 /opt/excluded_file_2",
|
||||
"mkdir -p /root/restic-rclone-backup",
|
||||
)
|
||||
|
||||
server.fail(
|
||||
restic.fail(
|
||||
# test that noinit backup in fact does not initialize the repository
|
||||
# and thus fails without a pre-initialized repository
|
||||
"systemctl start restic-backups-remote-noinit-backup.service",
|
||||
)
|
||||
|
||||
server.succeed(
|
||||
restic.succeed(
|
||||
# test that remotebackup runs custom commands and produces a snapshot
|
||||
"timedatectl set-time '2016-12-13 13:45'",
|
||||
"systemctl start restic-backups-remotebackup.service",
|
||||
"rm /root/backupCleanupCommand",
|
||||
'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
|
||||
)
|
||||
|
||||
restic.succeed(
|
||||
# test that remotebackup runs custom commands and produces a snapshot
|
||||
"timedatectl set-time '2016-12-13 13:45'",
|
||||
"systemctl start restic-backups-remotebackup.service",
|
||||
@@ -231,15 +305,29 @@ in
|
||||
'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 4"',
|
||||
'restic-rclonebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 4"',
|
||||
|
||||
# test that SFTP backup works by copying from the remotebackup
|
||||
'restic-remote-sftp init --from-repo ${remoteRepository} --from-password-file ${passwordFile} --copy-chunker-params',
|
||||
'restic-remote-sftp copy --from-repo ${remoteRepository} --from-password-file ${passwordFile}',
|
||||
'restic-remote-sftp snapshots --json | ${pkgs.jq}/bin/jq "length | . == 4"',
|
||||
|
||||
# test that remoteprune brings us back to 1 snapshot in remotebackup
|
||||
"systemctl start restic-backups-remoteprune.service",
|
||||
'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
|
||||
|
||||
# test that remoteprune brings us back to 1 snapshot in remotebackup
|
||||
"systemctl start restic-backups-remoteprune.service",
|
||||
'restic-remotebackup snapshots --json | ${pkgs.jq}/bin/jq "length | . == 1"',
|
||||
)
|
||||
|
||||
# test that the inhibit option is working
|
||||
server.systemctl("start --no-block restic-backups-inhibit-test.service")
|
||||
server.wait_until_succeeds(
|
||||
restic.systemctl("start --no-block restic-backups-inhibit-test.service")
|
||||
restic.wait_until_succeeds(
|
||||
"systemd-inhibit --no-legend --no-pager | grep -q restic",
|
||||
5
|
||||
)
|
||||
# test that the inhibit option is working
|
||||
restic.systemctl("start --no-block restic-backups-inhibit-test.service")
|
||||
restic.wait_until_succeeds(
|
||||
"systemd-inhibit --no-legend --no-pager | grep -q restic",
|
||||
5
|
||||
)
|
||||
|
||||
@@ -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!\"")
|
||||
'';
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{ ... }:
|
||||
|
||||
let
|
||||
grpcPort = 19090;
|
||||
queryPort = 9090;
|
||||
@@ -30,10 +32,9 @@ let
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
import ./make-test-python.nix {
|
||||
name = "prometheus";
|
||||
{
|
||||
name = "thanos";
|
||||
|
||||
nodes = {
|
||||
prometheus =
|
||||
|
||||
@@ -268,17 +268,40 @@ in
|
||||
tableDDL = pkgs.writeText "table.sql" ''
|
||||
CREATE TABLE IF NOT EXISTS dnstap.records (
|
||||
timestamp DateTime64(6),
|
||||
dataType LowCardinality(String),
|
||||
dataTypeId UInt8,
|
||||
messageType LowCardinality(String),
|
||||
messageTypeId UInt8,
|
||||
dataType Enum('Message' = 1),
|
||||
messageType Enum(
|
||||
'AuthQuery' = 1,
|
||||
'AuthResponse' = 2,
|
||||
'ResolverQuery' = 3,
|
||||
'ResolverResponse' = 4,
|
||||
'ClientQuery' = 5,
|
||||
'ClientResponse' = 6,
|
||||
'ForwarderQuery' = 7,
|
||||
'ForwarderResponse' = 8,
|
||||
'StubQuery' = 9,
|
||||
'StubResponse' = 10,
|
||||
'ToolQuery' = 11,
|
||||
'ToolResponse' = 12,
|
||||
'UpdateQuery' = 13,
|
||||
'UpdateResponse' = 14
|
||||
),
|
||||
queryZone Nullable(String),
|
||||
requestData Nullable(JSON),
|
||||
responseAddress String,
|
||||
responseData Nullable(JSON),
|
||||
responsePort UInt16,
|
||||
serverId LowCardinality(String),
|
||||
serverVersion LowCardinality(String),
|
||||
socketFamily LowCardinality(String),
|
||||
socketProtocol LowCardinality(String),
|
||||
socketFamily Enum('INET' = 1, 'INET6' = 2),
|
||||
socketProtocol Enum(
|
||||
'UDP' = 1,
|
||||
'TCP' = 2,
|
||||
'DOT' = 3,
|
||||
'DOH' = 4,
|
||||
'DNSCryptUDP' = 5,
|
||||
'DNSCryptTCP' = 6,
|
||||
'DOQ' = 7
|
||||
),
|
||||
sourceAddress String,
|
||||
sourcePort UInt16,
|
||||
)
|
||||
@@ -304,7 +327,7 @@ in
|
||||
JSONExtractString(requestData.question[1]::String, 'domainName') as domain,
|
||||
JSONExtractString(requestData.question[1]::String, 'questionType') as record_type
|
||||
FROM dnstap.records
|
||||
WHERE messageTypeId = 5 # ClientQuery
|
||||
WHERE messageType = 'ClientQuery'
|
||||
'';
|
||||
|
||||
selectDomainCountQuery = pkgs.writeText "select-domain-count.sql" ''
|
||||
|
||||
@@ -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";
|
||||
@@ -15025,6 +15038,19 @@ final: prev: {
|
||||
meta.hydraPlatforms = [ ];
|
||||
};
|
||||
|
||||
themery-nvim = buildVimPlugin {
|
||||
pname = "themery.nvim";
|
||||
version = "2025-01-01";
|
||||
src = fetchFromGitHub {
|
||||
owner = "zaldih";
|
||||
repo = "themery.nvim";
|
||||
rev = "bfa58f4b279d21cb515b28023e1b68ec908584b2";
|
||||
sha256 = "0wrd3965wss9qzz4qfy5ryfj71napm5ckx98lwxrxszah6pmz3fl";
|
||||
};
|
||||
meta.homepage = "https://github.com/zaldih/themery.nvim/";
|
||||
meta.hydraPlatforms = [ ];
|
||||
};
|
||||
|
||||
thesaurus_query-vim = buildVimPlugin {
|
||||
pname = "thesaurus_query.vim";
|
||||
version = "2022-12-11";
|
||||
|
||||
@@ -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,
|
||||
@@ -1153,6 +1154,7 @@ https://github.com/let-def/texpresso.vim/,HEAD,
|
||||
https://github.com/johmsalas/text-case.nvim/,HEAD,
|
||||
https://github.com/jsongerber/thanks.nvim/,HEAD,
|
||||
https://github.com/vhsconnect/themed-tabs.nvim/,HEAD,
|
||||
https://github.com/zaldih/themery.nvim/,HEAD,
|
||||
https://github.com/ron89/thesaurus_query.vim/,,
|
||||
https://github.com/itchyny/thumbnail.vim/,,
|
||||
https://github.com/nvzone/timerly/,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 [
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
}:
|
||||
mkLibretroCore {
|
||||
core = "fbneo";
|
||||
version = "0-unstable-2025-08-01";
|
||||
version = "0-unstable-2025-08-13";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "libretro";
|
||||
repo = "fbneo";
|
||||
rev = "e90b821fc0507a6bdde3596ec32b7b59feae1d1a";
|
||||
hash = "sha256-DbY+bQ4vNj4q2Q/tmEZXngdlUHqfZXTl16m14VG5gYY=";
|
||||
rev = "525a07bd5abd52481a653dc790b987b8f50d0686";
|
||||
hash = "sha256-O1QEvQ2ZZ7rU6KObV1hFaYLVWwDZ6Lu30JMbln7Z7DA=";
|
||||
};
|
||||
|
||||
makefile = "Makefile";
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -802,7 +802,7 @@
|
||||
}
|
||||
},
|
||||
"ungoogled-chromium": {
|
||||
"version": "139.0.7258.66",
|
||||
"version": "139.0.7258.127",
|
||||
"deps": {
|
||||
"depot_tools": {
|
||||
"rev": "ea7a0baff0d8554cf6d38f525b4e7882c2b4ec18",
|
||||
@@ -813,16 +813,16 @@
|
||||
"hash": "sha256-m+z10s40Q/iYcoMw3o/+tmhIdqHMsYJjdGabHrK/aqo="
|
||||
},
|
||||
"ungoogled-patches": {
|
||||
"rev": "139.0.7258.66-1",
|
||||
"hash": "sha256-/8zIJk1RxmFPt81qKCXpEEOrH2Jg6cdHGPdtp0zxdHE="
|
||||
"rev": "139.0.7258.127-1",
|
||||
"hash": "sha256-CdzvDG4ZGRHVnRsLUDD8gWLzcwJJAqEZdEraqVYgs2U="
|
||||
},
|
||||
"npmHash": "sha256-R2gOpfPOUAmnsnUTIvzDPHuHNzL/b2fwlyyfTrywEcI="
|
||||
},
|
||||
"DEPS": {
|
||||
"src": {
|
||||
"url": "https://chromium.googlesource.com/chromium/src.git",
|
||||
"rev": "a62d329947691f76c376a873eae39f56381103c8",
|
||||
"hash": "sha256-RWqOw0Kogz2GwbICet7NdcGnZMrkkE4bu70jU+tbYFQ=",
|
||||
"rev": "5dc2cf9cf870d324cd9fba708f26d2572cc6d4d8",
|
||||
"hash": "sha256-YcOVErOKKruc3kPuXhmeibo3KL+Rrny1FEwF769+aEU=",
|
||||
"recompress": true
|
||||
},
|
||||
"src/third_party/clang-format/script": {
|
||||
@@ -897,8 +897,8 @@
|
||||
},
|
||||
"src/third_party/angle": {
|
||||
"url": "https://chromium.googlesource.com/angle/angle.git",
|
||||
"rev": "0145c376fadde16390298681252785f98ae90185",
|
||||
"hash": "sha256-8ztvupTvp5v8lTq3eo/viR9X85qm+bw8299jxr6XslE="
|
||||
"rev": "5f3636345f1d8afd495e2fcc474fd81e91c4866b",
|
||||
"hash": "sha256-fx+QD0T85Js9jPQx2aghJU8UOL6WbR0bOkGY2i87A3w="
|
||||
},
|
||||
"src/third_party/angle/third_party/glmark2/src": {
|
||||
"url": "https://chromium.googlesource.com/external/github.com/glmark2/glmark2",
|
||||
@@ -1202,8 +1202,8 @@
|
||||
},
|
||||
"src/third_party/libaom/source/libaom": {
|
||||
"url": "https://aomedia.googlesource.com/aom.git",
|
||||
"rev": "0ddc6630b3723b14b164752d46c27752f078ddd3",
|
||||
"hash": "sha256-cs1+5vBEFPqzi1vbxiSgujrLIoaXZROZaRJq2gRdUrE="
|
||||
"rev": "90c632fc6c01cd8637186c783ca8012bab3c3260",
|
||||
"hash": "sha256-e+rUkNOakv6WQrgx1ozoJTynk/GZy1zdsnYX4oz+6ks="
|
||||
},
|
||||
"src/third_party/crabbyavif/src": {
|
||||
"url": "https://chromium.googlesource.com/external/github.com/webmproject/CrabbyAvif.git",
|
||||
@@ -1432,8 +1432,8 @@
|
||||
},
|
||||
"src/third_party/skia": {
|
||||
"url": "https://skia.googlesource.com/skia.git",
|
||||
"rev": "cbc694239b06ecf694676aba22d5263dbc23ee5e",
|
||||
"hash": "sha256-5vIwNP9RbtUVtgKKDiZd6NVkR2Ed3DUqZWESTUM+fIs="
|
||||
"rev": "2d6f1aa4be9c33b013c322b2bc9cd99a682243b6",
|
||||
"hash": "sha256-VysJkpCRRYNdCStnXvo6wyMCv1gLHecMwefKiwypARc="
|
||||
},
|
||||
"src/third_party/smhasher/src": {
|
||||
"url": "https://chromium.googlesource.com/external/smhasher.git",
|
||||
@@ -1597,8 +1597,8 @@
|
||||
},
|
||||
"src/v8": {
|
||||
"url": "https://chromium.googlesource.com/v8/v8.git",
|
||||
"rev": "b07b4e9376489c7f7c0ff2af5eceb4261b3bb784",
|
||||
"hash": "sha256-MnrieVgkvlkWKZ0O790gDSCrgF9c+XEk/XLHQDzMqVY="
|
||||
"rev": "505ec917b67c535519bebec58c62a34f145dd49f",
|
||||
"hash": "sha256-fsf8j2Spe++vSnuO8763eWWmMhYqcyybpILb7OkkXq4="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "helm-diff";
|
||||
version = "3.12.4";
|
||||
version = "3.12.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "databus23";
|
||||
repo = "helm-diff";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-w57EhXjaOEZaQV4FcvzjV4rMUVIwLlUJ3XlD+SLcLa8=";
|
||||
hash = "sha256-vylkjmQHnT69HqkSPGSpgEkP6eeknGq4BGr1eBEvTlw=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-FSyWFJSQBCRpHNrQTPz392H0dE37w1JcwJmoL0dg9fE=";
|
||||
vendorHash = "sha256-PPWL98qEdV/J96N0JsglxUsuT+yFiOg1t4DdiY++/OY=";
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
|
||||
@@ -153,11 +153,11 @@
|
||||
"vendorHash": null
|
||||
},
|
||||
"azurerm": {
|
||||
"hash": "sha256-mYADF+vzpYt9RMxjNrZnEnBgpF4s0h2qBxize52DLw8=",
|
||||
"hash": "sha256-YbnWigxznOZtY/lElLo/SEXnF3LPm6QKflnBoJ1B1Wo=",
|
||||
"homepage": "https://registry.terraform.io/providers/hashicorp/azurerm",
|
||||
"owner": "hashicorp",
|
||||
"repo": "terraform-provider-azurerm",
|
||||
"rev": "v4.38.1",
|
||||
"rev": "v4.39.0",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": null
|
||||
},
|
||||
@@ -171,11 +171,11 @@
|
||||
"vendorHash": null
|
||||
},
|
||||
"baiducloud": {
|
||||
"hash": "sha256-bmKoxLvWc1mX1NaV3ksHeuRX8yYDKnfFhPiASPBVlnM=",
|
||||
"hash": "sha256-sF+S14e6o66iJj/X0jm8sVRmuEJv9UsmJvcLFTFTpVY=",
|
||||
"homepage": "https://registry.terraform.io/providers/baidubce/baiducloud",
|
||||
"owner": "baidubce",
|
||||
"repo": "terraform-provider-baiducloud",
|
||||
"rev": "v1.22.9",
|
||||
"rev": "v1.22.10",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": null
|
||||
},
|
||||
@@ -225,13 +225,13 @@
|
||||
"vendorHash": "sha256-r4Q7b7ZzK+ZDXhIabTSgP7HY5Q51Hz5ErnW+nV+ZIqA="
|
||||
},
|
||||
"buildkite": {
|
||||
"hash": "sha256-pF46n0PJ2ru7s/1S6mznpJnlZx+3BQmPj5dlttjta+Q=",
|
||||
"hash": "sha256-w+ljPDKyVlylr87tFhuu/7oCkY/fFeK+LPr7mY7rbP0=",
|
||||
"homepage": "https://registry.terraform.io/providers/buildkite/buildkite",
|
||||
"owner": "buildkite",
|
||||
"repo": "terraform-provider-buildkite",
|
||||
"rev": "v1.23.0",
|
||||
"rev": "v1.24.0",
|
||||
"spdx": "MIT",
|
||||
"vendorHash": "sha256-PuhOICFZJi6Fnu0cwrXc5YtJ3m5D1tC8C1wj6m9cfPY="
|
||||
"vendorHash": "sha256-2xZ2//qMKfgqob39k++fX6vJEx9YE1NJpGCbDyM1L10="
|
||||
},
|
||||
"ccloud": {
|
||||
"hash": "sha256-Dpx0eugcHCJV8GNPqjxx4P9ohgJgB10DTnHr+CeN/iQ=",
|
||||
@@ -372,11 +372,11 @@
|
||||
"vendorHash": "sha256-quoFrJbB1vjz+MdV+jnr7FPACHuUe5Gx9POLubD2IaM="
|
||||
},
|
||||
"digitalocean": {
|
||||
"hash": "sha256-Bdc28nkev+i91ze/oyPSPeVegw/+eEn2FleaosCvDE0=",
|
||||
"hash": "sha256-kqJVwh3Myu8pfNfO2uVQFO/aU/7trDKktRdXdFQvnOg=",
|
||||
"homepage": "https://registry.terraform.io/providers/digitalocean/digitalocean",
|
||||
"owner": "digitalocean",
|
||||
"repo": "terraform-provider-digitalocean",
|
||||
"rev": "v2.62.0",
|
||||
"rev": "v2.65.0",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": null
|
||||
},
|
||||
@@ -525,13 +525,13 @@
|
||||
"vendorHash": "sha256-eE9AY/79xQSbRl5kA0rwS8Oz8I9jaxT/KlVd0v0GAa8="
|
||||
},
|
||||
"google": {
|
||||
"hash": "sha256-pDYqzdPUnCKpbQqe58o4CU605gdF8vovPR3fCAdf4zQ=",
|
||||
"hash": "sha256-enfKikX5raeLzZCnslaiAJ6hF/7+AXpKlDbNDm2v1qE=",
|
||||
"homepage": "https://registry.terraform.io/providers/hashicorp/google",
|
||||
"owner": "hashicorp",
|
||||
"repo": "terraform-provider-google",
|
||||
"rev": "v6.46.0",
|
||||
"rev": "v6.48.0",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": "sha256-n6UUSCQt3mJESEfqVHX4sfr1XqOXu+u7Qejjps6RmBs="
|
||||
"vendorHash": "sha256-IwUmrRZC2KXNzbKajKisaqKbv0RMIH8tgiKsOOlduIo="
|
||||
},
|
||||
"google-beta": {
|
||||
"hash": "sha256-8woiWjYYaojpKykxd9eMT4qXfpHVkXFA9eN3qzhEu+8=",
|
||||
@@ -660,11 +660,11 @@
|
||||
"vendorHash": null
|
||||
},
|
||||
"ibm": {
|
||||
"hash": "sha256-541obBfBV/odhFvJISxeBtBmaLGoUB7rYymA0U7rhpY=",
|
||||
"hash": "sha256-llsHIVqRN1yKQnMYA0MIinbUk2TL+NYeI0UlUcpCnN0=",
|
||||
"homepage": "https://registry.terraform.io/providers/IBM-Cloud/ibm",
|
||||
"owner": "IBM-Cloud",
|
||||
"repo": "terraform-provider-ibm",
|
||||
"rev": "v1.81.0",
|
||||
"rev": "v1.81.1",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": "sha256-cWfISNNeVPb6BU2V3sLbvlnFKzf3fVniV5Lu1Kpb9f0="
|
||||
},
|
||||
@@ -931,22 +931,22 @@
|
||||
"vendorHash": "sha256-LRIfxQGwG988HE5fftGl6JmBG7tTknvmgpm4Fu1NbWI="
|
||||
},
|
||||
"oci": {
|
||||
"hash": "sha256-bfe55ApaalhJpQtkl8YD9k5U7uyuqMuzOcM/ksBRglw=",
|
||||
"hash": "sha256-Fh3GSSO+MBumdx5BxmINKhci8x0zHZ1jzMcGLyT0DIQ=",
|
||||
"homepage": "https://registry.terraform.io/providers/oracle/oci",
|
||||
"owner": "oracle",
|
||||
"repo": "terraform-provider-oci",
|
||||
"rev": "v7.12.0",
|
||||
"rev": "v7.13.0",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": null
|
||||
},
|
||||
"okta": {
|
||||
"hash": "sha256-Up75XRwe7bnns+ahHtQfK7IG2gptDKNIY8pWG5QcjVI=",
|
||||
"hash": "sha256-+3IYynRuV+iYI8FMpQmLUstNgEf3oAnPah4LmX6UjZw=",
|
||||
"homepage": "https://registry.terraform.io/providers/okta/okta",
|
||||
"owner": "okta",
|
||||
"repo": "terraform-provider-okta",
|
||||
"rev": "v5.2.0",
|
||||
"rev": "v5.3.0",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": "sha256-7zB+ZdrisV+C2kbDWHCaR4uNV3TZAh4EAQcT4jdJpQs="
|
||||
"vendorHash": "sha256-CdXsClQLswfo/xVr5V65vpmvQg26TZv539zK9uodOco="
|
||||
},
|
||||
"oktaasa": {
|
||||
"hash": "sha256-2LhxgowqKvDDDOwdznusL52p2DKP+UiXALHcs9ZQd0U=",
|
||||
@@ -1165,13 +1165,13 @@
|
||||
"vendorHash": "sha256-Icua01a4ILF+oAO5nMeCGPZrWc3V/SVObWydO72CU3I="
|
||||
},
|
||||
"scaleway": {
|
||||
"hash": "sha256-/LyxYC+x6e5SQ12iZLxtbgFkF9MvotUlBYdK3/BiiAo=",
|
||||
"hash": "sha256-YUOfCTtlPn9UBnmmPNODUwEbGR4EkknkdIVdZpmDnQw=",
|
||||
"homepage": "https://registry.terraform.io/providers/scaleway/scaleway",
|
||||
"owner": "scaleway",
|
||||
"repo": "terraform-provider-scaleway",
|
||||
"rev": "v2.58.0",
|
||||
"rev": "v2.59.0",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": "sha256-Fsa4I8aYHiK9V8arwd64piASA8qAPmGZRqDPK5ec3uk="
|
||||
"vendorHash": "sha256-VH20r9RBlygGXuriXCzs3xBar/l3blPR+UcgCobIdWU="
|
||||
},
|
||||
"secret": {
|
||||
"hash": "sha256-MmAnA/4SAPqLY/gYcJSTnEttQTsDd2kEdkQjQj6Bb+A=",
|
||||
|
||||
@@ -30,7 +30,7 @@ mkDerivation rec {
|
||||
"out"
|
||||
"dev"
|
||||
];
|
||||
version = "15.67.4";
|
||||
version = "15.68.5";
|
||||
|
||||
src =
|
||||
let
|
||||
@@ -39,11 +39,11 @@ mkDerivation rec {
|
||||
{
|
||||
x86_64-linux = fetchurl {
|
||||
url = "${base_url}/teamviewer_${version}_amd64.deb";
|
||||
hash = "sha256-ibKRYgsvBmh18LfG29ve/yrDEFTdgsNZ3kJu8YkMbsw=";
|
||||
hash = "sha256-+MTp2ArZTcGFr1YwHIRfBIpjkRm0i9C1Pt5TzDE1SNE=";
|
||||
};
|
||||
aarch64-linux = fetchurl {
|
||||
url = "${base_url}/teamviewer_${version}_arm64.deb";
|
||||
hash = "sha256-MDNxqmu4dJA6dWKy8EFNOy2V253+UgsYwmZ3RidQqFE=";
|
||||
hash = "sha256-3IVZya1WTGl2AtQ2F9jyX2sDLBa2L2/sfsszhyvzu4A=";
|
||||
};
|
||||
}
|
||||
.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
|
||||
|
||||
@@ -15,3 +15,9 @@ if [[ "$latest_version" == "$current_version" ]]; then
|
||||
fi
|
||||
|
||||
update-source-version teamviewer "$latest_version"
|
||||
|
||||
systems=$(nix eval --json -f . teamviewer.meta.platforms | jq --raw-output '.[]')
|
||||
for system in $systems; do
|
||||
hash=$(nix --extra-experimental-features nix-command hash convert --to sri --hash-algo sha256 $(nix-prefetch-url $(nix eval --raw -f . teamviewer.src.url --system "$system")))
|
||||
update-source-version teamviewer $latest_version $hash --system=$system --ignore-same-version --ignore-same-hash
|
||||
done
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -43,12 +43,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 {
|
||||
@@ -98,7 +98,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 ];
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "agenix-cli";
|
||||
version = "0.1.0";
|
||||
version = "0.1.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cole-h";
|
||||
repo = "agenix-cli";
|
||||
tag = "v${version}";
|
||||
sha256 = "sha256-0+QVY1sDhGF4hAN6m2FdKZgm9V1cuGGjY4aitRBnvKg=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
sha256 = "sha256-eJp6t8h8uOP0YupYn8x6VAAmUbVrXypxNMGx4SK/6d8=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-xpA9BTA7EK3Pw8EJOjIq1ulBAcX4yNhc4kqhxsoCbv0=";
|
||||
cargoHash = "sha256-2xTkCdWKQVg8Sp0LDkC/LH9GYBXNpxdoLX30Ndz0muM=";
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
@@ -30,4 +30,4 @@ rustPlatform.buildRustPackage rec {
|
||||
maintainers = with lib.maintainers; [ misuzu ];
|
||||
mainProgram = "agenix";
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "aide";
|
||||
version = "0.19.1";
|
||||
version = "0.19.2";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/aide/aide/releases/download/v${version}/${pname}-${version}.tar.gz";
|
||||
sha256 = "sha256-bfi/XwQD10r329uR6zyPYf4H6WRmnbjPoe5+TuPpC1I=";
|
||||
sha256 = "sha256-I3YrBfRhEe3rPIoFAWyHMcAb24wfkb5IwVbDGrhedMQ=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "alt-tab-macos";
|
||||
version = "7.26.0";
|
||||
version = "7.27.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/lwouis/alt-tab-macos/releases/download/v${finalAttrs.version}/AltTab-${finalAttrs.version}.zip";
|
||||
hash = "sha256-tDy+GFZw9hD2kelPOJioRvcmbPZ9bQu+IRDBEOamsJs=";
|
||||
hash = "sha256-jjtgpfKzLj2cAUvpjlC9STmp8EN3y+rdQVKJvTHzoXM=";
|
||||
};
|
||||
|
||||
sourceRoot = ".";
|
||||
|
||||
@@ -40,13 +40,11 @@ stdenvNoCC.mkDerivation {
|
||||
# [3]: https://gitlab.com/trueNAHO/antora-ui-default/-/commit/11f563294248e9b64124b9289d639e349f2e9f5f
|
||||
src = fetchFromGitLab srcFetchFromGitLab;
|
||||
|
||||
phases = [ "installPhase" ];
|
||||
|
||||
# Install '$src/ui-bundle.zip' to '$out/ui-bundle.zip' instead of '$out' to
|
||||
# prevent the ZIP from being misidentified as a binary [1].
|
||||
#
|
||||
# [1]: https://github.com/NixOS/nixpkgs/blob/8885a1e21ad43f8031c738a08029cd1d4dcbc2f7/pkgs/stdenv/generic/setup.sh#L792-L795
|
||||
installPhase = ''
|
||||
buildCommand = ''
|
||||
mkdir --parents "$out"
|
||||
cp "$src/ui-bundle.zip" "$out"
|
||||
'';
|
||||
|
||||
@@ -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 ];
|
||||
|
||||
@@ -15,13 +15,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "apriltags";
|
||||
version = "3.4.3";
|
||||
version = "3.4.4";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "AprilRobotics";
|
||||
repo = "AprilTags";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-1XbsyyadUvBZSpIc9KPGiTcp+3G7YqHepWoORob01Ss=";
|
||||
hash = "sha256-fHVwRE7qAJZ5Q1SFUfS5du91CUcb3+3n12M/NThDEV4=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "bazel-gazelle";
|
||||
version = "0.44.0";
|
||||
version = "0.45.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bazelbuild";
|
||||
repo = "bazel-gazelle";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-vkGLzrseERxl0LygFm1zCC7kK7j+pHpTbG2fy4fLztw=";
|
||||
hash = "sha256-ulfZPb3MRIOVt8M6XVuuGKmgOgcglJcWsscj2BiMTpY=";
|
||||
};
|
||||
|
||||
vendorHash = null;
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "bearer";
|
||||
version = "1.50.0";
|
||||
version = "1.50.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bearer";
|
||||
repo = "bearer";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-6GggGsimQShDs/F/H80aBykQYowH55plDQDRjiWKFsA=";
|
||||
hash = "sha256-cUfuTYk3ckijSZbniHaZuprlv9rKNIxzILEdTGdvVQ0=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-+2iiMb2+/a3GCUMVA9boJJxuFgB3NmxpTePyMEA46jw=";
|
||||
|
||||
@@ -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 ];
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "bottom";
|
||||
version = "0.10.2";
|
||||
version = "0.11.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ClementTsang";
|
||||
repo = "bottom";
|
||||
tag = version;
|
||||
hash = "sha256-hm0Xfd/iW+431HflvZErjzeZtSdXVb/ReoNIeETJ5Ik=";
|
||||
hash = "sha256-7AK1Nf10nT2Zbu/s7rkCfGuxFa3iIFeh2hy5XbJTSPo=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-feMgkCP6e3HsOppTYLtVrRn/vbSLLRKV0hp85gqr4qM=";
|
||||
cargoHash = "sha256-IpAliZvmhOZw+94kgmfd3Rif8mcqe3LRR5q+i2JLY+s=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
autoAddDriverRunpath
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
let
|
||||
pname = "cables";
|
||||
version = "0.7.0";
|
||||
version = "0.7.1";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/cables-gl/cables_electron/releases/download/v${version}/cables-${version}-linux-x64.AppImage";
|
||||
sha256 = "sha256-8PYHX23E91rUEfzU6fthSTVOnnHeoRjbcNFbuOyeBS8=";
|
||||
sha256 = "sha256-CsKwb9anK7yHM+1mf9tPyjQ1GLYiUkrO7oP+GxFTqx0=";
|
||||
};
|
||||
|
||||
appimageContents = appimageTools.extract {
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "camunda-modeler";
|
||||
version = "5.37.0";
|
||||
version = "5.38.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/camunda/camunda-modeler/releases/download/v${version}/camunda-modeler-${version}-linux-x64.tar.gz";
|
||||
hash = "sha256-YcMe+YBxNYZ9bQzdixckbN5qrCqtaplWCw88i9GAcSA=";
|
||||
hash = "sha256-KiRAsRzIeUc8akizH6zgKCyG55vrYhfWGw572etGgWg=";
|
||||
};
|
||||
sourceRoot = "camunda-modeler-${version}-linux-x64";
|
||||
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "cargo-deny";
|
||||
version = "0.18.3";
|
||||
version = "0.18.4";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "EmbarkStudios";
|
||||
repo = "cargo-deny";
|
||||
rev = version;
|
||||
hash = "sha256-cFgc3bdNVLeuie4sVC+klmQ1/C6W3LkTgORMCfOte4Q=";
|
||||
hash = "sha256-5aa13eFfGEJZBRB4/PAKKLwxw2wt8sBI7ZVOpgnO+t8=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-3TfyFsBSjo8VEDrUehoV2ccXh+xY+iQ9xihj1Bl2MhI=";
|
||||
cargoHash = "sha256-RW+drxVouQbiZsjEL+XZBE2VMzEiCkLTOC9jMxI76T8=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
let
|
||||
argset = {
|
||||
pname = "chezmoi";
|
||||
version = "2.63.1";
|
||||
version = "2.64.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "twpayne";
|
||||
repo = "chezmoi";
|
||||
rev = "v${argset.version}";
|
||||
hash = "sha256-gf79aJhyN3qrCMg7IZqUxHCl6qj6GY5BOXjoJvpKql4=";
|
||||
hash = "sha256-MiIZfT2ax5LszSboXOtDp0hOpOJ8gXqeBTXyoacl+BY=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-2Pnj5QoCL8B5qF7YlQFJttj4nlOSobJKySnIvg+82Ew=";
|
||||
vendorHash = "sha256-LVq++K5ElXeArEpXLnSxg+8D9XJoXCHozOPeJrFbDRE=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
installShellFiles
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
|
||||
python3Packages.buildPythonApplication {
|
||||
pname = "chirp";
|
||||
version = "0.4.0-unstable-2025-08-04";
|
||||
version = "0.4.0-unstable-2025-08-13";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "kk7ds";
|
||||
repo = "chirp";
|
||||
rev = "a8fb306f5627f2478d55541d21f7e9ed51363010";
|
||||
hash = "sha256-SQWKHkIf9d23AKnJQv58XlTmuL07HRj6oS8LW4BM+7Y=";
|
||||
rev = "acb1a78384a804dab1f2f0cc453b3da972d39072";
|
||||
hash = "sha256-+1hzT7peZWtiREeOJqpCyrZNUxOVchxysv9RIAVKPds=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
8
pkgs/by-name/cl/claude-code/package-lock.json
generated
8
pkgs/by-name/cl/claude-code/package-lock.json
generated
@@ -6,13 +6,13 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-code": "^1.0.74"
|
||||
"@anthropic-ai/claude-code": "^1.0.81"
|
||||
}
|
||||
},
|
||||
"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.81",
|
||||
"resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.81.tgz",
|
||||
"integrity": "sha512-kiRgAhQ2vuodkHDAZjuR0aaNchl9SZLq0QF46JKsOw0Ik1eyEN0tdsF++AV//Ub1j4iS1fGIrU10uE7aqFfKYw==",
|
||||
"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.81";
|
||||
|
||||
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-MTugT72wrsUHQHUYx6HZPoE4kt1krYOhfNSSoOc/GjI=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-z+ZU8rT0rKcWxG4fZut7rA2rChVdyOyCw62+CNNObZU=";
|
||||
npmDepsHash = "sha256-1GBwoximrwJX5F7lp5KUXtt6uPABta8FBbYYoJ2Y7x8=";
|
||||
|
||||
postPatch = ''
|
||||
cp ${./package-lock.json} package-lock.json
|
||||
|
||||
179
pkgs/by-name/cl/clickhouse/generic.nix
Normal file
179
pkgs/by-name/cl/clickhouse/generic.nix
Normal file
@@ -0,0 +1,179 @@
|
||||
{
|
||||
lts ? false,
|
||||
version,
|
||||
hash,
|
||||
nixUpdateExtraArgs ? [ ],
|
||||
}:
|
||||
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
llvmPackages_19,
|
||||
fetchFromGitHub,
|
||||
cmake,
|
||||
ninja,
|
||||
python3,
|
||||
perl,
|
||||
nasm,
|
||||
yasm,
|
||||
nixosTests,
|
||||
darwin,
|
||||
findutils,
|
||||
libiconv,
|
||||
rustSupport ? true,
|
||||
rustc,
|
||||
cargo,
|
||||
rustPlatform,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
llvmPackages_19.stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "clickhouse" + lib.optionalString lts "-lts";
|
||||
inherit version;
|
||||
|
||||
src = fetchFromGitHub rec {
|
||||
owner = "ClickHouse";
|
||||
repo = "ClickHouse";
|
||||
tag = "v${finalAttrs.version}";
|
||||
fetchSubmodules = true;
|
||||
name = "clickhouse-${tag}.tar.gz";
|
||||
inherit hash;
|
||||
postFetch = ''
|
||||
# delete files that make the source too big
|
||||
rm -rf $out/contrib/llvm-project/llvm/test
|
||||
rm -rf $out/contrib/llvm-project/clang/test
|
||||
rm -rf $out/contrib/croaring/benchmarks
|
||||
|
||||
# fix case insensitivity on macos https://github.com/NixOS/nixpkgs/issues/39308
|
||||
rm -rf $out/contrib/sysroot/linux-*
|
||||
rm -rf $out/contrib/liburing/man
|
||||
|
||||
# compress to not exceed the 2GB output limit
|
||||
# try to make a deterministic tarball
|
||||
tar -I 'gzip -n' \
|
||||
--sort=name \
|
||||
--mtime=1970-01-01 \
|
||||
--owner=0 --group=0 \
|
||||
--numeric-owner --mode=go=rX,u+rw,a-s \
|
||||
--transform='s@^@source/@S' \
|
||||
-cf temp -C "$out" .
|
||||
rm -r "$out"
|
||||
mv temp "$out"
|
||||
'';
|
||||
};
|
||||
|
||||
strictDeps = true;
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
ninja
|
||||
python3
|
||||
perl
|
||||
llvmPackages_19.lld
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isx86_64 [
|
||||
nasm
|
||||
yasm
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
llvmPackages_19.bintools
|
||||
findutils
|
||||
darwin.bootstrap_cmds
|
||||
]
|
||||
++ lib.optionals rustSupport [
|
||||
rustc
|
||||
cargo
|
||||
rustPlatform.cargoSetupHook
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ];
|
||||
|
||||
dontCargoSetupPostUnpack = true;
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs src/ utils/
|
||||
|
||||
sed -i 's|/usr/bin/env perl|"${lib.getExe perl}"|' contrib/openssl-cmake/CMakeLists.txt
|
||||
|
||||
substituteInPlace utils/list-licenses/list-licenses.sh \
|
||||
--replace-fail '$(git rev-parse --show-toplevel)' "$NIX_BUILD_TOP/$sourceRoot"
|
||||
''
|
||||
+ lib.optionalString (lib.versions.majorMinor version <= "25.6") ''
|
||||
substituteInPlace src/Storages/System/StorageSystemLicenses.sh \
|
||||
--replace-fail '$(git rev-parse --show-toplevel)' "$NIX_BUILD_TOP/$sourceRoot"
|
||||
''
|
||||
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||
substituteInPlace cmake/tools.cmake \
|
||||
--replace-fail 'gfind' 'find' \
|
||||
--replace-fail 'ggrep' 'grep' \
|
||||
--replace-fail '--ld-path=''${LLD_PATH}' '-fuse-ld=lld'
|
||||
''
|
||||
# Rust is handled by cmake
|
||||
+ lib.optionalString rustSupport ''
|
||||
cargoSetupPostPatchHook() { true; }
|
||||
'';
|
||||
|
||||
cmakeFlags = [
|
||||
"-DENABLE_CHDIG=OFF"
|
||||
"-DENABLE_TESTS=OFF"
|
||||
"-DENABLE_DELTA_KERNEL_RS=0"
|
||||
"-DCOMPILER_CACHE=disabled"
|
||||
]
|
||||
++ lib.optional (
|
||||
stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64
|
||||
) "-DNO_ARMV81_OR_HIGHER=1";
|
||||
|
||||
env = {
|
||||
CARGO_HOME = "$PWD/../.cargo/";
|
||||
NIX_CFLAGS_COMPILE =
|
||||
# undefined reference to '__sync_val_compare_and_swap_16'
|
||||
lib.optionalString stdenv.hostPlatform.isx86_64 " -mcx16"
|
||||
+
|
||||
# Silence ``-Wimplicit-const-int-float-conversion` error in MemoryTracker.cpp and
|
||||
# ``-Wno-unneeded-internal-declaration` TreeOptimizer.cpp.
|
||||
lib.optionalString stdenv.hostPlatform.isDarwin
|
||||
" -Wno-implicit-const-int-float-conversion -Wno-unneeded-internal-declaration";
|
||||
};
|
||||
|
||||
# https://github.com/ClickHouse/ClickHouse/issues/49988
|
||||
hardeningDisable = [ "fortify" ];
|
||||
|
||||
postInstall = ''
|
||||
sed -i -e '\!<log>/var/log/clickhouse-server/clickhouse-server\.log</log>!d' \
|
||||
$out/etc/clickhouse-server/config.xml
|
||||
substituteInPlace $out/etc/clickhouse-server/config.xml \
|
||||
--replace-fail "<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>" "<console>1</console>" \
|
||||
--replace-fail "<level>trace</level>" "<level>warning</level>"
|
||||
'';
|
||||
|
||||
# Basic smoke test
|
||||
doCheck = true;
|
||||
checkPhase = lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
|
||||
$NIX_BUILD_TOP/$sourceRoot/build/programs/clickhouse local --query 'SELECT 1' | grep 1
|
||||
'';
|
||||
|
||||
# Builds in 7+h with 2 cores, and ~20m with a big-parallel builder.
|
||||
requiredSystemFeatures = [ "big-parallel" ];
|
||||
|
||||
passthru = {
|
||||
tests.clickhouse = if lts then nixosTests.clickhouse-lts else nixosTests.clickhouse;
|
||||
|
||||
updateScript = nix-update-script {
|
||||
extraArgs = nixUpdateExtraArgs;
|
||||
};
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://clickhouse.com";
|
||||
description = "Column-oriented database management system";
|
||||
license = licenses.asl20;
|
||||
maintainers = with maintainers; [
|
||||
orivej
|
||||
mbalatsko
|
||||
thevar1able
|
||||
];
|
||||
|
||||
# not supposed to work on 32-bit https://github.com/ClickHouse/ClickHouse/pull/23959#issuecomment-835343685
|
||||
platforms = lib.filter (x: (lib.systems.elaborate x).is64bit) (platforms.linux ++ platforms.darwin);
|
||||
broken = stdenv.buildPlatform != stdenv.hostPlatform;
|
||||
};
|
||||
})
|
||||
11
pkgs/by-name/cl/clickhouse/lts.nix
Normal file
11
pkgs/by-name/cl/clickhouse/lts.nix
Normal file
@@ -0,0 +1,11 @@
|
||||
import ./generic.nix {
|
||||
version = "25.3.6.56-lts";
|
||||
hash = "sha256-wpC6uw811IWImLWAatYbghp3aZ+esEEBFng6AHIesK4=";
|
||||
lts = true;
|
||||
nixUpdateExtraArgs = [
|
||||
"--version-regex"
|
||||
"^v?(.*-lts)$"
|
||||
"--override-filename"
|
||||
"pkgs/by-name/cl/clickhouse/lts.nix"
|
||||
];
|
||||
}
|
||||
@@ -1,169 +1,11 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
llvmPackages_19,
|
||||
fetchFromGitHub,
|
||||
cmake,
|
||||
ninja,
|
||||
python3,
|
||||
perl,
|
||||
nasm,
|
||||
yasm,
|
||||
nixosTests,
|
||||
darwin,
|
||||
findutils,
|
||||
libiconv,
|
||||
rustSupport ? true,
|
||||
rustc,
|
||||
cargo,
|
||||
rustPlatform,
|
||||
}:
|
||||
|
||||
llvmPackages_19.stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "clickhouse";
|
||||
version = "25.3.5.42";
|
||||
|
||||
src = fetchFromGitHub rec {
|
||||
owner = "ClickHouse";
|
||||
repo = "ClickHouse";
|
||||
tag = "v${finalAttrs.version}-lts";
|
||||
fetchSubmodules = true;
|
||||
name = "clickhouse-${tag}.tar.gz";
|
||||
hash = "sha256-LvGl9XJK6Emt7HnV/Orp7qEmJSr3TBJZtApL6GrWIMg=";
|
||||
postFetch = ''
|
||||
# delete files that make the source too big
|
||||
rm -rf $out/contrib/llvm-project/llvm/test
|
||||
rm -rf $out/contrib/llvm-project/clang/test
|
||||
rm -rf $out/contrib/croaring/benchmarks
|
||||
|
||||
# fix case insensitivity on macos https://github.com/NixOS/nixpkgs/issues/39308
|
||||
rm -rf $out/contrib/sysroot/linux-*
|
||||
rm -rf $out/contrib/liburing/man
|
||||
|
||||
# compress to not exceed the 2GB output limit
|
||||
# try to make a deterministic tarball
|
||||
tar -I 'gzip -n' \
|
||||
--sort=name \
|
||||
--mtime=1970-01-01 \
|
||||
--owner=0 --group=0 \
|
||||
--numeric-owner --mode=go=rX,u+rw,a-s \
|
||||
--transform='s@^@source/@S' \
|
||||
-cf temp -C "$out" .
|
||||
rm -r "$out"
|
||||
mv temp "$out"
|
||||
'';
|
||||
};
|
||||
|
||||
strictDeps = true;
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
ninja
|
||||
python3
|
||||
perl
|
||||
llvmPackages_19.lld
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isx86_64 [
|
||||
nasm
|
||||
yasm
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
llvmPackages_19.bintools
|
||||
findutils
|
||||
darwin.bootstrap_cmds
|
||||
]
|
||||
++ lib.optionals rustSupport [
|
||||
rustc
|
||||
cargo
|
||||
rustPlatform.cargoSetupHook
|
||||
import ./generic.nix {
|
||||
version = "25.7.4.11-stable";
|
||||
hash = "sha256-SKDnnBdl9Rwc+ONH1chXAOFIwRmVG2l5cPEwpaDogzU=";
|
||||
lts = false;
|
||||
nixUpdateExtraArgs = [
|
||||
"--version-regex"
|
||||
"^v?(.*-stable)$"
|
||||
"--override-filename"
|
||||
"pkgs/by-name/cl/clickhouse/package.nix"
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ];
|
||||
|
||||
dontCargoSetupPostUnpack = true;
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs src/
|
||||
patchShebangs utils/
|
||||
|
||||
sed -i 's|/usr/bin/env perl|"${lib.getExe perl}"|' contrib/openssl-cmake/CMakeLists.txt
|
||||
|
||||
substituteInPlace src/Storages/System/StorageSystemLicenses.sh \
|
||||
--replace-fail '$(git rev-parse --show-toplevel)' "$NIX_BUILD_TOP/$sourceRoot"
|
||||
substituteInPlace utils/check-style/check-ungrouped-includes.sh \
|
||||
--replace-fail '$(git rev-parse --show-toplevel)' "$NIX_BUILD_TOP/$sourceRoot"
|
||||
substituteInPlace utils/list-licenses/list-licenses.sh \
|
||||
--replace-fail '$(git rev-parse --show-toplevel)' "$NIX_BUILD_TOP/$sourceRoot"
|
||||
''
|
||||
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||
sed -i 's|gfind|find|' cmake/tools.cmake
|
||||
sed -i 's|ggrep|grep|' cmake/tools.cmake
|
||||
|
||||
# Make sure Darwin invokes lld.ld64 not lld.
|
||||
substituteInPlace cmake/tools.cmake \
|
||||
--replace '--ld-path=''${LLD_PATH}' '-fuse-ld=lld'
|
||||
''
|
||||
+ lib.optionalString rustSupport ''
|
||||
cargoSetupPostPatchHook() { true; }
|
||||
'';
|
||||
|
||||
cmakeFlags = [
|
||||
"-DENABLE_TESTS=OFF"
|
||||
"-DENABLE_DELTA_KERNEL_RS=0"
|
||||
"-DCOMPILER_CACHE=disabled"
|
||||
]
|
||||
++ lib.optional (
|
||||
stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64
|
||||
) "-DNO_ARMV81_OR_HIGHER=1";
|
||||
|
||||
env = {
|
||||
CARGO_HOME = "$PWD/../.cargo/";
|
||||
NIX_CFLAGS_COMPILE =
|
||||
# undefined reference to '__sync_val_compare_and_swap_16'
|
||||
lib.optionalString stdenv.hostPlatform.isx86_64 " -mcx16"
|
||||
+
|
||||
# Silence ``-Wimplicit-const-int-float-conversion` error in MemoryTracker.cpp and
|
||||
# ``-Wno-unneeded-internal-declaration` TreeOptimizer.cpp.
|
||||
lib.optionalString stdenv.hostPlatform.isDarwin
|
||||
" -Wno-implicit-const-int-float-conversion -Wno-unneeded-internal-declaration";
|
||||
};
|
||||
|
||||
# https://github.com/ClickHouse/ClickHouse/issues/49988
|
||||
hardeningDisable = [ "fortify" ];
|
||||
|
||||
postInstall = ''
|
||||
rm -rf $out/share/clickhouse-test
|
||||
|
||||
sed -i -e '\!<log>/var/log/clickhouse-server/clickhouse-server\.log</log>!d' \
|
||||
$out/etc/clickhouse-server/config.xml
|
||||
substituteInPlace $out/etc/clickhouse-server/config.xml \
|
||||
--replace-fail "<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>" "<console>1</console>"
|
||||
substituteInPlace $out/etc/clickhouse-server/config.xml \
|
||||
--replace-fail "<level>trace</level>" "<level>warning</level>"
|
||||
'';
|
||||
|
||||
# Basic smoke test
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
$NIX_BUILD_TOP/$sourceRoot/build/programs/clickhouse local --query 'SELECT 1' | grep 1
|
||||
'';
|
||||
|
||||
# Builds in 7+h with 2 cores, and ~20m with a big-parallel builder.
|
||||
requiredSystemFeatures = [ "big-parallel" ];
|
||||
|
||||
passthru.tests.clickhouse = nixosTests.clickhouse;
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://clickhouse.com";
|
||||
description = "Column-oriented database management system";
|
||||
license = licenses.asl20;
|
||||
maintainers = with maintainers; [
|
||||
orivej
|
||||
mbalatsko
|
||||
thevar1able
|
||||
];
|
||||
|
||||
# not supposed to work on 32-bit https://github.com/ClickHouse/ClickHouse/pull/23959#issuecomment-835343685
|
||||
platforms = lib.filter (x: (lib.systems.elaborate x).is64bit) (platforms.linux ++ platforms.darwin);
|
||||
broken = stdenv.buildPlatform != stdenv.hostPlatform;
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
buildGraalvmNativeImage (finalAttrs: {
|
||||
pname = "clj-kondo";
|
||||
version = "2025.07.26";
|
||||
version = "2025.07.28";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/clj-kondo/clj-kondo/releases/download/v${finalAttrs.version}/clj-kondo-${finalAttrs.version}-standalone.jar";
|
||||
sha256 = "sha256-jo8iY8vEtrGTQTV98y89i2OLWW4M3u6hsXZebd7cnUw=";
|
||||
sha256 = "sha256-ioKRFkm+zBAAM7oyR4F6rTHEhViuRNuMXcr1xwnjcms=";
|
||||
};
|
||||
|
||||
extraNativeImageBuildArgs = [
|
||||
|
||||
@@ -151,7 +151,6 @@ stdenv.mkDerivation rec {
|
||||
license = licenses.unfree;
|
||||
mainProgram = "warp-cli";
|
||||
maintainers = with maintainers; [
|
||||
devpikachu
|
||||
marcusramberg
|
||||
];
|
||||
platforms = [
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user