Compare commits

..

1 Commits

Author SHA1 Message Date
Jan Tojnar
460226e12c nixos/ibus: Do not force ibus input method module on GTK
The environment variable is meant for debugging and GTK should already choose the correct input method module automatically. For example, GTK 4 will use the `ibus` module on X11 and `wayland` module on Wayland.

It was introduced in f222abea44.

Other distros like [Ubuntu back in 2020](https://discourse.ubuntu.com/t/ibus-no-more-gtk-im-module-ibus/17727) recognised that setting this was not beneficial and instead lead to more issues, e.g. crashes in ibus.
2026-09-28 13:39:38 +02:00
2495 changed files with 45148 additions and 55472 deletions

View File

@@ -130,7 +130,7 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { default: checkCommitMessages } = await import('${{ github.workspace }}/trusted/ci/github-script/lint-commits.ts')
const { default: checkCommitMessages } = await import('${{ github.workspace }}/trusted/ci/github-script/lint-commits.js')
await checkCommitMessages({
github,

View File

@@ -38,8 +38,8 @@ jobs:
TARGET_SHA: ${{ inputs.targetSha }}
with:
script: |
const { classify } = await import('${{ github.workspace }}/ci/github-script/supportedBranches.ts')
const { default: supportedSystems } = await import('${{ github.workspace }}/ci/github-script/supportedSystems.ts')
const { classify } = await import('${{ github.workspace }}/ci/github-script/supportedBranches.js')
const { default: supportedSystems } = await import('${{ github.workspace }}/ci/github-script/supportedSystems.js')
const baseBranch = (
context.payload.merge_group?.base_ref ??

View File

@@ -64,8 +64,8 @@ jobs:
'.github/workflows/test.yml',
'ci/github-script/package.json',
'ci/github-script/package-lock.json',
'ci/github-script/supportedBranches.ts',
'ci/github-script/supportedSystems.ts',
'ci/github-script/supportedBranches.js',
'ci/github-script/supportedSystems.js',
'ci/pinned.json',
'pkgs/top-level/release-supported-systems.json',
].includes(file))) core.setOutput('merge-group', true)
@@ -82,8 +82,8 @@ jobs:
'ci/github-script/bot.js',
'ci/github-script/check-target-branch.ts',
'ci/github-script/commits.ts',
'ci/github-script/get-pr-commit-details.ts',
'ci/github-script/lint-commits.ts',
'ci/github-script/get-pr-commit-details.js',
'ci/github-script/lint-commits.js',
'ci/github-script/manual-file-edits.ts',
'ci/github-script/merge.js',
'ci/github-script/package.json',
@@ -91,9 +91,9 @@ jobs:
'ci/github-script/prepare.js',
'ci/github-script/reminders.ts',
'ci/github-script/reviewers.js',
'ci/github-script/reviews.ts',
'ci/github-script/supportedBranches.ts',
'ci/github-script/supportedSystems.ts',
'ci/github-script/reviews.js',
'ci/github-script/supportedBranches.js',
'ci/github-script/supportedSystems.js',
'ci/github-script/withRateLimit.js',
'ci/pinned.json',
'pkgs/top-level/release-supported-systems.json',

View File

@@ -444,9 +444,9 @@ nixos/tests/forgejo.nix @adamcstephens @bendlas @christoph-heiss @
/doc/hooks/zig.section.md @RossComputerGuy
# Buildbot
nixos/modules/services/continuous-integration/buildbot @Mic92
nixos/tests/buildbot.nix @Mic92
pkgs/development/tools/continuous-integration/buildbot @Mic92
nixos/modules/services/continuous-integration/buildbot @Mic92 @zowoq
nixos/tests/buildbot.nix @Mic92 @zowoq
pkgs/development/tools/continuous-integration/buildbot @Mic92 @zowoq
# Pretix
pkgs/by-name/pr/pretix/ @mweinelt

View File

@@ -48,7 +48,7 @@ To ensure security and a focused utility, the bot adheres to specific limitation
- approved by a [committer][@NixOS/nixpkgs-committers].
- backported via label.
- opened by a [committer][@NixOS/nixpkgs-committers].
- opened by [@r-ryantm](https://nixos.github.io/nixpkgs-update/r-ryantm/).
- opened by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/).
- The user attempting to merge is a member of [@NixOS/nixpkgs-maintainers].
- The user attempting to merge is a maintainer of all packages touched by the PR.
- No [committer][@NixOS/nixpkgs-committers] has an outstanding "changes requested" review.
@@ -104,7 +104,7 @@ For the purposes of CI, branches in the NixOS/nixpkgs repository are classified
Some branches also have a version component, which is either `unstable` or `YY.MM`.
`ci/github-script/supportedBranches.ts` is a script imported by CI to classify the base and head branches of a Pull Request.
`ci/github-script/supportedBranches.js` is a script imported by CI to classify the base and head branches of a Pull Request.
This classification will then be used to skip certain jobs.
This script can also be run locally to print basic test cases.

View File

@@ -1,6 +1,7 @@
{ lib, ... }:
rec {
inherit (lib) uniqueStrings;
# Borrowed from https://github.com/NixOS/nixpkgs/pull/355616
uniqueStrings = list: builtins.attrNames (builtins.groupBy lib.id list);
/*
Converts a `packagePlatformPath` into a `packagePlatformAttr`

View File

@@ -4,7 +4,7 @@ import path from 'node:path'
import { DefaultArtifactClient } from '@actions/artifact'
import { handleMerge } from './merge.js'
import { handleReviewers } from './reviewers.js'
import { classify } from './supportedBranches.ts'
import { classify } from './supportedBranches.js'
import withRateLimit from './withRateLimit.js'
export default async ({ github, context, core, dry }) => {

View File

@@ -1,4 +1,4 @@
import { classify, split } from './supportedBranches.ts'
import { classify, split } from './supportedBranches.js'
type TargetBranchPolicyFacts = {
base: string

View File

@@ -6,8 +6,8 @@ import {
evaluateTargetBranchPolicy,
getTargetBranchPolicy,
} from './check-target-branch-policy.ts'
import { dismissReviews, postReview } from './reviews.ts'
import { split } from './supportedBranches.ts'
import { dismissReviews, postReview } from './reviews.js'
import { split } from './supportedBranches.js'
// TODO: should this be combined with the branch checks in prepare.js?
// They do seem quite similar, but this needs to run after eval,

View File

@@ -2,8 +2,8 @@ import { execFileSync } from 'node:child_process'
import type * as actionsCore from '@actions/core'
import type { context as actionsContext } from '@actions/github'
import type { GitHub } from '@actions/github/lib/utils'
import { dismissReviews, postReview } from './reviews.ts'
import { classify } from './supportedBranches.ts'
import { dismissReviews, postReview } from './reviews.js'
import { classify } from './supportedBranches.js'
import withRateLimit from './withRateLimit.js'
const dirname = import.meta.dirname

View File

@@ -3,23 +3,26 @@ import { promisify } from 'node:util'
const execFile = promisify(nodeExecFile)
export type Commit = {
subject: string
sha: string
author: { name: string; email: string }
committer: { name: string; email: string }
changedPaths: string[]
changedPathSegments: Set<string>
}
/**
* @typedef {{
* subject: string,
* sha: string,
* author: { name: string, email: string },
* committer: { name: string, email: string}
* changedPaths: string[],
* changedPathSegments: Set<string>,
* }} Commit
*/
interface RunGitProps {
args: string[]
core: typeof import('@actions/core')
quiet?: boolean
repoPath?: string
}
async function runGit({ args, repoPath, core, quiet }: RunGitProps) {
/**
* @param {{
* args: string[]
* core: typeof import('@actions/core'),
* quiet?: boolean,
* repoPath?: string,
* }} RunGitProps
*/
async function runGit({ args, repoPath, core, quiet }) {
if (repoPath) {
args = ['-C', repoPath, ...args]
}
@@ -31,29 +34,21 @@ async function runGit({ args, repoPath, core, quiet }: RunGitProps) {
return await execFile('git', args)
}
interface GetCommitMessagesForPRProps {
core: typeof import('@actions/core')
pr: Awaited<
ReturnType<
InstanceType<
typeof import('@actions/github/lib/utils').GitHub
>['rest']['pulls']['get']
>
>['data']
repoPath?: string
}
/**
* Gets the SHA, subject and changed files for each commit in the given PR.
*
* Don't use GitHub API at all: the "list commits on PR" endpoint has a limit
* of 250 commits and doesn't return the changed files.
*
* @param {{
* core: typeof import('@actions/core'),
* pr: Awaited<ReturnType<InstanceType<typeof import('@actions/github/lib/utils').GitHub>["rest"]["pulls"]["get"]>>["data"]
* repoPath?: string,
* }} GetCommitMessagesForPRProps
*
* @returns {Promise<Commit[]>}
*/
export async function getCommitDetailsForPR({
core,
pr,
repoPath,
}: GetCommitMessagesForPRProps): Promise<Commit[]> {
export async function getCommitDetailsForPR({ core, pr, repoPath }) {
await runGit({
args: ['fetch', `--depth=1`, 'origin', pr.base.sha],
repoPath,

View File

@@ -1,23 +1,17 @@
import { type Commit, getCommitDetailsForPR } from './get-pr-commit-details.ts'
import { classify } from './supportedBranches.ts'
import { getCommitDetailsForPR } from './get-pr-commit-details.js'
import { classify } from './supportedBranches.js'
type GitHub = InstanceType<typeof import('@actions/github/lib/utils').GitHub>
type Context = typeof import('@actions/github').context
type Core = typeof import('@actions/core')
/** @typedef {import('./get-pr-commit-details.js').Commit} Commit */
interface LintCommitsProps {
github: GitHub
context: Context
core: Core
repoPath?: string
}
export default async function lintCommits({
github,
context,
core,
repoPath,
}: LintCommitsProps) {
/**
* @param {{
* github: InstanceType<typeof import('@actions/github/lib/utils').GitHub>,
* context: typeof import('@actions/github').context,
* core: typeof import('@actions/core'),
* repoPath?: string,
* }} LintCommitsProps
*/
export default async function lintCommits({ github, context, core, repoPath }) {
// This check should only be run when we have the pull_request context.
const pull_number = context.payload.pull_request?.number
if (!pull_number) {
@@ -59,15 +53,13 @@ export default async function lintCommits({
await checkCommitMetadata({ commits, core })
}
interface CheckCommitMessagesProps {
commits: Commit[]
core: Core
}
async function checkCommitMessages({
commits,
core,
}: CheckCommitMessagesProps) {
/**
* @param {{
* commits: Commit[],
* core: typeof import('@actions/core'),
* }} CheckCommitMessagesProps
*/
async function checkCommitMessages({ commits, core }) {
const failures = new Set()
const conventionalCommitTypes = [
@@ -88,13 +80,10 @@ async function checkCommitMessages({
]
/**
* @param types e.g. ["fix", "feat"]
* @param sha commit hash
* @param {string[]} types e.g. ["fix", "feat"]
* @param {string?} sha commit hash
*/
function makeConventionalCommitRegex(
types: string[],
sha: string | null = null,
) {
function makeConventionalCommitRegex(types, sha = null) {
core.info(
`${
sha
@@ -177,15 +166,17 @@ async function checkCommitMessages({
}
}
interface CheckGitFieldsProps {
commits: Commit[]
core: Core
}
async function checkCommitMetadata({ commits, core }: CheckGitFieldsProps) {
/**
* @param {{
* commits: Commit[],
* core: typeof import('@actions/core'),
* }} CheckGitFieldsProps
*/
async function checkCommitMetadata({ commits, core }) {
const failures = new Set()
const isEmail = (s: string) => /^.+@.*$/.test(s)
/** @type {(s: string) => boolean} */
const isEmail = (s) => /^.+@.*$/.test(s)
for (const commit of commits) {
if (!commit.author.name) {

View File

@@ -1,6 +1,6 @@
import { getCommitDetailsForPR } from './get-pr-commit-details.ts'
import { dismissReviews, postReview } from './reviews.ts'
import { classify } from './supportedBranches.ts'
import { getCommitDetailsForPR } from './get-pr-commit-details.js'
import { dismissReviews, postReview } from './reviews.js'
import { classify } from './supportedBranches.js'
export default async function checkManualFileEdits({
github,

View File

@@ -1,5 +1,5 @@
// @ts-nocheck
import { classify } from './supportedBranches.ts'
import { classify } from './supportedBranches.js'
function runChecklist({
committers,
@@ -71,7 +71,7 @@ function runChecklist({
pull_request.head.ref.startsWith('backport-'),
'Opened by a [committer](https://github.com/orgs/NixOS/teams/nixpkgs-committers).':
committers.has(pull_request.user.id),
'Opened by [@r-ryantm](https://nixos.github.io/nixpkgs-update/r-ryantm/).':
'Opened by [@r-ryantm](https://nix-community.github.io/nixpkgs-update/r-ryantm/).':
pull_request.user.login === 'r-ryantm',
},
'PR is not a draft': !pull_request.draft,
@@ -84,7 +84,7 @@ function runChecklist({
if (user) {
checklist[
`${user.login} is a member of [@NixOS/nixpkgs-maintainers](https://github.com/orgs/NixOS/teams/nixpkgs-maintainers) (_see [requesting a new invitation](https://github.com/NixOS/rfc39-record/blob/main/README.md#requesting-a-new-invitation)_).`
`${user.login} is a member of [@NixOS/nixpkgs-maintainers](https://github.com/orgs/NixOS/teams/nixpkgs-maintainers).`
] = userIsMaintainer
if (allByName) {
// We can only determine the below, if all packages are in by-name, since

View File

@@ -1,7 +1,7 @@
// @ts-nocheck
import { dismissReviews, postReview } from './reviews.ts'
import { classify } from './supportedBranches.ts'
import supportedSystems from './supportedSystems.ts'
import { dismissReviews, postReview } from './reviews.js'
import { classify } from './supportedBranches.js'
import supportedSystems from './supportedSystems.js'
const reviewKey = 'prepare'
@@ -66,7 +66,7 @@ export default async ({ github, context, core, dry }) => {
// commits between that base and head is the real base. We can query for this via GitHub's
// REST API. There can be multiple candidates for the real base with the same number of
// commits. In this case we pick the "best" candidate by a fixed ordering of branches,
// as defined in ci/github-script/supportedBranches.ts.
// as defined in ci/github-script/supportedBranches.js.
//
// These requests take a while, when comparing against the wrong release - they need
// to look at way more than 10k commits in that case. Thus, we try to minimize the

View File

@@ -3,9 +3,9 @@ import path from 'node:path'
import type * as actionsCore from '@actions/core'
import type { context as actionsContext } from '@actions/github'
import type { GitHub } from '@actions/github/lib/utils'
import { getCommitDetailsForPR } from './get-pr-commit-details.ts'
import { dismissReviews, postReview } from './reviews.ts'
import { classify } from './supportedBranches.ts'
import { getCommitDetailsForPR } from './get-pr-commit-details.js'
import { dismissReviews, postReview } from './reviews.js'
import { classify } from './supportedBranches.js'
/**
* Reminders to post as a non-blocking review when a pull request touches

View File

@@ -1,6 +1,6 @@
Thanks for contributing to the documentation
Make sure you follow the [documentation style guide](https://github.com/NixOS/nixpkgs/blob/master/doc/styleguide.md), most notably:
Make sure you follow the [documentation styleguide](https://github.com/NixOS/nixpkgs/blob/master/doc/styleguide.md), most notably:
- Show, don't tell: lead with a minimal working example; explanation follows the code.
- No meta-commentary: don't write "This section explains how to…", just do it.

View File

@@ -13,28 +13,30 @@ const reviewUsers = [
'manual-edit',
]
type GitHub = InstanceType<typeof import('@actions/github/lib/utils').GitHub>
type Context = typeof import('@actions/github').context
type Review = Awaited<
ReturnType<GitHub['rest']['pulls']['listReviews']>
>['data'][number]
type ReviewWithNonNullUser = Review & { user: NonNullable<Review['user']> }
interface DismissReviewsProps {
github: GitHub
context: Context
core: typeof import('@actions/core')
dry: boolean
reviewKey?: string
}
/**
* @typedef {InstanceType<typeof import('@actions/github/lib/utils').GitHub>} GitHub
* @typedef {typeof import('@actions/github').context} Context
*
* @typedef {Awaited<ReturnType<GitHub['rest']['pulls']['listReviews']>>['data'][number]} Review
* @typedef {Review & { user: NonNullable<Review['user']> }} ReviewWithNonNullUser
*/
/**
* @param {{
* github: GitHub,
* context: Context,
* core: typeof import('@actions/core'),
* dry: boolean,
* reviewKey?: string,
* }} DismissReviewsProps
*/
export async function dismissReviews({
github,
context,
core,
dry,
reviewKey,
}: DismissReviewsProps) {
}) {
const pull_number = context.payload.pull_request?.number
if (!pull_number) {
core.warning('dismissReviews called outside of pull_request context')
@@ -45,29 +47,23 @@ export async function dismissReviews({
return
}
const allReviews: Review[] = await github.paginate(
github.rest.pulls.listReviews,
{
...context.repo,
pull_number,
},
)
const allReviews = await github.paginate(github.rest.pulls.listReviews, {
...context.repo,
pull_number,
})
const reviews = allReviews
.filter((review): review is ReviewWithNonNullUser => !!review.user)
.filter(
const reviews = /** @type {ReviewWithNonNullUser[]} */ (
allReviews.filter(
(review) =>
review.user &&
review.state !== 'DISMISSED' &&
review.user.login.endsWith('[bot]') &&
reviewUsers.some((substr) => review.user?.login.includes(substr)),
)
)
const reviewsByUser = reviews.reduce(
(prev, curr) => {
if (!curr.user) {
return prev
}
if (!(curr.user.login in prev)) {
prev[curr.user.login] = []
}
@@ -76,7 +72,7 @@ export async function dismissReviews({
return prev
},
{} as Record<string, ReviewWithNonNullUser[]>,
/** @type {Record<string, ReviewWithNonNullUser[]> } */ ({}),
)
const commentRegex = new RegExp(
@@ -90,8 +86,8 @@ export async function dismissReviews({
)
let reviewsToMinimize = reviews
const reviewsToDismiss: ReviewWithNonNullUser[] = []
const reviewsToResolve: ReviewWithNonNullUser[] = []
const /** @type {ReviewWithNonNullUser[]} */ reviewsToDismiss = []
const /** @type {ReviewWithNonNullUser[]} */ reviewsToResolve = []
if (reviewKey && reviews.every((review) => commentRegex.test(review.body))) {
reviewsToMinimize = reviews.filter((review) =>
@@ -169,16 +165,17 @@ export async function dismissReviews({
])
}
interface PostReviewProps {
github: GitHub
context: Context
core: typeof import('@actions/core')
dry: boolean
body: string
event: keyof typeof eventToState
reviewKey: string
}
/**
* @param {{
* github: GitHub,
* context: Context,
* core: typeof import('@actions/core'),
* dry: boolean,
* body: string,
* event: keyof typeof eventToState,
* reviewKey: string,
* }} PostReviewProps
*/
export async function postReview({
github,
context,
@@ -187,7 +184,7 @@ export async function postReview({
body,
event = 'REQUEST_CHANGES',
reviewKey,
}: PostReviewProps) {
}) {
const pull_number = context.payload.pull_request?.number
if (!pull_number) {
core.warning('postReview called outside of pull_request context')
@@ -213,7 +210,8 @@ export async function postReview({
reviewUsers.some((substr) => review.user?.login.includes(substr)),
)
let pendingReview: null | Review
/** @type {null | Review} */
let pendingReview
const matchingReviews = reviews.filter((review) =>
reviewKeyRegex.test(review.body),
)

View File

@@ -101,7 +101,7 @@ program
.argument('<repo>', 'Name of the GitHub repository to run on (Example: nixpkgs)')
.argument('<pr>', 'Number of the Pull Request to run on')
.action(async (owner, repo, pr, options) => {
const checkCommitMessages = (await import('./lint-commits.ts')).default
const checkCommitMessages = (await import('./lint-commits.js')).default
await run(checkCommitMessages, owner, repo, pr, options)
})

View File

@@ -2,12 +2,11 @@
/*
#!nix-shell -i node -p nodejs
*/
// @ts-nocheck
import { resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
type BranchType = 'channel' | 'development' | 'primary' | 'secondary'
const typeConfig: Record<string, BranchType[]> = {
const typeConfig = {
master: ['development', 'primary'],
release: ['development', 'primary'],
staging: ['development', 'secondary'],
@@ -20,7 +19,7 @@ const typeConfig: Record<string, BranchType[]> = {
// "order" ranks the development branches by how likely they are the intended base branch
// when they are an otherwise equally good fit according to ci/github-script/prepare.js.
const orderConfig: Record<string, number> = {
const orderConfig = {
master: 0,
release: 1,
staging: 2,
@@ -29,30 +28,15 @@ const orderConfig: Record<string, number> = {
'staging-next': 4,
}
type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
type Version = `${Digit}${Digit}.${Digit}${Digit}` | 'unstable'
interface SplitResult {
prefix: string
version: Version
suffix?: string
function split(branch) {
return {
...branch.match(
/(?<prefix>.+?)(-(?<version>\d{2}\.\d{2}|unstable)(?:-(?<suffix>.*))?)?$/,
).groups,
}
}
function split(branch: string) {
const groups = branch.match(
/(?<prefix>.+?)(-(?<version>\d{2}\.\d{2}|unstable)(?:-(?<suffix>.*))?)?$/,
)!.groups!
return groups as unknown as SplitResult
}
interface BranchClassification {
branch: string
order: number
stable: boolean
type: BranchType[]
version: Version
}
function classify(branch: string): BranchClassification {
function classify(branch) {
const { prefix, version } = split(branch)
return {
branch,
@@ -71,7 +55,7 @@ if (
fileURLToPath(import.meta.url) === resolve(process.argv[1])
) {
console.log('split(branch)')
function testSplit(branch: string) {
function testSplit(branch) {
console.log(branch, split(branch))
}
testSplit('master')
@@ -88,7 +72,7 @@ if (
console.log('')
console.log('classify(branch)')
function testClassify(branch: string) {
function testClassify(branch) {
console.log(branch, classify(branch))
}
testClassify('master')

View File

@@ -0,0 +1,11 @@
// @ts-nocheck
export default async ({ github, context, targetSha }) => {
const { content, encoding } = (
await github.rest.repos.getContent({
...context.repo,
path: 'pkgs/top-level/release-supported-systems.json',
ref: targetSha,
})
).data
return JSON.parse(Buffer.from(content, encoding).toString())
}

View File

@@ -1,30 +0,0 @@
interface SupportedSystemsProps {
github: InstanceType<typeof import('@actions/github/lib/utils').GitHub>
context: typeof import('@actions/github').context
targetSha: string
}
export default async ({
github,
context,
targetSha,
}: SupportedSystemsProps) => {
const contentObject = (
await github.rest.repos.getContent({
...context.repo,
path: 'pkgs/top-level/release-supported-systems.json',
ref: targetSha,
})
).data
if ('type' in contentObject && contentObject.type === 'file') {
const { content, encoding } = contentObject
return JSON.parse(
Buffer.from(content, encoding as BufferEncoding).toString(),
)
} else {
throw new Error(
'Fetched pkgs/top-level/release-supported-systems.json is not a file',
)
}
}

View File

@@ -1,67 +1,77 @@
# Contributing to the Nixpkgs manual
This directory houses the source files for the Nixpkgs manual, including
- [Getting Started](./getting-started) guides
- [Onboarding guides](./using-nixpkgs.md) for using Nixpkgs
- [Language frameworks](./languages-frameworks) shipped with Nixpkgs.
There are renderings for the [rolling release](https://nixos.org/manual/nixpkgs/unstable/) and [latest stable release](https://nixos.org/manual/nixpkgs/stable/).
This directory houses the source files for the Nixpkgs manual.
> [!NOTE]
>
> We are actively restructuring our documentation to be more beginner friendly.
>
When writing new docs use **Progressive Disclosure:**
When writing new docs use **Progressive Disclosure**
- Start simple, pick up beginners.
- Use **examples** first to show how to get something done.
- Keep **explanation** lean.
Start simple, pick up beginners.
Use **examples** first to show how to get something done. Keep **Explanation** lean.
Use our [style guide](./styleguide.md) for more in depth guidance on writing good documentation.
Use our [styleguide](./styleguide.md) for more in depth guidance on writing good documentation.
Documentation about Nixpkgs belongs here, this includes 'getting-started'-guides and 'onboarding-guides' for *using* Nixpkgs and the language frameworks it ships.
Write **guides** task-first: lead with a working example, then explain in prose.
Write **reference** as the specification of functions and attributes.
We are actively working to generate reference documentation from the [doc-comments](https://github.com/NixOS/rfcs/blob/master/rfcs/0145-doc-strings.md) present in code, which also lets you view it locally with the `:doc` command in `nix repl`, e.g.:
```
nix-repl> :l <nixpkgs>
nix-repl> :doc lib.mapAttrsToList
```
We are actively working to generate reference documentation from the [doc-comments](https://github.com/NixOS/rfcs/blob/master/rfcs/0145-doc-strings.md) present in code, which also lets you view it locally with `:doc` in `nix repl`.
See [Document structure](#document-structure) for a structural template.
## Building and navigating documentation locally
Rendered documentation:
- [Unstable (from master)](https://nixos.org/manual/nixpkgs/unstable/)
- [Stable (from latest release)](https://nixos.org/manual/nixpkgs/stable/)
The Nixpkgs manual is rendered by [`nixos-render-docs`](../pkgs/by-name/ni/nixos-render-docs/).
Its index is [`nav.json`](./nav.json).
The rendering tool is [nixos-render-docs](../pkgs/by-name/ni/nixos-render-docs), sometimes abbreviated `nrd`.
## Contributing to this documentation
You can quickly check your edits with `nix-build`:
```ShellSession
$ cd /path/to/nixpkgs
$ nix-build doc
```
If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.html`.
### Development environment
Consider using the tooling in the documentation development environment.
To reduce repetition, consider using tools from the provided development environment:
Load it from the Nixpkgs documentation directory with
```ShellSession
$ cd /path/to/nixpkgs/doc
$ nix-shell
```
### Live preview
To load the development utilities automatically when entering that directory, [set up `nix-direnv`](https://nix.dev/guides/recipes/direnv).
Within the developer environment, run [`devmode`](../pkgs/by-name/de/devmode/README.md) for a live preview while editing the manual.
If the `nixos-render-docs` source-code changes, `devmode` must be restarted.
Make sure that your local files aren't added to Git history by adding the following lines to `.git/info/exclude` at the root of the Nixpkgs repository:
### Building the docs
```
/**/.envrc
/**/.direnv
```
To build the documentation, run `nix-build doc`.
A successful build is stored in `./result/share/doc/nixpkgs/manual.html`.
#### Live preview
Run [`devmode`](../pkgs/by-name/de/devmode/README.md) for a live preview while editing the manual: it rebuilds on every change and reloads the page in your browser automatically.
Changes to the renderer 'pkgs/by-name/ni/nixos-render-docs' need a manual restart. Run: `devmode` again.
### Testing redirects
Once you have a successful build, you can open the aforementioned path in a browser along with the anchor, and observe the redirection.
Once you have a successful build, you can open the relevant HTML (path mentioned above) in a browser along with the anchor, and observe the redirection.
To test redirects, perform a browser refresh, as browsers do not re-run client JS code when only the anchor has changed.
Note that if you already loaded the page and *then* input the anchor, you will need to perform a reload.
This is because browsers do not re-run client JS code when only the anchor has changed.
## Syntax
@@ -123,12 +133,14 @@ A few markups for other kinds of literals are also available:
- `` {env}`XDG_DATA_DIRS` ``
- `` {file}`/etc/passwd` ``
- `` {option}`networking.useDHCP` ``
- `` {var}`pkgs` ``
The values will be formatted as inline `<code>` elements.
- `` {var}`/etc/passwd` ``
These literal kinds are used mostly in NixOS option documentation.
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point).
Though, the feature originates from [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage) with slightly different syntax.
They are handled by `myst_role` defined per renderer. <!-- reverse references in code -->
#### Admonitions
Set off from the text to bring attention to something.
@@ -151,7 +163,7 @@ The following are supported:
- `example`
Example admonitions require a title to work.
If you don't provide one, the manual won't build.
If you don't provide one, the manual won't be built.
```markdown
::: {.example #ex-showing-an-example}
@@ -167,11 +179,11 @@ Text for the example.
For defining a group of terms:
```markdown
Pear
: Green or yellow bulbous fruit
pear
: green or yellow bulbous fruit
Watermelon
: Green fruit with red flesh
watermelon
: green fruit with red flesh
```
## Commit conventions
@@ -203,7 +215,7 @@ When needed, each convention explains why it exists, so you can make a decision
Note that these conventions are about the **structure** of the manual (and its source files), not about the content that goes in it.
You, as the writer of documentation, are still in charge of its content.
**For prose style, see the [documentation style guide](./styleguide.md).**
**For prose style, see the [documentation styleguide](./styleguide.md).**
### Document structure
@@ -273,7 +285,7 @@ When changing existing content, update formatting if possible, but avoid excessi
### Examples first
Put examples before detailed explanations (see the [style guide](./styleguide.md) for the rationale).
Put examples before detailed explanations (see the [styleguide](./styleguide.md) for the rationale).
Use this structure for each documented item:

View File

@@ -5,7 +5,7 @@ Create a `shell.nix` with the following:
```nix
# shell.nix
let
nixpkgs = fetchTarball "https://channels.nixos.org/nixos-unstable/nixexprs.tar.zst";
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz";
pkgs = import nixpkgs { };
in
pkgs.mkShell {
@@ -25,7 +25,7 @@ nix-shell
This activates your `shell.nix` and you should see:
```sh
unpacking 'https://channels.nixos.org/nixos-unstable/nixexprs.tar.zst' into the Git cache...
unpacking 'https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz' into the Git cache...
Welcome in your nix shell
```

View File

@@ -53,7 +53,7 @@ Pin Nixpkgs and call the package from `default.nix`:
```nix
# default.nix
let
nixpkgs = fetchTarball "https://channels.nixos.org/nixos-unstable/nixexprs.tar.zst";
nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz";
pkgs = import nixpkgs { };
in
pkgs.callPackage ./package.nix { }

View File

@@ -3,7 +3,7 @@
This hook defaults a variety of environment variables known
to control thread counts to 1. Many of these otherwise default
to `$(nproc)`, which causes massive overloads on build machines
if nix build jobs and build cores are already tuned to fully use
if nix build jobs and build cores are already tuned to fully utilize
compute capacity of a builder without additional parallelism.
Currently sets the following environment variables:

View File

@@ -1,28 +0,0 @@
# `guileImportsCheckHook` {#guileImportsCheckHook}
This hook checks if a guile package can be imported. The hook is automatically
propagated by `guile`, so using it is as simple as:
```nix
{
lib,
stdenv,
guile,
# ...
}:
stdenv.mkDerivation (finalAttrs: {
# ...
nativeBuildInputs = [ guile ];
guileImportsCheck = [
"package"
];
# ...
})
```
The `guileImportsCheckHook` package can also included manually in
`nativeBuildInputs` if one desires.

View File

@@ -92,10 +92,3 @@ Meson setup hook.
- `prefixKey`
- `enableParallelBuilding`
- `enableParallelChecking`
- `disabledTests`
#### `disabledTests` {#meson-disabled-tests}
Specifies a list of tests to skip in `mesonCheckPhase`.
You can optionally specify a subproject using a colon prefix, e.g. `subproject:test_name`.
Meson will pick up the main project name as a default if no subproject is specified.

142
doc/hooks/pnpm.section.md Normal file
View File

@@ -0,0 +1,142 @@
# pnpmBuildHook {#pnpm-build-hook}
[pnpm](https://pnpm.io/) is a an NPM-compatible package manager focused on increasing managment speeds, and reducing disk space.
The `pnpmBuildHook` in Nixpkgs overrides the default build phase for building packages that use pnpm.
:::{.example #ex-pnpm-build-hook}
## pnpmBuildHook example code snippet {#pnpm-build-hook-code-snippet}
```nix
{
lib,
stdenv,
fetchFromGitHub,
fetchPnpmDeps,
pnpmConfigHook,
pnpmBuildHook,
makeBinaryWrapper,
pnpm_10,
}:
let
pnpm = pnpm_10;
in
stdenv.mkDerivation (finalAttrs: {
pname = "coolPackages";
version = "1.0";
src = fetchFromGitHub {
owner = "JaneCool";
repo = "coolpackage";
tag = finalAttrs.version;
hash = lib.fakeHash;
};
__structuredAttrs = true;
strictDeps = true;
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
inherit pnpm;
fetcherVersion = 4;
hash = lib.fakeHash;
};
nativeBuildInputs = [
pnpmConfigHook
pnpmBuildHook
makeBinaryWrapper
];
pnpmBuildScript = "build";
pnpmBuildFlags = [
"--mode"
"production"
];
pnpmWorkspaces = [
"test"
];
installPhase = ''
runHook preInstall
mkdir "$out"
cp -r dist/. "$out"
runHook postInstall
'';
meta = {
description = "very cool package that does cool things";
mainProgram = "cool";
};
})
```
:::
## Variables controlling pnpmBuildHook {#pnpm-build-hook-variables}
### pnpm Exclusive Variables {#pnpm-build-hook-exclusive-variables}
#### `pnpmBuildScript` {#pnpm-build-hook-script}
Controls the script ran to build the package, by default the script is `build`.
#### `pnpmFlags` {#pnpm-build-hook-flags}
Controls flags used for all invocations of pnpm across all hooks local to this derivation.
#### `pnpmBuildFlags` {#pnpm-build-hook-build-flags}
Controls the flags pass only to the pnpm build script invocation.
#### `dontPnpmBuild` {#pnpm-build-hook-dont}
Disables automatically running `pnpmBuildHook`. The build can still be run manually if needed, for example:
```nix
{
lib,
rustPlatform,
pnpmBuildHook,
pnpmConfigHook,
fetchPnpmDeps,
emptyDirectory,
pnpm_10,
}:
let
pnpm = pnpm_10;
in
rustPlatform.buildRustPackage (finalAttrs: {
pname = "super-fast-application";
version = "1.0";
src = emptyDirectory;
cargoHash = lib.fakeHash;
nativeBuildInputs = [
pnpmBuildHook
pnpmConfigHook
];
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
inherit pnpm;
fetcherVersion = 4;
hash = lib.fakeHash;
};
dontPnpmBuild = true;
postBuild = ''
pnpmBuildHook
'';
})
```
### Honored Variables {#pnpm-build-hook-honored-variables}
The following variables are honored by `pnpmBuildHook`.
* [`pnpmRoot`](#javascript-pnpm-sourceRoot)
* [`pnpmWorkspaces`](#javascript-pnpm-workspaces)

View File

@@ -5,7 +5,7 @@
COSMIC (Computer Operating System Main Interface Components) is a desktop environment developed by
System76, primarily for the Pop!_OS Linux distribution. Applications in the COSMIC ecosystem are
written in Rust and use libcosmic, which builds on the Iced GUI framework. This section explains
how to package and integrate COSMIC applications within Nix.
how to properly package and integrate COSMIC applications within Nix.
### libcosmicAppHook {#ssec-cosmic-libcosmic-app-hook}
@@ -17,7 +17,7 @@ and wrapping applications based on libcosmic. It handles many common requirement
- Managing Vergen environment variables for build-time information
- Setting up Rust linker flags for specific libraries
Add the hook to your package's `nativeBuildInputs`:
To use the hook, simply add it to your package's `nativeBuildInputs`:
```nix
{
@@ -61,9 +61,8 @@ rustPlatform.buildRustPackage {
}
```
> [!Note]
> `cosmic-settings` is a separate application and not a part of the libcosmic settings
> system itself. It's included by default in `libcosmicAppHook` only to provide these fallback theme
Note that `cosmic-settings` is a separate application and not a part of the libcosmic settings
system itself. It's included by default in `libcosmicAppHook` only to provide these fallback theme
settings.
### Icons {#ssec-cosmic-icons}

View File

@@ -6,12 +6,6 @@ Package JavaScript applications with the tools below.
## Tools overview {#javascript-tools-overview}
- **npm**: [`buildNpmPackage`](#javascript-buildNpmPackage), [`prefetch-npm-deps` (CLI)](#javascript-buildNpmPackage-prefetch-npm-deps), [`fetchNpmDeps`](#javascript-buildNpmPackage-fetchNpmDeps), [`importNpmLock`](#javascript-buildNpmPackage-importNpmLock)
- [**corepack**](#javascript-corepack)
- **pnpm**: [`fetchPnpmDeps`](#javascript-pnpm), [`pnpmConfigHook`](#javascript-pnpm-pnpmConfigHook), [`pnpmBuildHook`](#javascript-pnpm-pnpmBuildHook)
- [**Yarn v1**](#javascript-yarn-v1): [`fetchYarnDeps`](#javascript-fetchyarndeps), [`yarnConfigHook`](#javascript-yarnconfighook), [`yarnBuildHook`](#javascript-yarnbuildhook), [`yarnInstallHook`](#javascript-yarninstallhook)
- [**Yarn Berry (v3/v4)**](#javascript-yarn-v3-v4): [`fetchYarnBerryDeps`](#javascript-fetchYarnBerryDeps), [`yarnBerryConfigHook`](#javascript-yarnBerryConfigHook)
## General principles {#javascript-general-principles}
The principles below are ordered by importance.
@@ -294,7 +288,9 @@ This package puts the corepack wrappers for pnpm and yarn in your PATH, and they
pnpm is available as the top-level package `pnpm`. Additionally, there are variants pinned to certain major versions, like `pnpm_9`, `pnpm_10`, `pnpm_10_29_2` and `pnpm_11`, which support different sets of lock file versions.
When packaging an application that includes a `pnpm-lock.yaml`, you need to fetch the pnpm store for that project using a fixed-output-derivation. The function `fetchPnpmDeps` can create this pnpm store derivation. In conjunction, the setup hook [`pnpmConfigHook`](#javascript-pnpm-pnpmConfigHook) prepares the build environment to install the pre-fetched dependencies store. The example below uses the fetcher and setup hook for a package that has `package.json` and `pnpm-lock.yaml`:
When packaging an application that includes a `pnpm-lock.yaml`, you need to fetch the pnpm store for that project using a fixed-output-derivation. The function `fetchPnpmDeps` can create this pnpm store derivation. In conjunction, the setup hook `pnpmConfigHook` prepares the build environment to install the pre-fetched dependencies store. The example below uses the fetcher and setup hook for a package that has `package.json` and `pnpm-lock.yaml`:
There is also the [`pnpmBuildHook`](#pnpm-build-hook) for building packages with `pnpm`, as seen in [](#ex-pnpm-build-hook).
```nix
{
@@ -302,7 +298,6 @@ When packaging an application that includes a `pnpm-lock.yaml`, you need to fetc
nodejs,
pnpm_11,
pnpmConfigHook,
pnpmBuildHook,
stdenv,
}:
let
@@ -324,8 +319,7 @@ stdenv.mkDerivation (finalAttrs: {
nativeBuildInputs = [
nodejs # in case scripts are run outside of a pnpm call
pnpmConfigHook
pnpmBuildHook
pnpm # At least required by pnpmConfigHook and pnpmBuildHook, if not other (custom) phases
pnpm # At least required by pnpmConfigHook, if not other (custom) phases
];
pnpmDeps = fetchPnpmDeps {
@@ -337,11 +331,49 @@ stdenv.mkDerivation (finalAttrs: {
})
```
The example also uses [`pnpmBuildHook`](#javascript-pnpm-pnpmBuildHook), which runs `pnpm run build` in the build phase.
Use a pinned version of pnpm (for example `pnpm_9` or `pnpm_10`) to increase reproducibility. An older version may be required if the package needs a certain lock file version. To do so, pass the `pnpm` argument to `fetchPnpmDeps`. Then override the `pnpm` arg in `pnpmConfigHook`. Here are the changes in the example above to use a pinned pnpm version:
In case you are patching `package.json` or `pnpm-lock.yaml`, make sure to pass `finalAttrs.patches` to the `fetchPnpmDeps` function as well (i.e., `inherit (finalAttrs) patches`).
<!-- TODO: Does splicing still work when overriding in nativeBuildInputs here? -->
#### pnpmConfigHook {#javascript-pnpm-pnpmConfigHook}
```diff
{
fetchPnpmDeps,
nodejs,
- pnpm,
+ pnpm_10,
pnpmConfigHook,
stdenv,
}:
+let
+ # Optionally override pnpm to use a custom nodejs version
+ # Make sure that the same nodejs version is referenced in nativeBuildInputs
+ # pnpm = pnpm_10.override { nodejs-slim = nodejs-slim_22; };
+in
stdenv.mkDerivation (finalAttrs: {
pname = "foo";
version = "0-unstable-1980-01-01";
src = {
#...
};
nativeBuildInputs = [
nodejs # in case scripts are run outside of a pnpm call
pnpmConfigHook
- pnpm # At least required by pnpmConfigHook, if not other (custom) phases
+ pnpm_10 # At least required by pnpmConfigHook, if not other (custom) phases
];
pnpmDeps = fetchPnpmDeps {
inherit (finalAttrs) pname version src;
+ pnpm = pnpm_10;
fetcherVersion = 4;
hash = "...";
};
})
```
In case you are patching `package.json` or `pnpm-lock.yaml`, make sure to pass `finalAttrs.patches` to the function as well (i.e., `inherit (finalAttrs) patches`).
`pnpmConfigHook` supports adding additional `pnpm install` flags via `pnpmInstallFlags` which can be set to a Nix string array:
@@ -359,33 +391,6 @@ In case you are patching `package.json` or `pnpm-lock.yaml`, make sure to pass `
If needed, set `dontPnpmConfigure = true;` to fully disable `pnpmConfigHook` without removing it from inputs manually.
#### pnpmBuildHook {#javascript-pnpm-pnpmBuildHook}
The `pnpmBuildHook` in overrides the default build phase with `pnpm run <build-script>`.
```nix
{
nativeBuildInputs = [
pnpmBuildHook
];
pnpmBuildScript = "build-ui";
pnpmBuildFlags = [
"--mode"
"production"
];
}
```
Available options:
- `pnpmBuildScript`: select which script from `package.json` to run. Defaults to `build`.
- `pnpmBuildFlags`: array of flags to pass to the build script.
- `pnpmFlags`: currently the same as `pnpmBuildFlags`, but might be used by other hooks in the future.
- `dontPnpmBuild`: disable this hook from running automatically. The hook can still be invoked manually.
Both [`pnpmRoot`](#javascript-pnpm-sourceRoot) and [`pnpmWorkspaces`](#javascript-pnpm-workspaces) are honored by this hook.
#### Dealing with `sourceRoot` {#javascript-pnpm-sourceRoot}
If the pnpm project is in a subdirectory, you can define `sourceRoot` or `setSourceRoot` for `fetchPnpmDeps`.
@@ -598,8 +603,13 @@ To install the package, `yarnInstallHook` uses both `npm` and `yarn` to clean up
- `yarnKeepDevDeps`: Disables the removal of devDependencies from `node_modules` before installation.
#### Yarn Berry v3/v4 {#javascript-yarn-v3-v4}
Yarn Berry (v3 / v4) versions have similar formats. They start with blocks like these:
Yarn Berry (v3 / v4) versions have similar formats. The `yarn.lock` file starts with blocks like these:
```yaml
__metadata:
version: 6
cacheKey: 8[cX]
```
```yaml
__metadata:
@@ -624,6 +634,7 @@ Explicitly pin the major version. For example, capture the `yarn-berry_Xn` argum
let
yarn-berry = yarn-berry_4;
in
stdenv.mkDerivation (finalAttrs: {
pname = "foo";
@@ -646,7 +657,6 @@ stdenv.mkDerivation (finalAttrs: {
```
##### `yarn-berry_X.fetchYarnBerryDeps` {#javascript-fetchYarnBerryDeps}
`fetchYarnBerryDeps` runs `yarn-berry-fetcher fetch` in a fixed-output-derivation. It is a custom fetcher designed to reproducibly download all files in the `yarn.lock` file, validating their hashes in the process. For git dependencies, it creates a checkout at `${offlineCache}/checkouts/<40-character-commit-hash>` (relying on the git commit hash to describe the contents of the checkout).
To produce the `hash` argument for the `fetchYarnBerryDeps` call, run `yarn-berry-fetcher prefetch`:
@@ -658,17 +668,14 @@ $ yarn-berry-fetcher prefetch </path/to/yarn.lock> [/path/to/missing-hashes.json
This prints the hash to stdout. Use it in update scripts to recalculate the hash for a new `yarn.lock`.
##### `yarn-berry_X.yarnBerryConfigHook` {#javascript-yarnBerryConfigHook}
`yarnBerryConfigHook` uses the store path `offlineCache` points to, to run a `yarn install` during the build, producing a usable `node_modules` directory from the downloaded dependencies.
Internally, this uses a patched version of Yarn to ensure git dependencies are re-packed and any attempted downloads fail immediately.
##### Patching the project's `package.json` or `yarn.lock` files {#javascript-yarnBerry-patching}
In case patching the project's `package.json` or `yarn.lock` is needed, it's important to pass `finalAttrs.patches` to `fetchYarnBerryDeps` as well, so the patched variants are picked up (i.e., `inherit (finalAttrs) patches`).
##### Missing hashes in the `yarn.lock` file {#javascript-yarnBerry-missing-hashes}
Unfortunately, `yarn.lock` files do not include hashes for optional/platform-specific dependencies. This is [by design](https://github.com/yarnpkg/berry/issues/6759).
To compensate for this, run the `yarn-berry-fetcher missing-hashes` subcommand to produce all missing hashes. These are stored in a `missing-hashes.json` file, which needs to be passed to both the build itself, as well as the `fetchYarnBerryDeps` helper:
@@ -682,6 +689,7 @@ To compensate for this, run the `yarn-berry-fetcher missing-hashes` subcommand t
let
yarn-berry = yarn-berry_4;
in
stdenv.mkDerivation (finalAttrs: {
pname = "foo";

View File

@@ -63,7 +63,7 @@ For instance, `sqlite-lua` needs `g:sqlite_clib_path` to be set to work. Nixpkgs
- `wrapperArgs`: Extra arguments forwarded to the `makeWrapper` call.
- `wrapRc`: Nix, not being able to write in your `$HOME`, loads the
generated Neovim configuration via the `$VIMINIT` environment variable, i.e. : `export VIMINIT='lua dofile("/nix/store/…-init.lua")'`. This has side effects like preventing Neovim from sourcing your `init.lua` in `$XDG_CONFIG_HOME/nvim` (see bullet 7 of [`:help startup`](https://neovim.io/doc/user/starting.html#startup) in Neovim). Disable it if you want to generate your own wrapper. You can still reuse the generated vimscript init code via `neovim.passthru.initRc`.
- `plugins`: A list of plugins to add to the wrapper. If a plugin is not available in nixpkgs, you can [package it yourself](#what-if-your-favourite-vim-plugin-isnt-already-packaged).
- `plugins`: A list of plugins to add to the wrapper.
- `extraLuaPackages`: A function passed on to `lua.withPackages`.
- `extraPython3Packages`: A function passed on to `python3.withPackages`.
- `withPython3`, `withNodeJs`, `withRuby`, `withPerl` control when to enable neovim

View File

@@ -11,86 +11,47 @@ nix-shell -p swift --run 'swiftc -' <<< 'print("Hello world!")'
The `swift` package also provides the `swift` command, with some caveats:
- Swift Package Manager (SwiftPM) is packaged separately as `swiftpm`.
If you need functionality like `swift build`, `swift run`, `swift test`, you must also add the `swiftpm` package to your closure.
- On Darwin, the `swift repl` command requires an Xcode installation.
This is because it uses the system LLDB debugserver, which has special entitlements.
- Swift Package Manager (SwiftPM) is packaged separately as `swiftpm`. If you
need functionality like `swift build`, `swift run`, `swift test`, you must
also add the `swiftpm` package to your closure.
- On Darwin, the `swift repl` command requires an Xcode installation. This is
because it uses the system LLDB debugserver, which has special entitlements.
## Module search paths {#ssec-swift-module-search-paths}
The Swift compiler executables are patched to find the C and C++ standard libraries associated with its target platform, but they are not wrapped.
They will not find your application’s dependencies automatically in the Nix store.
Your build system is expected to handle this for you.
Like other toolchains in Nixpkgs, the Swift compiler executables are wrapped
to help Swift find your application's dependencies in the Nix store. These
wrappers scan the `buildInputs` of your package derivation for specific
directories where Swift modules are placed by convention, and automatically
add those directories to the Swift compiler search paths.
SwiftPM provides a hook that scans the `buildInputs` of your package derivation for specific directories where the Swift modules are placed by convention.
These directories are added automatically to `swiftpmFlags` when the hook runs.
Swift in Nixpkgs follows a few conventions when installing dependencies:
Swift follows different conventions depending on the platform. The wrappers
look for the following directories:
- Libraries (both shared and static) are installed to `lib`.
This differs from upstream packaging, but it matches how other langauges are packaged in Nixpkgs.
This allows Swift packages to take advantage of existing tooling that expects libraries to be installed in this standard location.
- Modules are installed to `lib/swift/<platform>` where `<platform>` is the Swift platform for your host platform (e.g., `lib/swift/macosx` or `lib/swift/linux`).
Note that Linux modules may be installed in a directory specific to the target architecture(e.g., `lib/swift/linux/x86_64`), but this is uncommon.
Upstream Swift appears to be moving away from this convention.
- On Darwin platforms: `lib/swift/macosx`
(If not targeting macOS, replace `macosx` with the Xcode platform name.)
- On other platforms: `lib/swift/linux/x86_64`
(Where `linux` and `x86_64` are from lowercase `uname -sm`.)
- For convenience, Nixpkgs also adds `lib/swift` to the search path.
This can save a bit of work packaging Swift modules, because many Nix builds
will produce output for just one target anyway.
## Core libraries {#ssec-swift-core-libraries}
The `swift` package contains a complete toolchain with the Swift stdlib, Dispatch, Foundation, XCTest, and Swift Testing.
These packages do not need to be added to `buildInputs` when packaging applications.
The Swift compiler will find them automatically in the `swift` toolchain.
In addition to the standard library, the Swift toolchain contains some
additional 'core libraries' that, on Apple platforms, are normally distributed
as part of the OS or Xcode. These are packaged separately in Nixpkgs and can
be found (for use in `buildInputs`) as:
If you do need to use these packages outside of the Swift toolchain, they are available in the following packages:
- `swiftPackages.stdlib` contains the Swift stdlib and backdeployment dylibs.
- `swiftPackages.swift-corelibs-libdispatch` contains the Dispatch framework.
- `swiftPackages.swift-corelibs-foundation` contains the Foundation framework.
- `swiftPackages.swift-corelibs-xctest` and `swiftPackages.swift-testing` contain the XCTest and Swift Testing frameworks respectively.
Note: On Darwin, the Swift stdlib has been removed from the SDK.
The Swift toolchain contains the stubs and modules required to build Swift applications with the following exceptions:
- Swift Differentiation is shipped as a dylib in Nixpkgs because it is no longer shipped with the OS (as of macOS 26.4).
This allows packages using Swift Differentiation to work regardless of OS version.
- The Span back-deployment dylib is shipped with the stdlib.
- This is expected because back-deployment dylibs are normally shipped with the toolchain.
- FoundationMacros is built and shipped as a dylib in `swiftPackages.swift-foundation` and included in the toolchain.
Macros are actually compiler plugins executed at build time.
Without this, FoundationMacros would not work on Darwin.
- `swiftPackages.Dispatch`
- `swiftPackages.Foundation`
- `swiftPackages.XCTest`
## Packaging with SwiftPM {#ssec-swift-packaging-with-swiftpm}
Nixpkgs includes two ways to package dependencies for Swift applications: `fetchSwiftPMDeps` and `swiftpm2nix`.
While `swiftpm2nix` is not deprecated, using `fetchSwiftPMDeps` is preferred because it is easier to use and does not (usually) require shipping extra files with your package.
### Packaging with `fetchSwiftPMDeps` {#ssec-swift-packaging-with-fetch-swiftpm-deps}
Swift provides a fetcher that will download all of your dependencies based on the `Package.resolved` shipped by your package.
If your package does not ship one, you will have to generate it yourself and provide it with your package.
Otherwise, set `swiftpmDeps` as follows:
```nix
{
swiftpmDeps = fetchSwiftPMDeps {
inherit src;
hash = "sha256-1KfyrQXE1HaO9WsuskzgiiEZxM/oelp40Jwzr8xJEL4=";
};
}
```
The `src` attribute is required as is the `hash`.
The first time you build your package, you will need to set `hash` to an empty value by using `lib.fakeHash` to get the hash for your dependencies.
The following optional attributes can also be used:
- `name`: Sets the name of the vendored dependencies fixed-output derivation.
You can also use `pname` and `version` to set the `name`.
This is often easier because you can inherit them from `finalAttrs`.
- `sourceRoot`: Sets the path where `Package.swift` and `Package.resolved` can be found if they are not in their default, top-level location.
- `patches`: Can be used to apply patches to your project before the dependencies are vendored.
This is useful to update `Package.swift` or `Package.resolved`.
- `postPatch`: Can be used to perform extra steps after patching.
You can copy a custom `Package.resolved` in `postPatch`.
### Packaging with `swiftpm2nix` {#ssec-swift-packaging-with-swiftpm2nix}
Nixpkgs includes a small helper `swiftpm2nix` that can fetch your SwiftPM
dependencies for you, when you need to write a Nix expression to package your
application.
The first step is to run the generator:
@@ -104,8 +65,8 @@ swift package resolve
swiftpm2nix
```
This produces some files in a directory `nix`, which will be part of your Nix expression.
The next step is to write that expression:
This produces some files in a directory `nix`, which will be part of your Nix
expression. The next step is to write that expression:
```nix
{
@@ -165,13 +126,45 @@ stdenv.mkDerivation (finalAttrs: {
})
```
#### Patching dependencies {#ssec-swiftpm-patching-dependencies}
### Custom build flags {#ssec-swiftpm-custom-build-flags}
In some cases, it may be necessary to patch a SwiftPM dependency.
SwiftPM dependencies are located in `.build/checkouts`, but the `swiftpm2nix` helper provides these as symlinks to read-only `/nix/store` paths.
To patch them, we need to make them writable.
If you'd like to build a different configuration than `release`:
A special function `swiftpmMakeMutable` is available to replace the symlink with a writable copy:
```nix
{ swiftpmBuildConfig = "debug"; }
```
It is also possible to provide additional flags to `swift build`:
```nix
{ swiftpmFlags = [ "--disable-dead-strip" ]; }
```
The default `buildPhase` already passes `-j` for parallel building.
If these two customization options are insufficient, provide your own
`buildPhase` that invokes `swift build`.
### Running tests {#ssec-swiftpm-running-tests}
Including `swiftpm` in your `nativeBuildInputs` also provides a default
`checkPhase`, but it must be enabled with:
```nix
{ doCheck = true; }
```
This essentially runs: `swift test -c release`
### Patching dependencies {#ssec-swiftpm-patching-dependencies}
In some cases, it may be necessary to patch a SwiftPM dependency. SwiftPM
dependencies are located in `.build/checkouts`, but the `swiftpm2nix` helper
provides these as symlinks to read-only `/nix/store` paths. To patch
them, we need to make them writable.
A special function `swiftpmMakeMutable` is available to replace the symlink
with a writable copy:
```nix
{
@@ -190,76 +183,21 @@ A special function `swiftpmMakeMutable` is available to replace the symlink with
}
```
### Custom build flags {#ssec-swiftpm-custom-build-flags}
If you'd like to build a different configuration than `release`:
```nix
{ swiftpmBuildConfig = "debug"; }
```
It is also possible to provide additional flags to `swift build`:
```nix
{ swiftpmFlags = [ "--disable-dead-strip" ]; }
```
The default `buildPhase` already passes `-j` for parallel building.
If these two customization options are insufficient, provide your own `buildPhase` that invokes `swift build`.
### Running tests {#ssec-swiftpm-running-tests}
Including `swiftpm` in your `nativeBuildInputs` also provides a default `checkPhase`, but it must be enabled with:
```nix
{ doCheck = true; }
```
This essentially runs: `swift test -c release`
### Installing packages {#ssec-swiftpm-install-phase}
SwiftPM provides a default install phase that installs any products specified in your package’s `Package.swift`.
If your package does not specify any products, which is not uncommon, you will have to manually install them to `out`.
To disable the SwiftPM install phase, include the following in your derivation:
```nix
{ dontUseSwiftpmInstall = true; }
```
## Hooks {#ssec-swift-hooks}
Swift provides the following hooks to automate builds and unpack dependencies:
- `swiftpmHook`: Propagated by `swiftpm`.
Also propagates `swiftpmUnpackHook`.
Provides build, install, and check phases. It also adds any dependencies found in `buildInputs` to `swiftpmFlags`.
- `swiftpmUnpackHook`: Sets up `workspace-state.json` and links vendored dependencies to the top-level `Packages` directory in the build environment.
Swift also provides a hook with the toolchain to replace rpath references to the toolchain with references to the stdlib package.
This hook is used automatically by the `swift` package.
This avoids pulling the entire toolchain into the closure of your package.
## Considerations for custom build tools {#ssec-swift-considerations-for-custom-build-tools}
### Linking the standard library {#ssec-swift-linking-the-standard-library}
The Swift stdlib is packaged separately as `swiftPackages.stdlib`.
The shared and static libraries are installed to `lib`.
Most tooling in Nixpkgs should find them automatically when linking.
The stdlib provides a hook to change any rpaths pointing to the toolchain to point to the stdlib instead.
The `swift` package has a separate `lib` output containing just the Swift
standard library, to prevent Swift applications needing a dependency on the
full Swift compiler at runtime. Linking with the Nixpkgs Swift toolchain
already ensures binaries correctly reference the `lib` output.
The stdlib modules are installed to `lib/swift/<platform>` in the `dev` output of the stdlib package.
These are symlinked together into the `swift` toolchain.
If your build tools locate the modules relative to the `swift` compiler executable, it should do the right thing automatically.
Sometimes, Swift is used only to compile part of a mixed codebase, and the
link step is manual. Custom build tools often locate the standard library
relative to the `swift` compiler executable, and while the result will work,
when this path ends up in the binary, it will have the Swift compiler as an
unintended dependency.
### Accessing properties of the Swift platform {#ssec-swift-platform-properties}
The architecture, platform, and triple used by Swift is available as attributes on the build/host/targetPlatform for the `stdenv`.
- `stdenv.<platform>.swift.platform`: The Swift platform (e.g., `macosx` for macOS, `linux` for Linux, etc).
- `stdenv.<platform>.swift.arch`: The Swift architecture (e.g., `arm64` for Darwin or `aarch64` for Linux, `x86_64`, etc).
- `stdenv.<platform>.swift.triple`: The triple used by Swift.
This is the same as `stdenv.<platform>.config` except on Darwin.
On Darwin, it uses the OS name instead of `darwin` and includes the deployment target (e.g., `arm64-apple-macosx14.0`).
In this case, you should investigate how your build process discovers the
standard library, and override the path. The correct path will be something
like: `"${swift.swift.lib}/${swift.swiftModuleSubdir}"`

View File

@@ -364,9 +364,6 @@
{
"file": "hooks/gnome.section.md"
},
{
"file": "hooks/guileImportsCheckHook.section.md"
},
{
"file": "hooks/haredo.section.md"
},
@@ -433,6 +430,9 @@
{
"file": "hooks/pkg-config.section.md"
},
{
"file": "hooks/pnpm.section.md"
},
{
"file": "hooks/postgresql-test-hook.section.md"
},

View File

@@ -128,6 +128,9 @@
"ex-pkgs-replace-vars-with": [
"index.html#ex-pkgs-replace-vars-with"
],
"ex-pnpm-build-hook": [
"index.html#ex-pnpm-build-hook"
],
"ex-shfmt": [
"index.html#ex-shfmt"
],
@@ -161,9 +164,6 @@
"ghc-deprecation-policy": [
"index.html#ghc-deprecation-policy"
],
"guileImportsCheckHook": [
"index.html#guileImportsCheckHook"
],
"how-channels-work": [
"index.html#how-channels-work"
],
@@ -406,6 +406,33 @@
"pkgs.treefmt.withConfig": [
"index.html#pkgs.treefmt.withConfig"
],
"pnpm-build-hook": [
"index.html#pnpm-build-hook"
],
"pnpm-build-hook-build-flags": [
"index.html#pnpm-build-hook-build-flags"
],
"pnpm-build-hook-code-snippet": [
"index.html#pnpm-build-hook-code-snippet"
],
"pnpm-build-hook-dont": [
"index.html#pnpm-build-hook-dont"
],
"pnpm-build-hook-exclusive-variables": [
"index.html#pnpm-build-hook-exclusive-variables"
],
"pnpm-build-hook-flags": [
"index.html#pnpm-build-hook-flags"
],
"pnpm-build-hook-script": [
"index.html#pnpm-build-hook-script"
],
"pnpm-build-hook-variables": [
"index.html#pnpm-build-hook-variables"
],
"pnpm-build-hook-honored-variables": [
"index.html#pnpm-build-hook-honored-variables"
],
"preface": [
"index.html#preface",
"index.html#overview-of-nixpkgs"
@@ -1684,9 +1711,6 @@
"var-meta-mainProgram": [
"index.html#var-meta-mainProgram"
],
"var-meta-mainDarwinApp": [
"index.html#var-meta-mainDarwinApp"
],
"var-meta-priority": [
"index.html#var-meta-priority"
],
@@ -1957,9 +1981,6 @@
"sec-darwin-troubleshooting-xcodebuild-absolute-paths": [
"index.html#sec-darwin-troubleshooting-xcodebuild-absolute-paths"
],
"sec-darwin-missing-macros": [
"index.html#sec-darwin-missing-macros"
],
"sec-darwin-troubleshooting-libiconv": [
"index.html#sec-darwin-troubleshooting-libiconv"
],
@@ -2957,9 +2978,6 @@
"meson-honored-variables": [
"index.html#meson-honored-variables"
],
"meson-disabled-tests": [
"index.html#meson-disabled-tests"
],
"setup-hook-mpi-check": [
"index.html#setup-hook-mpi-check"
],
@@ -3862,23 +3880,7 @@
"index.html#javascript-corepack"
],
"javascript-pnpm": [
"index.html#javascript-pnpm",
"index.html#ex-pnpm-build-hook"
],
"javascript-pnpm-pnpmBuildHook": [
"index.html#javascript-pnpm-pnpmBuildHook",
"index.html#pnpm-build-hook",
"index.html#pnpm-build-hook-build-flags",
"index.html#pnpm-build-hook-code-snippet",
"index.html#pnpm-build-hook-dont",
"index.html#pnpm-build-hook-exclusive-variables",
"index.html#pnpm-build-hook-flags",
"index.html#pnpm-build-hook-script",
"index.html#pnpm-build-hook-variables",
"index.html#pnpm-build-hook-honored-variables"
],
"javascript-pnpm-pnpmConfigHook": [
"index.html#javascript-pnpm-pnpmConfigHook"
"index.html#javascript-pnpm"
],
"javascript-pnpm-sourceRoot": [
"index.html#javascript-pnpm-sourceRoot"
@@ -4591,26 +4593,14 @@
"ssec-swift-packaging-with-swiftpm": [
"index.html#ssec-swift-packaging-with-swiftpm"
],
"ssec-swift-packaging-with-fetch-swiftpm-deps": [
"index.html#ssec-swift-packaging-with-fetch-swiftpm-deps"
],
"ssec-swift-packaging-with-swiftpm2nix": [
"index.html#ssec-swift-packaging-with-swiftpm2nix"
],
"ssec-swiftpm-patching-dependencies": [
"index.html#ssec-swiftpm-patching-dependencies"
],
"ssec-swiftpm-custom-build-flags": [
"index.html#ssec-swiftpm-custom-build-flags"
],
"ssec-swiftpm-running-tests": [
"index.html#ssec-swiftpm-running-tests"
],
"ssec-swiftpm-install-phase": [
"index.html#ssec-swiftpm-install-phase"
],
"ssec-swift-hooks": [
"index.html#ssec-swift-hooks"
"ssec-swiftpm-patching-dependencies": [
"index.html#ssec-swiftpm-patching-dependencies"
],
"ssec-swift-considerations-for-custom-build-tools": [
"index.html#ssec-swift-considerations-for-custom-build-tools"
@@ -4618,9 +4608,6 @@
"ssec-swift-linking-the-standard-library": [
"index.html#ssec-swift-linking-the-standard-library"
],
"ssec-swift-platform-properties": [
"index.html#ssec-swift-platform-properties"
],
"sec-language-tcl": [
"index.html#sec-language-tcl"
],

View File

@@ -16,8 +16,6 @@
+nixpkgs.url = "https://channels.nixos.org/nixos-26.05/nixexprs.tar.zst";
```
- GCC has been updated from GCC 15 to GCC 16. This introduces some backwards-incompatible changes. Refer to the [upstream porting guide](https://gcc.gnu.org/gcc-16/porting_to.html) for details.
- Emacs has been updated to 31.
This introduces some backwards‐incompatible changes; see the NEWS for details.
NEWS can be viewed from Emacs by typing `C-h n`, or by clicking `Help->Emacs News` from the menu bar.
@@ -38,10 +36,6 @@
- `zabbix.<package>` now defaults to version 7.4. If you want to keep using Zabbix 6.0, use `pkgs.zabbix60.<package>`.
Note that Zabbix 6.0 is in limited support, and will be deprecated on February 28, 2027. Consider upgrading.
- `zabbix-agent2-plugin-postgresql` is now moved to `zabbix{60,70,74}.plugins.postgresql`.
- Official Zabbix plugins (ember-plus, mongodb, and mssql) have been added under `zabbix{60,70,74}.plugins.<plugin>`.
- `perlPackages.NetOAuth` has been updated from 0.28 to 0.33.
Callers that verify messages must now set `allowed_signature_methods` per message or configure `@Net::OAuth::ALLOWED_SIGNATURE_METHODS`; `verify` otherwise throws an exception.
See the [upstream changelog](https://metacpan.org/dist/Net-OAuth/changes) for details.
@@ -123,9 +117,6 @@
- `himalaya` has been updated from `v1.2.0` to `v2.0.0`, which introduces breaking changes. See the [release notes](https://github.com/pimalaya/himalaya/releases/tag/v2.0.0) and the [migration guide](https://github.com/pimalaya/himalaya/blob/master/MIGRATION.md).
- `proton-cli` has been updated from `2.2.3` to `3.4.0`, and installs its command as `proton`, with `proton-cli` kept beside it as a symlink.
`3.0.0` reworked the command line - `--output` is now the response format, secrets are no longer accepted as flag values, and several subcommands moved - so scripts need a review against the [upstream changelog](https://github.com/roman-16/proton-cli/blob/main/CHANGELOG.md).
- `tengine` has been removed as it has seen seriously delayed responses to security vulnerabilities.
- `jellyfin` has been upgraded to major version 12, which contains breaking changes. See the [upstream blog post](https://jellyfin.org/posts/jellyfin-release-12.0) for more information on how to safely upgrade.
@@ -180,8 +171,6 @@
- `replaceVarsWith` now enables `strictDeps` and `__structuredAttrs` and passing these attributes to the function is no longer allowed.
By extension, `replaceVars` now also enables `strictDeps` and `__structuredAttrs`.
- `nginx` / `nginxStable` is now built without the `rtmp` nginx module by default. You can enable it again using `nginx.override { modules = [ pkgs.nginxModules.rtmp ]; }`
- `buildFHSEnvChroot` has been removed after deprecation in 23.05.
- `leafnode` has been removed, as it was an unmaintained alpha-release of leafnode 2 and has a dependency on the EOL PRCE-library. Consider using `leafnode1` instead, which is still maintained.
@@ -204,11 +193,6 @@
- `librest` providing 0.7 ABI was removed. `librest_1_0` providing 1.0 ABI was renamed to `librest` and `librest_1_0` was kept as an alias.
- `secretspec-ffi` has been renamed to `libsecretspec` and updated to 0.21.0.
The old package attribute remains an alias, but native consumers must rebuild
against the new `libsecretspec` library and pkg-config module. The separate
`libsecretspec-resolver` package provides a C client for `secretspec serve`.
- `luaPackages.lrexlib-pcre` has been removed as part of the process to fully migrate from the end-of-life PRCE library to PCRE2. `luaPackages.lrexlib-pcre2` and multiple other versions of lrexlib can be used instead.
- `hostapd` was upgraded to version 2.12+, which moves move supported, basic, and beacon transmission rate configuration to be at BSS level instead of per-radio for all BSSs. Refer to the [upstream example config](https://git.w1.fi/cgit/hostap/plain/hostapd/hostapd.conf) for details.
@@ -241,16 +225,6 @@
- `nim-2_0` & `nim-2_2` and respective aliases have been removed; please migrate to `nim` or `nim-unwrapped` (nim 2.2.10).
- `domoticz` has been updated from `2024.7` to `2026.x`, breaking third party applications and scripts using the old RType calls. Review the [release notes](https://github.com/domoticz/domoticz/blob/2026.2/History.txt#L398) for more information.
- `swift` is no longer wrapped.
The `NIX_SWIFTFLAGS_COMPILE` variable is no longer supported.
If you need to pass custom flags to the Swift compiler, you must add them via your package’s build system.
The default target version used by `swiftc` on Darwin is the operating system major version.
This value may be overridden by the build system (e.g., SwiftPM defaults to 10.13 instead).
See the Swift documentation in Nixpkgs for details.
- `swiftpm` is no longer wrapped to include Git to fetch dependencies.
Users with Git-based dependencies will need to add `git` to their dev shells or include it in their environment if they weren’t already.
- `vimacs` has been removed, as it has not been maintained in 10 years and was built for an old version of vim (6.0).
- The deprecated `appimageTools.extractType1`, `appimageTools.extractType2`, and `appimageTools.wrapType1` aliases now emit warnings. Use `appimageTools.extract` and `appimageTools.wrapType2` instead.
@@ -287,27 +261,18 @@
- `nextpnr` introduced support for the nexus and gatemate architectures. Building support for each individual architecture can be configured using the package parameters.
- `mastodon` has been updated to 4.7. The [4.7.0 release notes](https://github.com/mastodon/mastodon/releases/tag/v4.7.0) mention some unusually long running migrations.
- Emacs loads the `early-default` library after `early-init.el`.
Users can add `early-init.el` via `emacs.pkgs.withPackages`
by packaging `early-init.el` into a library named `early-default`.
To prevent loading the `early-default` library,
set `inhibit-early-default-init` in `early-init.el`.
- Ceph has a vulnerability in old generated CephX keys.
The project recommends to rotate old keys.
This is a manual process, see https://ceph.io/en/news/blog/2026/v20-2-4-v19-2-6-combo-released
- `services.ceph` enabled the generation of Ceph log files at `/var/log/ceph/`.
They were missing before because Ceph omitted logs when this directory was missing.
Ceph logs can grow large, so you may want to configure rotation of these logs.
- Firefox wrapper now accepts an optional `appDataDir` argument, which sets `MOZ_APP_DATA` to relocate Firefox application data. This is especially useful on macOS 27 and later, where wrapped Firefox applications may be denied access to profiles in traditional application data directory.
- Swift has been upgraded to Swift 6.2.4 from Swift 5.10.1.
The Swift packaging has been rewritten.
## Nixpkgs Library {#sec-nixpkgs-release-26.11-lib}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
@@ -318,9 +283,6 @@
- `typescript` 7.0.2 now uses the Golang implementation. The [announcement document](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/) has information on what was changed.
- `macaulay2` no longer installs Emacs files.
Users can now get the files from an Emacs lisp package, like `emacs.pkgs.withPackages (epkgs: [ epkgs.m2 ])`.
- `navidrome`'s plugin infrastructure has significantly changed. `buildNavidromePlugin` is renamed to `buildNavidromeGoPlugin` to allow for other language types. Plugins must now be sourced from `pkgsCross.wasi32.navidromePlugins.<name>`.
- `navidromePlugins.apple-music` now uses a `bundleName` attribute which sets the plugin's name to match the plugin's documentation for easier use. You will need to update your Agent from `apple-music-plugin` to `apple-music` as noted in [their docs](https://github.com/navidrome/apple-music-plugin#installation).

View File

@@ -105,10 +105,6 @@ A list of the teams of this Nix expression. Teams are defined in [`nixpkgs/maint
The name of the main binary for the package. This affects the binary `nix run` executes. Example: `"rg"`
### `mainDarwinApp` {#var-meta-mainDarwinApp}
The name of the main Darwin/macOS Application for the package. It must end in `.app`. Example: `"VSCodium.app"`
### `priority` {#var-meta-priority}
The *priority* of the package, used by `nix-env` to resolve file name conflicts between packages. See the [manual page for `nix-env`](https://nixos.org/manual/nix/stable/command-ref/nix-env) for details. Example: `"10"` (a low-priority package).

View File

@@ -121,8 +121,7 @@ Generally, only the last SDK release for a major version is packaged.
|---------------|-------------|------------------------------|
| 15.0–15.4 | 14.4 | `apple-sdk_14` / `apple-sdk` |
| 16.0 | 15.0 | `apple-sdk_15` |
| 26.0 | 26.0 | `apple-sdk_26` |
| 27.0+ | 27.0+ | `apple-sdk_27`, etc |
| 26.0+ | 26.0+ | `apple-sdk_26`, etc |
#### Darwin Default SDK versions {#sec-darwin-troubleshooting-darwin-defaults}
@@ -193,13 +192,6 @@ stdenv.mkDerivation {
}
```
### Macro library not available {#sec-darwin-missing-macros}
Some frameworks provide macros that are only shipped with Xcode.
For example, the AppleIntelligence framework, Swift Data, and SwiftUI (as of the 27.0 SDK).
A non-free package making these available will be added at a later date.
Until then, they are unfortunately not available in Nixpkgs.
#### How to use libiconv on Darwin {#sec-darwin-troubleshooting-libiconv}
The libiconv package is included in the SDK by default along with libresolv and libsbuf.

View File

@@ -1,4 +1,4 @@
# Style guide
# Styleguide
Use this page as a reference and style guide for our internal and external documentation.
@@ -22,7 +22,7 @@ Write for someone who knows a great deal — up to but not including this projec
If specific knowledge is required, mention it at the start of the page.
### Show, don't tell
### Show, Don't Tell
The fastest path to understanding is a working example.
People learn by doing, not by reading about doing.
@@ -34,7 +34,7 @@ People learn by doing, not by reading about doing.
- Cover edge cases or variations
- Link to further information instead of including it
### Grammar and style
### Grammar and Style
**Sentence structure:**
@@ -54,7 +54,7 @@ Users care about *detecting hardware*, not *the tool that does it*.
> This command detects your hardware and saves the configuration.
### Content organization
### Content Organization
Lead with value. State what the reader will accomplish before explaining how.
@@ -83,23 +83,21 @@ Use **progressive disclosure**. Introduce concepts only when needed.
3. Explain concepts if needed
4. Provide advanced options separately or link to the reference
### No meta-commentary
### No Meta-commentary
Don't describe what the documentation does. Just do it.
**Don't:**
> This section explains how to configure networking.
> The following guide walks you through setting up a web server.
**Do:**
> Configure networking by setting:
> Set up a web server:
### Code examples
### Code Examples
**Keep examples focused:**
@@ -132,7 +130,7 @@ Paste code examples directly and without further alteration.
}
```
### Lead with practical examples
### Lead with Practical Examples
Don't front-load theory. Readers want to accomplish something first, then understand why it works.
@@ -168,7 +166,7 @@ Users learn the NixOS module system by seeing patterns first.
- Link deeper concepts instead of inlining them
- Link to `nix.dev` for optional learning
### General rules
### General Rules
- Abbreviate keys like `ssh-ed25519 AAAAC3NzaC…`
- Abbreviate IP addresses like `192.168.XXX.XXX`
@@ -202,7 +200,7 @@ Use sentence case. A reader scanning only headings should understand the page.
> Configure networking
> Add a user to the system
### Imperative mood, voice, and person
### Imperative Mood, Voice, and Person
Use imperative mood for instructions. Address the reader as "you", not "the user". Use active voice; in other words, make the subject do the action.
@@ -232,7 +230,7 @@ Use present tense for descriptions. Future tense makes documentation feel tentat
> This creates a new folder.
> Running this command installs the package.
### Be confident
### Be Confident
State facts. Don't hedge with "should," "might," "typically," or "usually" unless the behavior genuinely varies.
@@ -246,7 +244,7 @@ State facts. Don't hedge with "should," "might," "typically," or "usually" unles
> This creates the configuration file.
> The service starts automatically.
### Avoid nominalizations
### Avoid Nominalizations
A nominalization is a verb turned into a noun, often by adding *-tion*, *-meant*, or *-ance* (e.g. "explanation", "selection"). The fix: find the hidden verb and use it directly.
@@ -260,7 +258,7 @@ A nominalization is a verb turned into a noun, often by adding *-tion*, *-meant*
> Select from the list.
> Explain the error.
### Plain words
### Plain Words
Technical precision for technical terms; plain language for everything else.
@@ -272,7 +270,7 @@ Technical precision for technical terms; plain language for everything else.
- "set up" not "establish"
- "find out" not "ascertain"
### Filler words and weak phrases
### Filler Words and Weak Phrases
Cut words and phrases that add length without meaning.
@@ -298,7 +296,7 @@ Delete on sight:
Every word must earn its place.
### Writing procedures
### Writing Procedures
One instruction per sentence. Don't pack multiple actions into one sentence.
@@ -322,7 +320,7 @@ Don't bury the negative. Key limitations should be prominent, not a footnote aft
> This service does not support multiple instances.
### Consistent terminology
### Consistent Terminology
Pick a term and stick to it. Don't swap synonyms to avoid repetition. In technical documentation, repetition is clarity.
@@ -361,7 +359,7 @@ Only link when the destination is directly relevant, not for generic background
> See `[database schema](url)` for the full table structure.
### UI language
### UI Language
Match UI element names exactly: wording, casing, and spacing (even if a label seems oddly worded).

View File

@@ -22,7 +22,7 @@ import <nixpkgs> {
}
```
Note that we set `linker` to `lld`. This is because LLVM has its own linker, called "lld". By setting it, we use Clang and lld within this new instance of Nixpkgs. There is a shorthand method for building everything with LLVM: `pkgsLLVM`. This is easier to use with `nix-build` (or `nix build`):
Note that we set `linker` to `lld`. This is because LLVM has its own linker, called "lld". By setting it, we utilize Clang and lld within this new instance of Nixpkgs. There is a shorthand method for building everything with LLVM: `pkgsLLVM`. This is easier to use with `nix-build` (or `nix build`):
```bash
nix-build -A pkgsLLVM.hello

View File

@@ -105,48 +105,27 @@ There are several ways to tweak how Nix handles a package which has been marked
$ export NIXPKGS_ALLOW_UNFREE=1
```
- To allow specific unfree packages, add their names to your Nixpkgs configuration file:
- It is possible to permanently allow individual unfree packages, while still blocking unfree packages by default using the `allowUnfreePredicate` configuration option in the user configuration file.
This option is a function which accepts a package as a parameter, and returns a boolean. The following example configuration accepts a package and always returns false:
```nix
{ allowUnfreePredicate = (pkg: false); }
```
For a more useful example, try the following. This configuration only allows unfree packages named roon-server and Visual Studio Code:
```nix
{
allowUnfreePackages = [
"fence"
"roon-server"
"vscode"
];
allowUnfreePredicate =
pkg:
builtins.elem (lib.getName pkg) [
"roon-server"
"vscode"
];
}
```
`allowUnfreePackages` permits the listed unfree packages.
In NixOS modules, lists set through `nixpkgs.config.allowUnfreePackages` merge additively across modules. This allows you to declare your unfree exceptions in the same modules that triggered them.
To allow unfree packages programmatically:
```nix
{ lib, ... }:
{
allowUnfreePredicate = pkg: lib.hasPrefix "roon" (lib.getName pkg);
}
```
This permits packages such as `roon-bridge` and `roon-server`.
To combine the list and predicate, set both options:
```nix
{ lib, ... }:
{
allowUnfreePackages = [
"fence"
"vscode"
];
allowUnfreePredicate = pkg: lib.hasPrefix "roon" (lib.getName pkg);
}
```
This permits unfree packages that match either option.
- It is also possible to allow and block licenses that are specifically acceptable or not acceptable, using `allowlistedLicenses` and `blocklistedLicenses`, respectively.
The following example configuration allowlists the licenses `amd` and `wtfpl`:

View File

@@ -699,7 +699,20 @@ rec {
*/
filterAttrsRecursive =
pred: set:
mapAttrs (_: v: if isAttrs v then filterAttrsRecursive pred v else v) (filterAttrs pred set);
listToAttrs (
concatMap (
name:
let
v = set.${name};
in
if pred name v then
[
(nameValuePair name (if isAttrs v then filterAttrsRecursive pred v else v))
]
else
[ ]
) (attrNames set)
);
/**
Like [`lib.lists.foldl'`](#function-library-lib.lists.foldl-prime) but for attribute sets.
@@ -1515,7 +1528,12 @@ rec {
*/
zipAttrsWithNames =
names: f: sets:
genAttrs names (name: f name (catAttrs name sets));
listToAttrs (
map (name: {
inherit name;
value = f name (catAttrs name sets);
}) names
);
/**
Merge sets of attributes and use the function `f` to merge attribute values.

View File

@@ -87,7 +87,7 @@ rec {
mySed = overrideDerivation pkgs.gnused (oldAttrs: {
name = "sed-4.2.2-pre";
src = fetchurl {
url = "ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2";
url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
hash = "sha256-MxBJRcM2rYzQYwJ5XKxhXTQByvSg5jZc5cSHEZoB2IY=";
};
patches = [];

View File

@@ -452,8 +452,6 @@ let
getLicenseFromSpdxIdOr
getExe
getExe'
getDarwinApp
getDarwinApp'
;
inherit (self.filesystem)
pathType

View File

@@ -341,8 +341,9 @@ rec {
f: g: final: prev:
let
fApplied = f final prev;
prev' = prev // fApplied;
in
fApplied // g final (prev // fApplied);
fApplied // g final prev';
/**
Composes a list of [`overlays`](#chap-overlays) and returns a single overlay function that combines them.
@@ -408,7 +409,7 @@ rec {
```
:::
*/
composeManyExtensions = lib.foldr composeExtensions (final: prev: { });
composeManyExtensions = lib.foldr (x: y: composeExtensions x y) (final: prev: { });
/**
Create an overridable, recursive attribute set. For example:
@@ -509,16 +510,13 @@ rec {
:::
*/
toExtension =
let
inherit (lib) isFunction;
in
f:
if isFunction f then
if lib.isFunction f then
final: prev:
let
fPrev = f prev;
in
if isFunction fPrev then
if lib.isFunction fPrev then
# f is (final: prev: { ... })
f final prev
else

View File

@@ -703,6 +703,11 @@ lib.mapAttrs mkLicense (
url = "https://www.schristiancollins.com/generaluser.php"; # license included in sources
};
gfl = {
fullName = "GUST Font License";
url = "https://www.gust.org.pl/projects/e-foundry/licenses/GUST-FONT-LICENSE.txt";
};
gfsl = {
fullName = "GUST Font Source License";
url = "https://www.gust.org.pl/projects/e-foundry/licenses/GUST-FONT-SOURCE-LICENSE.txt";

View File

@@ -581,90 +581,6 @@ rec {
|| throw "lib.meta.getExe': The second argument \"${y}\" is a nested path with a \"/\" character, but it should just be the name of the executable instead.";
"${getBin x}/bin/${y}";
/**
Get the path to the main darwin app of a package based on `meta.mainDarwinApp`
# Inputs
`x`
: 1\. Function argument
# Type
```
getDarwinApp :: Derivation -> StorePath
```
# Examples
:::{.example}
## `lib.meta.getDarwinApp` usage example
```nix
getDarwinApp pkgs.vscodium
=> "/nix/store/0y95mgmlrs8cayv2cnj23xjfljwhlib0-vscodium-1.121.03429/Applications/VSCodium.app"
getDarwinApp pkgs.slack
=> "/nix/store/g52cl8dblki8dr5bkr0vajpkralkmhi0-slack-4.49.89/Applications/Slack.app"
```
:::
*/
getDarwinApp =
x:
getDarwinApp' x (
x.meta.mainDarwinApp or (builtins.throw "getDarwinApp: Package ${
lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name
} does not have the meta.mainDarwinApp attribute. If the package has a main darwin app, please set `meta.mainDarwinApp` in its definition to make this error go away. Otherwise, if the package does not have a main darwin app, or if you don't control its definition, use getDarwinApp' to specify the name to the program, such as lib.getDarwinApp' vscodium \"VSCodium.app\".")
);
/**
Get the path of an darwin app for a derivation.
# Inputs
`x`
: 1\. Function argument
`y`
: 2\. Function argument
# Type
```
getDarwinApp' :: Derivation -> String -> StorePath
```
# Examples
:::{.example}
## `lib.meta.getDarwinApp'` usage example
```nix
getDarwinApp' pkgs.linear "Linear.app"
=> "/nix/store/z4vh6ldb2vpspv307q7mk6wazfmh5dic-linear-1.30.2/Applications/Linear.app"
getDarwinApp' pkgs.vscodium "VSCodium.app"
=> "/nix/store/0y95mgmlrs8cayv2cnj23xjfljwhlib0-vscodium-1.121.03429/Applications/VSCodium.app"
```
:::
*/
getDarwinApp' =
x: y:
assert
isDerivation x
|| throw "lib.meta.getDarwinApp': The first argument is of type ${typeOf x}, but it should be a derivation instead.";
assert
isString y
|| throw "lib.meta.getDarwinApp': The second argument is of type ${typeOf y}, but it should be a string instead.";
assert
lib.hasInfix "/" y == false
|| throw "lib.meta.getDarwinApp': The second argument \"${y}\" is a nested path with a \"/\" character, but it should just be the name of the app instead.";
assert
lib.hasSuffix ".app" y
|| throw "lib.meta.getDarwinApp': The second argument \"${y}\" must end in `.app`";
"${lib.getOutput "out" x}/Applications/${y}";
/**
Generate [CPE parts](#var-meta-identifiers-cpeParts) from inputs. Copies `vendor` and `version` to the output, and sets `update` to `*`.

View File

@@ -1595,76 +1595,17 @@ let
*/
mkDefinition = args@{ file, value, ... }: args // { _type = "definition"; };
/**
Labels a definition with a priority.
See the documentation of `filterOverrides` for the interpretation of the priority value.
Nesting this function usually leads to an invalid definition.
`mkDefault`, `mkOptionDefault`, and `mkForce` partially apply `mkOverride` with common priorities used in the NixOS module system.
# Inputs
`priority`
: A numeric value representing the precedence.
See the documentation of `filterOverrides` for the interpretation of this value.
`content`
: The definition to be labeled with a given priority.
# Examples
:::{.example}
## `lib.modules.mkOverride` usage example
```nix
mkOverride 1000 "hello, world!"
=> { _type = "override"; content = "hello, world!"; priority = 1000; }
```
```nix
(lib.evalModules {
modules = [
{ options.foo = lib.mkOption { }; }
{ config.foo = lib.mkOverride 20 1; }
{ config.foo = lib.mkOverride 10 2; }
];
}).config
=> { foo = 2; }
```
:::
*/
mkOverride = priority: content: {
_type = "override";
inherit priority content;
};
/**
Labels a definition with the priority of option declaration defaults.
*/
mkOptionDefault = mkOverride 1500;
/**
Labels a definition with the priority used in config sections of non-user modules to set a default.
*/
mkDefault = mkOverride 1000;
mkOptionDefault = mkOverride 1500; # priority of option defaults
mkDefault = mkOverride 1000; # used in config sections of non-user modules to set a default
defaultOverridePriority = 100;
/**
Labels a definition with the priority used in image media profiles.
Image media profiles can be derived by inclusion into host config, hence needing to override host config, but do allow users to `mkForce`.
*/
mkImageMediaOverride = mkOverride 60;
/**
Labels a definition with a high priority (low value).
*/
mkImageMediaOverride = mkOverride 60; # image media profiles can be derived by inclusion into host config, hence needing to override host config, but do allow user to mkForce
mkForce = mkOverride 50;
/**
Labels a definition with used by {command}`nixos-rebuild build-vm`.
*/
mkVMOverride = mkOverride 10;
mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’
mkFixStrictness = warn "lib.mkFixStrictness has no effect and will be removed. It returns its argument unmodified, so you can just remove any calls." id;

View File

@@ -719,26 +719,6 @@ let
else
null;
};
swift = {
arch = final.uname.processor;
platform =
if final.isMacOS then
"macosx"
else if final.isiOS then
"iphoneos"
else if final.isLinux then
"linux"
else if final.isWindows then
"windows"
else
null;
triple =
if final.isDarwin then
# FIXME: Can this be done a better way?
"${final.swift.arch}-${final.parsed.vendor.name}-${final.swift.platform}${final.darwinMinVersion}"
else
final.config;
};
};
in
# Platforms elaborated by pre-26.11 Nixpkgs will include the `linux-kernel` attr,

View File

@@ -61,8 +61,6 @@ let
genList
getExe
getExe'
getDarwinApp
getDarwinApp'
getLicenseFromSpdxIdOr
groupBy
groupBy'
@@ -4754,31 +4752,6 @@ runTests {
testGetExe'FailureSecondArg = testingThrow (getExe' { type = "derivation"; } "dir/executable");
testGetDarwinAppOutput = {
expr = getDarwinApp {
type = "derivation";
out = "somelonghash";
bin = "somelonghash";
meta.mainDarwinApp = "mainDarwinApp.app";
};
expected = "somelonghash/Applications/mainDarwinApp.app";
};
testGetDarwinApp'Output = {
expr = getDarwinApp' {
type = "derivation";
out = "somelonghash";
bin = "somelonghash";
} "app.app";
expected = "somelonghash/Applications/app.app";
};
testGetDarwinApp'FailureFirstArg = testingThrow (getDarwinApp' "not a derivation" "executable");
testGetDarwinApp'FailureSecondArg = testingThrow (
getDarwinApp' { type = "derivation"; } "dir/executable"
);
testGetLicenseFromSpdxIdOrExamples = {
expr = [
(getLicenseFromSpdxIdOr "MIT" null)

View File

@@ -161,7 +161,8 @@
"samuela": 226872
},
"members": {
"ethancedwards8": 60861925
"ethancedwards8": 60861925,
"prusnak": 42201
},
"name": "cuda-maintainers"
},
@@ -247,6 +248,7 @@
"mstone": 412508,
"n8henrie": 1234956,
"ofalvai": 1694986,
"prusnak": 42201,
"reckenrode": 7413633,
"ryand56": 22267679,
"samrose": 115821,
@@ -384,31 +386,6 @@
},
"name": "Freedesktop"
},
"gaming": {
"description": "Maintain games, game engines, launchers, compatibility layers, game-related utilities and other gaming software in nixpkgs.",
"id": 19617985,
"maintainers": {
"TomaSajt": 62384384,
"ethancedwards8": 60861925,
"iedame": 60272,
"keenanweaver": 37268985,
"l0b0": 168301
},
"members": {
"DrymarchonShaun": 40149778,
"Gliczy": 129636582,
"Mistyttm": 51770769,
"PaulGrandperrin": 1748936,
"RoGreat": 64620440,
"carlossless": 498906,
"dwt": 57199,
"liamthexpl0rer": 119797945,
"liberodark": 4238928,
"qubitnano": 146656568,
"yvnth": 201552597
},
"name": "Gaming"
},
"geospatial": {
"description": "Maintain geospatial, remote sensing and OpenStreetMap software",
"id": 7084621,
@@ -468,7 +445,8 @@
"id": 4020424,
"maintainers": {
"Mic92": 96200,
"kalbasit": 87115
"kalbasit": 87115,
"katexochen": 49727155
},
"members": {
"mfrw": 4929861,
@@ -962,16 +940,16 @@
"name": "Scala"
},
"sdl": {
"description": "Maintain core SDL libraries. Matrix: #nixpkgs-sdl-team:nixos.org",
"description": "Maintain core SDL libraries",
"id": 13033942,
"maintainers": {
"LordGrimmauld": 49513131,
"marcin-serwin": 12128106,
"pbsds": 140964
},
"members": {
"LordGrimmauld": 49513131,
"evysgarden": 92547295,
"jansol": 2588851
"jansol": 2588851,
"marcin-serwin": 12128106
},
"name": "SDL"
},

View File

@@ -251,7 +251,7 @@
};
_365tuwe = {
name = "Uwe Schlifkowitz";
email = "uwe.schlifkowitz@secunet.com";
email = "supertuwe@gmail.com";
github = "365tuwe";
githubId = 10263091;
};
@@ -460,7 +460,6 @@
name = "aaravrav";
github = "aaravrav";
githubId = 37036762;
matrix = "@hepara:matrix.org";
};
aarnphm = {
email = "contact@aarnphm.xyz";
@@ -3256,12 +3255,6 @@
githubId = 766221;
name = "Ngoc Nguyen";
};
baptiste0928 = {
email = "contact@bgirardeau.me";
github = "baptiste0928";
githubId = 22115890;
name = "Baptiste Girardeau";
};
barab-i = {
email = "barab_i@outlook.com";
github = "barab-i";
@@ -5097,12 +5090,6 @@
githubId = 1689801;
name = "Mikhail Chekan";
};
chemonke = {
email = "nixpkgs@chemonke.ch";
github = "chemonke";
githubId = 183837749;
name = "Curdin Bosshart";
};
chen = {
email = "i@cuichen.cc";
github = "cu1ch3n";
@@ -9526,12 +9513,6 @@
github = "fkautz";
githubId = 135706;
};
fkokosinski = {
name = "Filip Kokosiński";
email = "filip@kokosinski.me";
github = "fkokosinski";
githubId = 19800410;
};
fkomarek = {
name = "Filip Komárek";
github = "filip2cz";
@@ -10824,12 +10805,6 @@
githubId = 273582;
name = "greg";
};
gregl83 = {
email = "general+nixpkgs@gregorylanglais.com";
github = "gregl83";
githubId = 1258023;
name = "gregory langlais";
};
gregshuflin = {
email = "greg@everdayimshuflin.com";
github = "neunenak";
@@ -11538,13 +11513,6 @@
githubId = 58676303;
name = "hhydraa";
};
hideyosh1 = {
email = "penelope.zhong@proton.me";
keys = [ { fingerprint = "01E9 0D3E 815F 84CA 1003 E7D7 2F75 2D18 C2C1 7AF8"; } ];
name = "Penelope Zhong";
github = "hideyosh1";
githubId = 64223175;
};
higebu = {
name = "Yuya Kusakabe";
email = "yuya.kusakabe@gmail.com";
@@ -12175,12 +12143,6 @@
githubId = 71074737;
name = "Simon Wick";
};
ilovelinux = {
email = "nix+nixpkgs@ilovelinux.dev";
github = "ilovelinux";
githubId = 9268789;
name = "Antonio Spadaro";
};
ilya-epifanov = {
email = "mail@ilya.network";
github = "ilya-epifanov";
@@ -12675,12 +12637,6 @@
github = "j0hax";
githubId = 3802620;
};
j0schu = {
name = "Jonas";
email = "Joschu2015@t-online.de";
github = "J0schu";
githubId = 56407950;
};
j0xaf = {
email = "j0xaf@j0xaf.de";
name = "Jörn Gersdorf";
@@ -13197,13 +13153,6 @@
githubId = 2377;
name = "Jonathan del Strother";
};
jderrac = {
email = "jeremy@derrac.fr";
github = "jderrac";
githubId = 1788613;
name = "Jérémy Derrac";
keys = [ { fingerprint = "7B18 DA58 169F AEB8 6826 D1D6 BED4 91C6 40AB 31DD"; } ];
};
jdev082 = {
email = "jdev0894@gmail.com";
github = "jdev082";
@@ -13674,12 +13623,6 @@
githubId = 474643;
name = "José Miguel Martínez Carrasco";
};
jm5905938 = {
email = "jm5905938@gmail.com";
github = "jm5905938";
githubId = 187073435;
name = "Aveline Noir";
};
jmagnusj = {
email = "jmagnusj@gmail.com";
github = "magnusjonsson";
@@ -14144,12 +14087,6 @@
github = "jooooscha";
githubId = 57965027;
};
joseg313 = {
name = "Jose Garcia";
email = "501jag3@gmail.com";
github = "joseg313";
githubId = 215610619;
};
josephschmitt = {
name = "Joseph Schmitt";
email = "dev@joe.sh";
@@ -15068,11 +15005,6 @@
githubId = 45126464;
name = "Adam J.";
};
kfears = {
github = "kfearsoff";
githubId = 66781795;
name = "KFears";
};
kfiz = {
email = "doroerose@gmail.com";
github = "kfiz";
@@ -15375,13 +15307,6 @@
githubId = 231780064;
name = "Klea";
};
kleiner3 = {
name = "kleiner3";
email = "nixos@dasriley.de";
github = "kleiner3";
githubId = 49880817;
matrix = "@riley:catgirl.industries";
};
klntsky = {
email = "klntsky@gmail.com";
name = "Vladimir Kalnitsky";
@@ -15850,11 +15775,6 @@
github = "kumpelinus";
githubId = 174106140;
};
kunkka19xx = {
name = "Kunkka";
github = "kunkka19xx";
githubId = 53131553;
};
KunyaKud = {
name = "KunyaKud";
email = "wafuu@posteo.net";
@@ -16440,12 +16360,6 @@
githubId = 80920;
name = "Levi Gross";
};
levihuayuzhang = {
email = "zhanghuayu.dev@gmail.com";
name = "Huayu Zhang";
github = "levihuayuzhang";
githubId = 68364307;
};
Levizor = {
email = "levizor@disroot.org";
github = "Levizor";
@@ -17667,12 +17581,6 @@
githubId = 85435692;
name = "Maxwell Berg";
};
Mahdi-zarei = {
email = "mahdi.zrei@gmail.com";
github = "Mahdi-zarei";
githubId = 80265960;
name = "Mahdi";
};
mahe = {
email = "matthias.mh.herrmann@gmail.com";
github = "2chilled";
@@ -18601,11 +18509,6 @@
{ fingerprint = "838A FE0D 55DC 074E 360F 943A 84B6 9CE6 F3F6 B767"; }
];
};
MCT32 = {
github = "MCT32";
githubId = 32090502;
name = "MCT32";
};
mcuste = {
email = "github@muratcanuste.com";
github = "mcuste";
@@ -18825,13 +18728,6 @@
github = "mfairley";
githubId = 4374785;
};
mfocko = {
name = "Matej Focko";
github = "mfocko";
githubId = 8149784;
email = "me@mfocko.xyz";
matrix = "@mfocko:fedora.im";
};
mfossen = {
email = "msfossen@gmail.com";
github = "mfossen";
@@ -20198,12 +20094,6 @@
githubId = 52401682;
name = "myul";
};
Myxogastria0808 = {
email = "r.rstudio.c@gmail.com";
github = "Myxogastria0808";
githubId = 78744619;
name = "Yuki Osada";
};
myypo = {
email = "nikirsmcgl@gmail.com";
github = "myypo";
@@ -26076,12 +25966,6 @@
githubId = 11632726;
name = "Arijit Basu";
};
saylesss88 = {
email = "saylesss87@proton.me";
github = "saylesss88";
githubId = 209646716;
name = "T. Sawyer";
};
sb0 = {
email = "sb@m-labs.hk";
github = "sbourdeauducq";
@@ -26797,11 +26681,6 @@
github = "shimunn";
githubId = 41011289;
};
shinbunbun = {
name = "shinbunbun";
github = "shinbunbun";
githubId = 34409044;
};
shiphan = {
email = "timlin940511@gmail.com";
name = "Shiphan";
@@ -28718,11 +28597,6 @@
githubId = 2389333;
name = "Andy Tockman";
};
Teamofeyy = {
name = "Teamofeyy";
github = "Teamofeyy";
githubId = 128955381;
};
teatwig = {
email = "nix@teatwig.net";
name = "tea";
@@ -29104,13 +28978,6 @@
github = "thelissimus";
githubId = 70096720;
};
thelolcoder2007 = {
name = "thelolcoder2007";
github = "thelolcoder2007";
githubId = 52106896;
matrix = "@erents:dapperepoging.nl";
keys = [ { fingerprint = "E374 815F C754 462B 1C34 3562 FDC3 99DE 8F7E 200B"; } ];
};
themadbit = {
name = "Mark Tanui";
email = "marktanui75@gmail.com";
@@ -31704,10 +31571,10 @@
];
};
wrench-exile-legacy = {
email = "hello@wrenchd.dev";
email = "user@wrench-exile-legacy.site";
github = "wrench-exile-legacy";
githubId = 280737824;
name = "wrenchd";
name = "wrench";
};
wrmilling = {
name = "Winston R. Milling";

View File

@@ -108,6 +108,7 @@ with lib.maintainers;
members = [
lopsided98
mic92
zowoq
];
scope = "Maintain Buildbot CI framework";
shortName = "Buildbot";
@@ -291,10 +292,6 @@ with lib.maintainers;
github = "freedesktop";
};
gaming = {
github = "gaming";
};
gcc = {
members = [
vcunat
@@ -754,7 +751,6 @@ with lib.maintainers;
swift = {
members = [
reckenrode
samasaur
stephank
];

View File

@@ -144,14 +144,10 @@
- [Netbird Relay](https://netbird.io/), a module to relay traffic when a point-to-point connection is not possible.
- [ollaya](https://ollaya.dev), a server for local decision models, with an Ollama-style CLI and a TypeSafe-compatible API. Available as [services.ollaya](#opt-services.ollaya.enable).
## Backward Incompatibilities {#sec-release-26.11-incompatibilities}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
- `services.autobrr.secretFile` has been removed, as autobrr no longer uses a session secret since version 1.82.0. Remove the option from your configuration.
- Artalk has been updated to 2.10.0. Its default configuration and data
directory discovery changed; see the [upstream migration
guide](https://artalk.js.org/en/guide/releases/v2.10.0.html) when invoking
@@ -211,8 +207,6 @@
- The `jetty_11` package has been removed as it reached end of life. Use `jetty_12` instead.
- The postsrsd module now supports integrating with Postfix as a milter. The [](#opt-services.postsrsd.configurePostfix) option has become an enum to reflect the different integration options. Boolean values are deprecated and will be removed in NixOS 27.05. The previous default `true` is equivalent to `socketmap`.
- The Mullvad VPN service now has a separate toggle to enable the Mullvad VPN graphical user interface. If you have previously used Mullvad on a desktop by setting `services.mullvad-vpn.package` to `pkgs.mullvad-vpn`, you should now **unset that option**, and enable `services.mullvad-vpn.gui.enable`. The VPN will not work if `services.mullvad-vpn.package` is set to `pkgs.mullvad-vpn`, as `pkgs.mullvad-vpn` no longer contains the Mullvad Daemon; please ensure that `services.mullvad-vpn.package` is set to `pkgs.mullvad`, regardless if you plan to enable the graphical user interface or not.
- TUI command of `tracexec` now allocates a pseudo terminal by default. Use `--no-tty` to run without one and redirect the tracee's stdin, stdout, and
@@ -308,11 +302,9 @@
- `chatgpt` has been retargeted to OpenAI's new ChatGPT desktop app, while the previous app has been renamed to `chatgpt-classic`.
- NetBox was updated to `>= 4.7.0`. Have a look at the breaking changes
of the [4.6 release](https://github.com/netbox-community/netbox/releases/tag/v4.6.0)
and the [4.7 release](https://github.com/netbox-community/netbox/releases/tag/v4.7.0),
make the required changes to your configuration and database, if needed,
before you upgrade to NixOS 26.11.
- NetBox was updated to `>= 4.6.8`. Have a look at the breaking changes
of the [4.6 release](https://github.com/netbox-community/netbox/releases/tag/v4.6.0),
make the required changes to your database, if needed, then upgrade by setting `services.netbox.package = pkgs.netbox_4_6;` in your configuration.
- The COSMIC desktop module now enables by default `system76-power` and `system76-scheduler` following upstream recommended packages. The previous power managment service can be enabled back by setting `services.power-profiles-daemon.enable = true`.
@@ -338,41 +330,6 @@
- The `shell_interact()` function on interactive runs of NixOS VM tests has been deprecated. Use the SSH backdoor instead.
- The {option}`programs.fish.shellFunctions` option can now be used to create custom fish functions in a structured manner, as opposed to concatenating strings with {option}`program.fish.interactiveShellInit`.
:::{.example}
# Migrating fish functions to `programs.fish.shellFunctions`
Custom fish functions have historically been defined like so:
```nix
{
programs.fish.interactiveShellInit = ''
function backup --argument filename --description "Creates a backup copy of a file in the current directory."
cp $filename $filename.bak
end
'';
}
```
The above example can be migrated via the following structured code block:
```nix
{
programs.fish.shellFunctions = {
backup = {
modifiers = {
description = "Creates a backup copy of a file in the current directory.";
argument = "filename";
};
body = ''
cp $filename $filename.bak
'';
};
};
}
```
:::
- NixOS VM tests now prefer to express durations and timeouts as `datetime.timedelta` values instead of bare numbers. Methods such as `machine.wait_until_succeeds`, `machine.sleep`, `retry`, and `polling_condition` now accept a `timedelta` (e.g., `machine.wait_for_unit("sshd.service", timeout=datetime.timedelta(minutes=1))`). Passing an `int`/`float` as seconds still works but now emits a deprecation warning. Argument names that explicitly defined units were preserved but have had `timedelta` equivalents introduced (`timeout_seconds` → `timeout`, `secs` → `duration`, `seconds_interval` → `interval`).
- `darwin.linux-builder-vz` has been added: a variant of `darwin.linux-builder` that runs the builder guest on Apple's Virtualization.framework via the new `vzvm` package, translating `x86_64-linux` builds with Rosetta instead of emulating them. Apple silicon hosts only. As part of this, the `nixos/modules/profiles/nix-builder-vm.nix` profile has been split into the backend-neutral `nixos/modules/profiles/nix-builder.nix` and a QEMU-specific part. Existing imports of `nix-builder-vm.nix` keep working unchanged.
@@ -399,8 +356,6 @@ The above example can be migrated via the following structured code block:
- `boot.loader.systemd-boot` gained support for [Automatic Boot Assessment](https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT/) via the new [`boot.loader.systemd-boot.bootCounting`](#opt-boot.loader.systemd-boot.bootCounting.enable) options, allowing automatic detection of and recovery from bad NixOS generations. As part of this change, boot loader entries on the ESP/XBOOTLDR partition are now named `nixos-<content-hash>.conf` instead of `nixos-generation-<n>.conf`; existing entries are migrated automatically on the next `nixos-rebuild boot`/`switch`.
- The Wordpress module now supports auto database migrations using wp-cli, which gets triggered after every package version update.
- `services.nginx` gained a [`lua`](#opt-services.nginx.lua.enable) option to enable Lua scripting via OpenResty's lua-nginx-module on a stock nginx, configuring `lua_package_path`/`lua_package_cpath` from the packages listed in [`services.nginx.lua.extraPackages`](#opt-services.nginx.lua.extraPackages). Use this to add Lua to a regular nginx; for the full OpenResty platform (libraries that rely on its bundled lualib, such as `lua-resty-openidc`), set `services.nginx.package` to `pkgs.openresty` instead — the option configures the Lua search path for it too.
- `services.nginx.virtualHosts.<name>.locations.<name>` gained a new `useGrpcErrorPages` option. If enabled, it sets up error pages that are valid gRPC messages. This is useful if you proxy gRPC and want to emit errors from nginx, for example when adding authentication on top.

View File

@@ -335,7 +335,7 @@ class BaseMachine(ABC):
...
@abstractmethod
def wait_for_shutdown(self, timeout: dt.timedelta | None = None) -> None:
def wait_for_shutdown(self) -> None:
"""Wait for the machine to power off. This does *not* initiate a shutdown;
that's usually done via `shutdown()`.
"""
@@ -1061,7 +1061,7 @@ class QemuMachine(BaseMachine):
break
self.send_console(char.decode())
def wait_for_shutdown(self, timeout: dt.timedelta | None = None) -> None:
def wait_for_shutdown(self) -> None:
"""
Wait for the VM to power off. This does *not* initiate a shutdown;
that's usually done via `shutdown()`.
@@ -1072,9 +1072,7 @@ class QemuMachine(BaseMachine):
with self.nested("waiting for the VM to power off"):
sys.stdout.flush()
assert self.process
self.process.wait(
timeout=timeout.total_seconds() if timeout is not None else None
)
self.process.wait()
self.pid = None
self.booted = False
@@ -1905,7 +1903,7 @@ class NspawnMachine(BaseMachine):
self.systemctl("poweroff")
self.wait_for_shutdown()
def wait_for_shutdown(self, timeout: dt.timedelta | None = None) -> None:
def wait_for_shutdown(self) -> None:
"""
Wait for the container to power off. This does *not* initiate a shutdown;
that's usually done via `shutdown()`.
@@ -1914,9 +1912,7 @@ class NspawnMachine(BaseMachine):
return
with self.nested("waiting for the container to power off"):
self.process.wait(
timeout=timeout.total_seconds() if timeout is not None else None
)
self.process.wait()
self.process = None

View File

@@ -42,7 +42,7 @@ in
};
};
settings.nix-path = mkOption {
nixPath = mkOption {
type = types.listOf types.str;
default =
if cfg.channel.enable then
@@ -80,11 +80,8 @@ in
};
};
imports = [
(lib.mkRenamedOptionModule [ "nix" "nixPath" ] [ "nix" "settings" "nix-path" ])
];
config = mkIf cfg.enable {
environment.extraInit = mkIf cfg.channel.enable ''
if [ -e "$HOME/.nix-defexpr/channels" ]; then
export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
@@ -98,7 +95,7 @@ in
# NIX_PATH has a non-empty default according to Nix docs, so we don't unset
# it when empty.
environment.sessionVariables = {
NIX_PATH = cfg.settings.nix-path;
NIX_PATH = cfg.nixPath;
};
systemd.tmpfiles.rules = lib.mkIf cfg.channel.enable [

View File

@@ -46,7 +46,7 @@ in
powerManagement.powerDownCommands = ''
#flush any bytes in pipe
while read -r -n 1 -t 1 < /tmp/PmMessagesPort_out; do : ; done;
while read -n 1 -t 1 SUSPEND_RESULT < /tmp/PmMessagesPort_out; do : ; done;
#suspend DisplayLinkManager
echo "S" > /tmp/PmMessagesPort_in
@@ -54,7 +54,7 @@ in
#wait until suspend of DisplayLinkManager finish
if [ -f /tmp/PmMessagesPort_out ]; then
#wait until suspend of DisplayLinkManager finish
read -r -n 1 -t 10 < /tmp/PmMessagesPort_out
read -n 1 -t 10 SUSPEND_RESULT < /tmp/PmMessagesPort_out
fi
'';

View File

@@ -63,7 +63,7 @@ in
default = false;
description = ''
Use the Wayland input method frontend.
This doesn't set `GTK_IM_MODULE` and `QT_IM_MODULE` environment variables.
This doesn't set `QT_IM_MODULE` environment variable.
See [Using Fcitx 5 on Wayland](https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland#GTK_IM_MODULE).
'';
};
@@ -90,7 +90,6 @@ in
XMODIFIERS = "@im=ibus";
}
// lib.optionalAttrs (!cfg.waylandFrontend) {
GTK_IM_MODULE = "ibus";
QT_IM_MODULE = "ibus";
};

View File

@@ -72,20 +72,6 @@ $ nixos-version --configuration-revision
aa314ebd1592f6cdd53cb5bba8bcae97d9323de8
.Ed
.
.It Fl -kernel-version
Show the kernel version, e.g.
.Bd -literal -offset indent
$ nixos-version --kernel-version
7.2.5
.Ed
.
.It Fl -specialisations
Show specialisations, separated by spaces, if available, e.g.
.Bd -literal -offset indent
$ nixos-version --specialisations
foo bar
.Ed
.
.It Fl -json
Print a JSON representation of the versions of NixOS and the top-level
configuration flake.

View File

@@ -20,23 +20,8 @@ case "$1" in
fi
echo "@configurationRevision@"
;;
--kernel-version)
if [[ "@kernelVersion@" =~ "@" ]]; then
echo "$0: kernel version is unknown" >&2
exit 1
fi
echo "@kernelVersion@"
;;
--specialisations)
specialisations=@specialisations@
if [[ -z "$specialisations" ]]; then
echo "$0: no specialisations found" >&2
exit 1
fi
printf '%s\n' "$specialisations"
;;
--json)
cat <<'EOF'
cat <<EOF
@json@
EOF
;;

View File

@@ -53,27 +53,13 @@ let
nixos-version = makeProg {
name = "nixos-version";
src = ./nixos-version.sh;
replacements = rec {
replacements = {
inherit (pkgs) runtimeShell;
inherit (config.system.nixos) version codeName revision;
inherit (config.system) configurationRevision;
kernelVersion =
if config.boot.kernel.enable then
# modDirVersion returns 6.18.54-xanmod1 instead of 6.18.54
config.boot.kernelPackages.kernel.modDirVersion or config.boot.kernelPackages.kernel.version
else
null;
specialisations = lib.escapeShellArg (
lib.concatStringsSep " " (lib.attrNames config.specialisation)
);
json = builtins.toJSON (
{
nixosVersion = config.system.nixos.version;
specialisations = lib.attrNames config.specialisation;
}
// lib.optionalAttrs (kernelVersion != null) {
inherit kernelVersion;
}
// lib.optionalAttrs (config.system.nixos.revision != null) {
nixpkgsRevision = config.system.nixos.revision;
@@ -306,7 +292,7 @@ in
{
options.system.tools.${name}.enable = lib.mkEnableOption "${name} script" // {
default = config.nix.enable && !config.system.disableInstallerTools;
defaultText = lib.literalExpression "config.nix.enable && !config.system.disableInstallerTools";
defaultText = "config.nix.enable && !config.system.disableInstallerTools";
};
config = lib.mkIf config.system.tools.${name}.enable {

View File

@@ -102,7 +102,7 @@ in
# because we would need some kind of evil shim taking the *calling* flake's self path,
# perhaps, to ever make that work (in order to know where the Nix expr for the system came
# from and how to call it).
nix.settings.nix-path = lib.mkDefault (
nix.nixPath = lib.mkDefault (
[ "nixpkgs=flake:nixpkgs" ]
++ lib.optional config.nix.channel.enable "/nix/var/nix/profiles/per-user/root/channels"
);

View File

@@ -959,7 +959,6 @@
./services/misc/nzbhydra2.nix
./services/misc/octoprint.nix
./services/misc/ollama.nix
./services/misc/ollaya.nix
./services/misc/ombi.nix
./services/misc/omnom.nix
./services/misc/open-webui.nix
@@ -1259,6 +1258,7 @@
./services/networking/gnunet.nix
./services/networking/go-autoconfig.nix
./services/networking/go-camo.nix
./services/networking/go-neb.nix
./services/networking/go-shadowsocks2.nix
./services/networking/gobgpd.nix
./services/networking/godns.nix

View File

@@ -61,10 +61,11 @@ in
#!${pkgs.runtimeShell}
# Import environment variables
${cfg.extraSessionCommands}
# Start dwl, then set up the systemd user environment once dwl
# has actually set WAYLAND_DISPLAY (see dwl(1) -s), instead of
# importing it before dwl exists.
exec ${lib.getExe cfg.package} -s "systemctl --user import-environment DISPLAY WAYLAND_DISPLAY; systemctl --user start dwl-session.target"
# Setup systemd user environment
systemctl --user import-environment DISPLAY WAYLAND_DISPLAY
systemctl --user start dwl-session.target
# Start dwl
exec ${lib.getExe cfg.package}
'';
mode = "0755"; # Make it executable
};

View File

@@ -33,13 +33,7 @@ in
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
environment.systemPackages = [
cfg.package
];
# Needed to add the freedesktop sound theme
# It's only a runtime dependency for noctalia, so it's not made a package dependency.
xdg.sounds.enable = true;
environment.systemPackages = [ cfg.package ];
systemd.user.services.noctalia = lib.mkIf cfg.systemd.enable {
description = "Noctalia Wayland desktop shell";

View File

@@ -486,10 +486,6 @@ in
See https://www.isc.org/blogs/isc-dhcp-eol/ for details.
Please switch to a different implementation like kea or dnsmasq.
'')
(lib.mkRemovedOptionModule [ "services" "go-neb" ] ''
The Go-NEB project was discontinued by Matrix.org and archived in June
2023. Use matrix-hookshot or another maintained Matrix bot instead.
'')
(mkRemovedOptionModule [ "services" "gsignond" ] ''
The corresponding package was unmaintained, abandoned upstream, used outdated library and thus removed from nixpkgs.
'')

View File

@@ -51,10 +51,7 @@ in
sockets.pwupdd.wantedBy = lib.optional config.users.mutableUsers "sockets.target"; # immutable users do not need password updating
sockets.newidmapd.wantedBy = [ "sockets.target" ];
services."pwupdd@".environment.PWUPDD_OPTS = lib.escapeShellArgs cfg.extraArgs;
services."pwaccessd".environment = {
LD_LIBRARY_PATH = config.system.nssModules.path;
PWACCESSD_OPTS = lib.escapeShellArgs cfg.extraArgs;
};
services."pwaccessd".environment.PWACCESSD_OPTS = lib.escapeShellArgs cfg.extraArgs;
};
environment.systemPackages = [ cfg.package ];

View File

@@ -13,8 +13,6 @@ let
mkPackageOption
mkOption
maintainers
optionals
optionalString
;
inherit (lib.types)
addCheck
@@ -25,10 +23,6 @@ let
str
submodule
;
inherit (pkgs)
writeShellScriptBin
;
cfg = config.services.navidrome;
settingsFormat = pkgs.formats.json { };
in
@@ -152,29 +146,6 @@ in
let
inherit (lib) mkIf optional getExe;
WorkingDirectory = "/var/lib/navidrome";
settingsFile = settingsFormat.generate "navidrome.json" cfg.settings;
# Wrapper so that users can do admin tasks with the configured navidrome
#
# Since it is common that the user may be running this from their home directory,
# or possible something else, we should not inherit the CWD or else it may error
# trying to chdir to it since this runs as the navidrome user.
wrappedNavi = writeShellScriptBin "navidrome-cli" ''
exec systemd-run \
--quiet \
--pty \
--wait \
--service-type=exec \
--collect \
--working-directory=${WorkingDirectory} \
${optionalString (cfg.environmentFile != null) "-p EnvironmentFile=${cfg.environmentFile}"} \
-p Group=${cfg.user} \
-p User=${cfg.group} \
-u navidrome-admin.service \
-- \
${lib.getExe cfg.package} --configfile ${settingsFile} "$@"
'';
in
mkIf cfg.enable {
systemd = {
@@ -198,7 +169,9 @@ in
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${lib.getExe cfg.finalPackage} --configfile ${settingsFile}";
ExecStart = ''
${getExe cfg.finalPackage} --configfile ${settingsFormat.generate "navidrome.json" cfg.settings}
'';
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) [ cfg.environmentFile ];
User = cfg.user;
Group = cfg.group;
@@ -262,10 +235,6 @@ in
users.groups = mkIf (cfg.group == "navidrome") { navidrome = { }; };
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.Port ];
environment.systemPackages = [
wrappedNavi
];
};
meta.doc = ./navidrome.md;

View File

@@ -30,7 +30,6 @@ let
cosmic-launcher
cosmic-notifications
cosmic-osd
cosmic-osk
cosmic-panel
cosmic-session
cosmic-settings
@@ -91,7 +90,6 @@ in
cosmic-reader
cosmic-screenshot
cosmic-term
cosmic-viewer
cosmic-wallpapers
cosmic-sound-theme
glib
@@ -136,11 +134,6 @@ in
open-sans
];
qt = {
enable = lib.mkDefault true;
platformTheme = lib.mkDefault "qt5ct";
};
# Required options for the COSMIC DE
environment.sessionVariables.X11_BASE_RULES_XML = "${config.services.xserver.xkb.dir}/rules/base.xml";
environment.sessionVariables.X11_EXTRA_RULES_XML = "${config.services.xserver.xkb.dir}/rules/base.extras.xml";
@@ -171,7 +164,6 @@ in
hardware.system76.power-daemon.enable = lib.mkDefault (
!config.services.power-profiles-daemon.enable && !config.services.tuned.enable
);
services.switcherooControl.enable = lib.mkDefault true;
warnings = lib.optionals (cfg.showExcludedPkgsWarning && excludedCorePkgs != [ ]) [
''

View File

@@ -48,7 +48,6 @@
# Accounts daemon looks for dbus interfaces in $XDG_DATA_DIRS/accountsservice
environment.XDG_DATA_DIRS = "${config.system.path}/share";
environment.LD_LIBRARY_PATH = config.system.nssModules.path;
}
(

View File

@@ -174,7 +174,7 @@ in
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${cfg.package}/bin/ras-mc-ctl dimm --register-labels";
ExecStart = "${cfg.package}/bin/ras-mc-ctl --register-labels";
RemainAfterExit = true;
};
};

View File

@@ -90,6 +90,8 @@ let
}) cfg.sieve.pipeBins
);
yesOrNo = v: if v then "yes" else "no";
toOption =
i: n: v:
"${i}${toString n} = ${v}";
@@ -101,7 +103,7 @@ let
if isInt v then
toString v
else if isBool v then
lib.boolToYesNo v
yesOrNo v
else if isString v then
v
else if isPath v || isDerivation v then

View File

@@ -6,6 +6,8 @@
}:
let
concatMapLines = f: l: lib.concatStringsSep "\n" (map f l);
cfg = config.services.mlmmj;
stateDir = "/var/lib/mlmmj";
spoolDir = "/var/spool/mlmmj";
@@ -139,10 +141,10 @@ in
];
};
extraAliases = lib.concatMapStringsSep "\n" (alias cfg.listDomain) cfg.mailLists;
extraAliases = concatMapLines (alias cfg.listDomain) cfg.mailLists;
virtual = lib.concatMapStringsSep "\n" (virtual cfg.listDomain) cfg.mailLists;
transport = lib.concatMapStringsSep "\n" (transport cfg.listDomain) cfg.mailLists;
virtual = concatMapLines (virtual cfg.listDomain) cfg.mailLists;
transport = concatMapLines (transport cfg.listDomain) cfg.mailLists;
};
environment.systemPackages = [ pkgs.mlmmj ];
@@ -163,7 +165,7 @@ in
ExecStart = "${pkgs.mlmmj}/bin/mlmmj-maintd -F -d ${spoolDir}/${cfg.listDomain}";
};
preStart = ''
${lib.concatMapStringsSep "\n" (createList cfg.listDomain) cfg.mailLists}
${concatMapLines (createList cfg.listDomain) cfg.mailLists}
${lib.getExe' config.services.postfix.package "postmap"} /etc/postfix/virtual
${lib.getExe' config.services.postfix.package "postmap"} /etc/postfix/transport
'';

View File

@@ -244,6 +244,8 @@ in
"noroot"
"noroot-locked"
];
RuntimeDirectory = "postfix-tlspol";
RuntimeDirectoryMode = "1750";
WorkingDirectory = "/var/cache/postfix-tlspol";
UMask = "0077";
};

View File

@@ -46,14 +46,6 @@ let
configFile = pkgs.writeText "postsrsd.conf" (
renderAttr (lib.filterAttrsRecursive (_: v: v != null) cfg.settings)
);
postfixIntegration =
if cfg.configurePostfix == true then
"socketmap"
else if cfg.configurePostfix == false then
"none"
else
cfg.configurePostfix;
in
{
imports = [
@@ -130,15 +122,6 @@ in
'';
};
milter = lib.mkOption {
type = with lib.types; nullOr (strMatching "^(unix|inet):.+");
default = "unix:/run/postsrsd/milter";
example = "inet:localhost:9997";
description = ''
Milter listener configuration in `unix:/path/to/socket` or `inet:host:port` format.
'';
};
secrets-file = lib.mkOption {
type = lib.types.str;
default = "\${CREDENTIALS_DIRECTORY}/secrets-file";
@@ -185,11 +168,11 @@ in
};
socketmap = lib.mkOption {
type = with lib.types; nullOr (strMatching "^(unix|inet):.+");
default = "unix:/run/postsrsd/socketmap";
type = lib.types.strMatching "^(unix|inet):.+";
default = "unix:/run/postsrsd/socket";
example = "inet:localhost:10003";
description = ''
Socketmap listener configuration in `unix:/path/to/socket` or `inet:host:port` format.
Listener configuration in socket map format native to Postfix configuration.
'';
};
@@ -229,23 +212,10 @@ in
};
configurePostfix = lib.mkOption {
type = lib.types.enum [
true
false
"none"
"socketmap"
"milter"
];
default = "socketmap";
example = "milter";
type = lib.types.bool;
default = true;
description = ''
Whether and how to integrate postsrsd into the local Postfix instance.
::: {.caution}
Boolean values are deprecated and retained for backwards
compatibility. `true` is equivalent to `socketmap`, and `false` is
equivalent to `none`.
:::
Whether to configure the required settings to use postsrsd in the local Postfix instance.
'';
};
@@ -264,41 +234,17 @@ in
};
config = lib.mkMerge [
{
warnings = lib.optionals (cfg.enable && isBool cfg.configurePostfix) [
''
Boolean values are deprecated for `services.postsrsd.configurePostfix` and will be rejected in NixOS 27.05.
Use `none`, `socketmap`, or `milter` instead. `true` is equivalent to `socketmap` and `false` is equivalent to `none`.
''
];
}
(lib.mkIf (cfg.enable && postfixIntegration != "none" && config.services.postfix.enable) {
assertions = [
{
assertion = postfixIntegration == "milter" -> cfg.settings.milter != null;
message = "Configuring Postfix `smtpd_milters` requires `services.postsrsd.settings.milter` to be set.";
}
{
assertion = postfixIntegration == "socketmap" -> cfg.settings.socketmap != null;
message = "Configuring Postfix canonical maps requires `services.postsrsd.settings.socketmap` to be set.";
}
];
services.postfix.settings.main =
lib.optionalAttrs (postfixIntegration == "socketmap") {
# https://github.com/roehling/postsrsd#configuration
sender_canonical_maps = "socketmap:${cfg.settings.socketmap}:forward";
sender_canonical_classes = "envelope_sender";
recipient_canonical_maps = "socketmap:${cfg.settings.socketmap}:reverse";
recipient_canonical_classes = [
"envelope_recipient"
"header_recipient"
];
}
// lib.optionalAttrs (postfixIntegration == "milter") {
# https://github.com/roehling/postsrsd/tree/main#milter-support
smtpd_milters = [ cfg.settings.milter ];
};
(lib.mkIf (cfg.enable && cfg.configurePostfix && config.services.postfix.enable) {
services.postfix.settings.main = {
# https://github.com/roehling/postsrsd#configuration
sender_canonical_maps = "socketmap:${cfg.settings.socketmap}:forward";
sender_canonical_classes = "envelope_sender";
recipient_canonical_maps = "socketmap:${cfg.settings.socketmap}:reverse";
recipient_canonical_classes = [
"envelope_recipient"
"header_recipient"
];
};
users.users.postfix.extraGroups = [ cfg.group ];
})

View File

@@ -20,16 +20,11 @@ let
rawHomeserverUrl = cfg.homeserverUrl;
pantalaimon = {
use = cfg.pantalaimon.enable;
}
// lib.optionalAttrs cfg.pantalaimon.enable {
inherit (cfg.pantalaimon) username;
use = cfg.pantalaimon.enable;
password = "@PANTALAIMON_PASSWORD@"; # will be replaced in "generateConfig"
};
encryption = {
inherit (cfg.settings.encryption) username;
password = "@ENCRYPTION_PASSWORD@"; # will be replaced in "generateConfig"
};
};
moduleConfigFile = pkgs.writeText "module-config.yaml" (
@@ -77,9 +72,6 @@ let
${lib.optionalString (cfg.pantalaimon.passwordFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@PANTALAIMON_PASSWORD@' '${cfg.pantalaimon.passwordFile}' ${cfg.dataPath}/config/default.yaml
''}
${lib.optionalString (cfg.encryption.passwordFile != null) ''
${pkgs.replace-secret}/bin/replace-secret '@ENCRYPTION_PASSWORD@' '${cfg.encryption.passwordFile}' ${cfg.dataPath}/config/default.yaml
''}
''
);
in
@@ -106,14 +98,6 @@ in
'';
};
encryption.passwordFile = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
File containing the matrix password for the `mjolnir` user.
'';
};
pantalaimon = lib.mkOption {
description = ''
`pantalaimon` options (enables E2E Encryption support).
@@ -202,22 +186,17 @@ in
config = lib.mkIf config.services.mjolnir.enable {
assertions = [
{
assertion = !(cfg.settings.encryption.use && cfg.encryption.passwordFile == null);
message = "encryption.passwordFile must be specified when native encryption is used.";
}
{
assertion = !(cfg.pantalaimon.enable && cfg.pantalaimon.passwordFile == null);
message = "pantalaimon.passwordFile must be specified when pantalaimon is enabled.";
message = "Specify pantalaimon.passwordFile";
}
{
assertion = cfg.accessTokenFile == null -> cfg.pantalaimon.enable || cfg.settings.encryption.use;
message = "Do not specify accessTokenFile when using native encryption or pantalaimon";
assertion = !(cfg.pantalaimon.enable && cfg.accessTokenFile != null);
message = "Do not specify accessTokenFile when using pantalaimon";
}
{
assertion =
!(!cfg.pantalaimon.enable && !cfg.settings.encryption.use && cfg.accessTokenFile == null);
message = "Specify accessTokenFile when not using pantalaimon or native encryption.";
assertion = !(!cfg.pantalaimon.enable && cfg.accessTokenFile == null);
message = "Specify accessTokenFile when not using pantalaimon";
}
];

View File

@@ -11,14 +11,6 @@ let
configFile = configFormat.generate "autobrr.toml" cfg.settings;
in
{
imports = [
(lib.mkRemovedOptionModule [
"services"
"autobrr"
"secretFile"
] "autobrr no longer uses a session secret since version 1.82.0.")
];
options = {
services.autobrr = {
enable = lib.mkEnableOption "Autobrr";
@@ -29,6 +21,11 @@ in
description = "Open ports in the firewall for the Autobrr web interface.";
};
secretFile = lib.mkOption {
type = lib.types.path;
description = "File containing the session secret for the Autobrr web interface.";
};
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = configFormat.type;
@@ -70,6 +67,17 @@ in
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = !(cfg.settings ? sessionSecret);
message = ''
Session secrets should not be passed via settings, as
these are stored in the world-readable nix store.
Use the secretFile option instead.'';
}
];
systemd = {
tmpfiles.settings = {
"10-autobrr" = {
@@ -93,6 +101,8 @@ in
serviceConfig = {
Type = "simple";
DynamicUser = true;
LoadCredential = "sessionSecret:${cfg.secretFile}";
Environment = [ "AUTOBRR__SESSION_SECRET_FILE=%d/sessionSecret" ];
StateDirectory = "autobrr";
ExecStart = "${lib.getExe cfg.package} --config %S/autobrr";
Restart = "on-failure";

View File

@@ -1,6 +1,6 @@
# CLIProxyAPI {#module-services-cliproxyapi}
[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) exposes OAuth-based subscription CLIs (Claude Code, Codex, Grok, Antigravity, Kimi, Devin, Meta) behind OpenAI/Gemini/Anthropic-compatible HTTP APIs.
[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) exposes OAuth-based subscription CLIs (Claude Code, Codex, Gemini, Qwen, Grok, Antigravity) behind OpenAI/Gemini/Anthropic-compatible HTTP APIs.
Enable it with:
@@ -10,11 +10,11 @@ Enable it with:
}
```
The service runs as a dedicated `cliproxyapi` user and keeps its configuration and OAuth tokens under `/var/lib/cliproxyapi`. The configuration file is regenerated from [](#opt-services.cliproxyapi.settings) at startup, which overwrites any changes made through the management API.
The service runs as a dedicated `cliproxyapi` user and keeps its configuration and OAuth tokens under `/var/lib/cliproxyapi`.
## Authentication {#module-services-cliproxyapi-authentication}
Provider logins use OAuth and must land in the service's `oauth.auth-dir` (`/var/lib/cliproxyapi`), which is owned by the `cliproxyapi` user. Either of the approaches below writes the token with the correct ownership, and the running service picks it up without a restart.
Provider logins use OAuth and must land in the service's `auth-dir` (`/var/lib/cliproxyapi`), which is owned by the `cliproxyapi` user. Either of the approaches below writes the token with the correct ownership, and the running service picks it up without a restart.
### Management API {#module-services-cliproxyapi-authentication-management-api}
@@ -22,31 +22,19 @@ Set a management key in [](#opt-services.cliproxyapi.settings):
```nix
{
services.cliproxyapi.settings.management.secret-key._secret = "/run/secrets/cliproxyapi-mgmt-key";
services.cliproxyapi.settings.remote-management.secret-key._secret =
"/run/secrets/cliproxyapi-mgmt-key";
}
```
Request a login URL and open it in a browser:
Then request an authentication URL for the desired provider and open it in a browser:
```bash
curl -H "Authorization: Bearer <management-key>" \
"http://127.0.0.1:8317/v8/management/oauth/auth-url?provider=claude"
http://127.0.0.1:8317/v0/management/anthropic-auth-url
```
Other values for `provider` are `codex`, `antigravity`, `kimi`, `kimi-ai`, `xai`, `devin` and `meta`. `kimi`, `kimi-ai`, `xai` and `meta` use a device code, so the login finishes once it is approved in the browser.
For `claude`, `codex` and `antigravity`, the browser ends up on a `localhost` page that fails to load. Send that URL to the daemon to finish the login:
```bash
curl -H "Authorization: Bearer <management-key>" \
-H "Content-Type: application/json" \
-d '{"redirect_url": "<url>"}' \
http://127.0.0.1:8317/v8/management/oauth/callback
```
Alternatively, add `is_webui=true` to the login URL request, and the daemon will listen on the callback port and finish the login itself.
To check on a login, query `/v8/management/oauth/status?state=<state>` with the `state` from the login URL response. It returns `wait` while the login is pending, `ok` once the token is saved and `error` if it failed.
The daemon completes the OAuth flow itself and stores the token in its `auth-dir`. Authentication endpoints are available for the `anthropic`, `codex`, `xai`, `antigravity`, and `kimi` providers.
### Command-line login {#module-services-cliproxyapi-authentication-cli}
@@ -64,4 +52,4 @@ Then run the login as the service user, pointing at the managed configuration:
sudo -u cliproxyapi cliproxyapi -config /var/lib/cliproxyapi/config.yaml --claude-login
```
Other providers have their own flags, such as `--codex-login` or `--xai-login`; see `cliproxyapi -help`. On a headless host, add `-no-browser` to print the login URL. The Claude, Codex, Antigravity and Devin logins then ask you to paste the `localhost` URL you were redirected to.
Other providers use their matching flags, for example `--codex-login` or `--xai-login`. On a headless host, pass `-no-browser` to print the OAuth URL instead of launching a browser.

View File

@@ -10,9 +10,14 @@ let
format = pkgs.formats.yaml { };
stateDir = "/var/lib/cliproxyapi";
configPath = "${stateDir}/config.yaml";
settings = {
auth-dir = stateDir;
}
// cfg.settings;
secretsReplacement = utils.genJqSecretsReplacement {
loadCredential = true;
} cfg.settings configPath;
} settings configPath;
port = cfg.settings.port or 8317;
in
{
options.services.cliproxyapi = {
@@ -21,30 +26,14 @@ in
package = lib.mkPackageOption pkgs "cliproxyapi" { };
settings = lib.mkOption {
type = lib.types.submodule {
freeformType = format.type;
options = {
server.port = lib.mkOption {
type = lib.types.port;
default = 8317;
description = "Port on which CLIProxyAPI listens.";
};
oauth.auth-dir = lib.mkOption {
type = lib.types.str;
default = stateDir;
description = "Directory where OAuth tokens are stored.";
};
};
};
type = format.type;
default = { };
example = lib.literalExpression ''
{
server = {
host = "127.0.0.1";
port = 8317;
};
access.api-keys = [ { _secret = "/run/secrets/cliproxyapi-api-key"; } ];
management.secret-key._secret = "/run/secrets/cliproxyapi-management-key";
host = "127.0.0.1";
port = 8317;
api-keys = [ { _secret = "/run/secrets/cliproxyapi-api-key"; } ];
remote-management.secret-key._secret = "/run/secrets/cliproxyapi-management-key";
}
'';
description = ''
@@ -65,7 +54,7 @@ in
openFirewall = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Whether to open the firewall for {option}`services.cliproxyapi.settings.server.port`.";
description = "Whether to open the firewall for the specified port.";
};
user = lib.mkOption {
@@ -153,7 +142,7 @@ in
};
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.settings.server.port ];
allowedTCPPorts = [ port ];
};
};

View File

@@ -1801,6 +1801,7 @@ in
Slice = "system-gitlab.slice";
ExecStart = "${gitlab-rake}/bin/gitlab-rake gitlab:backup:create";
Type = "oneshot";
RemainAfterExit = true;
};
};

View File

@@ -1,228 +0,0 @@
{
config,
lib,
pkgs,
...
}:
let
inherit (lib) literalExpression types;
cfg = config.services.ollaya;
ollaya = lib.getExe cfg.package;
staticUser = cfg.user != null && cfg.group != null;
in
{
options.services.ollaya = {
enable = lib.mkEnableOption "ollaya server for local decision models";
package = lib.mkPackageOption pkgs "ollaya" { };
user = lib.mkOption {
type = types.nullOr types.str;
default = null;
example = "ollaya";
description = ''
User account under which to run ollaya. Defaults to
[`DynamicUser`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=)
when set to `null`.
The user will automatically be created when this option is non-null.
'';
};
group = lib.mkOption {
type = types.nullOr types.str;
default = cfg.user;
defaultText = literalExpression "config.services.ollaya.user";
example = "ollaya";
description = ''
Group under which to run ollaya. Only used when `services.ollaya.user` is set.
'';
};
home = lib.mkOption {
type = types.str;
default = "/var/lib/ollaya";
example = "/home/foo";
description = "The home directory that the ollaya service is started in.";
};
modelsDir = lib.mkOption {
type = types.str;
default = "${cfg.home}/models";
defaultText = literalExpression "\${config.services.ollaya.home}/models";
example = "/path/to/ollaya/models";
description = ''
Directory where ollaya reads and stores downloaded models.
'';
};
host = lib.mkOption {
type = types.str;
default = "127.0.0.1";
example = "0.0.0.0";
description = "IP address on which the server listens.";
};
port = lib.mkOption {
type = types.port;
default = 11435;
example = 11111;
description = "Port on which the server listens.";
};
settings = lib.mkOption {
type = types.submodule { freeformType = types.attrsOf types.str; };
default = { };
example = {
OLLAYA_DEVICE = "cuda";
OLLAYA_KEEP_ALIVE = "30m";
};
description = ''
Environment variables passed to the ollaya server process.
See <https://ollaya.dev/docs/cli#ollaya-serve> for available variables.
'';
};
loadModels = lib.mkOption {
type = types.listOf types.str;
apply = builtins.filter (model: model != "");
default = [ ];
example = [ "winnow:e4b" ];
description = ''
Models to download after the ollaya service starts. This creates a
separate `ollaya-model-loader.service`.
'';
};
openFirewall = lib.mkOption {
type = types.bool;
default = false;
description = ''
Whether to open the firewall for ollaya. This adds
`services.ollaya.port` to `networking.firewall.allowedTCPPorts`.
'';
};
};
config = lib.mkIf cfg.enable {
users = lib.mkIf staticUser {
users.${cfg.user} = {
inherit (cfg) home;
isSystemUser = true;
group = cfg.group;
};
groups.${cfg.group} = { };
};
systemd.services.ollaya = {
description = "Server for local decision models";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
environment = cfg.settings // {
HOME = cfg.home;
OLLAYA_MODELS = cfg.modelsDir;
OLLAYA_HOST = "${cfg.host}:${toString cfg.port}";
};
serviceConfig =
lib.optionalAttrs staticUser {
User = cfg.user;
Group = cfg.group;
}
// {
Type = "exec";
DynamicUser = true;
ExecStart = "${ollaya} serve";
WorkingDirectory = cfg.home;
StateDirectory = [ "ollaya" ];
ReadWritePaths = [
cfg.home
cfg.modelsDir
];
CapabilityBoundingSet = [ "" ];
DeviceAllow = [
"char-nvidiactl"
"char-nvidia-caps"
"char-nvidia-frontend"
"char-nvidia-uvm"
"char-drm"
"char-fb"
"char-kfd"
"/dev/dxg"
];
DevicePolicy = "closed";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = false;
PrivateTmp = true;
PrivateUsers = true;
ProcSubset = "all";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "strict";
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
SupplementaryGroups = [ "render" ];
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service @resources"
"~@privileged"
];
UMask = "0077";
};
};
systemd.services.ollaya-model-loader = lib.mkIf (cfg.loadModels != [ ]) {
description = "Download ollaya models in the background";
wantedBy = [
"multi-user.target"
"ollaya.service"
];
wants = [ "network-online.target" ];
after = [
"ollaya.service"
"network-online.target"
];
bindsTo = [ "ollaya.service" ];
environment = config.systemd.services.ollaya.environment;
serviceConfig = {
Type = "exec";
DynamicUser = true;
Restart = "on-failure";
RestartSec = "1s";
RestartMaxDelaySec = "2h";
RestartSteps = "10";
};
script =
let
nproc = lib.getExe' pkgs.coreutils "nproc";
xargs = lib.getExe' pkgs.findutils "xargs";
in
''
printf "%s\0" ${lib.escapeShellArgs cfg.loadModels} | '${xargs}' -0 -r -n 1 -P "$('${nproc}')" '${ollaya}' pull
'';
};
networking.firewall.allowedTCPPorts = lib.optional cfg.openFirewall cfg.port;
environment.systemPackages = [ cfg.package ];
};
meta.maintainers = with lib.maintainers; [ happysalada ];
}

View File

@@ -38,8 +38,12 @@ let
PAPERLESS_REDIS = "unix://${redisServer.unixSocket}";
}
// lib.optionalAttrs (cfg.settings.PAPERLESS_AI_ENABLED or true) {
NLTK_DATA = cfg.package.nltkDataDir;
TIKTOKEN_CACHE_DIR = cfg.package.tiktokenCacheDir;
}
// lib.optionalAttrs (cfg.settings.PAPERLESS_ENABLE_NLTK or true) {
PAPERLESS_NLTK_DIR = cfg.package.nltkDataDir;
}
// lib.optionalAttrs (cfg.openMPThreadingWorkaround) {
OMP_NUM_THREADS = "1";
}
@@ -713,9 +717,7 @@ in
"d '${cfg.exporter.directory}' - ${cfg.user} ${config.users.users.${cfg.user}.group} - -"
];
services.paperless.exporter.settings = lib.mapAttrs (
_: v: lib.mkDefault v
) options.services.paperless.exporter.settings.default;
services.paperless.exporter.settings = options.services.paperless.exporter.settings.default;
systemd.services.paperless-exporter = {
startAt = lib.defaultTo [ ] cfg.exporter.onCalendar;

View File

@@ -6,76 +6,6 @@
}:
let
cfg = config.services.beszel.agent;
hasVideoDriver = driver: builtins.elem driver config.services.xserver.videoDrivers;
# Collector names must match `isValidCollectorSource` in upstream's agent/gpu.go.
# macmon and powermetrics are macOS-only and omitted here.
gpuCollectors = {
# read sysfs directly, need no package or device access
"amd_sysfs" = { };
"intel_sysfs" = { };
"intel_gpu_top" = {
package = lib.getBin pkgs.intel-gpu-tools;
deviceAllow = [ "char-drm rw" ];
capabilities = [ "CAP_PERFMON" ];
# perf_event_open is in @debug, not @system-service
systemCalls = [ "perf_event_open" ];
};
"nvidia-smi" = {
package = lib.getBin config.hardware.nvidia.package;
deviceAllow = [ "char-nvidia* rw" ];
};
"nvml" = {
deviceAllow = [ "char-nvidia* rw" ];
};
"nvtop" = {
package = lib.getBin pkgs.nvtopPackages.full;
deviceAllow = [
"char-nvidia* rw"
"char-drm rw"
];
};
"rocm-smi" = {
package = lib.getBin pkgs.rocmPackages.rocm-smi;
deviceAllow = [
"char-drm rw"
"char-kfd rw"
];
};
};
activeCollectors = lib.optionals (!cfg.environment.SKIP_GPU) cfg.environment.GPU_COLLECTOR;
collectorAttrs =
attr: lib.unique (lib.concatMap (name: gpuCollectors.${name}.${attr} or [ ]) activeCollectors);
gpuPackages = map (name: gpuCollectors.${name}.package) (
lib.filter (name: gpuCollectors.${name} ? package) activeCollectors
);
gpuNeedsDevices = collectorAttrs "deviceAllow" != [ ];
# capabilities granted under PrivateUsers are void on the host, see
# systemd.exec(5), so these collectors also need the user namespace disabled
gpuNeedsCapabilities = collectorAttrs "capabilities" != [ ];
# Any explicit DeviceAllow turns DevicePolicy=auto into an allow-list, so the GPU
# devices are omitted when smartmon relies on full /dev access.
deviceAllowList =
lib.optionals (cfg.smartmon.enable && cfg.smartmon.deviceAllow != [ ]) (
map (device: "${device} r") cfg.smartmon.deviceAllow
)
++ lib.optionals (!cfg.smartmon.enable || cfg.smartmon.deviceAllow != [ ]) (
collectorAttrs "deviceAllow" ++ lib.optionals config.boot.zfs.enabled [ "/dev/zfs rw" ]
);
serviceCapabilities =
lib.optionals cfg.smartmon.enable [
"CAP_SYS_RAWIO"
"CAP_SYS_ADMIN"
]
++ collectorAttrs "capabilities";
in
{
meta.maintainers = with lib.maintainers; [
@@ -130,45 +60,6 @@ in
Enabling this option will skip systemd tracking and its setup in NixOS.
'';
};
SKIP_GPU = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to disable GPU monitoring.
Enabling this option will skip GPU tracking.
'';
};
GPU_COLLECTOR = lib.mkOption {
# upstream takes a comma-separated string, which used to be passed through as is
type =
with lib.types;
coercedTo str (value: map lib.trim (lib.splitString "," value)) (
listOf (enum (lib.attrNames gpuCollectors))
);
default =
lib.optionals (hasVideoDriver "nvidia") [ "nvidia-smi" ]
++ lib.optionals (hasVideoDriver "amdgpu") [ "amd_sysfs" ]
++ lib.optionals (hasVideoDriver "intel") [ "intel_sysfs" ];
defaultText = lib.literalMD ''
derived from {option}`services.xserver.videoDrivers`
'';
example = [
"nvidia-smi"
"intel_gpu_top"
];
description = ''
GPU collectors to use, in priority order. Overrides the agent's
auto-detection; the packages needed by the selected collectors are added
to the service path. If empty, the agent auto-detects available
collectors. `rocm-smi` is deprecated upstream in favour of `amd_sysfs`,
and `intel_gpu_top` is not used on the xe driver, where `intel_sysfs` is
preferred.
Access to GPU device nodes is only granted for the collectors listed
here, so a collector provided through
{option}`services.beszel.agent.extraPath` has to be listed as well.
'';
};
};
};
default = { };
@@ -238,22 +129,22 @@ in
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
# drop empty lists so an unset GPU_COLLECTOR keeps upstream auto-detection
environment = lib.mapAttrs (
_: value:
if lib.isBool value then
(lib.boolToString value)
else if lib.isList value then
lib.concatStringsSep "," value
else
value
) (lib.filterAttrs (_: value: value != [ ]) (cfg.environment // { DATA_DIR = cfg.dataDir; }));
_: value: if lib.isBool value then (lib.boolToString value) else value
) (cfg.environment // { DATA_DIR = cfg.dataDir; });
path =
cfg.extraPath
++ lib.optionals cfg.smartmon.enable [ cfg.smartmon.package ]
++ lib.optionals config.boot.zfs.enabled [ config.boot.zfs.package ]
++ gpuPackages;
++ lib.optionals (builtins.elem "nvidia" config.services.xserver.videoDrivers) [
(lib.getBin config.hardware.nvidia.package)
]
++ lib.optionals (builtins.elem "amdgpu" config.services.xserver.videoDrivers) [
(lib.getBin pkgs.rocmPackages.rocm-smi)
]
++ lib.optionals (builtins.elem "intel" config.services.xserver.videoDrivers) [
(lib.getBin pkgs.intel-gpu-tools)
];
serviceConfig = {
ExecStart = ''
@@ -274,22 +165,26 @@ in
DynamicUser = true;
User = "beszel-agent";
# Capabilities needed for SMART monitoring and GPU performance counters
AmbientCapabilities = serviceCapabilities;
CapabilityBoundingSet = serviceCapabilities;
# Capabilities needed for SMART monitoring
AmbientCapabilities = lib.mkIf cfg.smartmon.enable [
"CAP_SYS_RAWIO"
"CAP_SYS_ADMIN"
];
CapabilityBoundingSet = lib.mkIf cfg.smartmon.enable [
"CAP_SYS_RAWIO"
"CAP_SYS_ADMIN"
];
DeviceAllow = lib.mkIf (deviceAllowList != [ ]) deviceAllowList;
# Device access for SMART monitoring
DeviceAllow = lib.mkIf (cfg.smartmon.enable && cfg.smartmon.deviceAllow != [ ]) (
map (device: "${device} r") cfg.smartmon.deviceAllow
);
LockPersonality = true;
NoNewPrivileges = !cfg.smartmon.enable;
PrivateDevices = !cfg.smartmon.enable && !gpuNeedsDevices;
PrivateDevices = !cfg.smartmon.enable;
PrivateTmp = true;
# zfs commands fail inside a user namespace since zfs 2.2, see syncoid.nix
PrivateUsers =
!cfg.smartmon.enable
&& !config.boot.zfs.enabled
&& !cfg.environment.SKIP_SYSTEMD
&& !gpuNeedsCapabilities;
PrivateUsers = !cfg.smartmon.enable && !cfg.environment.SKIP_SYSTEMD;
ProtectClock = true;
ProtectControlGroups = "strict";
ProtectHome = "read-only";
@@ -304,7 +199,7 @@ in
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = [ "@system-service" ] ++ collectorAttrs "systemCalls";
SystemCallFilter = [ "@system-service" ];
Type = "simple";
UMask = 27;
};

View File

@@ -95,8 +95,8 @@ in
DynamicUser = true;
StateDirectory = "glpi-agent";
CapabilityBoundingSet = [ "CAP_DAC_READ_SEARCH" ];
AmbientCapabilities = [ "CAP_DAC_READ_SEARCH" ];
CapabilityBoundingSet = [ "CAP_SYS_ADMIN" ];
AmbientCapabilities = [ "CAP_SYS_ADMIN" ];
LimitCORE = 0;
LimitNOFILE = 65535;
@@ -104,7 +104,7 @@ in
MemorySwapMax = 0;
MemoryZSwapMax = 0;
PrivateTmp = true;
ProcSubset = "all";
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;

View File

@@ -32,14 +32,10 @@ let
inherit (package) phpPackage;
phpOptions = toKeyValue cfg.phpOptions;
preferLocalBuild = true;
strictDeps = true;
__structuredAttrs = true;
passAsFile = [ "phpOptions" ];
}
''
(
cat $phpPackage/etc/php.ini
printf "%s" "$phpOptions"
) > $out
cat $phpPackage/etc/php.ini $phpOptionsPath > $out
'';
artisanWrapper = pkgs.writeShellScriptBin "librenms-artisan" ''

View File

@@ -113,7 +113,20 @@ let
filterAttrsListRecursive =
pred: x:
if isAttrs x then
mapAttrs (_: filterAttrsListRecursive pred) (filterAttrs pred x)
listToAttrs (
concatMap (
name:
let
v = x.${name};
in
if pred name v then
[
(nameValuePair name (filterAttrsListRecursive pred v))
]
else
[ ]
) (attrNames x)
)
else if isList x then
map (filterAttrsListRecursive pred) x
else

View File

@@ -11,10 +11,6 @@ let
configFile = settingsFormat.generate "config.toml" cfg.extraConfig;
in
{
meta = {
inherit (pkgs.telegraf.meta) maintainers;
};
###### interface
options = {
services.telegraf = {

View File

@@ -240,8 +240,6 @@ in
"AF_INET"
"AF_INET6"
]
# AF_UNIX to be able to connect to e.g. /dev/log
++ lib.optionals (cfg.settings.log.file or "" == "syslog") [ "AF_UNIX" ]
++ lib.optionals cfg.allowDHCP [ "AF_PACKET" ];
RestrictNamespaces = true;
RestrictRealtime = true;

View File

@@ -21,6 +21,8 @@ let
(listOf settingType)
];
genAttrs' = names: f: lib.listToAttrs (map f names);
regexEscape =
let
# taken from https://github.com/python/cpython/blob/05cb728d68a278d11466f9a6c8258d914135c96c/Lib/re.py#L251-L266
@@ -298,7 +300,7 @@ in
lib.mapAttrsToList (name: cfg: {
${cfg.nginx.virtualHost} = {
locations =
(lib.genAttrs' [ "cgit.css" "cgit.js" "cgit.png" "favicon.ico" "robots.txt" ] (
(genAttrs' [ "cgit.css" "cgit.js" "cgit.png" "favicon.ico" "robots.txt" ] (
fileName:
lib.nameValuePair "= ${stripLocation cfg}/${fileName}" {
alias = lib.mkDefault "${cfg.package}/cgit/${fileName}";

View File

@@ -7,6 +7,7 @@
let
cfg = config.services.cloudflare-ddns;
boolToString = b: if b then "true" else "false";
formatList = l: lib.concatStringsSep "," l;
in
{
@@ -264,7 +265,7 @@ in
let
toEnv = name: value: "${name}=\"${toString value}\"";
toEnvList = name: value: "${name}=\"${formatList value}\"";
toEnvBool = name: value: "${name}=\"${lib.boolToString value}\"";
toEnvBool = name: value: "${name}=\"${boolToString value}\"";
toEnvMaybe =
pred: name: value:
lib.optionalString pred (toEnv name value);

View File

@@ -13,6 +13,7 @@ let
mkEnableOption
mkIf
mkOption
mkOverride
mkPackageOption
nameValuePair
recursiveUpdate
@@ -350,11 +351,13 @@ in
fedimintdName: cfg:
(nameValuePair cfg.nginx.fqdn (
lib.mkMerge [
(lib.mapAttrsRecursive (_: lib.mkDefault) cfg.nginx.config)
cfg.nginx.config
{
enableACME = true;
forceSSL = true;
# Note: we want by default to enable OpenSSL, but it seems anything 100 and above is
# overridden by default value from vhost-options.nix
enableACME = mkOverride 99 true;
forceSSL = mkOverride 99 true;
locations.${cfg.nginx.path_ws} = {
proxyPass = "http://127.0.0.1:${toString cfg.api_ws.port}/";
proxyWebsockets = true;

View File

@@ -0,0 +1,10 @@
{ lib, ... }:
{
imports = [
(lib.mkRemovedOptionModule [ "services" "go-neb" ] ''
The Go-NEB project was discontinued by Matrix.org and archived in June
2023. Use matrix-hookshot or another maintained Matrix bot instead.
'')
];
}

View File

@@ -20,24 +20,6 @@ in
default = null;
description = "Portal to discover targets on";
};
discoverType = mkOption {
description = ''
Target discovery type.
Change this if you want to discover your targes via an iSNS server
or use the targets provided via firmware settings.
See {manpage}`iscsiadm(8)`.
'';
default = "sendtargets";
example = "sendtargets";
type = enum [
"st"
"sendtargets"
"isns"
"fw"
];
};
name = mkOption {
type = str;
description = "Name of this iscsi initiator";
@@ -99,7 +81,7 @@ in
wantedBy = [ "remote-fs.target" ];
serviceConfig.ExecStartPre =
mkIf (cfg.discoverPortal != null)
"${cfg.package}/bin/iscsiadm --mode discoverydb --type ${cfg.discoverType} --portal ${escapeShellArg cfg.discoverPortal} --discover";
"${cfg.package}/bin/iscsiadm --mode discoverydb --type sendtargets --portal ${escapeShellArg cfg.discoverPortal} --discover";
};
environment.systemPackages = [ cfg.package ];

View File

@@ -43,23 +43,6 @@ in
type = nullOr str;
};
discoverType = mkOption {
description = ''
Target discovery type.
Change this if you want to discover your targes via an iSNS server
or use the targets provided via firmware settings.
See {manpage}`iscsiadm(8)`.
'';
default = "sendtargets";
example = "sendtargets";
type = enum [
"st"
"sendtargets"
"isns"
"fw"
];
};
target = mkOption {
description = ''
Name of the iSCSI target to boot from.
@@ -185,7 +168,7 @@ in
iscsid --foreground --no-pid-file --debug ${toString cfg.logLevel} &
iscsiadm --mode discoverydb \
--type ${cfg.discoverType} \
--type sendtargets \
--discover \
--portal ${escapeShellArg cfg.discoverPortal} \
--debug ${toString cfg.logLevel}

View File

@@ -292,7 +292,7 @@ in
assertions = lib.mapAttrsToList (netName: netCfg: {
# IFNAMSIZ caps network device names to 16 chars (including NULL terminator).
# Without this check, users might end up with a truncated interface name.
assertion = netCfg.tun.disable || builtins.stringLength netCfg.tun.device <= 15;
assertion = !netCfg.tun.disable && builtins.stringLength netCfg.tun.device <= 15;
message = ''
Network device names can't be longer than 15 chars.
`config.services.nebula.networks.${netName}.tun.device` is set to "${netCfg.tun.device}" which is above the limit.

View File

@@ -85,10 +85,12 @@ rec {
else
f (path ++ [ name ]) name value;
in
concatMapAttrs g set;
mapAttrs'' g set;
in
recurse [ ] set;
mapAttrs'' = f: set: foldl' (a: b: a // b) { } (mapAttrsToList f set);
# Extract the options from the given set of parameters.
paramsToOptions = ps: mapParamsRecursive (_path: name: param: { ${name} = param.option; }) ps;

View File

@@ -16,6 +16,10 @@ let
}:
attrsOfAttrs:
let
# map function to string for each key val
mapAttrsToStringsSep =
sep: mapFn: attrs:
lib.concatStringsSep sep (lib.mapAttrsToList mapFn attrs);
mkSection =
sectName: sectValues:
''
@@ -25,7 +29,7 @@ let
+ "}";
in
# map input to ini sections
lib.concatMapAttrsStringSep "\n" mkSection attrsOfAttrs;
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
configFile = pkgs.writeText "manticore.conf" (
toSphinx {

View File

@@ -405,9 +405,7 @@ in
extraConfig = nginxAuthRequest + ''
types {
video/mp4 mp4;
image/jpeg jpg jpeg;
image/png png;
image/webp webp;
image/jpeg jpg;
}
expires 7d;
@@ -495,6 +493,19 @@ in
}
'';
};
# frontend uses this to fetch the version
"/api/go2rtc/api" = {
proxyPass = "http://frigate-go2rtc/api";
recommendedProxySettings = true;
extraConfig =
nginxAuthRequest
+ nginxProxySettings
+ ''
limit_except GET {
deny all;
}
'';
};
# integrationn uses this to add webrtc candidate
"/api/go2rtc/webrtc" = {
proxyPass = "http://frigate-go2rtc/api/webrtc";
@@ -530,7 +541,6 @@ in
expires off;
proxy_cache frigate_api_cache;
proxy_cache_key "$scheme$proxy_host$request_uri|$role|$groups|$user";
proxy_cache_lock on;
proxy_cache_use_stale updating;
proxy_cache_valid 200 5s;
@@ -553,13 +563,6 @@ in
${nginxProxySettings}
}
location /api/logout {
auth_request off;
rewrite ^/api(/.*)$ $1 break;
proxy_pass http://frigate-api;
${nginxProxySettings}
}
location /api/auth/first_time_login {
auth_request off;
limit_except GET {
@@ -744,6 +747,7 @@ in
]
++ optionals (!stdenv.hostPlatform.isAarch64) [
# not available on aarch64-linux
intel-gpu-tools
rocmPackages.rocminfo
];
serviceConfig = {
@@ -771,10 +775,11 @@ in
Group = "frigate";
SupplementaryGroups = [ "render" ] ++ optionals withCoral [ "coral" ];
# No capabilities
CapabilityBoundingSet = [ "" ];
AmbientCapabilities = optionals (elem cfg.vaapiDriver [
"i965"
"iHD"
]) [ "CAP_PERFMON" ]; # for intel_gpu_top
# Allow delegating access
UMask = "0027";
StateDirectory = "frigate";
@@ -792,53 +797,9 @@ in
# Sockets/IPC
RuntimeDirectory = "frigate";
RemoveIPC = true;
# Reduce visible process scope to cgroup
ProtectProc = "invisible";
# Allow wide /proc inspection, e.g. for cpuinfo
ProcSubset = "all";
# Protect various system locations/interfaces
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
# No JIT compilation
MemoryDenyWriteExecute = true;
# No ABI personality changes
LockPersonality = true;
# Only IP/Unix sockets
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
# Deny namespace creation
RestrictNamespaces = true;
# No privilege escalation
NoNewPrivileges = true;
RestrictSUIDSGID = true;
# No realtime schedulign
RestrictRealtime = true;
# Restrict allowed syscalls
SystemCallFilter = [
"@system-service"
"~@privileged"
];
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
};
};

View File

@@ -1167,16 +1167,17 @@ in
};
config = mkIf cfg.enable {
assertions = [
{
assertion =
assertions =
optionals
(
cfg.config.":pleroma".":media_proxy".enabled
-> cfg.config.":pleroma".":media_proxy".base_url != null;
message = ''
`services.akkoma.config.":pleroma".":media_proxy".base_url` must be set to a URL with a different host component (domain name) than the web endpoint when the media proxy is enabled.
'';
}
];
&& cfg.config.":pleroma".":media_proxy".base_url == null
)
[
''
`services.akkoma.config.":pleroma".":media_proxy".base_url` must be set when the media proxy is enabled.
''
];
warnings =
optionals (with config.security; cfg.installWrapper && (!sudo.enable) && (!sudo-rs.enable))
[

View File

@@ -499,7 +499,6 @@ in
themePolicy =
let
builtinThemes = [
"builtin-flat-fields"
"builtin-qui"
"builtin-nord"
"builtin-catppuccin"

Some files were not shown because too many files have changed in this diff Show More