Merge 1efa528e94 into haskell-updates
This commit is contained in:
@@ -7,6 +7,8 @@ inputs:
|
||||
description: "Whether and which SHA to checkout for the merge commit in the ./nixpkgs/untrusted folder."
|
||||
target-as-trusted-at:
|
||||
description: "Whether and which SHA to checkout for the target commit in the ./nixpkgs/trusted folder."
|
||||
untrusted-pin-bump:
|
||||
description: "Commit that bumps ci/pinned.json; when set, ./nixpkgs/untrusted and ./nixpkgs/untrusted-pinned are derived from this commit."
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
@@ -15,6 +17,7 @@ runs:
|
||||
env:
|
||||
MERGED_SHA: ${{ inputs.merged-as-untrusted-at }}
|
||||
TARGET_SHA: ${{ inputs.target-as-trusted-at }}
|
||||
PIN_BUMP_SHA: ${{ inputs.untrusted-pin-bump }}
|
||||
with:
|
||||
script: |
|
||||
const { spawn } = require('node:child_process')
|
||||
@@ -52,13 +55,18 @@ runs:
|
||||
return pinned.pins.nixpkgs.revision
|
||||
}
|
||||
|
||||
const pin_bump_sha = process.env.PIN_BUMP_SHA
|
||||
|
||||
// When dealing with a pin bump commit, we need `--depth=2` to view & apply its diff
|
||||
const depth = pin_bump_sha ? 2 : 1
|
||||
|
||||
const commits = [
|
||||
{
|
||||
sha: process.env.MERGED_SHA,
|
||||
path: 'untrusted',
|
||||
},
|
||||
{
|
||||
sha: await getPinnedSha(process.env.MERGED_SHA),
|
||||
sha: await getPinnedSha(pin_bump_sha || process.env.MERGED_SHA),
|
||||
path: 'untrusted-pinned'
|
||||
},
|
||||
{
|
||||
@@ -68,14 +76,17 @@ runs:
|
||||
{
|
||||
sha: await getPinnedSha(process.env.TARGET_SHA),
|
||||
path: 'trusted-pinned'
|
||||
},
|
||||
{
|
||||
sha: pin_bump_sha
|
||||
}
|
||||
].filter(({ sha }) => Boolean(sha))
|
||||
|
||||
console.log('Checking out the following commits:', commits)
|
||||
console.log('Fetching the following commits:', commits)
|
||||
|
||||
// Fetching all commits at once is much faster than doing multiple checkouts.
|
||||
// This would fail without --refetch, because the we had a partial clone before, but changed it above.
|
||||
await run('git', 'fetch', '--depth=1', '--refetch', 'origin', ...(commits.map(({ sha }) => sha)))
|
||||
await run('git', 'fetch', `--depth=${depth}`, '--refetch', 'origin', ...(commits.map(({ sha }) => sha)))
|
||||
|
||||
// Checking out onto tmpfs takes 1s and is faster by at least factor 10x.
|
||||
await run('mkdir', 'nixpkgs')
|
||||
@@ -89,8 +100,27 @@ runs:
|
||||
}
|
||||
|
||||
// Create all worktrees in parallel.
|
||||
await Promise.all(commits.map(async ({ sha, path }) => {
|
||||
await run('git', 'worktree', 'add', join('nixpkgs', path), sha, '--no-checkout')
|
||||
await run('git', '-C', join('nixpkgs', path), 'sparse-checkout', 'disable')
|
||||
await run('git', '-C', join('nixpkgs', path), 'checkout', '--progress')
|
||||
}))
|
||||
await Promise.all(
|
||||
commits
|
||||
.filter(({ path }) => Boolean(path))
|
||||
.map(async ({ sha, path }) => {
|
||||
await run('git', 'worktree', 'add', join('nixpkgs', path), sha, '--no-checkout')
|
||||
await run('git', '-C', join('nixpkgs', path), 'sparse-checkout', 'disable')
|
||||
await run('git', '-C', join('nixpkgs', path), 'checkout', '--progress')
|
||||
})
|
||||
)
|
||||
|
||||
// Apply pin bump to untrusted worktree
|
||||
if (pin_bump_sha) {
|
||||
console.log('Applying untrusted ci/pinned.json bump:', pin_bump_sha)
|
||||
try {
|
||||
await run('git', '-C', join('nixpkgs', 'untrusted'), 'cherry-pick', '--no-commit', pin_bump_sha)
|
||||
} catch {
|
||||
core.setFailed([
|
||||
`Failed to apply ci/pinned.json bump commit ${pin_bump_sha}.`,
|
||||
`This commit does not apply cleanly onto the untrusted base ${process.env.MERGED_SHA}.`,
|
||||
`Please rebase the PR or ensure the pin bump is standalone.`
|
||||
].join(' '))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
- runner: ubuntu-24.04-arm
|
||||
name: aarch64-linux
|
||||
systems: aarch64-linux
|
||||
builds: [shell, manual-nixos, manual-nixpkgs, manual-nixpkgs-tests]
|
||||
builds: [shell, manual-nixos, manual-nixpkgs]
|
||||
desc: shell, docs
|
||||
- runner: macos-14
|
||||
name: darwin
|
||||
@@ -90,11 +90,7 @@ jobs:
|
||||
|
||||
- name: Build Nixpkgs manual
|
||||
if: contains(matrix.builds, 'manual-nixpkgs') && !cancelled()
|
||||
run: nix-build-uncached nixpkgs/untrusted/ci --arg nixpkgs ./nixpkgs/untrusted-pinned -A manual-nixpkgs -A manual-nixpkgs-tests
|
||||
|
||||
- name: Build Nixpkgs manual tests
|
||||
if: contains(matrix.builds, 'manual-nixpkgs-tests') && !cancelled()
|
||||
run: nix-build-uncached nixpkgs/untrusted/ci --arg nixpkgs ./nixpkgs/untrusted-pinned -A manual-nixpkgs-tests
|
||||
run: nix-build-uncached nixpkgs/untrusted/ci --arg nixpkgs ./nixpkgs/untrusted-pinned -A manual-nixpkgs
|
||||
|
||||
- name: Build lib tests
|
||||
if: contains(matrix.builds, 'lib-tests') && !cancelled()
|
||||
|
||||
@@ -9,7 +9,11 @@ on:
|
||||
mergedSha:
|
||||
required: true
|
||||
type: string
|
||||
headSha:
|
||||
required: false # only required when testVersions is true
|
||||
type: string
|
||||
targetSha:
|
||||
required: true
|
||||
type: string
|
||||
systems:
|
||||
required: true
|
||||
@@ -36,6 +40,8 @@ jobs:
|
||||
runs-on: ubuntu-slim
|
||||
outputs:
|
||||
versions: ${{ steps.versions.outputs.versions }}
|
||||
ciPinBumpCommit: ${{ steps.find-pinned-commit.outputs.ciPinBumpCommit }}
|
||||
ciPinBumpCommitShort: ${{ steps.find-pinned-commit.outputs.ciPinBumpCommitShort }}
|
||||
steps:
|
||||
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
||||
with:
|
||||
@@ -53,6 +59,78 @@ jobs:
|
||||
sparse-checkout: |
|
||||
ci/pinned.json
|
||||
|
||||
- name: Find commit that touched ci/pinned.json
|
||||
id: find-pinned-commit
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
env:
|
||||
TARGET_SHA: ${{ inputs.targetSha }}
|
||||
HEAD_SHA: ${{ inputs.headSha }}
|
||||
with:
|
||||
script: |
|
||||
const targetSha = process.env.TARGET_SHA
|
||||
const headSha = process.env.HEAD_SHA
|
||||
|
||||
if (!targetSha || !headSha) {
|
||||
core.setFailed('Error: Both targetSha and headSha inputs are required when testVersions is true.')
|
||||
return
|
||||
}
|
||||
|
||||
// Compare the two commits to get the list of commits in between
|
||||
const comparison = await github.rest.repos.compareCommitsWithBasehead({
|
||||
...context.repo,
|
||||
basehead: `${targetSha}...${headSha}`,
|
||||
})
|
||||
|
||||
if(comparison.data.commits.length > 50) {
|
||||
core.setFailed('Error: Too many commits in comparison, cannot reliably find pinned.json change.')
|
||||
return
|
||||
}
|
||||
|
||||
const logRateLimit = async (label) => {
|
||||
const { data } = await github.rest.rateLimit.get()
|
||||
const { remaining, limit, used } = data.rate
|
||||
core.info(`[Rate Limit ${label}] ${remaining}/${limit} remaining (${used} used)`)
|
||||
}
|
||||
|
||||
await logRateLimit('before commit filtering')
|
||||
|
||||
// Filter commits that modified ci/pinned.json
|
||||
const commitsModifyingPinned = (
|
||||
await Promise.all(
|
||||
comparison.data.commits.map(async (commit) => {
|
||||
const commitDetails = await github.rest.repos.getCommit({
|
||||
...context.repo,
|
||||
ref: commit.sha,
|
||||
})
|
||||
const modifiesPinned = commitDetails.data.files?.some(
|
||||
(file) => file.filename === "ci/pinned.json"
|
||||
)
|
||||
return modifiesPinned ? commit.sha : null
|
||||
})
|
||||
)
|
||||
).filter((sha) => sha !== null)
|
||||
|
||||
await logRateLimit('after commit filtering')
|
||||
|
||||
if (commitsModifyingPinned.length === 0) {
|
||||
// This should not happen as testVersions should only be true
|
||||
// when ci/pinned.json was modified in the PR.
|
||||
core.setFailed("Error: ci/pinned.json was not modified in this PR")
|
||||
return
|
||||
} else if (commitsModifyingPinned.length > 1) {
|
||||
core.setFailed([
|
||||
"Error: Multiple commits touch ci/pinned.json in this PR:",
|
||||
...commitsModifyingPinned,
|
||||
"Please ensure only a single commit modifies ci/pinned.json for accurate version matrix evaluation."
|
||||
].join("\n"))
|
||||
return
|
||||
}
|
||||
|
||||
const ciPinBumpCommit = commitsModifyingPinned[0]
|
||||
core.setOutput("ciPinBumpCommit", ciPinBumpCommit)
|
||||
core.setOutput("ciPinBumpCommitShort", ciPinBumpCommit.substring(0, 7))
|
||||
core.info(`Found pinned.json commit: ${ciPinBumpCommit}`)
|
||||
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31
|
||||
|
||||
@@ -75,7 +153,7 @@ jobs:
|
||||
# Failures for versioned Evals will be collected in a separate job below
|
||||
# to not interrupt main Eval's compare step.
|
||||
continue-on-error: ${{ matrix.version != '' }}
|
||||
name: ${{ matrix.system }}${{ matrix.version && format(' @ {0}', matrix.version) || '' }}
|
||||
name: ${{ matrix.system }}${{ matrix.version && format(' @ {0} ({1})', matrix.version, needs.versions.outputs.ciPinBumpCommitShort) || '' }}
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
# This is not supposed to be used and just acts as a fallback.
|
||||
@@ -96,7 +174,9 @@ jobs:
|
||||
- name: Check out the PR at merged and target commits
|
||||
uses: ./.github/actions/checkout
|
||||
with:
|
||||
merged-as-untrusted-at: ${{ inputs.mergedSha }}
|
||||
# For versioned evals, use the target as the untrusted base and apply the pin-bump commit
|
||||
merged-as-untrusted-at: ${{ matrix.version && inputs.targetSha || inputs.mergedSha }}
|
||||
untrusted-pin-bump: ${{ matrix.version && needs.versions.outputs.ciPinBumpCommit }}
|
||||
target-as-trusted-at: ${{ inputs.targetSha }}
|
||||
|
||||
- name: Install Nix
|
||||
@@ -284,6 +364,7 @@ jobs:
|
||||
ARTIFACT_PREFIX: ${{ inputs.artifact-prefix }}
|
||||
SYSTEMS: ${{ inputs.systems }}
|
||||
VERSIONS: ${{ needs.versions.outputs.versions }}
|
||||
CI_PIN_BUMP_COMMIT: ${{ needs.versions.outputs.ciPinBumpCommit }}
|
||||
with:
|
||||
script: |
|
||||
const { readFileSync } = require('node:fs')
|
||||
@@ -292,8 +373,10 @@ jobs:
|
||||
const prefix = process.env.ARTIFACT_PREFIX
|
||||
const systems = JSON.parse(process.env.SYSTEMS)
|
||||
const versions = JSON.parse(process.env.VERSIONS)
|
||||
const ciPinBumpCommit = process.env.CI_PIN_BUMP_COMMIT
|
||||
|
||||
core.summary.addHeading('Lix/Nix version comparison')
|
||||
core.summary.addRaw(`\n*Evaluated at commit: \`${ciPinBumpCommit}\` (commit that modified ci/pinned.json)*\n`, true)
|
||||
core.summary.addTable(
|
||||
[].concat(
|
||||
[
|
||||
@@ -324,7 +407,11 @@ jobs:
|
||||
.filter((attr) => attr.split('.').length > 1)
|
||||
if (attrs.length > 0) {
|
||||
core.setFailed(
|
||||
`${version} on ${system} has changed outpaths!\nNote: Please make sure to update ci/pinned.json separately from changes to other packages.`,
|
||||
`${version} on ${system} has changed outpaths!\n` +
|
||||
`Note: This indicates that commit ${ciPinBumpCommit} ` +
|
||||
`(which modified ci/pinned.json) also contains other ` +
|
||||
`changes affecting package outputs. ` +
|
||||
`Please ensure ci/pinned.json is updated in a standalone commit.`
|
||||
)
|
||||
return { data: ':x:' }
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ jobs:
|
||||
with:
|
||||
artifact-prefix: ${{ inputs.artifact-prefix }}
|
||||
mergedSha: ${{ needs.prepare.outputs.mergedSha }}
|
||||
headSha: ${{ github.event.pull_request.head.sha }}
|
||||
targetSha: ${{ needs.prepare.outputs.targetSha }}
|
||||
systems: ${{ needs.prepare.outputs.systems }}
|
||||
testVersions: ${{ contains(fromJSON(needs.prepare.outputs.touched), 'pinned') && !contains(fromJSON(needs.prepare.outputs.headBranch).type, 'development') }}
|
||||
|
||||
@@ -172,7 +172,6 @@ rec {
|
||||
lib-tests = import ../lib/tests/release.nix { inherit pkgs; };
|
||||
manual-nixos = (import ../nixos/release.nix { }).manual.${system} or null;
|
||||
manual-nixpkgs = (import ../doc { inherit pkgs; });
|
||||
manual-nixpkgs-tests = (import ../doc { inherit pkgs; }).tests;
|
||||
nixpkgs-vet = pkgs.callPackage ./nixpkgs-vet.nix {
|
||||
nix = pkgs.nixVersions.latest;
|
||||
};
|
||||
|
||||
+5
-12
@@ -133,6 +133,11 @@ module.exports = async ({ github, context, core, dry }) => {
|
||||
id,
|
||||
})
|
||||
.then((resp) => resp.data)
|
||||
.catch((e) => {
|
||||
// User may have deleted their account
|
||||
if (e.status === 404) return null
|
||||
throw e
|
||||
})
|
||||
}
|
||||
|
||||
return users[id]
|
||||
@@ -145,22 +150,10 @@ module.exports = async ({ github, context, core, dry }) => {
|
||||
|
||||
// This API request is important for the merge-conflict label, because it triggers the
|
||||
// creation of a new test merge commit. This is needed to actually determine the state of a PR.
|
||||
//
|
||||
// NOTE (2025-12-15): Temporarily skipping mergeability checks here
|
||||
// on GitHub’s request to measure the impact of the resulting ref
|
||||
// writes on their internal metrics; merge conflicts resulting from
|
||||
// changes to target branches will not have labels applied for the
|
||||
// duration. The label should still be updated on pushes.
|
||||
//
|
||||
// TODO: Restore mergeability checks in some form after a few days
|
||||
// or when we hear back from GitHub.
|
||||
const pull_request = (
|
||||
await github.rest.pulls.get({
|
||||
...context.repo,
|
||||
pull_number,
|
||||
// Undocumented parameter (as of 2025-12-15), added by GitHub
|
||||
// for us; stability unclear.
|
||||
skip_mergeability_checks: true,
|
||||
})
|
||||
).data
|
||||
|
||||
|
||||
@@ -42,9 +42,15 @@ async function handleReviewers({
|
||||
}
|
||||
|
||||
const users = new Set([
|
||||
...(await Promise.all(
|
||||
maintainers.map(async (id) => (await getUser(id)).login.toLowerCase()),
|
||||
)),
|
||||
...(
|
||||
await Promise.all(
|
||||
maintainers.map(async (id) => {
|
||||
const user = await getUser(id)
|
||||
// User may have deleted their account
|
||||
return user?.login?.toLowerCase()
|
||||
}),
|
||||
)
|
||||
).filter(Boolean),
|
||||
...owners
|
||||
.filter((handle) => handle && !handle.includes('/'))
|
||||
.map((handle) => handle.toLowerCase()),
|
||||
|
||||
@@ -168,6 +168,7 @@ stdenvNoCC.mkDerivation (
|
||||
};
|
||||
|
||||
tests = {
|
||||
# Don't run this in CI because it's not reproducible
|
||||
manpage-urls = callPackage ../tests/manpage-urls.nix { };
|
||||
};
|
||||
};
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
|
||||
- `spoof` has been removed, as there are many issues upstream with it working on modern OS versions, and it appears to be unmaintained.
|
||||
|
||||
- `nodePackages.wavedrom-cli` has been removed, as it was unmaintained within nixpkgs.
|
||||
|
||||
- `kanata` now requires `karabiner-dk` version 6.0+ or later.
|
||||
The package has been updated to use the new `karabiner-dk` package and the `darwinDriver` output stays at the version defined in the package.
|
||||
|
||||
|
||||
+24
-4
@@ -58,12 +58,19 @@ logFailure() {
|
||||
evalConfig() {
|
||||
local attr=$1
|
||||
shift
|
||||
local script="import ./default.nix { modules = [ $* ];}"
|
||||
|
||||
local nix_args=()
|
||||
|
||||
if [ "${ABORT_ON_WARN-0}" = "1" ]; then
|
||||
local-nix-instantiate --option abort-on-warn true -E "$script" -A "$attr"
|
||||
else
|
||||
local-nix-instantiate -E "$script" -A "$attr"
|
||||
nix_args+=(--option abort-on-warn true)
|
||||
fi
|
||||
|
||||
if [ "${STRICT_EVAL-0}" = "1" ]; then
|
||||
nix_args+=(--strict)
|
||||
fi
|
||||
|
||||
local script="import ./default.nix { modules = [ $* ];}"
|
||||
local-nix-instantiate "${nix_args[@]}" -E "$script" -A "$attr"
|
||||
}
|
||||
|
||||
reportFailure() {
|
||||
@@ -247,6 +254,19 @@ checkConfigError 'A definition for option .* is not of type .fileset.. Definitio
|
||||
checkConfigError 'A definition for option .* is not of type .fileset.. Definition values:\n.*' config.filesetCardinal.err3 ./fileset.nix
|
||||
checkConfigError 'A definition for option .* is not of type .fileset.. Definition values:\n.*' config.filesetCardinal.err4 ./fileset.nix
|
||||
|
||||
# types.serializableValueWith
|
||||
checkConfigOutput '^null$' config.nullableValue.null ./types.nix
|
||||
checkConfigOutput '^true$' config.nullableValue.bool ./types.nix
|
||||
checkConfigOutput '^1$' config.nullableValue.int ./types.nix
|
||||
checkConfigOutput '^1.1$' config.nullableValue.float ./types.nix
|
||||
checkConfigOutput '^"foo"$' config.nullableValue.str ./types.nix
|
||||
checkConfigOutput '^".*/store.*"$' config.nullableValue.path ./types.nix
|
||||
STRICT_EVAL=1 checkConfigOutput '^\{"foo":1\}$' config.nullableValue.attrs ./types.nix
|
||||
STRICT_EVAL=1 checkConfigOutput '^\[\{"bar":\[1\]\}\]$' config.nullableValue.list ./types.nix
|
||||
|
||||
checkConfigError 'A definition for option .* is not of type .VAL value.. .*' config.nullableValue.lambda ./types.nix
|
||||
checkConfigError 'A definition for option .* is not of type .VAL value.. .*' config.structuredValue.null ./types.nix
|
||||
|
||||
# Check boolean option.
|
||||
checkConfigOutput '^false$' config.enable ./declare-enable.nix
|
||||
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./define-enable.nix
|
||||
|
||||
@@ -16,6 +16,19 @@ in
|
||||
options = {
|
||||
pathInStore = mkOption { type = types.lazyAttrsOf types.pathInStore; };
|
||||
externalPath = mkOption { type = types.lazyAttrsOf types.externalPath; };
|
||||
# serializableValueWith
|
||||
nullableValue = mkOption {
|
||||
type = types.attrsOf (types.serializableValueWith { typeName = "VAL"; });
|
||||
};
|
||||
structuredValue = mkOption {
|
||||
type = types.attrsOf (
|
||||
types.serializableValueWith {
|
||||
typeName = "VAL";
|
||||
nullable = false;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
assertions = mkOption { };
|
||||
};
|
||||
config = {
|
||||
@@ -35,6 +48,22 @@ in
|
||||
externalPath.ok1 = "/foo/bar";
|
||||
externalPath.ok2 = "/";
|
||||
|
||||
# serializableValueWith { nullable = true; }
|
||||
nullableValue.null = null; # null
|
||||
nullableValue.bool = true; # bool
|
||||
nullableValue.int = 1; # int
|
||||
nullableValue.float = 1.1; # float
|
||||
nullableValue.str = "foo"; # str
|
||||
nullableValue.path = ./.; # path
|
||||
nullableValue.attrs = {
|
||||
foo = 1;
|
||||
};
|
||||
nullableValue.list = [ { bar = [ 1 ]; } ]; # list
|
||||
nullableValue.lambda = x: x; # Error
|
||||
|
||||
# serializableValueWith { nullable = false; }
|
||||
structuredValue.null = null; # Error
|
||||
|
||||
assertions =
|
||||
with lib.types;
|
||||
|
||||
@@ -486,6 +515,9 @@ in
|
||||
assert (unique { message = "custom"; } (listOf str)).description == "list of string";
|
||||
assert (unique { message = "test"; } (either int str)).description == "signed integer or string";
|
||||
assert (unique { message = "test"; } (listOf str)).description == "list of string";
|
||||
# json & toml
|
||||
assert json.description == "JSON value";
|
||||
assert toml.description == "TOML value";
|
||||
# done
|
||||
"ok";
|
||||
};
|
||||
|
||||
@@ -1437,6 +1437,45 @@ rec {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
Creates a value type suitable for serialization formats.
|
||||
|
||||
Parameters:
|
||||
- typeName: String describing the format (e.g. "JSON", "YAML", "XML")
|
||||
- nullable: Whether the structured value type allows `null` values.
|
||||
|
||||
Returns a type suitable for structured data formats that supports:
|
||||
- Basic types: boolean, integer, float, string, path
|
||||
- Complex types: attribute sets and lists
|
||||
*/
|
||||
serializableValueWith =
|
||||
{
|
||||
typeName,
|
||||
nullable ? true,
|
||||
}:
|
||||
let
|
||||
baseType = oneOf [
|
||||
bool
|
||||
int
|
||||
float
|
||||
str
|
||||
path
|
||||
(attrsOf valueType)
|
||||
(listOf valueType)
|
||||
];
|
||||
valueType = (if nullable then nullOr baseType else baseType) // {
|
||||
description = "${typeName} value";
|
||||
};
|
||||
in
|
||||
valueType;
|
||||
|
||||
json = serializableValueWith { typeName = "JSON"; };
|
||||
|
||||
toml = serializableValueWith {
|
||||
typeName = "TOML";
|
||||
nullable = false;
|
||||
};
|
||||
|
||||
# Either value of type `t1` or `t2`.
|
||||
either =
|
||||
t1: t2:
|
||||
|
||||
@@ -497,6 +497,20 @@ Composed types are types that take a type as parameter. `listOf
|
||||
value of type *`to`*. Can be used to preserve backwards compatibility
|
||||
of an option if its type was changed.
|
||||
|
||||
`types.json`
|
||||
|
||||
: A type representing JSON-compatible values. This includes `null`, booleans,
|
||||
integers, floats, strings, paths, attribute sets, and lists.
|
||||
Attribute sets and lists can be arbitrarily nested and contain any JSON-compatible
|
||||
values.
|
||||
|
||||
`types.toml`
|
||||
|
||||
: A type representing TOML-compatible values. This includes booleans,
|
||||
integers, floats, strings, paths, attribute sets, and lists.
|
||||
Attribute sets and lists can be arbitrarily nested and contain any TOML-compatible
|
||||
values.
|
||||
|
||||
## Submodule {#section-option-types-submodule}
|
||||
|
||||
`submodule` is a very powerful type that defines a set of sub-options
|
||||
|
||||
@@ -109,6 +109,9 @@
|
||||
"modular-services": [
|
||||
"index.html#modular-services"
|
||||
],
|
||||
"module-services-amule": [
|
||||
"index.html#module-services-amule"
|
||||
],
|
||||
"module-services-anubis": [
|
||||
"index.html#module-services-anubis"
|
||||
],
|
||||
|
||||
@@ -32,14 +32,8 @@ let
|
||||
let
|
||||
qemu-common = import ../qemu-common.nix { inherit (pkgs) lib stdenv; };
|
||||
|
||||
# Convert legacy VLANs to named interfaces and merge with explicit interfaces.
|
||||
vlansNumbered = forEach (zipLists config.virtualisation.vlans (range 1 255)) (v: {
|
||||
name = "eth${toString v.snd}";
|
||||
vlan = v.fst;
|
||||
assignIP = true;
|
||||
});
|
||||
explicitInterfaces = lib.mapAttrsToList (n: v: v // { name = n; }) config.virtualisation.interfaces;
|
||||
interfaces = vlansNumbered ++ explicitInterfaces;
|
||||
interfaces = lib.attrValues config.virtualisation.allInterfaces;
|
||||
|
||||
interfacesNumbered = zipLists interfaces (range 1 255);
|
||||
|
||||
# Automatically assign IP addresses to requested interfaces.
|
||||
@@ -67,10 +61,10 @@ let
|
||||
{ fst, snd }: qemu-common.qemuNICFlags snd fst.vlan config.virtualisation.test.nodeNumber
|
||||
)
|
||||
);
|
||||
udevRules = forEach interfacesNumbered (
|
||||
{ fst, snd }:
|
||||
udevRules = forEach interfaces (
|
||||
interface:
|
||||
# MAC Addresses for QEMU network devices are lowercase, and udev string comparison is case-sensitive.
|
||||
''SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="${toLower (qemu-common.qemuNicMac fst.vlan config.virtualisation.test.nodeNumber)}",NAME="${fst.name}"''
|
||||
''SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="${toLower (qemu-common.qemuNicMac interface.vlan config.virtualisation.test.nodeNumber)}",NAME="${interface.name}"''
|
||||
);
|
||||
|
||||
networkConfig = {
|
||||
|
||||
@@ -77,6 +77,15 @@ in
|
||||
example = false;
|
||||
};
|
||||
|
||||
extraCompletionPackages = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.package;
|
||||
default = [ ];
|
||||
example = lib.literalExpression "config.users.users.alice.packages";
|
||||
description = ''
|
||||
Additional packages to generate completions from, if {option}`programs.fish.generateCompletions` is enabled.
|
||||
'';
|
||||
};
|
||||
|
||||
vendor.config.enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
@@ -295,7 +304,7 @@ in
|
||||
pkgs.buildEnv {
|
||||
name = "system_fish-completions";
|
||||
ignoreCollisions = true;
|
||||
paths = map generateCompletions config.environment.systemPackages;
|
||||
paths = map generateCompletions (config.environment.systemPackages ++ cfg.extraCompletionPackages);
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
@@ -377,7 +377,7 @@ systemd-tmpfiles --create
|
||||
systemctl start acme-example.com.service
|
||||
```
|
||||
|
||||
## Ensuring dependencies for services that need to be reloaded when a certificate challenges {#module-security-acme-reload-dependencies}
|
||||
## Ensuring dependencies for services that need to be reloaded when a certificate changes {#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:
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
device-name-strategy,
|
||||
discovery-mode,
|
||||
mounts,
|
||||
disable-hooks,
|
||||
enable-hooks,
|
||||
glibc,
|
||||
jq,
|
||||
lib,
|
||||
@@ -37,7 +39,8 @@ writeScriptBin "nvidia-cdi-generator" ''
|
||||
}
|
||||
--discovery-mode ${discovery-mode} \
|
||||
--device-name-strategy ${device-name-strategy} \
|
||||
--disable-hook create-symlinks \
|
||||
${lib.concatMapStringsSep " \\\n" (hook: "--disable-hook ${hook}") disable-hooks} \
|
||||
${lib.concatMapStringsSep " \\\n" (hook: "--enable-hook ${hook}") enable-hooks} \
|
||||
--ldconfig-path ${lib.getExe' glibc "ldconfig"} \
|
||||
--library-search-path ${lib.getLib nvidia-driver}/lib \
|
||||
--nvidia-cdi-hook-path ${lib.getOutput "tools" nvidia-container-toolkit}/bin/nvidia-cdi-hook \
|
||||
|
||||
@@ -120,6 +120,26 @@
|
||||
|
||||
package = lib.mkPackageOption pkgs "nvidia-container-toolkit" { };
|
||||
|
||||
disable-hooks = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.nonEmptyStr;
|
||||
default = [ "create-symlinks" ];
|
||||
description = ''
|
||||
List of hooks to disable when generating the CDI specification.
|
||||
Each hook name will be passed as `--disable-hook <hook-name>` to nvidia-ctk.
|
||||
Set to an empty list to disable no hooks.
|
||||
'';
|
||||
};
|
||||
|
||||
enable-hooks = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.nonEmptyStr;
|
||||
default = [ ];
|
||||
description = ''
|
||||
List of hooks to enable when generating the CDI specification.
|
||||
Each hook name will be passed as `--enable-hook <hook-name>` to nvidia-ctk.
|
||||
Set to an empty list to enable no hooks.
|
||||
'';
|
||||
};
|
||||
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
@@ -306,6 +326,8 @@
|
||||
device-name-strategy
|
||||
discovery-mode
|
||||
mounts
|
||||
disable-hooks
|
||||
enable-hooks
|
||||
extraArgs
|
||||
;
|
||||
nvidia-container-toolkit = config.hardware.nvidia-container-toolkit.package;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# aMule {#module-services-amule}
|
||||
|
||||
[aMule](https://www.amule.org/) is a free and open-source peer-to-peer file sharing client that supports the eD2k and Kad networks.
|
||||
It allows users to search for, download, and share files with others on these networks.
|
||||
The `amuled` daemon is the command-line version of aMule, designed to run as a background service without a graphical user interface, making it suitable for servers or headless systems.
|
||||
It handles finding sources, managing download and upload queues, and interacting with the eD2k servers and Kad network.
|
||||
|
||||
Here an example which also enables the web server and sets custom paths for the downloads:
|
||||
|
||||
```nix
|
||||
{
|
||||
services.amule = {
|
||||
enable = true;
|
||||
openPeerPorts = true;
|
||||
openWebServerPort = true;
|
||||
ExternalConnectPasswordFile = "/run/secrets/amule-password";
|
||||
WebServerPasswordFile = "/run/secrets/amule-web/password";
|
||||
settings = {
|
||||
eMule = {
|
||||
IncomingDir = "/mnt/hd/amule";
|
||||
TempDir = "/mnt/hd/amule/Temp";
|
||||
};
|
||||
WebServer.Enabled = 1;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
You can connect using `amulegui` and choosing the host, port (`4712` by default) and password, the username is always `amule`.
|
||||
Otherwise, if you enabled the web server, connect using the browser (port `4711` by default).
|
||||
@@ -1,89 +1,323 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
utils,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.amule;
|
||||
opt = options.services.amule;
|
||||
user = if cfg.user != null then cfg.user else "amule";
|
||||
in
|
||||
|
||||
{
|
||||
settingsFormat = pkgs.formats.ini { };
|
||||
|
||||
###### interface
|
||||
inherit (lib)
|
||||
mkOption
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
types
|
||||
optionalAttrs
|
||||
mkIf
|
||||
mkMerge
|
||||
literalExpression
|
||||
optionalString
|
||||
optionals
|
||||
getExe
|
||||
;
|
||||
|
||||
options = {
|
||||
|
||||
services.amule = {
|
||||
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
settingsOptions = {
|
||||
eMule = {
|
||||
Port = mkOption {
|
||||
type = types.port;
|
||||
default = 4662;
|
||||
description = ''
|
||||
Whether to run the AMule daemon. You need to manually run "amuled --ec-config" to configure the service for the first time.
|
||||
TCP port for eD2k connections.
|
||||
Required for connecting to servers and achieving a High ID.
|
||||
'';
|
||||
};
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/home/${user}/";
|
||||
defaultText = lib.literalExpression ''
|
||||
"/home/''${config.${opt.user}}/"
|
||||
'';
|
||||
UDPPort = mkOption {
|
||||
type = types.port;
|
||||
default = 4672;
|
||||
description = ''
|
||||
The directory holding configuration, incoming and temporary files.
|
||||
UDP port for eD2k traffic (searches, source exchange) and all Kad network communication.
|
||||
Essential for a High ID on both networks and proper Kad functioning.
|
||||
'';
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
TempDir = mkOption {
|
||||
type = types.path;
|
||||
default = "${cfg.dataDir}/Temp";
|
||||
defaultText = literalExpression "\${config.services.amule.dataDir}/Temp";
|
||||
description = ''
|
||||
The user the AMule daemon should run as.
|
||||
Directory where aMule stores incomplete downloads (.part/.part.met files).
|
||||
'';
|
||||
};
|
||||
|
||||
IncomingDir = mkOption {
|
||||
type = types.path;
|
||||
default = "${cfg.dataDir}/Incoming";
|
||||
defaultText = literalExpression "\${config.services.amule.dataDir}/Incoming";
|
||||
description = ''
|
||||
Directory where aMule moves completed downloads.
|
||||
Files in this directory are automatically shared.
|
||||
Ensure the aMule service has write permissions
|
||||
'';
|
||||
};
|
||||
OSDirectory = mkOption {
|
||||
type = types.path;
|
||||
default = cfg.dataDir;
|
||||
defaultText = literalExpression "\${config.services.amule.dataDir}";
|
||||
description = "On-disk state directory, probably you don't want to change this";
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
ExternalConnect = {
|
||||
AcceptExternalConnections = mkOption {
|
||||
type = types.enum [
|
||||
0
|
||||
1
|
||||
];
|
||||
default = 1;
|
||||
description = "Whether to accept external connections, if disabled amuled refuses to start";
|
||||
internal = true;
|
||||
};
|
||||
ECPort = mkOption {
|
||||
type = types.port;
|
||||
default = 4712;
|
||||
description = "TCP port for external connections, like remote control via amule-gui";
|
||||
};
|
||||
ECPassword = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
MD5 hash of the password, obtainaible with `echo "<password>" | md5sum | cut -d ' ' -f 1`
|
||||
'';
|
||||
};
|
||||
};
|
||||
WebServer = {
|
||||
Enabled = lib.mkOption {
|
||||
type = types.enum [
|
||||
0
|
||||
1
|
||||
];
|
||||
default = 0;
|
||||
description = "Set to 1 to enable the web server";
|
||||
};
|
||||
Password = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
description = ''
|
||||
MD5 hash of the password, obtainaible with `echo "<password>" | md5sum | cut -d ' ' -f 1`
|
||||
'';
|
||||
};
|
||||
Port = mkOption {
|
||||
type = types.port;
|
||||
default = 4711;
|
||||
description = "Web server port";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
###### implementation
|
||||
webServerEnabled = cfg.settings.WebServer.Enabled == 1;
|
||||
in
|
||||
{
|
||||
options.services.amule = {
|
||||
enable = mkEnableOption "aMule daemon";
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
package = mkPackageOption pkgs "amule-daemon" { };
|
||||
|
||||
users.users = lib.mkIf (cfg.user == null) [
|
||||
amuleWebPackage = mkPackageOption pkgs "amule-web" { };
|
||||
|
||||
extraArgs = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
description = "Additional passed arguments";
|
||||
};
|
||||
|
||||
dataDir = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/amuled";
|
||||
description = "Directory holding configuration and by default also incoming and temporary files";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "amule";
|
||||
description = "The user the aMule daemon should run as";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "amule";
|
||||
description = "Group under which amule runs";
|
||||
};
|
||||
|
||||
openPeerPorts = mkEnableOption "open the peer port(s) in the firewall";
|
||||
|
||||
openExternalConnectPort = mkEnableOption "open the external connect port";
|
||||
|
||||
openWebServerPort = mkEnableOption "open the web server port";
|
||||
|
||||
ExternalConnectPasswordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing the password for connecting with amule-gui,
|
||||
set this only if you didn't set `settings.ExternalConnect.ECPassword`
|
||||
'';
|
||||
};
|
||||
|
||||
WebServerPasswordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
File containing the password for connecting to the web server,
|
||||
set this only if you didn't set `settings.ExternalConnect.ECPassword`
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = settingsOptions;
|
||||
};
|
||||
description = ''
|
||||
Free form attribute set for aMule settings.
|
||||
The final configuration file is generated merging the default settings with these options.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
eMule = {
|
||||
IncomingDir = "/mnt/hd/amule/Incoming";
|
||||
TempDir = "/mnt/hd/amule/Temp";
|
||||
};
|
||||
WebServer.Enabled = 1;
|
||||
}
|
||||
'';
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
name = "amule";
|
||||
description = "AMule daemon";
|
||||
group = "amule";
|
||||
assertion = isNull cfg.ExternalConnectPasswordFile -> cfg.settings.ExternalConnect.ECPassword != "";
|
||||
message = "Set only one between `ExternalConnectPasswordFile` and `settings.ExternalConnect.ECPassword`";
|
||||
}
|
||||
]
|
||||
++ optionals webServerEnabled [
|
||||
{
|
||||
assertion = isNull cfg.WebServerPasswordFile -> cfg.settings.WebServer.Password != "";
|
||||
message = "Set only one between `ExternalWebServerFile` `settings.WebServer.Password`";
|
||||
}
|
||||
];
|
||||
|
||||
users.users = optionalAttrs (cfg.user == "amule") {
|
||||
amule = {
|
||||
group = cfg.group;
|
||||
description = "aMule user";
|
||||
isSystemUser = true;
|
||||
uid = config.ids.uids.amule;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
users.groups = lib.mkIf (cfg.user == null) [
|
||||
{
|
||||
name = "amule";
|
||||
gid = config.ids.gids.amule;
|
||||
}
|
||||
];
|
||||
users.groups = optionalAttrs (cfg.group == "amule") {
|
||||
amule.gid = config.ids.gids.amule;
|
||||
};
|
||||
|
||||
systemd.tmpfiles.settings."10-amuled".${cfg.dataDir}.d = {
|
||||
inherit (cfg) user group;
|
||||
mode = "0755";
|
||||
};
|
||||
|
||||
services.amule.settings = {
|
||||
eMule.AppVersion = lib.getVersion cfg.package;
|
||||
};
|
||||
|
||||
systemd.services.amuled = {
|
||||
description = "AMule daemon";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [ pkgs.crudini ];
|
||||
|
||||
preStart = ''
|
||||
mkdir -p ${cfg.dataDir}
|
||||
chown ${user} ${cfg.dataDir}
|
||||
AMULE_CONF="${cfg.dataDir}/amule.conf"
|
||||
|
||||
if [ ! -f "$AMULE_CONF" ]; then
|
||||
echo "First run detected: starting aMule to generate default configuration..."
|
||||
echo "aMule will fail with an error - this is expected and normal"
|
||||
rm -f ${cfg.dataDir}/lastversion
|
||||
set +e
|
||||
${getExe cfg.package} --config-dir ${cfg.dataDir}
|
||||
set -e
|
||||
fi
|
||||
''
|
||||
+ (lib.concatMapAttrsStringSep "" (
|
||||
section:
|
||||
lib.concatMapAttrsStringSep "" (
|
||||
param: value: ''
|
||||
crudini --inplace --set "$AMULE_CONF" "${section}" "${param}" "${builtins.toString value}"
|
||||
''
|
||||
)
|
||||
) cfg.settings)
|
||||
+ optionalString (!isNull cfg.ExternalConnectPasswordFile) ''
|
||||
EC_PASSWORD=$(cat ${cfg.ExternalConnectPasswordFile} | md5sum | cut -d ' ' -f 1)
|
||||
crudini --inplace --set "$AMULE_CONF" "ExternalConnect" "ECPassword" "$EC_PASSWORD"
|
||||
''
|
||||
+ optionalString (!isNull cfg.WebServerPasswordFile) ''
|
||||
WEB_PASSWORD=$(cat ${cfg.WebServerPasswordFile} | md5sum | cut -d ' ' -f 1)
|
||||
crudini --inplace --set "$AMULE_CONF" "WebServer" "Password" "$WEB_PASSWORD"
|
||||
'';
|
||||
|
||||
script = ''
|
||||
${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${user} \
|
||||
-c 'HOME="${cfg.dataDir}" ${pkgs.amule-daemon}/bin/amuled'
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
|
||||
ExecStart = utils.escapeSystemdExecArgs (
|
||||
[
|
||||
(getExe cfg.package)
|
||||
"--config-dir"
|
||||
cfg.dataDir
|
||||
]
|
||||
++ optionals webServerEnabled [ "--use-amuleweb=${getExe cfg.amuleWebPackage}" ]
|
||||
++ cfg.extraArgs
|
||||
);
|
||||
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
|
||||
# Hardening
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
DevicePolicy = "closed";
|
||||
ProtectSystem = "strict";
|
||||
ProtectControlGroups = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ReadWritePaths = [
|
||||
cfg.dataDir
|
||||
cfg.settings.eMule.TempDir
|
||||
cfg.settings.eMule.IncomingDir
|
||||
];
|
||||
RestrictAddressFamilies = "AF_INET";
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
LockPersonality = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = mkMerge [
|
||||
(mkIf cfg.openPeerPorts {
|
||||
allowedTCPPorts = [ cfg.settings.eMule.Port ];
|
||||
allowedUDPPorts = [ cfg.settings.eMule.UDPPort ];
|
||||
})
|
||||
(mkIf cfg.openWebServerPort {
|
||||
allowedTCPPorts = [ cfg.settings.WebServer.Port ];
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ aciceri ];
|
||||
doc = ./amuled.md;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -78,15 +78,57 @@ It is possible to configure default settings for all instances of Anubis, via {o
|
||||
```nix
|
||||
{
|
||||
services.anubis.defaultOptions = {
|
||||
botPolicy = {
|
||||
dnsbl = false;
|
||||
};
|
||||
settings.DIFFICULTY = 3;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Note that at the moment, a custom bot policy is not merged with the baked-in one. That means to only override a setting
|
||||
like `dnsbl`, copying the entire bot policy is required. Check
|
||||
[the upstream repository](https://github.com/TecharoHQ/anubis/blob/1509b06cb921aff842e71fbb6636646be6ed5b46/cmd/anubis/botPolicies.json)
|
||||
for the policy.
|
||||
By default, this module uses Anubis's built-in policy (`botPolicies.yaml`), which includes sensible defaults for bot
|
||||
rules, thresholds, status codes, and storage backend. A custom policy file is only generated when you explicitly
|
||||
customize the policy via {option}`services.anubis.instances.<name>.policy`.
|
||||
|
||||
To add custom bot rules while keeping the defaults:
|
||||
|
||||
```nix
|
||||
{
|
||||
services.anubis.instances.default = {
|
||||
settings.TARGET = "http://localhost:8000";
|
||||
policy.extraBots = [
|
||||
{
|
||||
name = "my-allowed-bot";
|
||||
user_agent_regex = "MyBot/.*";
|
||||
action = "ALLOW";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
To opt out of the default bot rules entirely and define your own:
|
||||
|
||||
```nix
|
||||
{
|
||||
services.anubis.instances.default = {
|
||||
settings.TARGET = "http://localhost:8000";
|
||||
policy = {
|
||||
useDefaultBotRules = false;
|
||||
extraBots = [
|
||||
{
|
||||
name = "my-rule";
|
||||
path_regex = ".*";
|
||||
action = "CHALLENGE";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
::: {.note}
|
||||
When you customize the policy, a custom policy file is generated. This file imports the default bot rules via
|
||||
`(data)/meta/default-config.yaml` when {option}`services.anubis.instances.<name>.policy.useDefaultBotRules` is enabled,
|
||||
but uses Anubis's simpler legacy threshold instead of the 5-tier thresholds from `botPolicies.yaml`. If you need custom
|
||||
thresholds, specify them in {option}`services.anubis.instances.<name>.policy.settings`.
|
||||
:::
|
||||
|
||||
See [the upstream documentation](https://anubis.techaro.lol/docs/admin/policies) for all available policy options.
|
||||
|
||||
@@ -12,6 +12,32 @@ let
|
||||
enabledInstances = lib.filterAttrs (_: conf: conf.enable) cfg.instances;
|
||||
instanceName = name: if name == "" then "anubis" else "anubis-${name}";
|
||||
|
||||
# Only generates a custom policy file when the user has explicitly customized
|
||||
# something (extraBots, settings, or disabled default bot rules). When nothing
|
||||
# is customized, returns null so Anubis uses its built-in botPolicies.yaml
|
||||
# which includes sensible defaults for thresholds, status_codes, store, etc.
|
||||
mkPolicyFile =
|
||||
name: instance:
|
||||
let
|
||||
hasCustomization =
|
||||
!instance.policy.useDefaultBotRules
|
||||
|| instance.policy.extraBots != [ ]
|
||||
|| instance.policy.settings != { };
|
||||
bots =
|
||||
(lib.optional instance.policy.useDefaultBotRules {
|
||||
import = "(data)/meta/default-config.yaml";
|
||||
})
|
||||
++ instance.policy.extraBots;
|
||||
policyContent = {
|
||||
inherit bots;
|
||||
}
|
||||
// instance.policy.settings;
|
||||
in
|
||||
if hasCustomization then
|
||||
jsonFormat.generate "${instanceName name}-policy.json" policyContent
|
||||
else
|
||||
null;
|
||||
|
||||
unixAddr = network: addr: lib.strings.optionalString (network == "unix") addr;
|
||||
unixSocketAddrs =
|
||||
settings:
|
||||
@@ -40,6 +66,10 @@ let
|
||||
in
|
||||
{ name, ... }:
|
||||
{
|
||||
imports = [
|
||||
(lib.mkRenamedOptionModule [ "botPolicy" ] [ "policy" "settings" ])
|
||||
];
|
||||
|
||||
options = {
|
||||
enable = lib.mkEnableOption "this instance of Anubis" // {
|
||||
default = true;
|
||||
@@ -65,18 +95,71 @@ let
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
botPolicy = mkDefaultOption "botPolicy" {
|
||||
default = null;
|
||||
policy = lib.mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Anubis policy configuration in Nix syntax. Set to `null` to use the baked-in policy which should be
|
||||
sufficient for most use-cases.
|
||||
|
||||
This option has no effect if `settings.POLICY_FNAME` is set to a different value, which is useful for
|
||||
importing an existing configuration.
|
||||
Anubis policy configuration.
|
||||
|
||||
See [the documentation](https://anubis.techaro.lol/docs/admin/policies) for details.
|
||||
'';
|
||||
type = types.nullOr jsonFormat.type;
|
||||
type = types.submodule {
|
||||
options = {
|
||||
useDefaultBotRules = mkDefaultOption "policy.useDefaultBotRules" {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to include Anubis's default bot detection rules via the
|
||||
`(data)/meta/default-config.yaml` import.
|
||||
|
||||
Set to `false` to define your own bot rules from scratch using
|
||||
{option}`extraBots`.
|
||||
'';
|
||||
};
|
||||
|
||||
extraBots = mkDefaultOption "policy.extraBots" {
|
||||
type = types.listOf jsonFormat.type;
|
||||
default = [ ];
|
||||
example = lib.literalExpression ''
|
||||
[
|
||||
{
|
||||
name = "my-bot";
|
||||
user_agent_regex = "MyBot/.*";
|
||||
action = "ALLOW";
|
||||
}
|
||||
]
|
||||
'';
|
||||
description = ''
|
||||
Additional bot rules appended to the policy.
|
||||
|
||||
When {option}`useDefaultBotRules` is `true`, these rules are added after
|
||||
Anubis's default rules. When `false`, only these rules are used.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkDefaultOption "policy.settings" {
|
||||
type = jsonFormat.type;
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
dnsbl = false;
|
||||
store = {
|
||||
backend = "bbolt";
|
||||
parameters.path = "/var/lib/anubis/data.bdb";
|
||||
};
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
Additional policy settings merged into the policy file.
|
||||
|
||||
Common settings include `dnsbl`, `store`, `logging`, `thresholds`,
|
||||
`impressum`, `openGraph`, and `statusCodes`.
|
||||
|
||||
See [the documentation](https://anubis.techaro.lol/docs/admin/policies) for
|
||||
available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
extraFlags = mkDefaultOption "extraFlags" {
|
||||
@@ -175,8 +258,8 @@ let
|
||||
POLICY_FNAME = mkDefaultOption "settings.POLICY_FNAME" {
|
||||
default = null;
|
||||
description = ''
|
||||
The bot policy file to use. Leave this as `null` to respect the value set in
|
||||
{option}`services.anubis.instances.<name>.botPolicy`.
|
||||
The policy file to use. Leave this as `null` to use the policy generated from
|
||||
{option}`services.anubis.instances.<name>.policy`.
|
||||
'';
|
||||
type = types.nullOr types.path;
|
||||
};
|
||||
@@ -306,10 +389,8 @@ in
|
||||
POLICY_FNAME =
|
||||
if instance.settings.POLICY_FNAME != null then
|
||||
instance.settings.POLICY_FNAME
|
||||
else if instance.botPolicy != null then
|
||||
jsonFormat.generate "${instanceName name}-botPolicy.json" instance.botPolicy
|
||||
else
|
||||
null;
|
||||
mkPolicyFile name instance;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -19,8 +19,6 @@ let
|
||||
};
|
||||
|
||||
settingsFormat = pkgs.formats.yaml { };
|
||||
configFile = settingsFormat.generate "headscale.yaml" cfg.settings;
|
||||
cliConfigFile = settingsFormat.generate "headscale.yaml" cliConfig;
|
||||
|
||||
assertRemovedOption = option: message: {
|
||||
assertion = !lib.hasAttrByPath option cfg;
|
||||
@@ -35,6 +33,16 @@ in
|
||||
|
||||
package = lib.mkPackageOption pkgs "headscale" { };
|
||||
|
||||
configFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
readOnly = true;
|
||||
default = settingsFormat.generate "headscale.yaml" cfg.settings;
|
||||
defaultText = lib.literalExpression ''(pkgs.formats.yaml { }).generate "headscale.yaml" config.services.headscale.settings'';
|
||||
description = ''
|
||||
Path to the configuration file of headscale.
|
||||
'';
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
default = "headscale";
|
||||
type = lib.types.str;
|
||||
@@ -621,7 +629,7 @@ in
|
||||
environment = {
|
||||
# Headscale CLI needs a minimal config to be able to locate the unix socket
|
||||
# to talk to the server instance.
|
||||
etc."headscale/config.yaml".source = cliConfigFile;
|
||||
etc."headscale/config.yaml".source = settingsFormat.generate "headscale.yaml" cliConfig;
|
||||
|
||||
systemPackages = [ cfg.package ];
|
||||
};
|
||||
@@ -646,7 +654,7 @@ in
|
||||
export HEADSCALE_DATABASE_POSTGRES_PASS="$(head -n1 ${lib.escapeShellArg cfg.settings.database.postgres.password_file})"
|
||||
''}
|
||||
|
||||
exec ${lib.getExe cfg.package} serve --config ${configFile}
|
||||
exec ${lib.getExe cfg.package} serve --config ${cfg.configFile}
|
||||
'';
|
||||
|
||||
serviceConfig =
|
||||
|
||||
@@ -13,7 +13,6 @@ let
|
||||
bool
|
||||
listOf
|
||||
str
|
||||
attrs
|
||||
submodule
|
||||
;
|
||||
cfg = config.services.yggdrasil;
|
||||
@@ -69,7 +68,7 @@ in
|
||||
|
||||
settings = mkOption {
|
||||
type = submodule {
|
||||
freeformType = attrs;
|
||||
freeformType = (pkgs.formats.json { }).type;
|
||||
options = {
|
||||
PrivateKeyPath = mkOption {
|
||||
type = nullOr path;
|
||||
|
||||
@@ -76,7 +76,7 @@ in
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
enableACME = true;
|
||||
forceHttps = true;
|
||||
forceSSL = true;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
@@ -140,7 +140,7 @@ in
|
||||
"pics.''${config.networking.domain}"
|
||||
];
|
||||
enableACME = true;
|
||||
forceHttps = true;
|
||||
forceSSL = true;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
|
||||
@@ -45,7 +45,7 @@ in
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
enableACME = true;
|
||||
forceHttps = true;
|
||||
forceSSL = true;
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
|
||||
+1
-7
@@ -10,13 +10,7 @@ let
|
||||
|
||||
runTests = stdenv.mkDerivation {
|
||||
name = "tests-activation-lib";
|
||||
src = fileset.toSource {
|
||||
root = ./.;
|
||||
fileset = fileset.unions [
|
||||
./lib.sh
|
||||
./test.sh
|
||||
];
|
||||
};
|
||||
src = ./lib;
|
||||
buildPhase = ":";
|
||||
doCheck = true;
|
||||
postUnpack = ''
|
||||
@@ -6,7 +6,7 @@
|
||||
}:
|
||||
let
|
||||
node-forbiddenDependencies-fail = nixos (
|
||||
{ ... }:
|
||||
{ config, ... }:
|
||||
{
|
||||
system.forbiddenDependenciesRegexes = [ "-dev$" ];
|
||||
environment.etc."dev-dependency" = {
|
||||
@@ -15,16 +15,22 @@ let
|
||||
documentation.enable = false;
|
||||
fileSystems."/".device = "ignore-root-device";
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
# Don't do this in an actual config
|
||||
system.stateVersion = config.system.nixos.release;
|
||||
}
|
||||
);
|
||||
node-forbiddenDependencies-succeed = nixos (
|
||||
{ ... }:
|
||||
{ config, ... }:
|
||||
{
|
||||
system.forbiddenDependenciesRegexes = [ "-dev$" ];
|
||||
system.extraDependencies = [ expect.dev ];
|
||||
documentation.enable = false;
|
||||
fileSystems."/".device = "ignore-root-device";
|
||||
boot.loader.grub.enable = false;
|
||||
|
||||
# Don't do this in an actual config
|
||||
system.stateVersion = config.system.nixos.release;
|
||||
}
|
||||
);
|
||||
in
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
# This module defines networking options for virtual machines and containers.
|
||||
# It is intended to be used with systemd-nspawn containers and QEMU virtual machines.
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib) types;
|
||||
|
||||
interfaceType = types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = types.str;
|
||||
default = name;
|
||||
description = ''
|
||||
Interface name
|
||||
'';
|
||||
};
|
||||
|
||||
vlan = lib.mkOption {
|
||||
type = types.ints.unsigned;
|
||||
description = ''
|
||||
VLAN to which the network interface is connected.
|
||||
'';
|
||||
};
|
||||
|
||||
assignIP = lib.mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Automatically assign an IP address to the network interface using the same scheme as
|
||||
virtualisation.vlans.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
cfg = config.virtualisation;
|
||||
|
||||
# Convert legacy VLANs to named interfaces.
|
||||
vlansNumbered = lib.listToAttrs (
|
||||
lib.forEach (lib.zipLists cfg.vlans (lib.range 1 255)) (
|
||||
v:
|
||||
let
|
||||
name = "eth${toString v.snd}";
|
||||
in
|
||||
lib.nameValuePair name {
|
||||
inherit name;
|
||||
vlan = v.fst;
|
||||
assignIP = true;
|
||||
}
|
||||
)
|
||||
);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
networking.primaryIPAddress = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = "Primary IP address used in /etc/hosts.";
|
||||
};
|
||||
|
||||
networking.primaryIPv6Address = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = "Primary IPv6 address used in /etc/hosts.";
|
||||
};
|
||||
|
||||
virtualisation.vlans = lib.mkOption {
|
||||
type = types.listOf types.ints.unsigned;
|
||||
default = if cfg.interfaces == { } then [ 1 ] else [ ];
|
||||
defaultText = lib.literalExpression ''if cfg.interfaces == {} then [ 1 ] else [ ]'';
|
||||
example = [
|
||||
1
|
||||
2
|
||||
];
|
||||
description = ''
|
||||
Virtual networks to which the container or VM is connected. Each number «N» in
|
||||
this list causes the container to have a virtual Ethernet interface
|
||||
attached to a separate virtual network on which it will be assigned IP
|
||||
address `192.168.«N».«M»`, where «M» is the index of this container in
|
||||
the list of containers.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.interfaces = lib.mkOption {
|
||||
default = { };
|
||||
example = {
|
||||
enp1s0.vlan = 1;
|
||||
};
|
||||
description = ''
|
||||
Extra network interfaces to add to the container or VM in addition to the ones
|
||||
created by {option}`virtualisation.vlans`.
|
||||
'';
|
||||
type = types.attrsOf interfaceType;
|
||||
};
|
||||
|
||||
virtualisation.allInterfaces = lib.mkOption {
|
||||
type = types.attrsOf interfaceType;
|
||||
readOnly = true;
|
||||
description = ''
|
||||
All network interfaces for the container or VM. Combines
|
||||
{option}`virtualisation.vlans` and {option}`virtualisation.interfaces`.
|
||||
'';
|
||||
default = vlansNumbered // cfg.interfaces;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
assertions = [
|
||||
(
|
||||
let
|
||||
conflictingKeys = lib.intersectAttrs vlansNumbered cfg.interfaces;
|
||||
in
|
||||
{
|
||||
assertion = conflictingKeys == { };
|
||||
message = ''
|
||||
`virtualisation.vlans` and `virtualisation.interfaces` have conflicting keys: ${lib.concatStringsSep "," (lib.attrNames conflictingKeys)}
|
||||
'';
|
||||
}
|
||||
)
|
||||
(
|
||||
let
|
||||
allInterfaceNames =
|
||||
(lib.mapAttrsToList (k: i: i.name) vlansNumbered)
|
||||
++ (lib.mapAttrsToList (k: i: i.name) cfg.interfaces);
|
||||
in
|
||||
{
|
||||
assertion = lib.allUnique allInterfaceNames;
|
||||
message = ''
|
||||
`virtualisation.vlans` and `virtualisation.interfaces` have conflicting interface names: ${lib.concatStringsSep "," allInterfaceNames}
|
||||
'';
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
# This module creates a lightweight "container" from the NixOS configuration.
|
||||
# Building the `config.system.build.nspawn` attribute gives you a command
|
||||
# that starts a systemd-nspawn container running the NixOS configuration
|
||||
# defined in `config`. By default, the Nix store is shared read-only with the
|
||||
# host, which makes (re)building very efficient.
|
||||
# This shares a lot in common with
|
||||
# `nixos/modules/virtualisation/nixos-containers.nix`, but doesn't use systemd
|
||||
# units.
|
||||
# The networking options here match the options in
|
||||
# `nixos/modules/virtualisation/nixos-containers.nix` which allows using these
|
||||
# lightweight containers for nixos integration tests.
|
||||
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib) types;
|
||||
cfg = config.virtualisation;
|
||||
in
|
||||
{
|
||||
imports = [ ../guest-networking-options.nix ];
|
||||
|
||||
options = {
|
||||
|
||||
virtualisation.cmdline = lib.mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [
|
||||
"systemd.unit=rescue.target"
|
||||
"systemd.log_level=debug"
|
||||
"systemd.log_target=console"
|
||||
];
|
||||
description = ''
|
||||
Command line arguments to pass to the init process (likely systemd).
|
||||
Useful for debugging.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.rootDir = lib.mkOption {
|
||||
type = types.str;
|
||||
default = "./${config.system.name}-root";
|
||||
defaultText = lib.literalExpression ''"./''${config.system.name}-root"'';
|
||||
description = ''
|
||||
Path to a directory for the root filesystem for the container.
|
||||
The directory will be created on startup if it does not
|
||||
exist.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.systemd-nspawn = {
|
||||
|
||||
package = lib.mkPackageOption pkgs "systemd" { };
|
||||
|
||||
options = lib.mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ ];
|
||||
example = [ "--bind=/home:/home" ];
|
||||
description = ''
|
||||
Options passed to systemd-nspawn.
|
||||
See [systemd-nspawn docs](https://www.freedesktop.org/software/systemd/man/latest/systemd-nspawn.html) for a complete list.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
boot.isNspawnContainer = true;
|
||||
|
||||
# TODO(arianvp): Remove after https://github.com/NixOS/nixpkgs/pull/480686 is merged
|
||||
console.enable = true;
|
||||
|
||||
virtualisation.systemd-nspawn.options = [
|
||||
"--private-network"
|
||||
"--machine=${config.system.name}"
|
||||
"--bind-ro=/nix/store:/nix/store"
|
||||
|
||||
# systemd-nspawn does some cleverness to mount a procfs and sysfs in an
|
||||
# unprivileged container, see
|
||||
# <https://github.com/systemd/systemd/blob/v258.2/src/nspawn/nspawn.c#L4341-L4349>.
|
||||
# Unfortunately, this doesn't work in the Nix build sandbox as we do not
|
||||
# have permission to mount filesystems of type `sysfs` nor `procfs`.
|
||||
# Fortunately, the build sandbox does provide a `/proc` and `/sys` that
|
||||
# we can just forward onto the container.
|
||||
"--private-users=no"
|
||||
"--bind=/proc:/run/host/proc"
|
||||
"--bind=/sys:/run/host/sys"
|
||||
|
||||
# From `man systemd-nspawn`:
|
||||
# > Use --keep-unit and --register=no in combination to disable any
|
||||
# > kind of unit allocation or registration with systemd-machined.
|
||||
"--keep-unit"
|
||||
"--register=no"
|
||||
];
|
||||
|
||||
system.build.nspawn =
|
||||
let
|
||||
run-nspawn = pkgs.callPackage ./run-nspawn { };
|
||||
commandLineOptions = lib.cli.toCommandLineShellGNU { } {
|
||||
container-name = config.system.name;
|
||||
root-dir = cfg.rootDir;
|
||||
interfaces-json = builtins.toJSON (lib.attrValues cfg.allInterfaces);
|
||||
init = "${config.system.build.toplevel}/init";
|
||||
cmdline-json = builtins.toJSON cfg.cmdline;
|
||||
};
|
||||
in
|
||||
pkgs.writers.writeDashBin "run-${config.system.name}-nspawn" ''
|
||||
exec ${lib.getExe run-nspawn} ${commandLineOptions} ${lib.escapeShellArgs config.virtualisation.systemd-nspawn.options} "$@"
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ python3Packages, systemd }:
|
||||
|
||||
python3Packages.callPackage ./package.nix {
|
||||
# We want `pkgs.systemd`, *not* `python3Packages.systemd`.
|
||||
inherit systemd;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
buildPythonApplication,
|
||||
e2fsprogs,
|
||||
iproute2,
|
||||
lib,
|
||||
mypy,
|
||||
ruff,
|
||||
setuptools,
|
||||
systemd,
|
||||
}:
|
||||
|
||||
buildPythonApplication {
|
||||
pname = "run-nspawn";
|
||||
version = "1.0";
|
||||
pyproject = true;
|
||||
|
||||
src = ./src;
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace run_nspawn/__init__.py \
|
||||
--replace-fail "@ip@" "${lib.getExe' iproute2 "ip"}" \
|
||||
--replace-fail "@systemd-nspawn@" "${lib.getExe' systemd "systemd-nspawn"}" \
|
||||
--replace-fail "@chattr@" "${lib.getExe' e2fsprogs "chattr"}"
|
||||
'';
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
systemd
|
||||
iproute2
|
||||
];
|
||||
|
||||
doCheck = true;
|
||||
|
||||
nativeCheckInputs = [
|
||||
mypy
|
||||
ruff
|
||||
];
|
||||
|
||||
checkPhase = ''
|
||||
echo -e "\x1b[32m## run mypy\x1b[0m"
|
||||
mypy run_nspawn
|
||||
echo -e "\x1b[32m## run ruff check\x1b[0m"
|
||||
ruff check .
|
||||
echo -e "\x1b[32m## run ruff format\x1b[0m"
|
||||
ruff format --check --diff .
|
||||
'';
|
||||
|
||||
meta = {
|
||||
mainProgram = "run-nspawn";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
pkgs ? import ../../../../.. { },
|
||||
}:
|
||||
pkgs.callPackage ./default.nix { }
|
||||
@@ -0,0 +1,13 @@
|
||||
[build-system]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "run-nspawn"
|
||||
version = "1.0"
|
||||
|
||||
[project.scripts]
|
||||
run-nspawn = "run_nspawn:main"
|
||||
|
||||
[tool.setuptools.packages]
|
||||
find = {}
|
||||
@@ -0,0 +1,250 @@
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import fcntl
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import typing
|
||||
from pathlib import Path
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
# Install a SIGTERM handler so all our context managers get a chance to
|
||||
# clean up.
|
||||
signal.signal(signal.SIGTERM, lambda _signum, _frame: sys.exit(0))
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class Netns:
|
||||
name: str
|
||||
path: Path
|
||||
|
||||
|
||||
def run_ip(*args: str) -> None:
|
||||
subprocess.run(
|
||||
["@ip@", *args],
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def mk_netns(name: str) -> typing.Generator[Netns, None, None]:
|
||||
logger.info("creating netns %s", name)
|
||||
run_ip("netns", "add", name)
|
||||
try:
|
||||
yield Netns(name=name, path=Path("/run/netns") / name)
|
||||
finally:
|
||||
logger.info("deleting netns %s", name)
|
||||
run_ip("netns", "delete", name)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def vlan_lock(vlan: int) -> typing.Generator[None, None, None]:
|
||||
lockfile = Path(f"/run/nixos-nspawn/vlan-{vlan}.lock")
|
||||
lockfile.parent.mkdir(parents=True, exist_ok=True)
|
||||
with lockfile.open("w") as f:
|
||||
# Grab an exclusive lock.
|
||||
fcntl.flock(f, fcntl.LOCK_EX)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
# Release the exclusive lock.
|
||||
fcntl.flock(f, fcntl.LOCK_UN)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def ensure_vlan_bridge(vlan: int) -> typing.Generator[str, None, None]:
|
||||
"""
|
||||
Ensure a bridge for the given vlan exists, and create one if it does not.
|
||||
|
||||
Note that this bridge may get used by other containers, so we're careful
|
||||
to not delete it unless we're sure nobody else is using it.
|
||||
"""
|
||||
# These IP addresses correspond to the static IP assignment logic in
|
||||
# <nixos/lib/testing/network.nix>.
|
||||
ipv4_addr = f"192.168.{vlan}.254/24"
|
||||
ipv6_addr = f"2001:db8:{vlan}::fe/64"
|
||||
|
||||
bridge_name = f"br{vlan}"
|
||||
bridge_path = Path("/sys/class/net") / bridge_name
|
||||
try:
|
||||
# To avoid racing against other nspawn containers that also
|
||||
# need this vlan, grab an exclusive lock.
|
||||
with vlan_lock(vlan):
|
||||
if not bridge_path.exists():
|
||||
logger.info("creating bridge %s", bridge_name)
|
||||
run_ip("link", "add", bridge_name, "type", "bridge")
|
||||
run_ip("link", "set", bridge_name, "up")
|
||||
run_ip("addr", "add", ipv4_addr, "dev", bridge_name)
|
||||
run_ip("addr", "add", ipv6_addr, "dev", bridge_name)
|
||||
|
||||
yield bridge_name
|
||||
finally:
|
||||
# To avoid racing against other nspawn containers that also
|
||||
# releasing this vlan, grab an exclusive lock.
|
||||
with vlan_lock(vlan):
|
||||
if bridge_path.exists():
|
||||
child_intf_count = len(list((bridge_path / "brif").iterdir()))
|
||||
if child_intf_count == 0:
|
||||
logger.info("deleting bridge %s", bridge_name)
|
||||
run_ip("link", "delete", bridge_name)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def mk_veth(
|
||||
container_name: str,
|
||||
netns: Netns,
|
||||
container_intf_name: str,
|
||||
vlan: int,
|
||||
) -> typing.Generator[None, None, None]:
|
||||
host_intf_name = f"{container_name}-{container_intf_name}"
|
||||
with ensure_vlan_bridge(vlan) as bridge_name:
|
||||
logger.info("creating interface %s", host_intf_name)
|
||||
run_ip(
|
||||
"link",
|
||||
"add",
|
||||
host_intf_name,
|
||||
"type",
|
||||
"veth",
|
||||
"peer",
|
||||
"name",
|
||||
container_intf_name,
|
||||
"netns",
|
||||
netns.name,
|
||||
)
|
||||
try:
|
||||
run_ip("link", "set", host_intf_name, "master", bridge_name)
|
||||
run_ip("link", "set", host_intf_name, "up")
|
||||
yield
|
||||
finally:
|
||||
logger.info("deleting interface %s", host_intf_name)
|
||||
run_ip("link", "delete", host_intf_name)
|
||||
|
||||
|
||||
def run(
|
||||
container_name: str,
|
||||
root_dir_str: str,
|
||||
interfaces: dict,
|
||||
nspawn_options: list[str],
|
||||
init: str,
|
||||
cmdline: list[str],
|
||||
) -> None:
|
||||
logging.basicConfig(
|
||||
format=f"nixos-nspawn({container_name}): %(message)s",
|
||||
level=logging.WARNING,
|
||||
)
|
||||
|
||||
assert os.geteuid() == 0, (
|
||||
f"systemd-nspawn requires root to work. You are {os.geteuid()}"
|
||||
)
|
||||
|
||||
root_dir = Path(root_dir_str)
|
||||
|
||||
root_dir.mkdir(parents=True, exist_ok=True)
|
||||
root_dir.chmod(0o755)
|
||||
|
||||
with (
|
||||
mk_netns(f"nixos-nspawn-{container_name}") as netns,
|
||||
contextlib.ExitStack() as stack,
|
||||
):
|
||||
for interface in interfaces:
|
||||
stack.enter_context(
|
||||
mk_veth(
|
||||
container_name=container_name,
|
||||
netns=netns,
|
||||
container_intf_name=interface["name"],
|
||||
vlan=interface["vlan"],
|
||||
)
|
||||
)
|
||||
|
||||
def print_pid() -> None:
|
||||
print(
|
||||
f"systemd-nspawn's PID is {os.getpid()}",
|
||||
# Need to flush stdout before systemd-nspawn gets exec-ed.
|
||||
flush=True,
|
||||
)
|
||||
|
||||
cp = subprocess.Popen(
|
||||
[
|
||||
"@systemd-nspawn@",
|
||||
*nspawn_options,
|
||||
f"--directory={root_dir}",
|
||||
f"--network-namespace-path={netns.path}",
|
||||
init,
|
||||
*cmdline,
|
||||
],
|
||||
preexec_fn=print_pid,
|
||||
)
|
||||
|
||||
try:
|
||||
exit_code = cp.wait()
|
||||
finally:
|
||||
# If we get interrupted for any reason (most likely a SIGTERM),
|
||||
# be sure to kill our child process.
|
||||
cp.terminate()
|
||||
|
||||
# NixOS creates `/var/empty` with the immutable filesystem attribute [0].
|
||||
# This makes it difficult to clean up the machine's root directory
|
||||
# (which the test driver does to ensure tests start fresh).
|
||||
# We unset that bit here so others are less likely to run into this issue.
|
||||
# Note: this may cause issues on filesystems that don't support
|
||||
# "Linux file attributes". Please improve this if you run into this!
|
||||
#
|
||||
# [0]: https://github.com/NixOS/nixpkgs/blob/d1eff395720e1fe15838263642a2bc1dca1eea32/nixos/modules/system/activation/activation-script.nix#L281
|
||||
subprocess.run(
|
||||
[
|
||||
"@chattr@",
|
||||
"-i",
|
||||
root_dir / "var/empty",
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
import json
|
||||
|
||||
arg_parser = argparse.ArgumentParser()
|
||||
arg_parser.add_argument(
|
||||
"--container-name", required=True, help="Name of the container"
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--root-dir",
|
||||
required=True,
|
||||
help="Path to container root directory (overridable with RUN_NSPAWN_ROOT_DIR)",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--interfaces-json",
|
||||
dest="interfaces",
|
||||
type=json.loads,
|
||||
required=True,
|
||||
help="JSON-encoded list of interfaces, each with 'name' and 'vlan' fields",
|
||||
)
|
||||
arg_parser.add_argument("--init", required=True, help="Path to init binary")
|
||||
arg_parser.add_argument(
|
||||
"--cmdline-json",
|
||||
dest="cmdline",
|
||||
type=json.loads,
|
||||
default=[],
|
||||
help="JSON-encoded list of command line arguments to pass to init",
|
||||
)
|
||||
# Parse only known args to allow for extra args to be passed to systemd-nspawn.
|
||||
args, nspawn_options = arg_parser.parse_known_args()
|
||||
|
||||
run(
|
||||
container_name=args.container_name,
|
||||
root_dir_str=os.getenv("RUN_NSPAWN_ROOT_DIR", default=args.root_dir),
|
||||
interfaces=args.interfaces,
|
||||
nspawn_options=nspawn_options,
|
||||
init=args.init,
|
||||
cmdline=args.cmdline,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -365,6 +365,7 @@ in
|
||||
imports = [
|
||||
../profiles/qemu-guest.nix
|
||||
./disk-size-option.nix
|
||||
./guest-networking-options.nix
|
||||
(mkRenamedOptionModule
|
||||
[
|
||||
"virtualisation"
|
||||
@@ -679,57 +680,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.vlans = mkOption {
|
||||
type = types.listOf types.ints.unsigned;
|
||||
default = if config.virtualisation.interfaces == { } then [ 1 ] else [ ];
|
||||
defaultText = lib.literalExpression ''if config.virtualisation.interfaces == {} then [ 1 ] else [ ]'';
|
||||
example = [
|
||||
1
|
||||
2
|
||||
];
|
||||
description = ''
|
||||
Virtual networks to which the VM is connected. Each
|
||||
number «N» in this list causes
|
||||
the VM to have a virtual Ethernet interface attached to a
|
||||
separate virtual network on which it will be assigned IP
|
||||
address
|
||||
`192.168.«N».«M»`,
|
||||
where «M» is the index of this VM
|
||||
in the list of VMs.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.interfaces = mkOption {
|
||||
default = { };
|
||||
example = {
|
||||
enp1s0.vlan = 1;
|
||||
};
|
||||
description = ''
|
||||
Network interfaces to add to the VM.
|
||||
'';
|
||||
type =
|
||||
with types;
|
||||
attrsOf (submodule {
|
||||
options = {
|
||||
vlan = mkOption {
|
||||
type = types.ints.unsigned;
|
||||
description = ''
|
||||
VLAN to which the network interface is connected.
|
||||
'';
|
||||
};
|
||||
|
||||
assignIP = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Automatically assign an IP address to the network interface using the same scheme as
|
||||
virtualisation.vlans.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
virtualisation.writableStore = mkOption {
|
||||
type = types.bool;
|
||||
default = cfg.mountHostNixStore;
|
||||
@@ -752,20 +702,6 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
networking.primaryIPAddress = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = "Primary IP address used in /etc/hosts.";
|
||||
};
|
||||
|
||||
networking.primaryIPv6Address = mkOption {
|
||||
type = types.str;
|
||||
default = "";
|
||||
internal = true;
|
||||
description = "Primary IPv6 address used in /etc/hosts.";
|
||||
};
|
||||
|
||||
virtualisation.host.pkgs = mkOption {
|
||||
type = options.nixpkgs.pkgs.type;
|
||||
default = pkgs;
|
||||
|
||||
@@ -99,7 +99,6 @@ rec {
|
||||
(onFullSupported "nixos.tests.firewall")
|
||||
(onFullSupported "nixos.tests.fontconfig-default-fonts")
|
||||
(onFullSupported "nixos.tests.gitlab.gitlab")
|
||||
(onFullSupported "nixos.tests.gitlab.runner")
|
||||
(onFullSupported "nixos.tests.gnome")
|
||||
(onSystems [ "x86_64-linux" ] "nixos.tests.hibernate")
|
||||
(onFullSupported "nixos.tests.i3wm")
|
||||
|
||||
@@ -200,7 +200,7 @@ in
|
||||
activation-bashless-image = runTest ./activation/bashless-image.nix;
|
||||
activation-etc-overlay-immutable = runTest ./activation/etc-overlay-immutable.nix;
|
||||
activation-etc-overlay-mutable = runTest ./activation/etc-overlay-mutable.nix;
|
||||
activation-lib = pkgs.callPackage ../modules/system/activation/lib/test.nix { };
|
||||
activation-lib = pkgs.callPackage ../modules/system/activation/lib-test.nix { };
|
||||
activation-nix-channel = runTest ./activation/nix-channel.nix;
|
||||
activation-nixos-init = runTest ./activation/nixos-init.nix;
|
||||
activation-perlless = runTest ./activation/perlless.nix;
|
||||
|
||||
+23
-40
@@ -1,36 +1,4 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
legacyBotPolicyJSON = ''
|
||||
{
|
||||
"bots": [
|
||||
{
|
||||
"import": "(data)/bots/_deny-pathological.yaml"
|
||||
},
|
||||
{
|
||||
"import": "(data)/meta/ai-block-aggressive.yaml"
|
||||
},
|
||||
{
|
||||
"import": "(data)/crawlers/_allow-good.yaml"
|
||||
},
|
||||
{
|
||||
"import": "(data)/bots/aggressive-brazilian-scrapers.yaml"
|
||||
},
|
||||
{
|
||||
"import": "(data)/common/keep-internet-working.yaml"
|
||||
},
|
||||
{
|
||||
"name": "generic-browser",
|
||||
"user_agent_regex": "Mozilla|Opera",
|
||||
"action": "CHALLENGE"
|
||||
}
|
||||
],
|
||||
"dnsbl": false,
|
||||
"status_codes": {
|
||||
"CHALLENGE": 200,
|
||||
"DENY": 200
|
||||
}
|
||||
}'';
|
||||
in
|
||||
{
|
||||
name = "anubis";
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
@@ -54,7 +22,6 @@ in
|
||||
|
||||
services.anubis = {
|
||||
defaultOptions = {
|
||||
botPolicy = builtins.fromJSON legacyBotPolicyJSON;
|
||||
settings = {
|
||||
DIFFICULTY = 3;
|
||||
USER_DEFINED_DEFAULT = true;
|
||||
@@ -92,14 +59,29 @@ in
|
||||
};
|
||||
};
|
||||
|
||||
instances."botPolicy-default" = {
|
||||
botPolicy = null;
|
||||
instances."policy-default" = {
|
||||
settings = {
|
||||
TARGET = "http://localhost:8080";
|
||||
};
|
||||
};
|
||||
|
||||
instances."botPolicy-file" = {
|
||||
instances."policy-custom" = {
|
||||
policy = {
|
||||
extraBots = [
|
||||
{
|
||||
name = "custom-allow";
|
||||
user_agent_regex = "CustomBot/.*";
|
||||
action = "ALLOW";
|
||||
}
|
||||
];
|
||||
settings.dnsbl = false;
|
||||
};
|
||||
settings = {
|
||||
TARGET = "http://localhost:8080";
|
||||
};
|
||||
};
|
||||
|
||||
instances."policy-file" = {
|
||||
settings = {
|
||||
TARGET = "http://localhost:8080";
|
||||
POLICY_FNAME = "/etc/anubis-botPolicy.json";
|
||||
@@ -191,9 +173,10 @@ in
|
||||
machine.succeed('cat /run/current-system/etc/systemd/system/anubis.service | grep "DIFFICULTY=5"')
|
||||
machine.succeed('cat /run/current-system/etc/systemd/system/anubis-tcp.service | grep "DIFFICULTY=3"')
|
||||
|
||||
# Check correct BotPolicy settings are applied
|
||||
machine.succeed('cat /run/current-system/etc/systemd/system/anubis.service | grep "POLICY_FNAME=/nix/store"')
|
||||
machine.fail('cat /run/current-system/etc/systemd/system/anubis-botPolicy-default.service | grep "POLICY_FNAME="')
|
||||
machine.succeed('cat /run/current-system/etc/systemd/system/anubis-botPolicy-file.service | grep "POLICY_FNAME=/etc/anubis-botPolicy.json"')
|
||||
# Check correct policy settings are applied.
|
||||
machine.fail('cat /run/current-system/etc/systemd/system/anubis.service | grep "POLICY_FNAME="')
|
||||
machine.fail('cat /run/current-system/etc/systemd/system/anubis-policy-default.service | grep "POLICY_FNAME="')
|
||||
machine.succeed('cat /run/current-system/etc/systemd/system/anubis-policy-custom.service | grep "POLICY_FNAME=/nix/store"')
|
||||
machine.succeed('cat /run/current-system/etc/systemd/system/anubis-policy-file.service | grep "POLICY_FNAME=/etc/anubis-botPolicy.json"')
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ in
|
||||
name = "kanidm-provisioning-${kanidmPackage.version}";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ oddlama ];
|
||||
|
||||
_module.args.kanidmPackage = pkgs.lib.mkDefault pkgs.kanidmWithSecretProvisioning;
|
||||
_module.args.kanidmPackage = pkgs.lib.mkDefault pkgs.kanidmWithSecretProvisioning_1_7;
|
||||
|
||||
nodes.provision =
|
||||
{ pkgs, lib, ... }:
|
||||
|
||||
@@ -21,7 +21,7 @@ in
|
||||
oddlama
|
||||
];
|
||||
|
||||
_module.args.kanidmPackage = pkgs.lib.mkDefault pkgs.kanidm;
|
||||
_module.args.kanidmPackage = pkgs.lib.mkDefault pkgs.kanidm_1_7;
|
||||
|
||||
nodes.server =
|
||||
{ pkgs, ... }:
|
||||
|
||||
@@ -6,12 +6,13 @@ let
|
||||
evalConfig = import ../lib/eval-config.nix;
|
||||
|
||||
nixos = evalConfig {
|
||||
system = null;
|
||||
modules = [
|
||||
{
|
||||
system.stateVersion = "25.05";
|
||||
fileSystems."/".device = "/dev/null";
|
||||
boot.loader.grub.device = "nodev";
|
||||
nixpkgs.hostPlatform = pkgs.system;
|
||||
nixpkgs.hostPlatform = pkgs.stdenv.hostPlatform.system;
|
||||
virtualisation.vmVariant.networking.hostName = "vm";
|
||||
virtualisation.vmVariantWithBootLoader.networking.hostName = "vm-w-bl";
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,11 +6,11 @@
|
||||
|
||||
melpaBuild rec {
|
||||
pname = "ebuild-mode";
|
||||
version = "1.80";
|
||||
version = "1.81";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://gitweb.gentoo.org/proj/ebuild-mode.git/snapshot/ebuild-mode-${version}.tar.bz2";
|
||||
hash = "sha256-pQ177zp0UTk9Koq+yhgaGIeFziV7KFng+Z6sAZs7qzY=";
|
||||
hash = "sha256-b+59Ec+NOHvFgbFOmnsvGjnq392VR1JCsPx/ORSdffo=";
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -1,3 +1,4 @@
|
||||
import bisect
|
||||
import os
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
@@ -30,7 +31,7 @@ def add_entries(sources, targets, hashes):
|
||||
if path == target["@url"]:
|
||||
raise ValueError(f"Unexpected target path {path}")
|
||||
|
||||
hashes.append({"url": url, "hash": artefact["sha256sum"], "path": path})
|
||||
bisect.insort(hashes, {"url": url, "hash": artefact["sha256sum"], "path": path}, key=lambda e: e["url"])
|
||||
|
||||
|
||||
def add_libraries(
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
pkgs,
|
||||
}:
|
||||
let
|
||||
version = "0.0.27-unstable-2026-01-09";
|
||||
version = "0.0.27-unstable-2026-01-20";
|
||||
src = fetchFromGitHub {
|
||||
owner = "yetone";
|
||||
repo = "avante.nvim";
|
||||
rev = "e89eb79abf5754645e20aa6074da10ed20bba33c";
|
||||
hash = "sha256-jxbDBvaVtgC0L/MSyoZjGjBxvRUdNofRsiUHwntab7c=";
|
||||
rev = "08b202a5c5dc93959bfe7dc276adfcba84ecc5be";
|
||||
hash = "sha256-YDlxwAOimaTFo7mTICQBdb7EQCp8vrBnwjWwxmBImis=";
|
||||
};
|
||||
avante-nvim-lib = rustPlatform.buildRustPackage {
|
||||
pname = "avante-nvim-lib";
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
}:
|
||||
mkLibretroCore {
|
||||
core = "flycast";
|
||||
version = "0-unstable-2025-12-29";
|
||||
version = "0-unstable-2026-01-19";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "flyinghead";
|
||||
repo = "flycast";
|
||||
rev = "4886dcb1c20cd4a85627cc4970d9d01cdf1c2d7d";
|
||||
hash = "sha256-Lp0MCf8MbqfeSdp6qrWi+q1xgatKl+8HDbTSd5xuzLM=";
|
||||
rev = "f86e195017fb1595c2622bca3c95e88198194784";
|
||||
hash = "sha256-Cd3vFpB66Bymv/Zjzd4XO3qJn5vaSnkWV1i5IxtaXXc=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
}:
|
||||
mkLibretroCore {
|
||||
core = "genesis-plus-gx";
|
||||
version = "0-unstable-2025-12-21";
|
||||
version = "0-unstable-2026-01-16";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "libretro";
|
||||
repo = "Genesis-Plus-GX";
|
||||
rev = "7c5819b7bd0b84c3265ee7dfcd7b90210ed7d687";
|
||||
hash = "sha256-3YrRWxKk6Uci5MKS5lQYU+edrLdsFYIAR6pTPXwiy8c=";
|
||||
rev = "3f0f44787b3c9f51eaad3abfbeb86f345d6d8fb1";
|
||||
hash = "sha256-ZrJIZqkJC39vreiNPeEm764vDW42uv6kZb0rFo4bAXw=";
|
||||
};
|
||||
|
||||
meta = {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
qtmultimedia,
|
||||
qtscript,
|
||||
qtserialport,
|
||||
qtwebsockets,
|
||||
alsa-lib,
|
||||
ola,
|
||||
libftdi1,
|
||||
@@ -19,13 +20,13 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "qlcplus";
|
||||
version = "4.13.1";
|
||||
version = "5.0.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mcallegari";
|
||||
repo = "qlcplus";
|
||||
rev = "QLC+_${version}";
|
||||
sha256 = "sha256-AKmPxHOlMtea3q0NDULp3XfJ0JnYeF/iFUJw0dDOiio=";
|
||||
hash = "sha256-gEwcTIJhY78Ts0lUn4MVciV7sPIBkqlxPMa9I1nTHO0=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -38,6 +39,7 @@ mkDerivation rec {
|
||||
qtmultimedia
|
||||
qtscript
|
||||
qtserialport
|
||||
qtwebsockets
|
||||
alsa-lib
|
||||
ola
|
||||
libftdi1
|
||||
|
||||
@@ -833,13 +833,13 @@
|
||||
"vendorHash": "sha256-duHOqjy8AthXuDX63GO3myJ9TJmV0Ts1a8OsbSOGZWI="
|
||||
},
|
||||
"launchdarkly_launchdarkly": {
|
||||
"hash": "sha256-4vOAkZac3dpYdzZDk+vvqmr/S37q/Gl0HmOAFuDKyag=",
|
||||
"hash": "sha256-95dvJa6yyBiBVa2/SIUD7vb5jUgKZ2lPhsoBouvswVg=",
|
||||
"homepage": "https://registry.terraform.io/providers/launchdarkly/launchdarkly",
|
||||
"owner": "launchdarkly",
|
||||
"repo": "terraform-provider-launchdarkly",
|
||||
"rev": "v2.26.0",
|
||||
"rev": "v2.26.1",
|
||||
"spdx": "MPL-2.0",
|
||||
"vendorHash": "sha256-Y1L1nIOubhBN5vNIXY7miQgR9OzoTCS7QA55DEMwDSA="
|
||||
"vendorHash": "sha256-JRqLG+lM7emw8F0J2mVt4xHKvLG/TC/FNZiiXd0dKZY="
|
||||
},
|
||||
"linode_linode": {
|
||||
"hash": "sha256-/igrYgWTM4vujH2PFzXijVhHw0gQzLUwFZJd+RM0hSQ=",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"linux-canary": {
|
||||
"hash": "sha256-2o0SBMbtozibAIL7lHDJ2LfNjbDKY578PvcNdFs/AC4=",
|
||||
"url": "https://canary.dl2.discordapp.net/apps/linux/0.0.844/discord-canary-0.0.844.tar.gz",
|
||||
"version": "0.0.844"
|
||||
"hash": "sha256-jomLXlIr+ajJspmh/seNb48alPSuCw8ybYkfc0uAziE=",
|
||||
"url": "https://canary.dl2.discordapp.net/apps/linux/0.0.852/discord-canary-0.0.852.tar.gz",
|
||||
"version": "0.0.852"
|
||||
},
|
||||
"linux-development": {
|
||||
"hash": "sha256-EVkjWoqWl9Z+iHCLPOLu4PIUb2wC3HVcPVjOVz++IVw=",
|
||||
@@ -15,19 +15,19 @@
|
||||
"version": "0.0.172"
|
||||
},
|
||||
"linux-stable": {
|
||||
"hash": "sha256-/NfgHBXsUWYoDEVGz13GBU1ISpSdB5OmrjhSN25SBMg=",
|
||||
"url": "https://stable.dl2.discordapp.net/apps/linux/0.0.119/discord-0.0.119.tar.gz",
|
||||
"version": "0.0.119"
|
||||
"hash": "sha256-4rJ0l0zSoOz7L65sy3Gegcsb/nJGGFu6h5TGAb0fqUI=",
|
||||
"url": "https://stable.dl2.discordapp.net/apps/linux/0.0.120/discord-0.0.120.tar.gz",
|
||||
"version": "0.0.120"
|
||||
},
|
||||
"osx-canary": {
|
||||
"hash": "sha256-qh5+hCEQXivdugj5jzS+i1ftmyh6l2YEE63oS+qV2Go=",
|
||||
"url": "https://canary.dl2.discordapp.net/apps/osx/0.0.948/DiscordCanary.dmg",
|
||||
"version": "0.0.948"
|
||||
"hash": "sha256-ZzqakVB2Rkcq5zME2WnSCw1CLzpD3VDM/pu4nQ7rRNs=",
|
||||
"url": "https://canary.dl2.discordapp.net/apps/osx/0.0.956/DiscordCanary.dmg",
|
||||
"version": "0.0.956"
|
||||
},
|
||||
"osx-development": {
|
||||
"hash": "sha256-y840b3WlWnSK+22l7AoasQbDmbB+2LOzbxA13yJxrPA=",
|
||||
"url": "https://development.dl2.discordapp.net/apps/osx/0.0.106/DiscordDevelopment.dmg",
|
||||
"version": "0.0.106"
|
||||
"hash": "sha256-B1//zMlTv2+RWHfWZSaaU8ubVOwWob+EYjNdtFRwlgg=",
|
||||
"url": "https://development.dl2.discordapp.net/apps/osx/0.0.107/DiscordDevelopment.dmg",
|
||||
"version": "0.0.107"
|
||||
},
|
||||
"osx-ptb": {
|
||||
"hash": "sha256-tjWbvWOvSinVZDvJYFFcbmr+y7W5PmIr/alrS82ECBo=",
|
||||
@@ -35,8 +35,8 @@
|
||||
"version": "0.0.204"
|
||||
},
|
||||
"osx-stable": {
|
||||
"hash": "sha256-OjHYJNZlM/cOLM61qvoauzNl3f/GVPdJMsnM+kxc/38=",
|
||||
"url": "https://stable.dl2.discordapp.net/apps/osx/0.0.371/Discord.dmg",
|
||||
"version": "0.0.371"
|
||||
"hash": "sha256-PkZU/1GxPmfxq2qP/5gGU85EFYPI1V42iHfoy9x9fKI=",
|
||||
"url": "https://stable.dl2.discordapp.net/apps/osx/0.0.372/Discord.dmg",
|
||||
"version": "0.0.372"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,14 +435,14 @@ in
|
||||
|
||||
docker_29 =
|
||||
let
|
||||
version = "29.1.3";
|
||||
version = "29.1.5";
|
||||
in
|
||||
callPackage dockerGen {
|
||||
inherit version;
|
||||
cliRev = "v${version}";
|
||||
cliHash = "sha256-8VpFDYn9mRFv7BnHek2+HvIu6jNPYNC1asozJvRX/A4=";
|
||||
cliHash = "sha256-fg18lmJsMoy7lpL4hGkIhM0LKnhEY5nl5f0YuW8yg0A=";
|
||||
mobyRev = "docker-v${version}";
|
||||
mobyHash = "sha256-yB6FF4tzi6R+wH6U0JS8PMZGVRl1gWCY2Cjb/JR+62w=";
|
||||
mobyHash = "sha256-iUoqJT0lIiVh5WaHzlw71QXxc3sEsSpQpADb0KveXNQ=";
|
||||
runcRev = "v1.3.4";
|
||||
runcHash = "sha256-1IfY08sBoDpbLrwz1AKBRSTuCZyOgQzYPHTDUI6fOZ8=";
|
||||
containerdRev = "v2.2.0";
|
||||
|
||||
@@ -53,6 +53,12 @@
|
||||
buildInputs = [ alsa-lib ];
|
||||
};
|
||||
|
||||
# Force using the cmake backend. At least on Darwin, the build else gets confused and fails.
|
||||
aws-lc-sys = prev: {
|
||||
nativeBuildInputs = [ cmake ];
|
||||
env.AWS_LC_SYS_CMAKE_BUILDER = 1;
|
||||
};
|
||||
|
||||
cairo-rs = attrs: {
|
||||
buildInputs = [ cairo ];
|
||||
};
|
||||
|
||||
@@ -29,15 +29,15 @@
|
||||
},
|
||||
"beta": {
|
||||
"linux": {
|
||||
"version": "8.11.22-26.BETA",
|
||||
"version": "8.12.0-11.BETA",
|
||||
"sources": {
|
||||
"x86_64": {
|
||||
"url": "https://downloads.1password.com/linux/tar/beta/x86_64/1password-8.11.22-26.BETA.x64.tar.gz",
|
||||
"hash": "sha256-lkQypBqr1VX/+8yz5PhUULKG9ZpuXjeS/ZNLL1Qzdcs="
|
||||
"url": "https://downloads.1password.com/linux/tar/beta/x86_64/1password-8.12.0-11.BETA.x64.tar.gz",
|
||||
"hash": "sha256-0PDkZAqlY/afocvc/rcly/nwZeSSbXdRyXH57aVPUoQ="
|
||||
},
|
||||
"aarch64": {
|
||||
"url": "https://downloads.1password.com/linux/tar/beta/aarch64/1password-8.11.22-26.BETA.arm64.tar.gz",
|
||||
"hash": "sha256-1PrkmOWBenPvQIiHlq4RAKzItYLVj5DkGD38eGFDlHM="
|
||||
"url": "https://downloads.1password.com/linux/tar/beta/aarch64/1password-8.12.0-11.BETA.arm64.tar.gz",
|
||||
"hash": "sha256-0YDJKexCdOeU0/KPsJzI5rBUlbDEFW5N33LFXtDo3tg="
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "ali";
|
||||
version = "0.7.5";
|
||||
version = "0.8.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "nakabonne";
|
||||
repo = "ali";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-/pdHlI20IzSTX2pnsbxPiJiWmOCbp13eJWLi0Tcsueg=";
|
||||
hash = "sha256-iwuvWqDaaf/U8f4KDeq1gs+FlDoC11uDs+l2Z7Npd6M=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-YWx9K04kTMaI0FXebwRQVCt0nxIwZ6xlbtI2lk3qp0M=";
|
||||
vendorHash = "sha256-pRxkRY0MkQGnNhA/3CtT0ohKAPNx8QeyuD6bcacYHGI=";
|
||||
|
||||
meta = {
|
||||
description = "Generate HTTP load and plot the results in real-time";
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
enableDaemon ? false, # build amule daemon
|
||||
httpServer ? false, # build web interface for the daemon
|
||||
client ? false, # build amule remote gui
|
||||
mainProgram ? "amule",
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
stdenv,
|
||||
@@ -103,10 +104,10 @@ stdenv.mkDerivation rec {
|
||||
no adware or spyware as is often found in proprietary P2P
|
||||
applications.
|
||||
'';
|
||||
|
||||
homepage = "https://github.com/amule-project/amule";
|
||||
license = lib.licenses.gpl2Plus;
|
||||
maintainers = [ ];
|
||||
maintainers = with lib.maintainers; [ aciceri ];
|
||||
inherit mainProgram;
|
||||
platforms = lib.platforms.unix;
|
||||
# Undefined symbols for architecture arm64: "_FSFindFolder"
|
||||
broken = stdenv.hostPlatform.isDarwin;
|
||||
|
||||
@@ -95,7 +95,7 @@ let
|
||||
(with pkgs; [
|
||||
xorg.libxkbfile
|
||||
xorg.libxshmfence
|
||||
xcb-util-cursor-HEAD
|
||||
libxcb-cursor
|
||||
krb5
|
||||
zstd
|
||||
]);
|
||||
|
||||
@@ -13,13 +13,13 @@ let
|
||||
|
||||
pkg = buildGoModule (finalAttrs: {
|
||||
pname = "arduino-cli";
|
||||
version = "1.4.0";
|
||||
version = "1.4.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "arduino";
|
||||
repo = "arduino-cli";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-H7vccxDzJt0e/91PIV6Qg8nRD0beb/3g7AZ4uk2ebXU=";
|
||||
hash = "sha256-2m0V7yj6C7Lvlu9RaM54pbGKSwrek6WYuwH1yqYHdB0=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
@@ -31,7 +31,7 @@ let
|
||||
|
||||
subPackages = [ "." ];
|
||||
|
||||
vendorHash = "sha256-GPZLvEgL/2Ekfj58d8dsbc6e2hHB2zUapvFdIT43hhQ=";
|
||||
vendorHash = "sha256-5bkaHEzQ2gLV1epkScbCf1qv5XeuewLwqNcpPCSdbh4=";
|
||||
|
||||
postPatch =
|
||||
let
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "arti";
|
||||
version = "1.7.0";
|
||||
version = "1.9.0";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
domain = "gitlab.torproject.org";
|
||||
@@ -20,10 +20,10 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
owner = "core";
|
||||
repo = "arti";
|
||||
tag = "arti-v${finalAttrs.version}";
|
||||
hash = "sha256-4Vx5ATVdE8AoMWjDKKkwGOFVOwI0Qhyfr8MiAo+7MNw=";
|
||||
hash = "sha256-b5DWu38/iKwKcmp4BNgkeE5F522YRZZiev9gUZ/Rb1E=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-x1Pws9XbvwZqxJTJmPHQd6qbNLgkHxCK3YIZbRylk2M=";
|
||||
cargoHash = "sha256-SGxSZaY8//FHhySbarfgleafF5YEWJW/fUAwo3576NI=";
|
||||
|
||||
nativeBuildInputs = lib.optionals stdenv.hostPlatform.isLinux [ pkg-config ];
|
||||
|
||||
@@ -54,12 +54,13 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
checkFlags = [
|
||||
# problematic test that hangs the build
|
||||
"--skip=reload_cfg::test::watch_single_file"
|
||||
|
||||
# some of the cli tests attempt to validate that the filesystem and build
|
||||
# is securely configured, which is somewhat broken by the nix build sandbox
|
||||
"--skip=cli_tests"
|
||||
];
|
||||
|
||||
# some of the CLI tests attempt to validate that the filesystem and runtime
|
||||
# environment are securely configured, which breaks inside the nix build
|
||||
# sandbox. this does NOT affect downstream users of Arti.
|
||||
env.ARTI_FS_DISABLE_PERMISSION_CHECKS = 1;
|
||||
|
||||
nativeInstallCheckInputs = [
|
||||
versionCheckHook
|
||||
];
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "asusctl";
|
||||
version = "6.2.0";
|
||||
version = "6.3.1";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "asus-linux";
|
||||
repo = "asusctl";
|
||||
tag = version;
|
||||
hash = "sha256-frQbfCdK7bD6IAUa+MAOaRLhMrbdFRdHocQ0Z1tzsqE=";
|
||||
hash = "sha256-x3WKxjYrWYaLWDi52b3uQSYnr/Qunf6JYu4ikt4ajls=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-Z3JFp/qH3mD3Hy/kqSONOZ+syulgr+t0ZzFRvNN+Ayg=";
|
||||
cargoHash = "sha256-FyVbeHzwMr8UJ2OoVYVekXJFhus/ab7KwfGK4eaua6A=";
|
||||
|
||||
postPatch = ''
|
||||
files="
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "babl";
|
||||
version = "0.1.116";
|
||||
version = "0.1.120";
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
@@ -23,7 +23,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://download.gimp.org/pub/babl/${lib.versions.majorMinor finalAttrs.version}/babl-${finalAttrs.version}.tar.xz";
|
||||
hash = "sha256-UPrgaYZ8et4SWYiP8ePbhf7IbXCCUuU4W1pPOaeOxIM=";
|
||||
hash = "sha256-9HatFSAftO0MkMF0xSSx5CcczWmjdyQtamn834fOrMI=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
@@ -46,6 +46,9 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
mesonFlags = [
|
||||
"-Dprefix-dev=${placeholder "dev"}"
|
||||
# On Linux, this would be disabled by default but we have -Dauto_features=enabled.
|
||||
# Disable it on other platforms too, since I cannot test it there.
|
||||
"-Drelocatable=disabled"
|
||||
]
|
||||
++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
|
||||
# Docs are opt-out in native but opt-in in cross builds.
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
}:
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "base16-schemes";
|
||||
version = "0-unstable-2025-11-08";
|
||||
version = "0-unstable-2026-01-15";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "tinted-theming";
|
||||
repo = "schemes";
|
||||
rev = "4ac26dc99141c1b2a26eb7fefe46e22e07eec77c";
|
||||
hash = "sha256-pr+RtDs+3qo0v7ZXfcSdtP0PoDDPU9EHw2Oe5EUwWtQ=";
|
||||
rev = "43dd14f6466a782bd57419fdfb5f398c74d6ac53";
|
||||
hash = "sha256-AWTIYZ1tZab0YwAQwgt5yO4ucqZoc4iXX002Byy7pRY=";
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
lib,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
nix-update-script,
|
||||
stdenv,
|
||||
pkg-config,
|
||||
makeWrapper,
|
||||
@@ -13,16 +14,16 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "bilibili-tui";
|
||||
version = "1.0.6";
|
||||
version = "1.0.9";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "MareDevi";
|
||||
repo = "bilibili-tui";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-nWUFcKQgUNaiVU0zgSB8LTdvUruc8fovCAembQz5w3I=";
|
||||
hash = "sha256-LACNDpVhlYEgT3fN+Ff2MVipblUqPlqwOUpTLaXSCbk=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-KvJpMQuvZM/s3b4/Pzmeucb95KeuuUx4bz3sJsKyLc8=";
|
||||
cargoHash = "sha256-q3jRjmzQA64sZjVShoEmu1x2CFOAgBGgZYyTq7Lg4is=";
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ] ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [ pkg-config ];
|
||||
|
||||
@@ -41,6 +42,8 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
}
|
||||
'';
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Terminal user interface (TUI) client for Bilibili";
|
||||
homepage = "https://maredevi.moe/projects/bilibili-tui/";
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "butane";
|
||||
version = "0.25.1";
|
||||
version = "0.26.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "coreos";
|
||||
repo = "butane";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-HrLnXkaayCmMrvW79NSYrmI0ujfHtRwWmonkbvTXEXY=";
|
||||
hash = "sha256-htD/FecmBVUp0bmzDJpUNw8rVr9mheFwagUISFu8lJM=";
|
||||
};
|
||||
|
||||
vendorHash = null;
|
||||
|
||||
@@ -13,7 +13,7 @@ rustPlatform.buildRustPackage rec {
|
||||
src = fetchFromGitHub {
|
||||
owner = "nextest-rs";
|
||||
repo = "nextest";
|
||||
rev = "cargo-nextest-${version}";
|
||||
tag = "cargo-nextest-${version}";
|
||||
hash = "sha256-Ff9GibY6pm7+NbgAB8iNO+uj+uK1sxU+UkaiIS5BLEk=";
|
||||
};
|
||||
|
||||
@@ -33,7 +33,9 @@ rustPlatform.buildRustPackage rec {
|
||||
"cargo-nextest"
|
||||
];
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
passthru.updateScript = nix-update-script {
|
||||
extraArgs = [ "--version-regex=^cargo-nextest-([0-9.]+)$" ];
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "Next-generation test runner for Rust projects";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
fetchurl,
|
||||
libX11,
|
||||
bison,
|
||||
ksh,
|
||||
mksh,
|
||||
perl,
|
||||
libXinerama,
|
||||
libXt,
|
||||
@@ -33,15 +33,18 @@
|
||||
flex,
|
||||
libXpm,
|
||||
rpcsvc-proto,
|
||||
sessreg,
|
||||
pkg-config,
|
||||
lmdb,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "cde";
|
||||
version = "2.5.1";
|
||||
version = "2.5.3";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://sourceforge/cdesktopenv/cde-${version}.tar.gz";
|
||||
hash = "sha256-caslezz2kbljwApv5igDPH345PK2YqQUTi1YZgvM1Dw=";
|
||||
url = "mirror://sourceforge/cdesktopenv/cde-${finalAttrs.version}.tar.gz";
|
||||
hash = "sha256-K1jAjr8Ka7nUoyGRzSXiBPXYy6gbzKo2/HL1xKqXmFQ=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
@@ -62,7 +65,7 @@ stdenv.mkDerivation rec {
|
||||
done
|
||||
|
||||
substituteInPlace configure.ac \
|
||||
--replace "-I/usr/include/tirpc" "-I${libtirpc.dev}/include/tirpc"
|
||||
--replace-warn "-I/usr/include/tirpc" "-I${libtirpc.dev}/include/tirpc"
|
||||
|
||||
patchShebangs autogen.sh config.rpath contrib programs
|
||||
'';
|
||||
@@ -82,9 +85,11 @@ stdenv.mkDerivation rec {
|
||||
libXScrnSaver
|
||||
tcl
|
||||
libXaw
|
||||
ksh
|
||||
mksh
|
||||
libxcrypt
|
||||
libXpm
|
||||
sessreg
|
||||
lmdb
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
bison
|
||||
@@ -100,10 +105,15 @@ stdenv.mkDerivation rec {
|
||||
perl
|
||||
flex
|
||||
rpcsvc-proto
|
||||
pkg-config
|
||||
];
|
||||
|
||||
enableParallelBuilding = true;
|
||||
|
||||
# Can probably remove after next release
|
||||
# https://sourceforge.net/p/cdesktopenv/code/ci/f0154141b1f1501490bac8e0235214bf8f00f715/
|
||||
env.NIX_CFLAGS_COMPILE = "-std=gnu17";
|
||||
|
||||
preConfigure = ''
|
||||
export LOCALE_ARCHIVE="${glibcLocales}/lib/locale/locale-archive"
|
||||
'';
|
||||
@@ -123,4 +133,4 @@ stdenv.mkDerivation rec {
|
||||
maintainers = [ ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "cgif";
|
||||
version = "0.5.0";
|
||||
version = "0.5.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "dloebl";
|
||||
repo = "cgif";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-i8xngmVhRCGkczY3NzomLkXj+iqPb81lvLn6dXsByYs=";
|
||||
hash = "sha256-Vnm0YIMoU6gJCxSP28mqBtqZnfhmhmvaSp5DvZJqW/A=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -1,33 +1,46 @@
|
||||
{
|
||||
stdenv,
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
rustPlatform,
|
||||
openssl,
|
||||
pkg-config,
|
||||
alsa-lib,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "chess-tui";
|
||||
version = "2.0.0";
|
||||
version = "2.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "thomas-mauran";
|
||||
repo = "chess-tui";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-SIQoi/pnbS1TyX6iA8azo0nVfsCQd6ntn9VZCz/Zkgw=";
|
||||
hash = "sha256-g+rKib+ZoBa2ssYKgS0tg0xngurY1z3DbBZZEn/LJU4=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-aWj8ruu/Y/VCgvhAkWVfDDztmVzHsZix88JUAOYttmg=";
|
||||
cargoHash = "sha256-Brj+9AS0ZR/b188jkJa84WRHk0HtiKpMlyMUSLmzBfA=";
|
||||
|
||||
checkFlags = [
|
||||
# assertion failed: result.is_ok()
|
||||
"--skip=tests::test_config_create"
|
||||
];
|
||||
|
||||
buildInputs = [ openssl ];
|
||||
buildInputs = [
|
||||
openssl
|
||||
]
|
||||
# alsa-lib is required for the alsa-sys. alsa-lib does not compile on darwin
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [ alsa-lib ]
|
||||
# bindgenHook is required for coreaudio-sys on darwin
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ rustPlatform.bindgenHook ];
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
PKG_CONFIG_PATH = "${openssl.dev}/lib/pkgconfig";
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Chess TUI implementation in rust";
|
||||
homepage = "https://github.com/thomas-mauran/chess-tui";
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "cirrus-cli";
|
||||
version = "0.159.1";
|
||||
version = "0.160.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cirruslabs";
|
||||
repo = "cirrus-cli";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-Zf7muVwJQzye5YEeQtRbHQ2SmFFap7BMze9YuJv1ABU=";
|
||||
hash = "sha256-odD2ap2Z+Wsrz3XIDJrGyxbsrMvZBp3kQJ64LhIpc74=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-n2Bmx4EJ+L6+rlvfG/2FD4Ua9bG9GVcnvD+QPfQg/HE=";
|
||||
vendorHash = "sha256-zW0xX4E2Wr/liL2RMGiU1wpwFbeiuex1owWisysHJsc=";
|
||||
|
||||
ldflags = [
|
||||
"-X github.com/cirruslabs/cirrus-cli/internal/version.Version=v${version}"
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "cnquery";
|
||||
version = "12.18.0";
|
||||
version = "12.19.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mondoohq";
|
||||
repo = "cnquery";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-aDpWVujFSKTRDZW764LzNmqJkb61tfdLPN/JT81NrZs=";
|
||||
hash = "sha256-lFnXkBPokDO/eduWhg/lSqqjRhC8/5tGqkS/RZHhZnU=";
|
||||
};
|
||||
|
||||
subPackages = [ "apps/cnquery" ];
|
||||
|
||||
vendorHash = "sha256-OliliGBpFPPJnYZ3wQ2q7t+9bsiN5ik0FJrNGlVxivo=";
|
||||
vendorHash = "sha256-WnUCDiDfIC2Cl1LEpkZlT5tGFMaWb5htX8VFmJBEjbI=";
|
||||
|
||||
ldflags = [
|
||||
"-w"
|
||||
|
||||
@@ -9,17 +9,17 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "codeberg-cli";
|
||||
version = "0.5.1";
|
||||
version = "0.5.4";
|
||||
|
||||
src = fetchFromGitea {
|
||||
domain = "codeberg.org";
|
||||
owner = "Aviac";
|
||||
repo = "codeberg-cli";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-81435dgw7fy4igUN3TYNjRans8uRZ/6TQWBxu0benwU=";
|
||||
hash = "sha256-o+Jf9JKDGsnSVV8sJcJddZG+9DBn6DB4HfaxLxxwa+U=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-1E7UuDbJKrnhMQI6trk7nHkeywCPFg1021pQhRcb4kQ=";
|
||||
cargoHash = "sha256-HBVswxako/Djv8ayhEfgGVaFWblNn6ngtbQh9jNaxcQ=";
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
installShellFiles
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"codebuff": "^1.0.581"
|
||||
"codebuff": "^1.0.589"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
@@ -18,9 +18,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/codebuff": {
|
||||
"version": "1.0.581",
|
||||
"resolved": "https://registry.npmjs.org/codebuff/-/codebuff-1.0.581.tgz",
|
||||
"integrity": "sha512-3lMaeo/TqALXwPWwPvwaIGaVlJcz7cXisEvEGqG4qjOUIFPd+mpiZBw1nF64U67fSxkjvll1/JNKk/mZTEAVng==",
|
||||
"version": "1.0.589",
|
||||
"resolved": "https://registry.npmjs.org/codebuff/-/codebuff-1.0.589.tgz",
|
||||
"integrity": "sha512-e6Fxe49DgX9qx8itMEM7HBro73MhZZXUUYkbQh4+NBHQs9711bja1DN9PzqzKpluFJ3BmU/e67CG70uBrxmavA==",
|
||||
"cpu": [
|
||||
"x64",
|
||||
"arm64"
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
buildNpmPackage rec {
|
||||
pname = "codebuff";
|
||||
version = "1.0.581";
|
||||
version = "1.0.589";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://registry.npmjs.org/codebuff/-/codebuff-${version}.tgz";
|
||||
hash = "sha256-A5sEqkw9nm9ijyq7FT0vVNegbDl1LXQHI62dfdP/0WI=";
|
||||
hash = "sha256-kW8I+Aw87O21g56Gy5Z8R+Snuxqr78fHVTckuIp31hQ=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-CEoacNXow99r4i9cF2BUA5dNcgU1dCBc4dq0n0p7CBU=";
|
||||
npmDepsHash = "sha256-8+u7/1oQ19ZnA1EZrAgrwppliOZWPb+PJ22xHr6WFKE=";
|
||||
|
||||
postPatch = ''
|
||||
cp ${./package-lock.json} package-lock.json
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
cmake,
|
||||
pkg-config,
|
||||
boxed-cpp,
|
||||
cairo,
|
||||
freetype,
|
||||
fontconfig,
|
||||
libunicode,
|
||||
@@ -28,13 +29,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "contour";
|
||||
version = "0.6.1.7494";
|
||||
version = "0.6.2.8008";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "contour-terminal";
|
||||
repo = "contour";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-jgasZhdcJ+UF3VIl8HLcxBayvbA/dkaOG8UtANRgeP4=";
|
||||
hash = "sha256-xbJxV1q7+ddhnH0jDYzqVHwARCD0EyVh3POFRkl4d1Q=";
|
||||
};
|
||||
|
||||
patches = lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
@@ -59,6 +60,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
buildInputs = [
|
||||
boxed-cpp
|
||||
cairo
|
||||
fontconfig
|
||||
freetype
|
||||
libunicode
|
||||
@@ -79,8 +81,6 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
darwin.libutil
|
||||
];
|
||||
|
||||
cmakeFlags = [ "-DCONTOUR_QT_VERSION=6" ];
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $out/nix-support $terminfo/share
|
||||
''
|
||||
|
||||
@@ -60,7 +60,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
meta = {
|
||||
description = "Schrodinger-developed 2D Coordinate Generation";
|
||||
homepage = "https://github.com/schrodinger/coordgenlibs";
|
||||
changelog = "https://github.com/schrodinger/coordgenlibs/releases/tag/${finalAttrs.version}";
|
||||
changelog = "https://github.com/schrodinger/coordgenlibs/releases/tag/v${finalAttrs.version}";
|
||||
maintainers = [ lib.maintainers.rmcgibbo ];
|
||||
license = lib.licenses.bsd3;
|
||||
};
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "coroot-node-agent";
|
||||
version = "1.27.2";
|
||||
version = "1.27.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "coroot";
|
||||
repo = "coroot-node-agent";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-bA23qnC94hrmyQWR5kAKR27wzs55AJPC3Ix/l/9YCEY=";
|
||||
hash = "sha256-uIj74Su2ICB5v/khMgCJXps+HQUT67U6kI06QzNs+nc=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-jMR/ylMEgNDOn5mDkJU38h9h2rinCX7/jtOyjDos5Qc=";
|
||||
vendorHash = "sha256-adrXNMdR20K+DLexLebvjgcQFV9XLqYdHZW5hg/Zk8w=";
|
||||
|
||||
buildInputs = [ systemdLibs ];
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
};
|
||||
|
||||
meta = {
|
||||
changelog = "https://github.com/cowsql/cowsql/releases/tag/${finalAttrs.version}";
|
||||
changelog = "https://github.com/cowsql/cowsql/releases/tag/v${finalAttrs.version}";
|
||||
description = "Embeddable, replicated and fault tolerant SQL engine";
|
||||
homepage = "https://github.com/cowsql/cowsql";
|
||||
license = lib.licenses.lgpl3Only;
|
||||
|
||||
@@ -8,23 +8,25 @@
|
||||
nix-update-script,
|
||||
withServer ? true,
|
||||
}:
|
||||
let
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "cup-docker";
|
||||
version = "3.4.3";
|
||||
version = "3.5.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "sergi0g";
|
||||
repo = "cup";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-RRhUSL9TR7qr93F5+fyhGW7j6VTs+yVvpni/JHmC5os=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-l7TQwCzQNwrsM+xRcRcQaxIsnd8SVzrqEMwIoZGVBR0=";
|
||||
};
|
||||
web = stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "${pname}-web";
|
||||
inherit version src;
|
||||
|
||||
web = stdenvNoCC.mkDerivation (finalAttrsWeb: {
|
||||
pname = "${finalAttrs.pname}-web";
|
||||
inherit (finalAttrs) version src;
|
||||
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [
|
||||
"GIT_PROXY_COMMAND"
|
||||
"SOCKS_SERVER"
|
||||
];
|
||||
sourceRoot = "${finalAttrs.src.name}/web";
|
||||
sourceRoot = "${finalAttrsWeb.src.name}/web";
|
||||
nativeBuildInputs = [
|
||||
bun
|
||||
nodejs-slim_latest
|
||||
@@ -47,17 +49,10 @@ let
|
||||
cp -R ./dist $out
|
||||
runHook postInstall
|
||||
'';
|
||||
outputHash = "sha256-Ac1PJYmTQv9XrmhmF1p77vdXh8252hz0CUKxJA+VQR4=";
|
||||
outputHash = "sha256-uLsWppRabaI7JSHYf3YsEvf0Y36kU/iuNXnDXd+6AXY=";
|
||||
outputHashAlgo = "sha256";
|
||||
outputHashMode = "recursive";
|
||||
});
|
||||
in
|
||||
rustPlatform.buildRustPackage {
|
||||
inherit
|
||||
src
|
||||
version
|
||||
pname
|
||||
;
|
||||
|
||||
cargoHash = "sha256-1VSbv6lDRRLZIu7hYrAqzQmvxcuhnPU0rcWfg7Upcm4=";
|
||||
|
||||
@@ -70,11 +65,10 @@ rustPlatform.buildRustPackage {
|
||||
];
|
||||
|
||||
preConfigure = lib.optionalString withServer ''
|
||||
cp -r ${web}/dist src/static
|
||||
cp -r ${finalAttrs.web}/dist src/static
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
inherit web;
|
||||
updateScript = nix-update-script {
|
||||
extraArgs = [
|
||||
"--subpackage"
|
||||
@@ -94,4 +88,4 @@ rustPlatform.buildRustPackage {
|
||||
kuflierl
|
||||
];
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -2,28 +2,41 @@
|
||||
lib,
|
||||
buildGoModule,
|
||||
fetchFromGitHub,
|
||||
nix-update-script,
|
||||
|
||||
# testing
|
||||
sqlite,
|
||||
}:
|
||||
|
||||
buildGoModule rec {
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "dbmate";
|
||||
version = "2.28.0";
|
||||
version = "2.29.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "amacneil";
|
||||
repo = "dbmate";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-DQTeLqlZmzfTQoJBTFTX8x3iplkmrl1cplDQQcCGCZM=";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-H/HBDM2uBRrlgetU2S9ZS1c6//Le+DlrYlnnJpTs3XM=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-Js0hiRt6l3ur7+pfeYa35C17gr77NHvapaSrgF9cP8c=";
|
||||
vendorHash = "sha256-wfcVb8fqnpT8smKuL6SPANAK86tLXglhQPZCA4G8P9E=";
|
||||
|
||||
doCheck = false;
|
||||
tags = [ "fts5" ];
|
||||
|
||||
nativeCheckInputs = [
|
||||
sqlite
|
||||
];
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Database migration tool";
|
||||
mainProgram = "dbmate";
|
||||
homepage = "https://github.com/amacneil/dbmate";
|
||||
changelog = "https://github.com/amacneil/dbmate/releases/tag/v${version}";
|
||||
changelog = "https://github.com/amacneil/dbmate/releases/tag/${finalAttrs.src.tag}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
sarahec
|
||||
];
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,16 +3,17 @@
|
||||
buildGoModule,
|
||||
fetchFromGitHub,
|
||||
stdenv,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
buildGoModule rec {
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "delve";
|
||||
version = "1.26.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "go-delve";
|
||||
repo = "delve";
|
||||
rev = "v${version}";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-tFd8g866nRSNUVNz+6SM6YLl4ys3AUP3c8eT1kWbjKY=";
|
||||
};
|
||||
|
||||
@@ -24,6 +25,11 @@ buildGoModule rec {
|
||||
|
||||
subPackages = [ "cmd/dlv" ];
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
"-w"
|
||||
];
|
||||
|
||||
hardeningDisable = [ "fortify" ];
|
||||
|
||||
preCheck = ''
|
||||
@@ -44,11 +50,17 @@ buildGoModule rec {
|
||||
ln $out/bin/dlv $out/bin/dlv-dap
|
||||
'';
|
||||
|
||||
# delve doesn't support --version
|
||||
doInstallCheck = false;
|
||||
|
||||
passthru.updateScript = nix-update-script { };
|
||||
|
||||
meta = {
|
||||
description = "Debugger for the Go programming language";
|
||||
homepage = "https://github.com/go-delve/delve";
|
||||
changelog = "https://github.com/go-delve/delve/blob/v${finalAttrs.version}/CHANGELOG.md";
|
||||
maintainers = with lib.maintainers; [ vdemeester ];
|
||||
license = lib.licenses.mit;
|
||||
mainProgram = "dlv";
|
||||
};
|
||||
}
|
||||
})
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "dnscontrol";
|
||||
version = "4.30.0";
|
||||
version = "4.31.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "StackExchange";
|
||||
repo = "dnscontrol";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-SLcOG42Pd0RgDT98qNgceovDYbBvF0N7/ItkjBlEtLY=";
|
||||
hash = "sha256-8Pb/njUjiyUQZA3UnZ+4INJBnmXCo+F7+BhCDt1hJGQ=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-OsBVyWCPoVKBXmE/NH3r7KUH4TFCNkKu3LGJlW7dNqI=";
|
||||
vendorHash = "sha256-GMzLaV3LQNa4K111P6DLG28KAAgj9AHyPua4XSih14k=";
|
||||
|
||||
nativeBuildInputs = [ installShellFiles ];
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@ let
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "dnsmasq";
|
||||
version = "2.91";
|
||||
version = "2.92";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://www.thekelleys.org.uk/dnsmasq/${pname}-${version}.tar.xz";
|
||||
hash = "sha256-9iJoKEizNnetsratCCZGGKKuCgHaSGqT/YzZEYaz0VM=";
|
||||
hash = "sha256-S/UMLBAY+fvCYDffUbkOzqDLc9RhYoRnY7kt8NbDpFg=";
|
||||
};
|
||||
|
||||
postPatch = lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
buildGoModule,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "docui";
|
||||
version = "2.0.4";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "skanehira";
|
||||
repo = "docui";
|
||||
rev = version;
|
||||
hash = "sha256-tHv1caNGiWC9Dc/qR4ij9xGM1lotT0KyrpJpdBsHyks=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-5xQ5MmGpyzVh4gXZAhCY16iVw8zbCMzMA5IOsPdn7b0=";
|
||||
|
||||
meta = {
|
||||
description = "TUI Client for Docker";
|
||||
homepage = "https://github.com/skanehira/docui";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ aethelz ];
|
||||
broken = stdenv.hostPlatform.isDarwin;
|
||||
mainProgram = "docui";
|
||||
};
|
||||
}
|
||||
@@ -8,18 +8,18 @@
|
||||
|
||||
php.buildComposerProject2 (finalAttrs: {
|
||||
pname = "drupal";
|
||||
version = "11.3.1";
|
||||
version = "11.3.2";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
domain = "git.drupalcode.org";
|
||||
owner = "project";
|
||||
repo = "drupal";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-dVCDIKqLbYHlVwv5wveXG0oHc2g3Zl6J6LG1/e8IIZw=";
|
||||
hash = "sha256-RrBnVDjB6aKW6btmX604saXfPKo18oRka+SdlNmFqUo=";
|
||||
};
|
||||
|
||||
composerNoPlugins = false;
|
||||
vendorHash = "sha256-7FwwkPTKc/miStdHv1wfLoZhV4Gku1KwNgSlWdpPG8g=";
|
||||
vendorHash = "sha256-c3pqPnyeuSqpMhh1an1NAnDC+IyeRVUT+dCN19/nrMQ=";
|
||||
|
||||
passthru = {
|
||||
tests = {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
}:
|
||||
let
|
||||
pname = "e1s";
|
||||
version = "1.0.52";
|
||||
version = "1.0.53";
|
||||
in
|
||||
buildGoModule {
|
||||
inherit pname version;
|
||||
@@ -14,7 +14,7 @@ buildGoModule {
|
||||
owner = "keidarcy";
|
||||
repo = "e1s";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-ObqCd27gMG1WWqAObZZP1rGLJuh8weCdC0zrLfoPwMo=";
|
||||
hash = "sha256-Cy/aZVO6xM1oCeyT6x1O+otbUZ5lS90fl3iZzkf02QM=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-8z2RVT2W8TLXdZBAmi/2fu63pijVgzqSvF9xpGexlQ0=";
|
||||
|
||||
@@ -10,18 +10,18 @@
|
||||
}:
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "eas-cli";
|
||||
version = "16.23.1";
|
||||
version = "16.28.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "expo";
|
||||
repo = "eas-cli";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-hMUDtl5lMAZzlvPdzO7J3JTw0B5/fjssuqQlg1MUO3w=";
|
||||
hash = "sha256-/1E26CDD+vXR6/v9zOFOcJEuU/evUSVovQwnuyoV4SA=";
|
||||
};
|
||||
|
||||
yarnOfflineCache = fetchYarnDeps {
|
||||
yarnLock = finalAttrs.src + "/yarn.lock"; # Point to the root lockfile
|
||||
hash = "sha256-ybctj6TgW9JluDIsSaNm18wUXSBPuIT45te5HoQuz5s=";
|
||||
hash = "sha256-W2FuU4J28/qtXUa+eqirpc7bjRdL1fk6mgGxR50icYI=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -63,7 +63,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
meta = {
|
||||
description = "Fast and effective C++ file optimizer";
|
||||
homepage = "https://github.com/fhanau/Efficient-Compression-Tool";
|
||||
changelog = "https://github.com/fhanau/Efficient-Compression-Tool/releases/tag/${finalAttrs.version}";
|
||||
changelog = "https://github.com/fhanau/Efficient-Compression-Tool/releases/tag/v${finalAttrs.version}";
|
||||
license = lib.licenses.asl20;
|
||||
maintainers = with lib.maintainers; [
|
||||
jwillikers
|
||||
|
||||
@@ -28,13 +28,13 @@ assert blas.isILP64 == scalapack.isILP64;
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "elpa";
|
||||
version = "2025.06.001";
|
||||
version = "2025.06.002";
|
||||
|
||||
passthru = { inherit (blas) isILP64; };
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://elpa.mpcdf.mpg.de/software/tarball-archive/Releases/${version}/elpa-${version}.tar.gz";
|
||||
sha256 = "sha256-/usf6hq0qGcLjTJAdl7wragoBi737JtzXuy6KEhRXJQ=";
|
||||
sha256 = "sha256-3jGAwG4rDbtWk56ErRpf0WhEZb04rSGWeS0PQCiTf9o=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
}:
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "embellish";
|
||||
version = "0.5.1";
|
||||
version = "0.6.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "getnf";
|
||||
repo = "embellish";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-Db7/vo9LVE7IeFFHx/BKs+qxzsvuB+6ZLRb7A1NHrxQ=";
|
||||
hash = "sha256-2WPOXrEhnFP3NHE+MksREYlIoGN8AJE7Y2aw3ObVHeM=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "fheroes2";
|
||||
version = "1.1.11";
|
||||
version = "1.1.13";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ihhub";
|
||||
repo = "fheroes2";
|
||||
rev = version;
|
||||
hash = "sha256-U8iJAhubMHGPXNph+kWhMzRDbh3e4bikgQKbPPeKqV8=";
|
||||
hash = "sha256-ct58Rkc6ORXldINQZVzMuObMl0BMk6QG88oU4tT0WcE=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ imagemagick ];
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "flake-edit";
|
||||
version = "0.3.1";
|
||||
version = "0.3.3";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "a-kenji";
|
||||
repo = "flake-edit";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-Ptg/Wt8H6vOvk/V6juDmFd6Vzu/F3LzxDIGObuwySLA=";
|
||||
hash = "sha256-CDz7iDOPearlxsqLuAuG+cmKneFavxJmdCbnWwEIvcU=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-5i3wll3CdrRbwN8zsD4MQg62hvsMPESMW4YrtjPeySw=";
|
||||
cargoHash = "sha256-IvBrJBSAMLfqefyUnS3Ex+JvHJAWJtVtkBVp2kFvA4s=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
installShellFiles
|
||||
|
||||
@@ -7,16 +7,16 @@
|
||||
}:
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "framework-tool-tui";
|
||||
version = "0.7.3";
|
||||
version = "0.7.6";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "grouzen";
|
||||
repo = "framework-tool-tui";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-+m92Q5rfINS/TDAXpHDpwJPyV8kGrdS4y72DWw9NLe0=";
|
||||
hash = "sha256-reIsJK2bGuMf83SmjCVu9PdUrd4zilCxpvbZllnU6vo=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-feA+Jn3ldq6pJe/xFqBAaemNcT0Kjfl61IWIXKHHp9o=";
|
||||
cargoHash = "sha256-E2lVpu+sI/Bf1YwqCbwg3pr15kfo4DUddwI+5/Dwh40=";
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ udev ];
|
||||
|
||||
@@ -70,13 +70,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "freerdp";
|
||||
version = "3.20.2";
|
||||
version = "3.21.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "FreeRDP";
|
||||
repo = "FreeRDP";
|
||||
rev = finalAttrs.version;
|
||||
hash = "sha256-IcEWlNh0AI3Vkqf2FzQYOIq64J6iWJxWlUfYkcBpGUU=";
|
||||
hash = "sha256-oIws2HO2usOCtVDe6OTIdIDHYgb9tBIEctvCW6/Woxc=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -20,14 +20,13 @@ let
|
||||
in
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "freetube";
|
||||
version = "0.23.12-unstable-2026-01-15";
|
||||
version = "0.23.13";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "FreeTubeApp";
|
||||
repo = "FreeTube";
|
||||
# tag = "v${finalAttrs.version}-beta";
|
||||
rev = "e110a4b603e0f5f275d210aea005698a0d4b26ad";
|
||||
hash = "sha256-kq6twf7ce2987iHtwikPzolzzbxr1xcoirqUGpPG4V8=";
|
||||
tag = "v${finalAttrs.version}-beta";
|
||||
hash = "sha256-vnqrl/2hxL0RQbLHkgRntyTRSWmhMM7hOi31r4pKCgs=";
|
||||
};
|
||||
|
||||
# Darwin requires writable Electron dist
|
||||
@@ -50,7 +49,7 @@ stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
|
||||
yarnOfflineCache = fetchYarnDeps {
|
||||
yarnLock = "${finalAttrs.src}/yarn.lock";
|
||||
hash = "sha256-E6D2Uo06MAcnOKy00e5JoLdKQOeGVr7y7Lu6rZ1F82M=";
|
||||
hash = "sha256-sM9CkDnATSEUf/uuUyT4JuRmjzwa1WzIyNYEw69MPtU=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
diff --git a/_scripts/ebuilder.config.mjs b/_scripts/ebuilder.config.mjs
|
||||
index 55e72b227..d218f5ac4 100644
|
||||
--- a/_scripts/ebuilder.config.mjs
|
||||
+++ b/_scripts/ebuilder.config.mjs
|
||||
@@ -2,6 +2,8 @@ import packageDetails from '../package.json' with { type: 'json' }
|
||||
diff --git a/_scripts/ebuilder.config.js b/_scripts/ebuilder.config.js
|
||||
index 14d0d9df1..c5fc569c8 100644
|
||||
--- a/_scripts/ebuilder.config.js
|
||||
+++ b/_scripts/ebuilder.config.js
|
||||
@@ -1,6 +1,8 @@
|
||||
const { name, productName } = require('../package.json')
|
||||
|
||||
/** @type {import('electron-builder').Configuration} */
|
||||
export default {
|
||||
const config = {
|
||||
+ electronVersion: "@electron-version@",
|
||||
+ electronDist: "electron-dist",
|
||||
appId: `io.freetubeapp.${packageDetails.name}`,
|
||||
appId: `io.freetubeapp.${name}`,
|
||||
copyright: 'Copyleft © 2020-2025 freetubeapp@protonmail.com',
|
||||
// asar: false,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
let
|
||||
pname = "gallery-dl";
|
||||
version = "1.31.2";
|
||||
version = "1.31.3";
|
||||
in
|
||||
python3Packages.buildPythonApplication {
|
||||
inherit pname version;
|
||||
@@ -18,7 +18,7 @@ python3Packages.buildPythonApplication {
|
||||
owner = "mikf";
|
||||
repo = "gallery-dl";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-cKgfIJFSlUmZa3ovInI98Yw29QurXNAy7J1dUSPAUfQ=";
|
||||
hash = "sha256-vheQA67lPeYt7wly/4AbiReDx9ZlUbgqxT5YTxI0gVo=";
|
||||
};
|
||||
|
||||
build-system = [ python3Packages.setuptools ];
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
pkg-config,
|
||||
poppler,
|
||||
proj,
|
||||
python3,
|
||||
python3Packages,
|
||||
qhull,
|
||||
rav1e,
|
||||
sqlite,
|
||||
@@ -98,8 +98,8 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
doxygen
|
||||
graphviz
|
||||
pkg-config
|
||||
python3.pkgs.setuptools
|
||||
python3.pkgs.wrapPython
|
||||
python3Packages.setuptools
|
||||
python3Packages.wrapPython
|
||||
swig
|
||||
]
|
||||
++ lib.optionals useJava [
|
||||
@@ -202,8 +202,8 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
libwebp
|
||||
zlib
|
||||
zstd
|
||||
python3
|
||||
python3.pkgs.numpy
|
||||
python3Packages.python
|
||||
python3Packages.numpy
|
||||
]
|
||||
++ tileDbDeps
|
||||
++ libAvifDeps
|
||||
@@ -219,7 +219,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
++ darwinDeps
|
||||
++ nonDarwinDeps;
|
||||
|
||||
pythonPath = [ python3.pkgs.numpy ];
|
||||
pythonPath = [ python3Packages.numpy ];
|
||||
postInstall = ''
|
||||
wrapPythonProgramsIn "$out/bin" "$out $pythonPath"
|
||||
''
|
||||
@@ -238,14 +238,14 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
pushd autotest
|
||||
|
||||
export HOME=$(mktemp -d)
|
||||
export PYTHONPATH="$out/${python3.sitePackages}:$PYTHONPATH"
|
||||
export PYTHONPATH="$out/${python3Packages.python.sitePackages}:$PYTHONPATH"
|
||||
export GDAL_DOWNLOAD_TEST_DATA=OFF
|
||||
# allows to skip tests that fail because of file handle leak
|
||||
# the issue was not investigated
|
||||
# https://github.com/OSGeo/gdal/blob/v3.9.0/autotest/gdrivers/bag.py#L54
|
||||
export CI=1
|
||||
'';
|
||||
nativeInstallCheckInputs = with python3.pkgs; [
|
||||
nativeInstallCheckInputs = with python3Packages; [
|
||||
pytestCheckHook
|
||||
pytest-benchmark
|
||||
pytest-env
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user