Merge branch staging into haskell-updates
This commit is contained in:
@@ -203,3 +203,6 @@ ce21e97a1f20dee15da85c084f9d1148d84f853b
|
||||
|
||||
# sqlc: format with nixfmt
|
||||
2bdec131b2bb2c8563f4556d741d34ccb77409e2
|
||||
|
||||
# treewide: migrate packages to pkgs/by-name, take 1
|
||||
571c71e6f73af34a229414f51585738894211408
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: Module requests
|
||||
about: For NixOS modules that you would like to see
|
||||
title: 'Module request: MODULENAME'
|
||||
labels: '9.needs: module (new)'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Description
|
||||
|
||||
<!-- Describe what the module should accomplish: -->
|
||||
|
||||
### Notify maintainers
|
||||
|
||||
<!-- If applicable, tag the maintainers of the package that corresponds to the module. If the search.nixos.org result shows no maintainers, tag the person that last updated the package. -->
|
||||
|
||||
-----
|
||||
|
||||
Note for maintainers: Please tag this issue in your PR.
|
||||
|
||||
---
|
||||
|
||||
Add a :+1: [reaction] to [issues you find important].
|
||||
|
||||
[reaction]: https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/
|
||||
[issues you find important]: https://github.com/NixOS/nixpkgs/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc
|
||||
@@ -229,7 +229,7 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
||||
/pkgs/servers/sql/postgresql @NixOS/postgres
|
||||
/nixos/modules/services/databases/postgresql.md @NixOS/postgres
|
||||
/nixos/modules/services/databases/postgresql.nix @NixOS/postgres
|
||||
/nixos/tests/postgresql.nix @NixOS/postgres
|
||||
/nixos/tests/postgresql @NixOS/postgres
|
||||
|
||||
# Hardened profile & related modules
|
||||
/nixos/modules/profiles/hardened.nix @joachifm
|
||||
@@ -248,13 +248,13 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt
|
||||
|
||||
# Network Time Daemons
|
||||
/pkgs/by-name/ch/chrony @thoughtpolice
|
||||
/pkgs/tools/networking/ntp @thoughtpolice
|
||||
/pkgs/tools/networking/openntpd @thoughtpolice
|
||||
/pkgs/by-name/nt/ntp @thoughtpolice
|
||||
/pkgs/by-name/op/openntpd @thoughtpolice
|
||||
/nixos/modules/services/networking/ntp @thoughtpolice
|
||||
|
||||
# Network
|
||||
/pkgs/tools/networking/kea/default.nix @mweinelt
|
||||
/pkgs/tools/networking/babeld/default.nix @mweinelt
|
||||
/pkgs/by-name/ke/kea @mweinelt
|
||||
/pkgs/by-name/ba/babeld @mweinelt
|
||||
/nixos/modules/services/networking/babeld.nix @mweinelt
|
||||
/nixos/modules/services/networking/kea.nix @mweinelt
|
||||
/nixos/modules/services/networking/knot.nix @mweinelt
|
||||
@@ -407,12 +407,12 @@ pkgs/by-name/lx/lxc* @adamcstephens
|
||||
|
||||
# GNU Tar & Zip
|
||||
/pkgs/tools/archivers/gnutar @RossComputerGuy
|
||||
/pkgs/tools/archivers/zip @RossComputerGuy
|
||||
/pkgs/by-name/zi/zip @RossComputerGuy
|
||||
|
||||
# SELinux
|
||||
/pkgs/os-specific/linux/checkpolicy @RossComputerGuy
|
||||
/pkgs/os-specific/linux/libselinux @RossComputerGuy
|
||||
/pkgs/os-specific/linux/libsepol @RossComputerGuy
|
||||
/pkgs/by-name/ch/checkpolicy @RossComputerGuy
|
||||
/pkgs/by-name/li/libselinux @RossComputerGuy
|
||||
/pkgs/by-name/li/libsepol @RossComputerGuy
|
||||
|
||||
# installShellFiles
|
||||
/pkgs/by-name/in/installShellFiles/* @Ericson2314
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# `aws-c-common` {#aws-c-common}
|
||||
|
||||
This hook exposes its own [CMake](#cmake) modules by setting [`CMAKE_MODULE_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html) through [the `cmakeFlags` variable](#cmake-flags)
|
||||
to the nonstandard `$out/lib/cmake` directory, as a workaround for [an upstream bug](https://github.com/awslabs/aws-c-common/issues/844).
|
||||
@@ -8,6 +8,7 @@ The stdenv built-in hooks are documented in [](#ssec-setup-hooks).
|
||||
autoconf.section.md
|
||||
automake.section.md
|
||||
autopatchelf.section.md
|
||||
aws-c-common.section.md
|
||||
bmake.section.md
|
||||
breakpoint.section.md
|
||||
cernlib.section.md
|
||||
|
||||
@@ -2,242 +2,301 @@
|
||||
|
||||
## Darwin (macOS) {#sec-darwin}
|
||||
|
||||
Some common issues when packaging software for Darwin:
|
||||
The Darwin `stdenv` differs from most other ones in Nixpkgs in a few key ways.
|
||||
These differences reflect the default assumptions for building software on that platform.
|
||||
In many cases, you can ignore these differences because the software you are packaging is already written with them in mind.
|
||||
When you do that, write your derivation as normal. You don’t have to include any Darwin-specific special cases.
|
||||
The easiest way to know whether your derivation requires special handling for Darwin is to write it as if it doesn’t and see if it works.
|
||||
If it does, you’re done; skip the rest of this.
|
||||
|
||||
- The Darwin `stdenv` uses clang instead of gcc. When referring to the compiler `$CC` or `cc` will work in both cases. Some builds hardcode gcc/g++ in their build scripts, that can usually be fixed with using something like `makeFlags = [ "CC=cc" ];` or by patching the build scripts.
|
||||
- Darwin uses Clang by default instead of GCC. Packages that refer to `$CC` or `cc` should just work in most cases.
|
||||
Some packages may hardcode `gcc` or `g++`. You can usually fix that by setting `makeFlags = [ "CC=cc" "CXX=C++" ]`.
|
||||
If that does not work, you will have to patch the build scripts yourself to use the correct compiler for Darwin.
|
||||
- Darwin needs an SDK to build software.
|
||||
The SDK provides a default set of frameworks and libraries to build software, most of which are specific to Darwin.
|
||||
There are multiple versions of the SDK packages in Nixpkgs, but one is included by default in the `stdenv`.
|
||||
Usually, you don’t have to change or pick a different SDK. When in doubt, use the default.
|
||||
- The SDK used by your build can be found using the `DEVELOPER_DIR` environment variable.
|
||||
There are also versions of this variable available when cross-compiling depending on the SDK’s role.
|
||||
The `SDKROOT` variable is also set with the path to the SDK’s libraries and frameworks.
|
||||
`SDKROOT` is always a sub-folder of `DEVELOPER_DIR`.
|
||||
- Darwin includes a platform-specific tool called `xcrun` to help builds locate binaries they need.
|
||||
A version of `xcrun` is part of the `stdenv` on Darwin.
|
||||
If your package invokes `xcrun` via an absolute path (such as `/usr/bin/xcrun`), you will need to patch the build scripts to use `xcrun` instead.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
buildPhase = ''
|
||||
$CC -o hello hello.c
|
||||
'';
|
||||
}
|
||||
```
|
||||
To reiterate: you usually don’t have to worry about this stuff.
|
||||
Start with writing your derivation as if everything is already set up for you (because in most cases it already is).
|
||||
If you run into issues or failures, continue reading below for how to deal with the most common issues you may encounter.
|
||||
|
||||
- On Darwin, libraries are linked using absolute paths, libraries are resolved by their `install_name` at link time. Sometimes packages won’t set this correctly causing the library lookups to fail at runtime. This can be fixed by adding extra linker flags or by running `install_name_tool -id` during the `fixupPhase`.
|
||||
### Darwin Issue Troubleshooting {#sec-darwin-troubleshooting}
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
makeFlags = lib.optional stdenv.hostPlatform.isDarwin "LDFLAGS=-Wl,-install_name,$(out)/lib/libfoo.dylib";
|
||||
}
|
||||
```
|
||||
#### Package requires a non-default SDK or fails to build due to missing frameworks or symbols {#sec-darwin-troubleshooting-using-sdks}
|
||||
|
||||
- Even if the libraries are linked using absolute paths and resolved via their `install_name` correctly, tests can sometimes fail to run binaries. This happens because the `checkPhase` runs before the libraries are installed.
|
||||
In some cases, you may have to use a non-default SDK.
|
||||
This can happen when a package requires APIs that are not present in the default SDK.
|
||||
For example, Metal Performance Shaders were added in macOS 12.
|
||||
If the default SDK is 11.3, then a package that requires Metal Performance Shaders will fail to build due to missing frameworks and symbols.
|
||||
|
||||
This can usually be solved by running the tests after the `installPhase` or alternatively by using `DYLD_LIBRARY_PATH`. More information about this variable can be found in the *dyld(1)* manpage.
|
||||
To use a non-default SDK, add it to your derivation’s `buildInputs`.
|
||||
It is not necessary to override the SDK in the `stdenv` nor is it necessary to override the SDK used by your dependencies.
|
||||
If your derivation needs a non-default SDK at build time (e.g., for a `depsBuildBuild` compiler), see the cross-compilation documentation for which input you should use.
|
||||
|
||||
```
|
||||
dyld: Library not loaded: /nix/store/7hnmbscpayxzxrixrgxvvlifzlxdsdir-jq-1.5-lib/lib/libjq.1.dylib
|
||||
Referenced from: /private/tmp/nix-build-jq-1.5.drv-0/jq-1.5/tests/../jq
|
||||
Reason: image not found
|
||||
./tests/jqtest: line 5: 75779 Abort trap: 6
|
||||
```
|
||||
When determining whether to use a non-default SDK, consider the following:
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
doInstallCheck = true;
|
||||
installCheckTarget = "check";
|
||||
}
|
||||
```
|
||||
- Try building your derivation with the default SDK. If it works, you’re done.
|
||||
- If the package specifies a specific version, use that. See below for how to map Xcode version to SDK version.
|
||||
- If the package’s documentation indicates it supports optional features on newer SDKs, consider using the SDK that enables those features.
|
||||
If you’re not sure, use the default SDK.
|
||||
|
||||
- Some packages assume Xcode is available and use `xcrun` to resolve build tools like `clang`, etc. The Darwin stdenv includes `xcrun`, and it will return the path to any binary available in a build.
|
||||
Note: It is possible to have multiple, different SDK versions in your inputs.
|
||||
When that happens, the one with the highest version is always used.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
nativeBuildInputs = [ bison ];
|
||||
buildCommand = ''
|
||||
xcrun bison foo.y # produces foo.tab.c
|
||||
# ...
|
||||
'';
|
||||
}
|
||||
```
|
||||
The package `xcbuild` can be used to build projects that really depend on Xcode. However, this replacement is not 100% compatible with Xcode and can occasionally cause issues.
|
||||
|
||||
Note: Some packages may hardcode an absolute path to `xcrun`, `xcodebuild`, or `xcode-select`. Those paths should be removed or replaced.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
prePatch = ''
|
||||
substituteInPlace Makefile \
|
||||
--replace-fail /usr/bin/xcrun xcrun
|
||||
# or: --replace-fail /usr/bin/xcrun '${lib.getExe' buildPackages.xcbuild "xcrun"}'
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
- Multiple SDKs are available for use in nixpkgs. Each platform has a default SDK (10.12.2 for x86_64-darwin and 11.3 for aarch64-darwin), which is available as the `apple-sdk` package.
|
||||
|
||||
The SDK provides the necessary headers and text-based stubs to link common frameworks and libraries (such as libSystem, which is effectively Darwin’s libc). Projects will sometimes indicate which SDK to use by the Xcode version. As a rule of thumb, subtract one from the Xcode version to get the available SDK in nixpkgs.
|
||||
|
||||
The `DEVELOPER_DIR` variable in the build environment has the path to the SDK in the build environment. The `SDKROOT` variable there contains a sysroot with the framework, header, and library paths. You can reference an SDK’s sysroot from Nix using the `sdkroot` attribute on the SDK package. Note that it is preferable to use `SDKROOT` because the latter will be resolved to the highest SDK version of any available to your derivation.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
env.PACKAGE_SPECIFIC_SDK_VAR = apple-sdk_10_15.sdkroot;
|
||||
# or
|
||||
buildInputs = [ apple-sdk_10_15 ];
|
||||
postPatch = ''
|
||||
export PACKAGE_SPECIFIC_SDK_VAR=$SDKROOT
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
The following is a list of Xcode versions, the SDK version in nixpkgs, and the attribute to use to add it. Generally, only the last SDK release for a major version is packaged (each _x_ in 10._x_ until 10.15 is considered a major version).
|
||||
|
||||
| Xcode version | SDK version | nixpkgs attribute |
|
||||
|--------------------|---------------------------------------------------|-------------------|
|
||||
| Varies by platform | 10.12.2 (x86_64-darwin)<br/>11.3 (aarch64-darwin) | `apple-sdk` |
|
||||
| 8.0–8.3.3 | 10.12.2 | `apple-sdk_10_12` |
|
||||
| 9.0–9.4.1 | 10.13.2 | `apple-sdk_10_13` |
|
||||
| 10.0–10.3 | 10.14.6 | `apple-sdk_10_14` |
|
||||
| 11.0–11.7 | 10.15.6 | `apple-sdk_10_15` |
|
||||
| 12.0–12.5.1 | 11.3 | `apple-sdk_11` |
|
||||
| 13.0–13.4.1 | 12.3 | `apple-sdk_12` |
|
||||
| 14.0–14.3.1 | 13.3 | `apple-sdk_13` |
|
||||
| 15.0–15.4 | 14.4 | `apple-sdk_14` |
|
||||
| 16.0 | 15.0 | `apple-sdk_15` |
|
||||
|
||||
To use a non-default SDK, add it to your build inputs.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
buildInputs = [ apple-sdk_15 ]; # Uses the 15.0 SDK instead of the default SDK for the platform.
|
||||
}
|
||||
```
|
||||
|
||||
If your derivation has multiple SDKs its inputs (e.g., because they have been propagated by its dependencies), it will use the highest SDK version available.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3"; # Upstream specifies that it needs Xcode 12 to build, so use the 11.3 SDK.
|
||||
# ...
|
||||
buildInputs = [ apple-sdk_11 ];
|
||||
nativeBuildInputs = [ swift ]; # Propagates the 13.3 SDK, so the 13.3 SDK package will be used instead of the 11.3 SDK.
|
||||
}
|
||||
```
|
||||
|
||||
- When a package indicates a minimum supported version, also called the deployment target, you can set it in your derivation using `darwinMinVersionHook`. If you need to set a minimum version higher than the default SDK, you should also add the corresponding SDK to your `buildInputs`.
|
||||
|
||||
The deployment target controls how Darwin handles availability and access to some APIs. In most cases, if a deployment target is newer than the first availability of an API, that API will be linked directly. Otherwise, the API will be weakly linked and checked at runtime.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3"; # Upstream specifies the minimum supported version as 12.5.
|
||||
buildInputs = [ (darwinMinVersionHook "12.5") ];
|
||||
}
|
||||
```
|
||||
|
||||
If your derivation has multiple versions of this hook in its inputs (e.g., because it has been propagated by one of your dependencies), it will use the highest deployment target available.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3"; # Upstream specifies the minimum supported version as 10.15.
|
||||
buildInputs = [ qt6.qtbase (darwinMinVersionHook "10.15") ];
|
||||
}
|
||||
# Qt 6 specifies a minimum version of 12.0, so the minimum version resolves to 12.0.
|
||||
```
|
||||
|
||||
|
||||
- You should rely on the default SDK when possible. If a package specifies a required SDK version, use that version (e.g., libuv requires 11.0, so it should use `apple-sdk_11`). When a package supports multiple SDKs, determine which SDK package to use based on the following rules of thumb:
|
||||
|
||||
- If a package supports multiple SDK versions, use the lowest supported SDK version by the package (but no lower than the default SDK). That ensures maximal platform compatibility for the package.
|
||||
|
||||
- If a package specifies a range of supported SDK versions _and_ a minimum supported version, assume the package is using availability checks to support the indicated minimum version. Add the highest supported SDK and a `darwinMinVersionHook` set to the minimum version supported by the upstream package.
|
||||
|
||||
Warning: Avoid using newer SDKs than an upstream package supports. When a binary is linked on Darwin, the SDK version used to build it is recorded in the binary. Runtime behavior can vary based on the SDK version, which may work fine but can also result in unexpected behavior or crashes when building with an unsupported SDK.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "foo-1.2.3";
|
||||
# ...
|
||||
buildInputs = [ apple-sdk_15 (darwinMinVersionHook "10.15") ]; # Upstream builds with the 15.0 SDK but supports 10.15.
|
||||
}
|
||||
```
|
||||
|
||||
- Libraries that require a minimum version can propagate an appropriate SDK and `darwinMinVersionHook`. Derivations using that library will automatically use an appropriate SDK and minimum version. Even if the library builds with a newer SDK, it should propagate the minimum supported SDK. Derivations that need a newer SDK can add it to their `buildInputs`.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
buildInputs = [ apple-sdk_15 ]; # Upstream builds with the 15.0 SDK but supports 10.15.
|
||||
propagatedBuildInputs = [ apple-sdk_10_15 (darwinMinVersionHook "10.15") ];
|
||||
}
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
stdenv.mkDerivation {
|
||||
name = "bar-1.2.3";
|
||||
# ...
|
||||
buildInputs = [ libfoo ]; # Builds with the 10.15 SDK
|
||||
}
|
||||
buildInputs = [ apple-sdk_14 ];
|
||||
}
|
||||
```
|
||||
|
||||
#### What is a “deployment target” (or minimum version)? {#sec-darwin-troubleshooting-using-deployment-targets}
|
||||
|
||||
The “deployment target” refers to the minimum version of macOS that is expected to run an application.
|
||||
In most cases, the default is fine, and you don’t have to do anything else.
|
||||
If you’re not sure, don’t do anything, and that will probably be fine.
|
||||
|
||||
Some packages require setting a non-default deployment target (or minimum version) to gain access to certain APIs.
|
||||
You do that using the `darwinMinVersionHook`, which takes the deployment target version as a parameter.
|
||||
There are primarily two ways to determine the deployment target.
|
||||
|
||||
- The upstream documentation will specify a deployment target or minimum version. Use that.
|
||||
- The build will fail because an API requires a certain version. Use that.
|
||||
- In all other cases, you probably don’t need to specify a minimum version. The default is usually good enough.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3"; # Upstream specifies the minimum supported version as 12.5.
|
||||
buildInputs = [ (darwinMinVersionHook "12.5") ];
|
||||
}
|
||||
```
|
||||
|
||||
Note: It is possible to have multiple, different instances of `darwinMinVerisonHook` in your inputs.
|
||||
When that happens, the one with the highest version is always used.
|
||||
|
||||
#### Picking an SDK version {#sec-darwin-troubleshooting-picking-sdk-version}
|
||||
|
||||
The following is a list of Xcode versions, the SDK version in Nixpkgs, and the attribute to use to add it.
|
||||
Check your package’s documentation (platform support or installation instructions) to find which Xcode or SDK version to use.
|
||||
Generally, only the last SDK release for a major version is packaged (each _x_ in 10._x_ until 10.15 is considered a major version).
|
||||
|
||||
| Xcode version | SDK version | Nixpkgs attribute |
|
||||
|--------------------|---------------------------------------------------|-------------------|
|
||||
| Varies by platform | 10.12.2 (x86_64-darwin)<br/>11.3 (aarch64-darwin) | `apple-sdk` |
|
||||
| 8.0–8.3.3 | 10.12.2 | `apple-sdk_10_12` |
|
||||
| 9.0–9.4.1 | 10.13.2 | `apple-sdk_10_13` |
|
||||
| 10.0–10.3 | 10.14.6 | `apple-sdk_10_14` |
|
||||
| 11.0–11.7 | 10.15.6 | `apple-sdk_10_15` |
|
||||
| 12.0–12.5.1 | 11.3 | `apple-sdk_11` |
|
||||
| 13.0–13.4.1 | 12.3 | `apple-sdk_12` |
|
||||
| 14.0–14.3.1 | 13.3 | `apple-sdk_13` |
|
||||
| 15.0–15.4 | 14.4 | `apple-sdk_14` |
|
||||
| 16.0 | 15.0 | `apple-sdk_15` |
|
||||
|
||||
|
||||
#### Darwin Default SDK versions {#sec-darwin-troubleshooting-darwin-defaults}
|
||||
|
||||
The current default versions of the deployment target (minimum version) and SDK are indicated by Darwin-specific attributes on the platform. Because of the ways that minimum version and SDK can be changed that are not visible to Nix, they should be treated as lower bounds.
|
||||
If you need to parameterize over a specific version, create a function that takes the version as a parameter instead of relying on these attributes.
|
||||
|
||||
- `darwinMinVersion` defaults to 10.12 on x86_64-darwin and 11.0 on aarch64-darwin.
|
||||
It sets the default deployment target.
|
||||
- `darwinSdkVersion` defaults to 10.12 on x86-64-darwin and 11.0 on aarch64-darwin.
|
||||
Only the major version determines the SDK version, resulting in the 10.12.2 and 11.3 SDKs being used on these platforms respectively.
|
||||
|
||||
|
||||
#### `xcrun` cannot find a binary {#sec-darwin-troubleshooting-xcrun}
|
||||
|
||||
`xcrun` searches `PATH` and the SDK’s toolchain for binaries to run.
|
||||
If it cannot find a required binary, it will fail. When that happens, add the package for that binary to your derivation’s `nativeBuildInputs` (or `nativeCheckInputs` if the failure is happening when running tests).
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
stdenv.mkDerivation {
|
||||
name = "baz-1.2.3";
|
||||
nativeBuildInputs = [ bison ];
|
||||
buildCommand = ''
|
||||
xcrun bison foo.y # produces foo.tab.c
|
||||
# ...
|
||||
buildInputs = [ apple-sdk_12 libfoo ]; # Builds with the 12.3 SDK
|
||||
}
|
||||
```
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
- Many SDK libraries and frameworks use text-based stubs to link against system libraries and frameworks, but several are built from source (typically corresponding to the source releases for the latest release of macOS). Several of these are propagated to your package automatically. They can be accessed via the `darwin` package set along with others that are not propagated by default.
|
||||
#### Package requires `xcodebuild` {#sec-darwin-troubleshooting-xcodebuild}
|
||||
|
||||
- libiconv
|
||||
- libresolv
|
||||
- libsbuf
|
||||
The xcbuild package provides an `xcodebuild` command for packages that really depend on Xcode.
|
||||
This replacement is not 100% compatible and may run into some issues, but it is able to build many packages.
|
||||
To use `xcodebuild`, add `xcbuildHook` to your package’s `nativeBuildInputs`.
|
||||
It will provide a `buildPhase` for your derivation.
|
||||
You can use `xcbuildFlags` to specify flags to `xcodebuild` such as the required schema.
|
||||
If a schema has spaces in its name, you must set `__structuredAttrs` to `true`.
|
||||
See MoltenVK for an example of setting up xcbuild.
|
||||
|
||||
Other common libraries are available in Darwin-specific versions with modifications from Apple. Note that these packages may be made the default on Darwin in the future.
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
xcbuildFlags = [
|
||||
"-configuration"
|
||||
"Release"
|
||||
"-project"
|
||||
"libfoo-project.xcodeproj"
|
||||
"-scheme"
|
||||
"libfoo Package (macOS only)"
|
||||
];
|
||||
__structuredAttrs = true;
|
||||
}
|
||||
```
|
||||
|
||||
- ICU (compatible with the top-level icu package, but it also provides `libicucore.B.dylib` with an ABI compatible with the Darwin system version)
|
||||
- libpcap (compatible with the top-level libpcap, but it includes Darwin-specific extensions)
|
||||
##### Fixing absolute paths to `xcodebuild`, `xcrun`, and `PlistBuddy` {#sec-darwin-troubleshooting-xcodebuild-absolute-paths}
|
||||
|
||||
- The legacy SDKs packages are still available in the `darwin` package set under their existing names, but all packages in these SDKs (frameworks, libraries, etc) are stub packages for evaluation compatibility.
|
||||
Many build systems hardcode the absolute paths to `xcodebuild`, `xcrun`, and `PlistBuddy` as `/usr/bin/xcodebuild`, `/usr/bin/xcrun`, and `/usr/libexec/PlistBuddy` respectively.
|
||||
These paths will need to be replaced with relative paths and the xcbuild package if `xcodebuild` or `PListBuddy` are used.
|
||||
|
||||
In most cases, a derivation can be updated by deleting all of its SDK inputs (frameworks, libraries, etc). If you had to override the SDK, see below for how to do that using the new SDK pattern. If your derivation depends on the layout of the old frameworks or other internal details, you have more work to do.
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
postPatch = ''
|
||||
subsituteInPlace Makefile \
|
||||
--replace-fail '/usr/bin/xcodebuild' 'xcodebuild' \
|
||||
--replace-fail '/usr/bin/xcrun' 'xcrun' \
|
||||
--replace-fail '/usr/bin/PListBuddy' 'PListBuddy'
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
When a package depended on the location of frameworks, references to those framework packages can usually be replaced with `${apple-sdk.sdkroot}/System` or `$SDKROOT/System`. For example, if you substituted `${darwin.apple_sdk.frameworks.OpenGL}/Library/Frameworks/OpenGL.framework` in your derivation, you should replace it with `${apple-sdk.sdkroot}/System/Library/Frameworks/OpenGL.framework` or `$SDKROOT/System/Library/Frameworks`. The latter is preferred because it supports using the SDK that is resolved when multiple SDKs are propagated (see above).
|
||||
#### How to use libiconv on Darwin {#sec-darwin-troubleshooting-libiconv}
|
||||
|
||||
Note: the new SDK pattern uses the name `apple-sdk` to better align with nixpkgs naming conventions. The old SDK pattern uses `apple_sdk`.
|
||||
The libiconv package is included in the SDK by default along with libresolv and libsbuf.
|
||||
You do not need to do anything to use these packages. They are available automatically.
|
||||
If your derivation needs the `iconv` binary, add the `libiconv` package to your `nativeBuildInputs` (or `nativeCheckInputs` for tests).
|
||||
|
||||
- There are two legacy patterns that are being phased out. These patterns were used in the past to change the SDK version. They have been reimplemented to use the `apple-sdk` packages.
|
||||
#### Library install name issues {#sec-darwin-troubleshooting-install-name}
|
||||
|
||||
- `pkgs.darwin.apple_sdk_11_0.callPackage` - this pattern was used to provide frameworks from the 11.0 SDK. It now adds the `apple-sdk_11` package to your derivation’s build inputs.
|
||||
- `overrideSDK` - this stdenv adapter would try to replace the frameworks used by your derivation and its transitive dependencies. It now adds the `apple-sdk_11` package for `11.0` or the `apple-sdk_12` package for `12.3`. If `darwinMinVersion` is specified, it will add `darwinMinVersionHook` with the specified minimum version. No other SDK versions are supported.
|
||||
Libraries on Darwin are usually linked with absolute paths.
|
||||
This is determined by something called an “install name”, which is resolved at link time.
|
||||
Sometimes packages will not set this correctly, causing binaries linking to it not to find their libraries at runtime.
|
||||
This can be fixed by adding extra linker flags or by using `install_name_tool` to set it in `fixupPhase`.
|
||||
|
||||
- Darwin supports cross-compilation between Darwin platforms. Cross-compilation from Linux is not currently supported but may be supported in the future. To cross-compile to Darwin, you can set `crossSystem` or use one of the Darwin systems in `pkgsCross`. The `darwinMinVersionHook` and the SDKs support cross-compilation. If you need to specify a different SDK version for a `depsBuildBuild` compiler, add it to your `nativeBuildInputs`.
|
||||
##### Setting the install name via linker flags {#sec-darwin-troubleshooting-install-name-linker-flags}
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||
nativeBuildInputs = [ apple-sdk_12 ];
|
||||
buildInputs = [ apple-sdk_13 ];
|
||||
depsTargetTargetPropagated = [ apple-sdk_14 ];
|
||||
}
|
||||
# The build-build clang will use the 12.3 SDK while the package build itself will use the 13.3 SDK.
|
||||
# Derivations that add this package as an input will have the 14.4 SDK propagated to them.
|
||||
```
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
makeFlags = lib.optional stdenv.hostPlatform.isDarwin "LDFLAGS=-Wl,-install_name,$(out)/lib/libfoo.dylib";
|
||||
}
|
||||
```
|
||||
|
||||
The different target SDK and hooks are mangled based on role:
|
||||
##### Setting the install name using `install_name_tool` {#sec-darwin-troubleshooting-install-name-install_name_tool}
|
||||
|
||||
- `DEVELOPER_DIR_FOR_BUILD` and `MACOSX_DEPLOYMENT_TARGET_FOR_BUILD` for the build platform;
|
||||
- `DEVELOPER_DIR` and `MACOSX_DEPLOYMENT_TARGET` for the host platform; and
|
||||
- `DEVELOPER_DIR_FOR_TARGET` and `MACOSX_DEPLOYMENT_TARGET_FOR_TARGET` for the build platform.
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
postFixup = ''
|
||||
# `-id <install_name>` takes the install name. The last parameter is the path to the library.
|
||||
${stdenv.cc.targetPrefix}install_name_tool -id "$out/lib/libfoo.dylib" "$out/lib/libfoo.dylib"
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
In static compilation situations, it is possible for the build and host platform to be the same platform but have different SDKs with the same version (one dynamic and one static). cc-wrapper takes care of handling this distinction.
|
||||
Even if libraries are linked using absolute paths and resolved via their install name correctly, tests in `checkPhase` can sometimes fail to run binaries because they are linked against libraries that have not yet been installed.
|
||||
This can usually be solved by running the tests after the `installPhase` or by using `DYLD_LIBRARY_PATH` (see {manpage}`dyld(1)` for more on setting `DYLD_LIBRARY_PATH`).
|
||||
|
||||
- The current default versions of the deployment target (minimum version) and SDK are indicated by Darwin-specific attributes on the platform. Because of the ways that minimum version and SDK can be changed that are not visible to Nix, they should be treated as lower bounds. If you need to parameterize over a specific version, create a function that takes the version as a parameter instead of relying on these attributes.
|
||||
##### Setting the install name using `fixDarwinDylibNames` hook {#sec-darwin-troubleshooting-install-name-fixDarwinDylibNames}
|
||||
|
||||
- `darwinMinVersion` defaults to 10.12 on x86_64-darwin and 11.0 on aarch64-darwin. It sets the default `MACOSX_DEPLOYMENT_TARGET`.
|
||||
- `darwinSdkVersion` defaults to 10.12 on x86-64-darwin and 11.0 on aarch64-darwin. Only the major version determines the SDK version, resulting in the 10.12.2 and 11.3 SDKs being used on these platforms respectively.
|
||||
If your package has numerous dylibs needing fixed, while it is preferable to fix the issue in the package’s build, you can update them all by adding the `fixDarwinDylibNames` hook to your `nativeBuildInputs`.
|
||||
This hook will scan your package’s outputs for dylibs and correct their install names.
|
||||
Note that if any binaries in your outputs linked those dylibs, you may need to use `install_name_tool` to replace references to them with the correct paths.
|
||||
|
||||
#### Propagating an SDK (advanced, compilers-only) {#sec-darwin-troubleshooting-propagating-sdks}
|
||||
|
||||
The SDK is a package, and it can be propagated.
|
||||
`darwinMinVersionHook` with a version specified can also be propagated.
|
||||
However, most packages should *not* do this.
|
||||
The exception is compilers.
|
||||
When you propagate an SDK, it becomes part of your derivation’s public API, and changing the SDK or removing it can be a breaking change.
|
||||
That is why propagating it is only recommended for compilers.
|
||||
|
||||
When authoring a compiler derivation, propagate the SDK only for the ways you expect users to use your compiler.
|
||||
Depending on your expected use cases, you may have to do one or all of these.
|
||||
|
||||
- Put it in `depsTargetTargetPropagated` when your compiler is expected to be added to `nativeBuildInputs`.
|
||||
That will ensure the SDK is effectively part of the target derivation’s `buildInputs`.
|
||||
- If your compiler uses a hook, put it in the hook’s `depsTargetTargetPropagated` instead.
|
||||
The effect should be the same as the above.
|
||||
- If your package uses the builder pattern, update your builder to add the SDK to the derivation’s `buildInputs`.
|
||||
|
||||
If you’re not sure whether to propagate an SDK, don’t.
|
||||
If your package is a compiler or language, and you’re not sure, ask @NixOS/darwin-maintainers for help deciding.
|
||||
|
||||
### Dealing with `darwin.apple_sdk.frameworks` {#sec-darwin-legacy-frameworks}
|
||||
|
||||
You may see references to `darwin.apple_sdk.frameworks`.
|
||||
This is the legacy SDK pattern, and it is being phased out.
|
||||
All packages in `darwin.apple_sdk`, `darwin.apple_sdk_11_0`, and `darwin.apple_sdk_12_3` are stubs that do nothing.
|
||||
If your derivation references them, you can delete them. The default SDK should be enough to build your package.
|
||||
|
||||
Note: the new SDK pattern uses the name `apple-sdk` to better align with Nixpkgs naming conventions.
|
||||
The legacy SDK pattern uses `apple_sdk`.
|
||||
You always know you are using the old SDK pattern if the name is `apple_sdk`.
|
||||
|
||||
Some derivations may depend on the location of frameworks in those old packages.
|
||||
To update your derivation to find them in the new SDK, use `$SDKROOT` instead in `preConfigure`.
|
||||
For example, if you substitute `${darwin.apple_sdk.frameworks.OpenGL}/Library/Frameworks/OpenGL.framework` in `postPatch`, replace it with `$SDKROOT/System/Library/Frameworks/OpenGL.framework` in `preConfigure`.
|
||||
|
||||
Note that if your derivation is changing a system path (such as `/System/Library/Frameworks/OpenGL.framework`), you may be able to remove the path.
|
||||
Compilers and binutils targeting Darwin look for system paths in the SDK sysroot.
|
||||
Some of them (such as Zig or `bindgen` for Rust) depend on it.
|
||||
|
||||
#### Updating legacy SDK overrides {#sec-darwin-legacy-frameworks-overrides}
|
||||
|
||||
The legacy SDK provided two ways of overriding the default SDK.
|
||||
These are both being phased out along with the legacy SDKs.
|
||||
They have been updated to set up the new SDK for you, but you should replace them with doing that directly.
|
||||
|
||||
- `pkgs.darwin.apple_sdk_11_0.callPackage` - this pattern was used to provide frameworks from the 11.0 SDK.
|
||||
It now adds the `apple-sdk_11` package to your derivation’s build inputs.
|
||||
- `overrideSDK` - this stdenv adapter would try to replace the frameworks used by your derivation and its transitive dependencies.
|
||||
It now adds the `apple-sdk_11` package for `11.0` or the `apple-sdk_12` package for `12.3`.
|
||||
If `darwinMinVersion` is specified, it will add `darwinMinVersionHook` with the specified minimum version.
|
||||
No other SDK versions are supported.
|
||||
|
||||
### Darwin Cross-Compilation {#sec-darwin-legacy-cross-compilation}
|
||||
|
||||
Darwin supports cross-compilation between Darwin platforms.
|
||||
Cross-compilation from Linux is not currently supported but may be supported in the future.
|
||||
To cross-compile to Darwin, you can set `crossSystem` or use one of the Darwin systems in `pkgsCross`.
|
||||
The `darwinMinVersionHook` and the SDKs support cross-compilation.
|
||||
If you need to specify a different SDK version for a `depsBuildBuild` compiler, add it to your `nativeBuildInputs`.
|
||||
|
||||
```nix
|
||||
stdenv.mkDerivation {
|
||||
name = "libfoo-1.2.3";
|
||||
# ...
|
||||
depsBuildBuild = [ buildPackages.stdenv.cc ];
|
||||
nativeBuildInputs = [ apple-sdk_12 ];
|
||||
buildInputs = [ apple-sdk_13 ];
|
||||
depsTargetTargetPropagated = [ apple-sdk_14 ];
|
||||
}
|
||||
# The build-build `clang` will use the 12.3 SDK while the package build itself will use the 13.3 SDK.
|
||||
# Derivations that add this package as an input will have the 14.4 SDK propagated to them.
|
||||
```
|
||||
|
||||
The different target SDK and hooks are mangled based on role:
|
||||
|
||||
- `DEVELOPER_DIR_FOR_BUILD` and `MACOSX_DEPLOYMENT_TARGET_FOR_BUILD` for the build platform;
|
||||
- `DEVELOPER_DIR` and `MACOSX_DEPLOYMENT_TARGET` for the host platform; and
|
||||
- `DEVELOPER_DIR_FOR_TARGET` and `MACOSX_DEPLOYMENT_TARGET_FOR_TARGET` for the build platform.
|
||||
|
||||
In static compilation situations, it is possible for the build and host platform to be the same platform but have different SDKs with the same version (one dynamic and one static).
|
||||
cc-wrapper and bintools-wrapper take care of handling this distinction.
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
# Expose the minimum required version for evaluating Nixpkgs
|
||||
"2.3"
|
||||
"2.3.17"
|
||||
|
||||
@@ -5126,6 +5126,11 @@
|
||||
githubId = 130508846;
|
||||
name = "Elliot Cameron";
|
||||
};
|
||||
deadbaed = {
|
||||
name = "Philippe Loctaux";
|
||||
github = "deadbaed";
|
||||
githubId = 8809909;
|
||||
};
|
||||
dearrude = {
|
||||
name = "Ebrahim Nejati";
|
||||
email = "dearrude@tfwno.gf";
|
||||
@@ -12538,6 +12543,12 @@
|
||||
githubId = 40217331;
|
||||
name = "LizeLive";
|
||||
};
|
||||
llakala = {
|
||||
email = "elevenaka11@gmail.com";
|
||||
github = "llakala";
|
||||
githubId = 78693624;
|
||||
name = "llakala";
|
||||
};
|
||||
lluchs = {
|
||||
email = "lukas.werling@gmail.com";
|
||||
github = "lluchs";
|
||||
@@ -13498,6 +13509,12 @@
|
||||
githubId = 322214;
|
||||
name = "Mathnerd314";
|
||||
};
|
||||
mathstlouis = {
|
||||
email = "matfino+gh@gmail.com";
|
||||
github = "mathstlouis";
|
||||
githubId = 35696151;
|
||||
name = "mathstlouis";
|
||||
};
|
||||
matklad = {
|
||||
email = "aleksey.kladov@gmail.com";
|
||||
github = "matklad";
|
||||
@@ -21761,6 +21778,12 @@
|
||||
githubId = 57180880;
|
||||
name = "Ansh Tyagi";
|
||||
};
|
||||
therealgramdalf = {
|
||||
email = "gramdalftech@gmail.com";
|
||||
github = "TheRealGramdalf";
|
||||
githubId = 79593869;
|
||||
name = "Gramdalf";
|
||||
};
|
||||
therealr5 = {
|
||||
email = "rouven@rfive.de";
|
||||
github = "therealr5";
|
||||
@@ -21891,6 +21914,12 @@
|
||||
githubId = 1391883;
|
||||
name = "Tom Hall";
|
||||
};
|
||||
thtrf = {
|
||||
email = "thtrf@proton.me";
|
||||
github = "thtrf";
|
||||
githubId = 82712122;
|
||||
name = "thtrf";
|
||||
};
|
||||
Thunderbottom = {
|
||||
email = "chinmaydpai@gmail.com";
|
||||
github = "Thunderbottom";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# - pkgs/development/lua-modules/updater/updater.py
|
||||
|
||||
# format:
|
||||
# $ nix run nixpkgs#black maintainers/scripts/pluginupdate.py
|
||||
# $ nix run nixpkgs#ruff maintainers/scripts/pluginupdate.py
|
||||
# type-check:
|
||||
# $ nix run nixpkgs#python3.pkgs.mypy maintainers/scripts/pluginupdate.py
|
||||
# linted:
|
||||
@@ -142,7 +142,7 @@ class Repo:
|
||||
return loaded
|
||||
|
||||
def prefetch(self, ref: Optional[str]) -> str:
|
||||
print("Prefetching %s", self.uri)
|
||||
log.info("Prefetching %s", self.uri)
|
||||
loaded = self._prefetch(ref)
|
||||
return loaded["sha256"]
|
||||
|
||||
@@ -195,7 +195,7 @@ class RepoGitHub(Repo):
|
||||
xml = req.read()
|
||||
|
||||
# Filter out illegal XML characters
|
||||
illegal_xml_regex = re.compile(b"[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]")
|
||||
illegal_xml_regex = re.compile(b"[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]")
|
||||
xml = illegal_xml_regex.sub(b"", xml)
|
||||
|
||||
root = ET.fromstring(xml)
|
||||
@@ -256,13 +256,7 @@ class PluginDesc:
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if self.alias is None:
|
||||
return self.repo.name
|
||||
else:
|
||||
return self.alias
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.repo.name < other.repo.name
|
||||
return self.alias or self.repo.name
|
||||
|
||||
@staticmethod
|
||||
def load_from_csv(config: FetchConfig, row: Dict[str, str]) -> "PluginDesc":
|
||||
@@ -270,7 +264,12 @@ class PluginDesc:
|
||||
branch = row["branch"]
|
||||
repo = make_repo(row["repo"], branch.strip())
|
||||
repo.token = config.github_token
|
||||
return PluginDesc(repo, branch.strip(), row["alias"])
|
||||
return PluginDesc(
|
||||
repo,
|
||||
branch.strip(),
|
||||
# alias is usually an empty string
|
||||
row["alias"] if row["alias"] else None,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def load_from_string(config: FetchConfig, line: str) -> "PluginDesc":
|
||||
@@ -328,12 +327,11 @@ def load_plugins_from_csv(
|
||||
return plugins
|
||||
|
||||
|
||||
|
||||
def run_nix_expr(expr, nixpkgs: str, **args):
|
||||
'''
|
||||
"""
|
||||
:param expr nix expression to fetch current plugins
|
||||
:param nixpkgs Path towards a nixpkgs checkout
|
||||
'''
|
||||
"""
|
||||
with CleanEnvironment(nixpkgs) as nix_path:
|
||||
cmd = [
|
||||
"nix",
|
||||
@@ -382,16 +380,14 @@ class Editor:
|
||||
fetch_config = FetchConfig(args.proc, args.github_token)
|
||||
editor = self
|
||||
for plugin_line in args.add_plugins:
|
||||
log.debug("using plugin_line", plugin_line)
|
||||
log.debug("using plugin_line %s", plugin_line)
|
||||
pdesc = PluginDesc.load_from_string(fetch_config, plugin_line)
|
||||
log.debug("loaded as pdesc", pdesc)
|
||||
log.debug("loaded as pdesc %s", pdesc)
|
||||
append = [pdesc]
|
||||
editor.rewrite_input(
|
||||
fetch_config, args.input_file, editor.deprecated, append=append
|
||||
)
|
||||
plugin, _ = prefetch_plugin(
|
||||
pdesc,
|
||||
)
|
||||
plugin, _ = prefetch_plugin(pdesc)
|
||||
autocommit = not args.no_commit
|
||||
if autocommit:
|
||||
commit(
|
||||
@@ -406,9 +402,9 @@ class Editor:
|
||||
# Expects arguments generated by 'update' subparser
|
||||
def update(self, args):
|
||||
"""CSV spec"""
|
||||
print("the update member function should be overriden in subclasses")
|
||||
print("the update member function should be overridden in subclasses")
|
||||
|
||||
def get_current_plugins(self, nixpkgs) -> List[Plugin]:
|
||||
def get_current_plugins(self, nixpkgs: str) -> List[Plugin]:
|
||||
"""To fill the cache"""
|
||||
data = run_nix_expr(self.get_plugins, nixpkgs)
|
||||
plugins = []
|
||||
@@ -440,6 +436,7 @@ class Editor:
|
||||
|
||||
plugins, redirects = check_results(results)
|
||||
|
||||
plugins = sorted(plugins, key=lambda v: v[1].normalized_name)
|
||||
self.generate_nix(plugins, outfile)
|
||||
|
||||
return redirects
|
||||
@@ -559,6 +556,7 @@ class Editor:
|
||||
parser = self.create_parser()
|
||||
args = parser.parse_args()
|
||||
command = args.command or "update"
|
||||
logging.basicConfig()
|
||||
log.setLevel(LOG_LEVELS[args.debug])
|
||||
log.info("Chose to run command: %s", command)
|
||||
self.nixpkgs = args.nixpkgs
|
||||
@@ -591,25 +589,24 @@ def prefetch_plugin(
|
||||
p: PluginDesc,
|
||||
cache: "Optional[Cache]" = None,
|
||||
) -> Tuple[Plugin, Optional[Repo]]:
|
||||
repo, branch, alias = p.repo, p.branch, p.alias
|
||||
name = alias or p.repo.name
|
||||
commit = None
|
||||
log.info(f"Fetching last commit for plugin {name} from {repo.uri}@{branch}")
|
||||
commit, date = repo.latest_commit()
|
||||
log.info(f"Fetching last commit for plugin {p.name} from {p.repo.uri}@{p.branch}")
|
||||
commit, date = p.repo.latest_commit()
|
||||
|
||||
cached_plugin = cache[commit] if cache else None
|
||||
if cached_plugin is not None:
|
||||
log.debug("Cache hit !")
|
||||
cached_plugin.name = name
|
||||
log.debug(f"Cache hit for {p.name}!")
|
||||
cached_plugin.name = p.name
|
||||
cached_plugin.date = date
|
||||
return cached_plugin, repo.redirect
|
||||
return cached_plugin, p.repo.redirect
|
||||
|
||||
has_submodules = repo.has_submodules()
|
||||
log.debug(f"prefetch {name}")
|
||||
sha256 = repo.prefetch(commit)
|
||||
has_submodules = p.repo.has_submodules()
|
||||
log.debug(f"prefetch {p.name}")
|
||||
sha256 = p.repo.prefetch(commit)
|
||||
|
||||
return (
|
||||
Plugin(name, commit, has_submodules, sha256, date=date),
|
||||
repo.redirect,
|
||||
Plugin(p.name, commit, has_submodules, sha256, date=date),
|
||||
p.repo.redirect,
|
||||
)
|
||||
|
||||
|
||||
@@ -624,7 +621,7 @@ def print_download_error(plugin: PluginDesc, ex: Exception):
|
||||
|
||||
|
||||
def check_results(
|
||||
results: List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]]
|
||||
results: List[Tuple[PluginDesc, Union[Exception, Plugin], Optional[Repo]]],
|
||||
) -> Tuple[List[Tuple[PluginDesc, Plugin]], Redirects]:
|
||||
""" """
|
||||
failures: List[Tuple[PluginDesc, Exception]] = []
|
||||
@@ -642,10 +639,9 @@ def check_results(
|
||||
|
||||
print(f"{len(results) - len(failures)} plugins were checked", end="")
|
||||
if len(failures) == 0:
|
||||
print()
|
||||
return plugins, redirects
|
||||
else:
|
||||
print(f", {len(failures)} plugin(s) could not be downloaded:\n")
|
||||
log.error(f", {len(failures)} plugin(s) could not be downloaded:\n")
|
||||
|
||||
for plugin, exception in failures:
|
||||
print_download_error(plugin, exception)
|
||||
@@ -738,10 +734,7 @@ def rewrite_input(
|
||||
append: List[PluginDesc] = [],
|
||||
):
|
||||
log.info("Rewriting input file %s", input_file)
|
||||
plugins = load_plugins_from_csv(
|
||||
config,
|
||||
input_file,
|
||||
)
|
||||
plugins = load_plugins_from_csv(config, input_file)
|
||||
|
||||
plugins.extend(append)
|
||||
|
||||
@@ -753,15 +746,25 @@ def rewrite_input(
|
||||
deprecations = json.load(f)
|
||||
# TODO parallelize this step
|
||||
for pdesc, new_repo in redirects.items():
|
||||
log.info("Rewriting input file %s", input_file)
|
||||
log.info("Resolving deprecated plugin %s -> %s", pdesc.name, new_repo.name)
|
||||
new_pdesc = PluginDesc(new_repo, pdesc.branch, pdesc.alias)
|
||||
|
||||
old_plugin, _ = prefetch_plugin(pdesc)
|
||||
new_plugin, _ = prefetch_plugin(new_pdesc)
|
||||
|
||||
if old_plugin.normalized_name != new_plugin.normalized_name:
|
||||
deprecations[old_plugin.normalized_name] = {
|
||||
"new": new_plugin.normalized_name,
|
||||
"date": cur_date_iso,
|
||||
}
|
||||
|
||||
# remove plugin from index file, so we won't add it to deprecations again
|
||||
for i, plugin in enumerate(plugins):
|
||||
if plugin.name == pdesc.name:
|
||||
plugins.pop(i)
|
||||
break
|
||||
plugins.append(new_pdesc)
|
||||
|
||||
with open(deprecated, "w") as f:
|
||||
json.dump(deprecations, f, indent=4, sort_keys=True)
|
||||
f.write("\n")
|
||||
@@ -772,7 +775,7 @@ def rewrite_input(
|
||||
fieldnames = ["repo", "branch", "alias"]
|
||||
writer = csv.DictWriter(f, fieldnames, dialect="unix", quoting=csv.QUOTE_NONE)
|
||||
writer.writeheader()
|
||||
for plugin in sorted(plugins):
|
||||
for plugin in sorted(plugins, key=lambda x: x.name):
|
||||
writer.writerow(asdict(plugin))
|
||||
|
||||
|
||||
@@ -792,9 +795,11 @@ def update_plugins(editor: Editor, args):
|
||||
|
||||
log.info("Start updating plugins")
|
||||
if args.proc > 1 and args.github_token == None:
|
||||
log.warning("You have enabled parallel updates but haven't set a github token.\n"
|
||||
"You may be hit with `HTTP Error 429: too many requests` as a consequence."
|
||||
"Either set --proc=1 or --github-token=YOUR_TOKEN. ")
|
||||
log.warning(
|
||||
"You have enabled parallel updates but haven't set a github token.\n"
|
||||
"You may be hit with `HTTP Error 429: too many requests` as a consequence."
|
||||
"Either set --proc=1 or --github-token=YOUR_TOKEN. "
|
||||
)
|
||||
|
||||
fetch_config = FetchConfig(args.proc, args.github_token)
|
||||
update = editor.get_update(args.input_file, args.outfile, fetch_config)
|
||||
@@ -810,11 +815,9 @@ def update_plugins(editor: Editor, args):
|
||||
if autocommit:
|
||||
try:
|
||||
repo = git.Repo(os.getcwd())
|
||||
updated = datetime.now(tz=UTC).strftime('%Y-%m-%d')
|
||||
updated = datetime.now(tz=UTC).strftime("%Y-%m-%d")
|
||||
print(args.outfile)
|
||||
commit(repo,
|
||||
f"{editor.attr_path}: update on {updated}", [args.outfile]
|
||||
)
|
||||
commit(repo, f"{editor.attr_path}: update on {updated}", [args.outfile])
|
||||
except git.InvalidGitRepositoryError as e:
|
||||
print(f"Not in a git repository: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -109,6 +109,8 @@
|
||||
|
||||
- [Firefly-iii Data Importer](https://github.com/firefly-iii/data-importer), a data importer for Firefly-III. Available as [services.firefly-iii-data-importer](options.html#opt-services.firefly-iii-data-importer.enable).
|
||||
|
||||
- [Dashy](https://dashy.to), an open source, highly customizable, easy to use, privacy-respecting dashboard app. Available as [services.dashy](options.html#opt-services.dashy).
|
||||
|
||||
- [QGroundControl], a ground station support and configuration manager for the PX4 and APM Flight Stacks. Available as [programs.qgroundcontrol](options.html#opt-programs.qgroundcontrol.enable).
|
||||
|
||||
- [Eintopf](https://eintopf.info), a community event and calendar web application. Available as [services.eintopf](options.html#opt-services.eintopf.enable).
|
||||
@@ -195,6 +197,8 @@
|
||||
|
||||
## Backward Incompatibilities {#sec-release-24.11-incompatibilities}
|
||||
|
||||
- Nixpkgs now requires Nix 2.3.17 or newer to allow for zstd compressed binary artifacts.
|
||||
|
||||
- The `sound` options have been removed or renamed, as they had a lot of unintended side effects. See [below](#sec-release-24.11-migration-sound) for details.
|
||||
|
||||
- The NVIDIA driver no longer defaults to the proprietary kernel module with versions >= 560. You will need to manually set `hardware.nvidia.open` to select the proprietary or open modules.
|
||||
|
||||
@@ -228,10 +228,10 @@ in
|
||||
in [
|
||||
(mkToolModule { name = "nixos-build-vms"; })
|
||||
(mkToolModule { name = "nixos-enter"; })
|
||||
(mkToolModule { name = "nixos-generate-config"; package = nixos-generate-config; })
|
||||
(mkToolModule { name = "nixos-install"; package = nixos-install; })
|
||||
(mkToolModule { name = "nixos-generate-config"; package = config.system.build.nixos-generate-config; })
|
||||
(mkToolModule { name = "nixos-install"; package = config.system.build.nixos-install; })
|
||||
(mkToolModule { name = "nixos-option"; })
|
||||
(mkToolModule { name = "nixos-rebuild"; package = nixos-rebuild; })
|
||||
(mkToolModule { name = "nixos-rebuild"; package = config.system.build.nixos-rebuild; })
|
||||
(mkToolModule { name = "nixos-version"; package = nixos-version; })
|
||||
];
|
||||
|
||||
|
||||
@@ -12,14 +12,19 @@ in
|
||||
options.programs.localsend = {
|
||||
enable = lib.mkEnableOption "localsend, an open source cross-platform alternative to AirDrop";
|
||||
|
||||
openFirewall = lib.mkEnableOption "opening the firewall port ${toString firewallPort} for receiving files" // {
|
||||
default = true;
|
||||
};
|
||||
package = lib.mkPackageOption pkgs "localsend" { };
|
||||
|
||||
openFirewall =
|
||||
lib.mkEnableOption "opening the firewall port ${toString firewallPort} for receiving files"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [ pkgs.localsend ];
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ firewallPort ];
|
||||
networking.firewall.allowedUDPPorts = lib.optionals cfg.openFirewall [ firewallPort ];
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ pandapip1 ];
|
||||
|
||||
@@ -101,7 +101,12 @@ in {
|
||||
};
|
||||
};
|
||||
|
||||
systemd.packages = [ cfg.package ];
|
||||
systemd = {
|
||||
packages = [ cfg.package ];
|
||||
tmpfiles.rules = [
|
||||
"d /etc/openvpn3/configs 0750 openvpn openvpn - -"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ shamilton progrm_jarvis ];
|
||||
|
||||
@@ -95,7 +95,7 @@ in
|
||||
after = ["network.target"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
script = ''
|
||||
${fhsEnvExecutable} --dir ${cfg.dataDir} ${allowRemoteGuiRpcFlag}
|
||||
exec ${fhsEnvExecutable} --dir ${cfg.dataDir} ${allowRemoteGuiRpcFlag}
|
||||
'';
|
||||
serviceConfig = {
|
||||
User = "boinc";
|
||||
|
||||
@@ -70,7 +70,7 @@ in
|
||||
LoadCredential = "bot-password-file:${cfg.botPasswordFile}";
|
||||
RestartSec = "10s";
|
||||
StateDirectory = "hebbot";
|
||||
WorkingDirectory = "hebbot";
|
||||
WorkingDirectory = "/var/lib/hebbot";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -275,7 +275,7 @@ in
|
||||
systemd.services.guix-daemon = {
|
||||
environment = serviceEnv;
|
||||
script = ''
|
||||
${lib.getExe' package "guix-daemon"} \
|
||||
exec ${lib.getExe' package "guix-daemon"} \
|
||||
--build-users-group=${cfg.group} \
|
||||
${lib.optionalString (cfg.substituters.urls != [ ])
|
||||
"--substitute-urls='${lib.concatStringsSep " " cfg.substituters.urls}'"} \
|
||||
@@ -384,7 +384,7 @@ in
|
||||
}
|
||||
'';
|
||||
script = ''
|
||||
${lib.getExe' package "guix"} publish \
|
||||
exec ${lib.getExe' package "guix"} publish \
|
||||
--user=${cfg.publish.user} --port=${builtins.toString cfg.publish.port} \
|
||||
${lib.escapeShellArgs cfg.publish.extraArgs}
|
||||
'';
|
||||
@@ -440,12 +440,10 @@ in
|
||||
description = "Guix garbage collection";
|
||||
startAt = cfg.gc.dates;
|
||||
script = ''
|
||||
${lib.getExe' package "guix"} gc ${lib.escapeShellArgs cfg.gc.extraArgs}
|
||||
exec ${lib.getExe' package "guix"} gc ${lib.escapeShellArgs cfg.gc.extraArgs}
|
||||
'';
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
|
||||
PrivateDevices = true;
|
||||
PrivateNetwork = true;
|
||||
ProtectControlGroups = true;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
cfg = config.services.nzbget;
|
||||
pkg = pkgs.nzbget;
|
||||
stateDir = "/var/lib/nzbget";
|
||||
configFile = "${stateDir}/nzbget.conf";
|
||||
configOpts = lib.concatStringsSep " " (lib.mapAttrsToList (name: value: "-o ${name}=${lib.escapeShellArg (toStr value)}") cfg.settings);
|
||||
@@ -24,6 +23,8 @@ in
|
||||
services.nzbget = {
|
||||
enable = lib.mkEnableOption "NZBGet, for downloading files from news servers";
|
||||
|
||||
package = lib.mkPackageOption pkgs "nzbget" { };
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nzbget";
|
||||
@@ -64,8 +65,8 @@ in
|
||||
InfoTarget = "screen";
|
||||
DetailTarget = "screen";
|
||||
# required paths
|
||||
ConfigTemplate = "${pkg}/share/nzbget/nzbget.conf";
|
||||
WebDir = "${pkg}/share/nzbget/webui";
|
||||
ConfigTemplate = "${cfg.package}/share/nzbget/nzbget.conf";
|
||||
WebDir = "${cfg.package}/share/nzbget/webui";
|
||||
# nixos handles package updates
|
||||
UpdateCheck = "none";
|
||||
};
|
||||
@@ -81,7 +82,7 @@ in
|
||||
|
||||
preStart = ''
|
||||
if [ ! -f ${configFile} ]; then
|
||||
${pkgs.coreutils}/bin/install -m 0700 ${pkg}/share/nzbget/nzbget.conf ${configFile}
|
||||
${pkgs.coreutils}/bin/install -m 0700 ${cfg.package}/share/nzbget/nzbget.conf ${configFile}
|
||||
fi
|
||||
'';
|
||||
|
||||
@@ -92,8 +93,8 @@ in
|
||||
Group = cfg.group;
|
||||
UMask = "0002";
|
||||
Restart = "on-failure";
|
||||
ExecStart = "${pkg}/bin/nzbget --server --configfile ${stateDir}/nzbget.conf ${configOpts}";
|
||||
ExecStop = "${pkg}/bin/nzbget --quit";
|
||||
ExecStart = "${cfg.package}/bin/nzbget --server --configfile ${stateDir}/nzbget.conf ${configOpts}";
|
||||
ExecStop = "${cfg.package}/bin/nzbget --quit";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ in {
|
||||
on how to set up a reverse proxy
|
||||
'';
|
||||
|
||||
package = lib.mkPackageOption pkgs "ombi" { };
|
||||
|
||||
dataDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/var/lib/ombi";
|
||||
@@ -58,7 +60,7 @@ in {
|
||||
Type = "simple";
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
ExecStart = "${pkgs.ombi}/bin/Ombi --storage '${cfg.dataDir}' --host 'http://*:${toString cfg.port}'";
|
||||
ExecStart = "${lib.getExe cfg.package} --storage '${cfg.dataDir}' --host 'http://*:${toString cfg.port}'";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,37 +1,31 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
cfg = config.services.teamviewer;
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
||||
###### interface
|
||||
|
||||
options = {
|
||||
|
||||
services.teamviewer.enable = mkEnableOption "TeamViewer daemon";
|
||||
|
||||
services.teamviewer = {
|
||||
enable = lib.mkEnableOption "TeamViewer daemon & system package";
|
||||
package = lib.mkPackageOption pkgs "teamviewer" { };
|
||||
};
|
||||
};
|
||||
|
||||
###### implementation
|
||||
config = lib.mkIf (cfg.enable) {
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
config = mkIf (cfg.enable) {
|
||||
|
||||
environment.systemPackages = [ pkgs.teamviewer ];
|
||||
|
||||
services.dbus.packages = [ pkgs.teamviewer ];
|
||||
services.dbus.packages = [ cfg.package ];
|
||||
|
||||
systemd.services.teamviewerd = {
|
||||
description = "TeamViewer remote control daemon";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" "network.target" "dbus.service" ];
|
||||
after = [
|
||||
"network-online.target"
|
||||
"network.target"
|
||||
"dbus.service"
|
||||
];
|
||||
requires = [ "dbus.service" ];
|
||||
preStart = "mkdir -pv /var/lib/teamviewer /var/log/teamviewer";
|
||||
|
||||
@@ -39,12 +33,11 @@ in
|
||||
startLimitBurst = 10;
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.teamviewer}/bin/teamviewerd -f";
|
||||
ExecStart = "${cfg.package}/bin/teamviewerd -f";
|
||||
PIDFile = "/run/teamviewerd.pid";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
Restart = "on-abort";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.types) package str;
|
||||
inherit (lib)
|
||||
mkIf
|
||||
mkOption
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
;
|
||||
cfg = config.services.dashy;
|
||||
in
|
||||
{
|
||||
options.services.dashy = {
|
||||
enable = mkEnableOption ''
|
||||
Dashy, a highly customizable, easy to use, privacy-respecting dashboard app.
|
||||
|
||||
Note that this builds a static web app as opposed to running a full node server, unlike the default docker image.
|
||||
|
||||
Writing config changes to disk through the UI, triggering a rebuild through the UI and application status checks are
|
||||
unavailable without the node server; Everything else will work fine.
|
||||
|
||||
See the deployment docs for [building from source](https://dashy.to/docs/deployment#build-from-source), [hosting with a CDN](https://dashy.to/docs/deployment#hosting-with-cdn) and [CDN cloud deploy](https://dashy.to/docs/deployment#cdn--cloud-deploy) for more information.
|
||||
'';
|
||||
|
||||
virtualHost = {
|
||||
enableNginx = mkEnableOption "a virtualhost to serve dashy through nginx";
|
||||
|
||||
domain = mkOption {
|
||||
description = ''
|
||||
Domain to use for the virtual host.
|
||||
|
||||
This can be used to change nginx options like
|
||||
```nix
|
||||
services.nginx.virtualHosts."$\{config.services.dashy.virtualHost.domain}".listen = [ ... ]
|
||||
```
|
||||
or
|
||||
```nix
|
||||
services.nginx.virtualHosts."example.com".listen = [ ... ]
|
||||
```
|
||||
'';
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "dashy-ui" { };
|
||||
|
||||
finalDrv = mkOption {
|
||||
readOnly = true;
|
||||
default =
|
||||
if cfg.settings != { } then cfg.package.override { inherit (cfg) settings; } else cfg.package;
|
||||
defaultText = ''
|
||||
if cfg.settings != {}
|
||||
then cfg.package.override {inherit (cfg) settings;}
|
||||
else cfg.package;
|
||||
'';
|
||||
type = package;
|
||||
description = ''
|
||||
Final derivation containing the fully built static files
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
default = { };
|
||||
description = ''
|
||||
Settings serialized into `user-data/conf.yml` before build.
|
||||
If left empty, the default configuration shipped with the package will be used instead.
|
||||
|
||||
Note that the full configuration will be written to the nix store as world readable, which may include secrets such as [password hashes](https://dashy.to/docs/configuring#appconfigauthusers-optional).
|
||||
|
||||
To add files such as icons or backgrounds, you can reference them in line such as
|
||||
```nix
|
||||
icon = "$\{./icon.png}";
|
||||
```
|
||||
This will add the file to the nix store upon build, referencing it by file path as expected by Dashy.
|
||||
'';
|
||||
example = ''
|
||||
{
|
||||
appConfig = {
|
||||
cssThemes = [
|
||||
"example-theme-1"
|
||||
"example-theme-2"
|
||||
];
|
||||
enableFontAwesome = true;
|
||||
fontAwesomeKey = "e9076c7025";
|
||||
theme = "thebe";
|
||||
};
|
||||
pageInfo = {
|
||||
description = "My Awesome Dashboard";
|
||||
navLinks = [
|
||||
{
|
||||
path = "/";
|
||||
title = "Home";
|
||||
}
|
||||
{
|
||||
path = "https://example.com";
|
||||
title = "Example 1";
|
||||
}
|
||||
{
|
||||
path = "https://example.com";
|
||||
title = "Example 2";
|
||||
}
|
||||
];
|
||||
title = "Dashy";
|
||||
};
|
||||
sections = [
|
||||
{
|
||||
displayData = {
|
||||
collapsed = true;
|
||||
cols = 2;
|
||||
customStyles = "border: 2px dashed red;";
|
||||
itemSize = "large";
|
||||
};
|
||||
items = [
|
||||
{
|
||||
backgroundColor = "#0079ff";
|
||||
color = "#00ffc9";
|
||||
description = "Source code and documentation on GitHub";
|
||||
icon = "fab fa-github";
|
||||
target = "sametab";
|
||||
title = "Source";
|
||||
url = "https://github.com/Lissy93/dashy";
|
||||
}
|
||||
{
|
||||
description = "View currently open issues, or raise a new one";
|
||||
icon = "fas fa-bug";
|
||||
title = "Issues";
|
||||
url = "https://github.com/Lissy93/dashy/issues";
|
||||
}
|
||||
{
|
||||
description = "Live Demo #1";
|
||||
icon = "fas fa-rocket";
|
||||
target = "iframe";
|
||||
title = "Demo 1";
|
||||
url = "https://dashy-demo-1.as93.net";
|
||||
}
|
||||
{
|
||||
description = "Live Demo #2";
|
||||
icon = "favicon";
|
||||
target = "newtab";
|
||||
title = "Demo 2";
|
||||
url = "https://dashy-demo-2.as93.net";
|
||||
}
|
||||
];
|
||||
name = "Getting Started";
|
||||
}
|
||||
];
|
||||
}
|
||||
'';
|
||||
inherit (pkgs.formats.json { }) type;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nginx = mkIf cfg.virtualHost.enableNginx {
|
||||
enable = true;
|
||||
virtualHosts."${cfg.virtualHost.domain}" = {
|
||||
locations."/" = {
|
||||
root = cfg.finalDrv;
|
||||
tryFiles = "$uri /index.html ";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = [
|
||||
lib.maintainers.therealgramdalf
|
||||
];
|
||||
}
|
||||
@@ -116,7 +116,7 @@ in
|
||||
description = ''
|
||||
Configuration for Immich.
|
||||
See <https://immich.app/docs/install/config-file/> or navigate to
|
||||
<https://your-immich-domain/admin/system-settings> for
|
||||
<https://my.immich.app/admin/system-settings> for
|
||||
options and defaults.
|
||||
Setting it to `null` allows configuring Immich in the web interface.
|
||||
'';
|
||||
@@ -270,7 +270,7 @@ in
|
||||
let
|
||||
postgresEnv =
|
||||
if isPostgresUnixSocket then
|
||||
{ DB_URL = "socket://${cfg.database.host}?dbname=${cfg.database.name}"; }
|
||||
{ DB_URL = "postgresql:///${cfg.database.name}?host=${cfg.database.host}"; }
|
||||
else
|
||||
{
|
||||
DB_HOSTNAME = cfg.database.host;
|
||||
@@ -317,6 +317,11 @@ in
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
inherit (cfg) environment;
|
||||
path = [
|
||||
# gzip and pg_dumpall are used by the backup service
|
||||
pkgs.gzip
|
||||
config.services.postgresql.package
|
||||
];
|
||||
|
||||
serviceConfig = commonServiceConfig // {
|
||||
ExecStart = lib.getExe cfg.package;
|
||||
|
||||
+29
-18
@@ -466,6 +466,15 @@ in {
|
||||
f"{switcher_path} test"
|
||||
)
|
||||
|
||||
# Start a unit explicitly, then wait for it to activate.
|
||||
# This is used for the acme-finished-* targets, as those
|
||||
# aren't started by switch-to-configuration, meaning
|
||||
# wait_for_unit(target) will fail with "no pending jobs"
|
||||
# if it wins the race and checks the target state before
|
||||
# the actual unit is started.
|
||||
def start_and_wait(node, unit):
|
||||
node.start_job(unit)
|
||||
node.wait_for_unit(unit)
|
||||
|
||||
# Ensures the issuer of our cert matches the chain
|
||||
# and matches the issuer we expect it to be.
|
||||
@@ -567,7 +576,7 @@ in {
|
||||
# Perform http-01 w/ lego test first
|
||||
with subtest("Can request certificate with Lego's built in web server"):
|
||||
switch_to(webserver, "http01lego")
|
||||
webserver.wait_for_unit("acme-finished-http.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-http.example.test.target")
|
||||
check_fullchain(webserver, "http.example.test")
|
||||
check_issuer(webserver, "http.example.test", "pebble")
|
||||
|
||||
@@ -581,7 +590,7 @@ in {
|
||||
with subtest("Can renew certificates when they expire"):
|
||||
hash = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
|
||||
switch_to(webserver, "renew")
|
||||
webserver.wait_for_unit("acme-finished-http.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-http.example.test.target")
|
||||
check_fullchain(webserver, "http.example.test")
|
||||
check_issuer(webserver, "http.example.test", "pebble")
|
||||
hash_after = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
|
||||
@@ -591,7 +600,7 @@ in {
|
||||
with subtest("Handles email change correctly"):
|
||||
hash = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
|
||||
switch_to(webserver, "accountchange")
|
||||
webserver.wait_for_unit("acme-finished-http.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-http.example.test.target")
|
||||
check_fullchain(webserver, "http.example.test")
|
||||
check_issuer(webserver, "http.example.test", "pebble")
|
||||
hash_after = webserver.succeed("sha256sum /var/lib/acme/http.example.test/cert.pem")
|
||||
@@ -602,15 +611,15 @@ in {
|
||||
switch_to(webserver, "general")
|
||||
|
||||
with subtest("Can request certificate with HTTP-01 challenge"):
|
||||
webserver.wait_for_unit("acme-finished-a.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-a.example.test.target")
|
||||
check_fullchain(webserver, "a.example.test")
|
||||
check_issuer(webserver, "a.example.test", "pebble")
|
||||
webserver.wait_for_unit("nginx.service")
|
||||
check_connection(client, "a.example.test")
|
||||
|
||||
with subtest("Runs 1 cert for account creation before others"):
|
||||
webserver.wait_for_unit("acme-finished-b.example.test.target")
|
||||
webserver.wait_for_unit("acme-finished-c.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-b.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-c.example.test.target")
|
||||
check_connection(client, "b.example.test")
|
||||
check_connection(client, "c.example.test")
|
||||
|
||||
@@ -645,12 +654,12 @@ in {
|
||||
|
||||
with subtest("Correctly implements OCSP stapling"):
|
||||
switch_to(webserver, "ocsp_stapling")
|
||||
webserver.wait_for_unit("acme-finished-a.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-a.example.test.target")
|
||||
check_stapling(client, "a.example.test")
|
||||
|
||||
with subtest("Can request certificate with HTTP-01 using lego's internal web server"):
|
||||
switch_to(webserver, "lego_server")
|
||||
webserver.wait_for_unit("acme-finished-lego.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-lego.example.test.target")
|
||||
webserver.wait_for_unit("nginx.service")
|
||||
webserver.succeed("echo HENLO && systemctl cat nginx.service")
|
||||
webserver.succeed('test "$(stat -c \'%U\' /var/lib/acme/* | uniq)" = "root"')
|
||||
@@ -660,23 +669,23 @@ in {
|
||||
with subtest("Can request certificate with HTTP-01 when nginx startup is delayed"):
|
||||
webserver.execute("systemctl stop nginx")
|
||||
switch_to(webserver, "slow_startup")
|
||||
webserver.wait_for_unit("acme-finished-slow.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-slow.example.test.target")
|
||||
check_issuer(webserver, "slow.example.test", "pebble")
|
||||
webserver.wait_for_unit("nginx.service")
|
||||
check_connection(client, "slow.example.test")
|
||||
|
||||
with subtest("Can limit concurrency of running renewals"):
|
||||
switch_to(webserver, "concurrency_limit")
|
||||
webserver.wait_for_unit("acme-finished-f.example.test.target")
|
||||
webserver.wait_for_unit("acme-finished-g.example.test.target")
|
||||
webserver.wait_for_unit("acme-finished-h.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-f.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-g.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-h.example.test.target")
|
||||
check_connection(client, "f.example.test")
|
||||
check_connection(client, "g.example.test")
|
||||
check_connection(client, "h.example.test")
|
||||
|
||||
with subtest("Works with caddy"):
|
||||
switch_to(webserver, "caddy")
|
||||
webserver.wait_for_unit("acme-finished-example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-example.test.target")
|
||||
webserver.wait_for_unit("caddy.service")
|
||||
# FIXME reloading caddy is not sufficient to load new certs.
|
||||
# Restart it manually until this is fixed.
|
||||
@@ -685,7 +694,7 @@ in {
|
||||
|
||||
with subtest("security.acme changes reflect on caddy"):
|
||||
switch_to(webserver, "caddy_change_acme_conf")
|
||||
webserver.wait_for_unit("acme-finished-example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-example.test.target")
|
||||
webserver.wait_for_unit("caddy.service")
|
||||
# FIXME reloading caddy is not sufficient to load new certs.
|
||||
# Restart it manually until this is fixed.
|
||||
@@ -703,7 +712,8 @@ in {
|
||||
switch_to(webserver, server)
|
||||
for domain in domains:
|
||||
if domain != "wildcard":
|
||||
webserver.wait_for_unit(
|
||||
start_and_wait(
|
||||
webserver,
|
||||
f"acme-finished-{server}-{domain}.example.test.target"
|
||||
)
|
||||
except Exception as err:
|
||||
@@ -737,7 +747,8 @@ in {
|
||||
with subtest("Can remove an alias from a domain + cert is updated"):
|
||||
test_alias = f"{server}-{domains[0]}-alias.example.test"
|
||||
switch_to(webserver, f"{server}_remove_alias")
|
||||
webserver.wait_for_unit(f"acme-finished-{test_domain}.target")
|
||||
wait_for_server()
|
||||
start_and_wait(webserver, f"acme-finished-{test_domain}.target")
|
||||
wait_for_server()
|
||||
check_connection(client, test_domain)
|
||||
rc, _s = client.execute(
|
||||
@@ -752,7 +763,7 @@ in {
|
||||
switch_to(webserver, server)
|
||||
wait_for_server()
|
||||
switch_to(webserver, f"{server}_change_acme_conf")
|
||||
webserver.wait_for_unit(f"acme-finished-{test_domain}.target")
|
||||
start_and_wait(webserver, f"acme-finished-{test_domain}.target")
|
||||
wait_for_server()
|
||||
check_connection_key_bits(client, test_domain, "384")
|
||||
|
||||
@@ -763,7 +774,7 @@ in {
|
||||
switch_to(webserver, "http01lego_legacyAccountHash", allow_fail=True)
|
||||
# unit is failed, but in a way that this throws no exception:
|
||||
try:
|
||||
webserver.wait_for_unit("acme-finished-http.example.test.target")
|
||||
start_and_wait(webserver, "acme-finished-http.example.test.target")
|
||||
except Exception:
|
||||
# The unit is allowed – or even expected – to fail due to not being able to
|
||||
# reach the actual letsencrypt server. We only use it for serialising the
|
||||
|
||||
@@ -775,13 +775,10 @@ in {
|
||||
peering-manager = handleTest ./web-apps/peering-manager.nix {};
|
||||
peertube = handleTestOn ["x86_64-linux"] ./web-apps/peertube.nix {};
|
||||
peroxide = handleTest ./peroxide.nix {};
|
||||
pg_anonymizer = handleTest ./pg_anonymizer.nix {};
|
||||
pgadmin4 = handleTest ./pgadmin4.nix {};
|
||||
pgbouncer = handleTest ./pgbouncer.nix {};
|
||||
pghero = runTest ./pghero.nix;
|
||||
pgjwt = handleTest ./pgjwt.nix {};
|
||||
pgmanage = handleTest ./pgmanage.nix {};
|
||||
pgvecto-rs = handleTest ./pgvecto-rs.nix {};
|
||||
phosh = handleTest ./phosh.nix {};
|
||||
photonvision = handleTest ./photonvision.nix {};
|
||||
photoprism = handleTest ./photoprism.nix {};
|
||||
@@ -814,13 +811,7 @@ in {
|
||||
postfix = handleTest ./postfix.nix {};
|
||||
postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
|
||||
postfixadmin = handleTest ./postfixadmin.nix {};
|
||||
postgis = handleTest ./postgis.nix {};
|
||||
apache_datasketches = handleTest ./apache_datasketches.nix {};
|
||||
postgresql = handleTest ./postgresql.nix {};
|
||||
postgresql-jit = handleTest ./postgresql-jit.nix {};
|
||||
postgresql-wal-receiver = handleTest ./postgresql-wal-receiver.nix {};
|
||||
postgresql-tls-client-cert = handleTest ./postgresql-tls-client-cert.nix {};
|
||||
postgresql-wal2json = handleTest ./postgresql-wal2json.nix {};
|
||||
postgresql = handleTest ./postgresql {};
|
||||
powerdns = handleTest ./powerdns.nix {};
|
||||
powerdns-admin = handleTest ./powerdns-admin.nix {};
|
||||
power-profiles-daemon = handleTest ./power-profiles-daemon.nix {};
|
||||
@@ -1047,7 +1038,6 @@ in {
|
||||
tiddlywiki = handleTest ./tiddlywiki.nix {};
|
||||
tigervnc = handleTest ./tigervnc.nix {};
|
||||
tika = runTest ./tika.nix;
|
||||
timescaledb = handleTest ./timescaledb.nix {};
|
||||
timezone = handleTest ./timezone.nix {};
|
||||
timidity = handleTestOn ["aarch64-linux" "x86_64-linux"] ./timidity {};
|
||||
tinc = handleTest ./tinc {};
|
||||
@@ -1067,7 +1057,6 @@ in {
|
||||
trezord = handleTest ./trezord.nix {};
|
||||
trickster = handleTest ./trickster.nix {};
|
||||
trilium-server = handleTestOn ["x86_64-linux"] ./trilium-server.nix {};
|
||||
tsja = handleTest ./tsja.nix {};
|
||||
tsm-client-gui = handleTest ./tsm-client-gui.nix {};
|
||||
ttyd = handleTest ./web-servers/ttyd.nix {};
|
||||
txredisapi = handleTest ./txredisapi.nix {};
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
name = "postgis";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ lsix ]; # TODO: Who's the maintener now?
|
||||
};
|
||||
|
||||
nodes = {
|
||||
master =
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.postgresql = let mypg = pkgs.postgresql_15; in {
|
||||
enable = true;
|
||||
package = mypg;
|
||||
extraPlugins = with mypg.pkgs; [
|
||||
apache_datasketches
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.sleep(10) # Hopefully this is long enough!!
|
||||
master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION datasketches;'")
|
||||
master.succeed("sudo -u postgres psql -c 'SELECT hll_sketch_to_string(hll_sketch_build(1));'")
|
||||
'';
|
||||
})
|
||||
@@ -16,6 +16,7 @@ import ./make-test-python.nix (
|
||||
machine.wait_for_open_port(53317)
|
||||
machine.wait_for_window("LocalSend", 10)
|
||||
machine.succeed("netstat --listening --program --tcp | grep -P 'tcp.*53317.*localsend'")
|
||||
machine.succeed("netstat --listening --program --udp | grep -P 'udp.*53317.*localsend'")
|
||||
'';
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
||||
name = "pg_anonymizer";
|
||||
meta.maintainers = lib.teams.flyingcircus.members;
|
||||
|
||||
nodes.machine = { pkgs, ... }: {
|
||||
environment.systemPackages = [ pkgs.pg-dump-anon ];
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
extraPlugins = ps: [ ps.anonymizer ];
|
||||
settings.shared_preload_libraries = [ "anon" ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_unit("postgresql.service")
|
||||
|
||||
with subtest("Setup"):
|
||||
machine.succeed("sudo -u postgres psql --command 'create database demo'")
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -d demo -f ${pkgs.writeText "init.sql" ''
|
||||
create extension anon cascade;
|
||||
select anon.init();
|
||||
create table player(id serial, name text, points int);
|
||||
insert into player(id,name,points) values (1,'Foo', 23);
|
||||
insert into player(id,name,points) values (2,'Bar',42);
|
||||
security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name();';
|
||||
security label for anon on column player.points is 'MASKED WITH VALUE NULL';
|
||||
''}"
|
||||
)
|
||||
|
||||
def get_player_table_contents():
|
||||
return [
|
||||
x.split(',') for x in machine.succeed("sudo -u postgres psql -d demo --csv --command 'select * from player'").splitlines()[1:]
|
||||
]
|
||||
|
||||
def check_anonymized_row(row, id, original_name):
|
||||
assert row[0] == id, f"Expected first row to have ID {id}, but got {row[0]}"
|
||||
assert row[1] != original_name, f"Expected first row to have a name other than {original_name}"
|
||||
assert not bool(row[2]), "Expected points to be NULL in first row"
|
||||
|
||||
def find_xsv_in_dump(dump, sep=','):
|
||||
"""
|
||||
Expecting to find a CSV (for pg_dump_anon) or TSV (for pg_dump) structure, looking like
|
||||
|
||||
COPY public.player ...
|
||||
1,Shields,
|
||||
2,Salazar,
|
||||
\.
|
||||
|
||||
in the given dump (the commas are tabs in case of pg_dump).
|
||||
Extract the CSV lines and split by `sep`.
|
||||
"""
|
||||
|
||||
try:
|
||||
from itertools import dropwhile, takewhile
|
||||
return [x.split(sep) for x in list(takewhile(
|
||||
lambda x: x != "\\.",
|
||||
dropwhile(
|
||||
lambda x: not x.startswith("COPY public.player"),
|
||||
dump.splitlines()
|
||||
)
|
||||
))[1:]]
|
||||
except:
|
||||
print(f"Dump to process: {dump}")
|
||||
raise
|
||||
|
||||
def check_original_data(output):
|
||||
assert output[0] == ['1','Foo','23'], f"Expected first row from player table to be 1,Foo,23; got {output[0]}"
|
||||
assert output[1] == ['2','Bar','42'], f"Expected first row from player table to be 2,Bar,42; got {output[1]}"
|
||||
|
||||
def check_anonymized_rows(output):
|
||||
check_anonymized_row(output[0], '1', 'Foo')
|
||||
check_anonymized_row(output[1], '2', 'Bar')
|
||||
|
||||
with subtest("Check initial state"):
|
||||
check_original_data(get_player_table_contents())
|
||||
|
||||
with subtest("Anonymous dumps"):
|
||||
check_original_data(find_xsv_in_dump(
|
||||
machine.succeed("sudo -u postgres pg_dump demo"),
|
||||
sep='\t'
|
||||
))
|
||||
check_anonymized_rows(find_xsv_in_dump(
|
||||
machine.succeed("sudo -u postgres pg_dump_anon -U postgres -h /run/postgresql -d demo"),
|
||||
sep=','
|
||||
))
|
||||
|
||||
with subtest("Anonymize"):
|
||||
machine.succeed("sudo -u postgres psql -d demo --command 'select anon.anonymize_database();'")
|
||||
check_anonymized_rows(get_player_table_contents())
|
||||
'';
|
||||
})
|
||||
@@ -1,35 +0,0 @@
|
||||
import ./make-test-python.nix ({ pkgs, lib, ...}:
|
||||
|
||||
with pkgs; {
|
||||
name = "pgjwt";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ spinus willibutz ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
master = { ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
extraPlugins = ps: with ps; [ pgjwt pgtap ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = { nodes, ... }:
|
||||
let
|
||||
sqlSU = "${nodes.master.services.postgresql.superUser}";
|
||||
pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}";
|
||||
inherit (nodes.master.services.postgresql.package.pkgs) pgjwt;
|
||||
in
|
||||
''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.succeed(
|
||||
"${pkgs.gnused}/bin/sed -e '12 i CREATE EXTENSION pgcrypto;\\nCREATE EXTENSION pgtap;\\nSET search_path TO tap,public;' ${pgjwt.src}/test.sql > /tmp/test.sql"
|
||||
)
|
||||
master.succeed(
|
||||
"${pkgs.sudo}/bin/sudo -u ${sqlSU} PGOPTIONS=--search_path=tap,public ${pgProve}/bin/pg_prove -d postgres -v -f /tmp/test.sql"
|
||||
)
|
||||
'';
|
||||
})
|
||||
@@ -1,76 +0,0 @@
|
||||
# mostly copied from ./timescaledb.nix which was copied from ./postgresql.nix
|
||||
# as it seemed unapproriate to test additional extensions for postgresql there.
|
||||
|
||||
{ system ? builtins.currentSystem
|
||||
, config ? { }
|
||||
, pkgs ? import ../.. { inherit system config; }
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
postgresql-versions = import ../../pkgs/servers/sql/postgresql pkgs;
|
||||
# Test cases from https://docs.pgvecto.rs/use-cases/hybrid-search.html
|
||||
test-sql = pkgs.writeText "postgresql-test" ''
|
||||
CREATE EXTENSION vectors;
|
||||
|
||||
CREATE TABLE items (
|
||||
id bigserial PRIMARY KEY,
|
||||
content text NOT NULL,
|
||||
embedding vectors.vector(3) NOT NULL -- 3 dimensions
|
||||
);
|
||||
|
||||
INSERT INTO items (content, embedding) VALUES
|
||||
('a fat cat sat on a mat and ate a fat rat', '[1, 2, 3]'),
|
||||
('a fat dog sat on a mat and ate a fat rat', '[4, 5, 6]'),
|
||||
('a thin cat sat on a mat and ate a thin rat', '[7, 8, 9]'),
|
||||
('a thin dog sat on a mat and ate a thin rat', '[10, 11, 12]');
|
||||
'';
|
||||
make-postgresql-test = postgresql-name: postgresql-package: makeTest {
|
||||
name = postgresql-name;
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ diogotcorreia ];
|
||||
};
|
||||
|
||||
nodes.machine = { ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = postgresql-package;
|
||||
extraPlugins = ps: with ps; [
|
||||
pgvecto-rs
|
||||
];
|
||||
settings.shared_preload_libraries = "vectors";
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def check_count(statement, lines):
|
||||
return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
|
||||
statement, lines
|
||||
)
|
||||
|
||||
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("Postgresql with extension vectors is available just after unit start"):
|
||||
machine.succeed(check_count("SELECT * FROM pg_available_extensions WHERE name = 'vectors' AND default_version = '${postgresql-package.pkgs.pgvecto-rs.version}';", 1))
|
||||
|
||||
machine.succeed("sudo -u postgres psql -f ${test-sql}")
|
||||
|
||||
machine.succeed(check_count("SELECT content, embedding FROM items WHERE to_tsvector('english', content) @@ 'cat & rat'::tsquery;", 2))
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
|
||||
};
|
||||
applicablePostgresqlVersions = filterAttrs (_: value: versionAtLeast value.version "14") postgresql-versions;
|
||||
in
|
||||
mapAttrs'
|
||||
(name: package: {
|
||||
inherit name;
|
||||
value = make-postgresql-test name package;
|
||||
})
|
||||
applicablePostgresqlVersions
|
||||
@@ -1,38 +0,0 @@
|
||||
import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
name = "postgis";
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ lsix ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
master =
|
||||
{ pkgs, ... }:
|
||||
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql;
|
||||
extraPlugins = ps: with ps; [
|
||||
postgis
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.sleep(10) # Hopefully this is long enough!!
|
||||
master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis;'")
|
||||
master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis_raster;'")
|
||||
master.succeed("sudo -u postgres psql -c 'CREATE EXTENSION postgis_topology;'")
|
||||
master.succeed("sudo -u postgres psql -c 'select postgis_version();'")
|
||||
master.succeed("[ \"$(sudo -u postgres psql --no-psqlrc --tuples-only -c 'select postgis_version();')\" = \" ${
|
||||
pkgs.lib.versions.major pkgs.postgis.version
|
||||
}.${
|
||||
pkgs.lib.versions.minor pkgs.postgis.version
|
||||
} USE_GEOS=1 USE_PROJ=1 USE_STATS=1\" ]")
|
||||
# st_makepoint goes through c code
|
||||
master.succeed("sudo -u postgres psql --no-psqlrc --tuples-only -c 'select st_makepoint(1, 1)'")
|
||||
'';
|
||||
})
|
||||
@@ -1,55 +0,0 @@
|
||||
{ system ? builtins.currentSystem
|
||||
, config ? {}
|
||||
, pkgs ? import ../.. { inherit system config; }
|
||||
, package ? null
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
packages = builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs);
|
||||
|
||||
mkJitTestFromName = name:
|
||||
mkJitTest pkgs.${name};
|
||||
|
||||
mkJitTest = package: makeTest {
|
||||
name = package.name;
|
||||
meta.maintainers = with lib.maintainers; [ ma27 ];
|
||||
nodes.machine = { pkgs, lib, ... }: {
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
enableJIT = true;
|
||||
initialScript = pkgs.writeText "init.sql" ''
|
||||
create table demo (id int);
|
||||
insert into demo (id) select generate_series(1, 5);
|
||||
'';
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql.service")
|
||||
|
||||
with subtest("JIT is enabled"):
|
||||
machine.succeed("sudo -u postgres psql <<<'show jit;' | grep 'on'")
|
||||
|
||||
with subtest("Test JIT works fine"):
|
||||
output = machine.succeed(
|
||||
"cat ${pkgs.writeText "test.sql" ''
|
||||
set jit_above_cost = 1;
|
||||
EXPLAIN ANALYZE SELECT CONCAT('jit result = ', SUM(id)) FROM demo;
|
||||
SELECT CONCAT('jit result = ', SUM(id)) from demo;
|
||||
''} | sudo -u postgres psql"
|
||||
)
|
||||
assert "JIT:" in output
|
||||
assert "jit result = 15" in output
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
if package == null then
|
||||
lib.genAttrs packages mkJitTestFromName
|
||||
else
|
||||
mkJitTest package
|
||||
@@ -1,141 +0,0 @@
|
||||
{ system ? builtins.currentSystem
|
||||
, config ? { }
|
||||
, pkgs ? import ../.. { inherit system config; }
|
||||
, package ? null
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`.
|
||||
makeTestAttribute = name:
|
||||
{
|
||||
inherit name;
|
||||
value = makePostgresqlTlsClientCertTest pkgs."${name}";
|
||||
};
|
||||
|
||||
makePostgresqlTlsClientCertTest = pkg:
|
||||
let
|
||||
runWithOpenSSL = file: cmd: pkgs.runCommand file
|
||||
{
|
||||
buildInputs = [ pkgs.openssl ];
|
||||
}
|
||||
cmd;
|
||||
caKey = runWithOpenSSL "ca.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
||||
caCert = runWithOpenSSL
|
||||
"ca.crt"
|
||||
''
|
||||
openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500
|
||||
'';
|
||||
serverKey =
|
||||
runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
||||
serverKeyPath = "/var/lib/postgresql";
|
||||
serverCert =
|
||||
runWithOpenSSL "server.crt" ''
|
||||
openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example"
|
||||
openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \
|
||||
-CAcreateserial -out $out -days 36500 -sha256
|
||||
'';
|
||||
clientKey =
|
||||
runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
||||
clientCert =
|
||||
runWithOpenSSL "client.crt" ''
|
||||
openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test"
|
||||
openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \
|
||||
-CAcreateserial -out $out -days 36500 -sha256
|
||||
'';
|
||||
clientKeyPath = "/root";
|
||||
|
||||
in
|
||||
makeTest {
|
||||
name = "postgresql-tls-client-cert-${pkg.name}";
|
||||
meta.maintainers = with lib.maintainers; [ erictapen ];
|
||||
|
||||
nodes.server = { ... }: {
|
||||
system.activationScripts = {
|
||||
keyPlacement.text = ''
|
||||
mkdir -p '${serverKeyPath}'
|
||||
cp '${serverKey}' '${serverKeyPath}/server.key'
|
||||
chown postgres:postgres '${serverKeyPath}/server.key'
|
||||
chmod 600 '${serverKeyPath}/server.key'
|
||||
'';
|
||||
};
|
||||
services.postgresql = {
|
||||
package = pkg;
|
||||
enable = true;
|
||||
enableTCPIP = true;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "test";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
ensureDatabases = [ "test" ];
|
||||
settings = {
|
||||
ssl = "on";
|
||||
ssl_ca_file = toString caCert;
|
||||
ssl_cert_file = toString serverCert;
|
||||
ssl_key_file = "${serverKeyPath}/server.key";
|
||||
};
|
||||
authentication = ''
|
||||
hostssl test test ::/0 cert clientcert=verify-full
|
||||
'';
|
||||
};
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv6.addresses = [
|
||||
{ address = "fc00::1"; prefixLength = 120; }
|
||||
];
|
||||
};
|
||||
firewall.allowedTCPPorts = [ 5432 ];
|
||||
};
|
||||
};
|
||||
|
||||
nodes.client = { ... }: {
|
||||
system.activationScripts = {
|
||||
keyPlacement.text = ''
|
||||
mkdir -p '${clientKeyPath}'
|
||||
cp '${clientKey}' '${clientKeyPath}/client.key'
|
||||
chown root:root '${clientKeyPath}/client.key'
|
||||
chmod 600 '${clientKeyPath}/client.key'
|
||||
'';
|
||||
};
|
||||
environment = {
|
||||
variables = {
|
||||
PGHOST = "db.test.example";
|
||||
PGPORT = "5432";
|
||||
PGDATABASE = "test";
|
||||
PGUSER = "test";
|
||||
PGSSLMODE = "verify-full";
|
||||
PGSSLCERT = clientCert;
|
||||
PGSSLKEY = "${clientKeyPath}/client.key";
|
||||
PGSSLROOTCERT = caCert;
|
||||
};
|
||||
systemPackages = [ pkg ];
|
||||
};
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv6.addresses = [
|
||||
{ address = "fc00::2"; prefixLength = 120; }
|
||||
];
|
||||
};
|
||||
hosts = { "fc00::1" = [ "db.test.example" ]; };
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
server.wait_for_unit("multi-user.target")
|
||||
client.wait_for_unit("multi-user.target")
|
||||
client.succeed("psql -c \"SELECT 1;\"")
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
if package == null then
|
||||
# all-tests.nix: Maps the generic function over all attributes of PostgreSQL packages
|
||||
builtins.listToAttrs (map makeTestAttribute (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs)))
|
||||
else
|
||||
# Called directly from <package>.tests
|
||||
makePostgresqlTlsClientCertTest package
|
||||
@@ -1,124 +0,0 @@
|
||||
{ system ? builtins.currentSystem,
|
||||
config ? {},
|
||||
pkgs ? import ../.. { inherit system config; },
|
||||
package ? null
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`.
|
||||
makeTestAttribute = name:
|
||||
{
|
||||
inherit name;
|
||||
value = makePostgresqlWalReceiverTest pkgs."${name}";
|
||||
};
|
||||
|
||||
makePostgresqlWalReceiverTest = pkg:
|
||||
let
|
||||
postgresqlDataDir = "/var/lib/postgresql/${pkg.psqlSchema}";
|
||||
replicationUser = "wal_receiver_user";
|
||||
replicationSlot = "wal_receiver_slot";
|
||||
replicationConn = "postgresql://${replicationUser}@localhost";
|
||||
baseBackupDir = "/var/cache/wals/pg_basebackup";
|
||||
walBackupDir = "/var/cache/wals/pg_wal";
|
||||
|
||||
recoveryFile = pkgs.writeTextDir "recovery.signal" "";
|
||||
|
||||
in makeTest {
|
||||
name = "postgresql-wal-receiver-${pkg.name}";
|
||||
meta.maintainers = with lib.maintainers; [ pacien ];
|
||||
|
||||
nodes.machine = { ... }: {
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/cache/wals 0750 postgres postgres - -"
|
||||
];
|
||||
|
||||
services.postgresql = {
|
||||
package = pkg;
|
||||
enable = true;
|
||||
settings = {
|
||||
max_replication_slots = 10;
|
||||
max_wal_senders = 10;
|
||||
recovery_end_command = "touch recovery.done";
|
||||
restore_command = "cp ${walBackupDir}/%f %p";
|
||||
wal_level = "archive"; # alias for replica on pg >= 9.6
|
||||
};
|
||||
authentication = ''
|
||||
host replication ${replicationUser} all trust
|
||||
'';
|
||||
initialScript = pkgs.writeText "init.sql" ''
|
||||
create user ${replicationUser} replication;
|
||||
select * from pg_create_physical_replication_slot('${replicationSlot}');
|
||||
'';
|
||||
};
|
||||
|
||||
services.postgresqlWalReceiver.receivers.main = {
|
||||
postgresqlPackage = pkg;
|
||||
connection = replicationConn;
|
||||
slot = replicationSlot;
|
||||
directory = walBackupDir;
|
||||
};
|
||||
# This is only to speedup test, it isn't time racing. Service is set to autorestart always,
|
||||
# default 60sec is fine for real system, but is too much for a test
|
||||
systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5;
|
||||
systemd.services.postgresql.serviceConfig.ReadWritePaths = [ "/var/cache/wals" ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
# make an initial base backup
|
||||
machine.wait_for_unit("postgresql")
|
||||
machine.wait_for_unit("postgresql-wal-receiver-main")
|
||||
# WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
|
||||
# required only for 9.4
|
||||
machine.sleep(5)
|
||||
machine.succeed(
|
||||
"${pkg}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}"
|
||||
)
|
||||
|
||||
# create a dummy table with 100 records
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'"
|
||||
)
|
||||
|
||||
# stop postgres and destroy data
|
||||
machine.systemctl("stop postgresql")
|
||||
machine.systemctl("stop postgresql-wal-receiver-main")
|
||||
machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}")
|
||||
|
||||
# restore the base backup
|
||||
machine.succeed(
|
||||
"cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}"
|
||||
)
|
||||
|
||||
# prepare WAL and recovery
|
||||
machine.succeed("chmod a+rX -R ${walBackupDir}")
|
||||
machine.execute(
|
||||
"for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done"
|
||||
) # make use of partial segments too
|
||||
machine.succeed(
|
||||
"cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*"
|
||||
)
|
||||
|
||||
# replay WAL
|
||||
machine.systemctl("start postgresql")
|
||||
machine.wait_for_file("${postgresqlDataDir}/recovery.done")
|
||||
machine.systemctl("restart postgresql")
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
# check that our records have been restored
|
||||
machine.succeed(
|
||||
"test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100"
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
if package == null then
|
||||
# all-tests.nix: Maps the generic function over all attributes of PostgreSQL packages
|
||||
builtins.listToAttrs (map makeTestAttribute (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs)))
|
||||
else
|
||||
# Called directly from <package>.tests
|
||||
makePostgresqlWalReceiverTest package
|
||||
@@ -1,60 +0,0 @@
|
||||
{
|
||||
system ? builtins.currentSystem,
|
||||
config ? { },
|
||||
pkgs ? import ../.. { inherit system config; },
|
||||
postgresql ? null,
|
||||
}:
|
||||
|
||||
let
|
||||
makeTest = import ./make-test-python.nix;
|
||||
# Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`.
|
||||
makeTestAttribute = name: {
|
||||
inherit name;
|
||||
value = makePostgresqlWal2jsonTest pkgs."${name}";
|
||||
};
|
||||
|
||||
makePostgresqlWal2jsonTest =
|
||||
postgresqlPackage:
|
||||
makeTest {
|
||||
name = "postgresql-wal2json-${postgresqlPackage.name}";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ euank ];
|
||||
|
||||
nodes.machine = {
|
||||
services.postgresql = {
|
||||
package = postgresqlPackage;
|
||||
enable = true;
|
||||
extraPlugins = with postgresqlPackage.pkgs; [ wal2json ];
|
||||
settings = {
|
||||
wal_level = "logical";
|
||||
max_replication_slots = "10";
|
||||
max_wal_senders = "10";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("postgresql")
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -qAt -f ${./postgresql/wal2json/example2.sql} postgres > /tmp/example2.out"
|
||||
)
|
||||
machine.succeed(
|
||||
"diff ${./postgresql/wal2json/example2.out} /tmp/example2.out"
|
||||
)
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -qAt -f ${./postgresql/wal2json/example3.sql} postgres > /tmp/example3.out"
|
||||
)
|
||||
machine.succeed(
|
||||
"diff ${./postgresql/wal2json/example3.out} /tmp/example3.out"
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
||||
in
|
||||
# By default, create one test per postgresql version
|
||||
if postgresql == null then
|
||||
builtins.listToAttrs (
|
||||
map makeTestAttribute (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs))
|
||||
)
|
||||
# but if postgresql is set, we're being made as a passthru test for a specific postgres + wal2json version, just run one
|
||||
else
|
||||
makePostgresqlWal2jsonTest postgresql
|
||||
@@ -1,226 +0,0 @@
|
||||
{ system ? builtins.currentSystem,
|
||||
config ? {},
|
||||
pkgs ? import ../.. { inherit system config; }
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
postgresql-versions = import ../../pkgs/servers/sql/postgresql pkgs;
|
||||
test-sql = pkgs.writeText "postgresql-test" ''
|
||||
CREATE EXTENSION pgcrypto; -- just to check if lib loading works
|
||||
CREATE TABLE sth (
|
||||
id int
|
||||
);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
CREATE TABLE xmltest ( doc xml );
|
||||
INSERT INTO xmltest (doc) VALUES ('<test>ok</test>'); -- check if libxml2 enabled
|
||||
'';
|
||||
make-postgresql-test = postgresql-name: postgresql-package: backup-all: makeTest {
|
||||
name = postgresql-name;
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ zagy ];
|
||||
};
|
||||
|
||||
nodes.machine = {...}:
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = postgresql-package;
|
||||
};
|
||||
|
||||
services.postgresqlBackup = {
|
||||
enable = true;
|
||||
databases = optional (!backup-all) "postgres";
|
||||
};
|
||||
};
|
||||
|
||||
testScript = let
|
||||
backupName = if backup-all then "all" else "postgres";
|
||||
backupService = if backup-all then "postgresqlBackup" else "postgresqlBackup-postgres";
|
||||
backupFileBase = "/var/backup/postgresql/${backupName}";
|
||||
in ''
|
||||
def check_count(statement, lines):
|
||||
return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
|
||||
statement, lines
|
||||
)
|
||||
|
||||
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("Postgresql is available just after unit start"):
|
||||
machine.succeed(
|
||||
"cat ${test-sql} | sudo -u postgres psql"
|
||||
)
|
||||
|
||||
with subtest("Postgresql survives restart (bug #1735)"):
|
||||
machine.shutdown()
|
||||
import time
|
||||
time.sleep(2)
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
machine.fail(check_count("SELECT * FROM sth;", 3))
|
||||
machine.succeed(check_count("SELECT * FROM sth;", 5))
|
||||
machine.fail(check_count("SELECT * FROM sth;", 4))
|
||||
machine.succeed(check_count("SELECT xpath('/test/text()', doc) FROM xmltest;", 1))
|
||||
|
||||
with subtest("Backup service works"):
|
||||
machine.succeed(
|
||||
"systemctl start ${backupService}.service",
|
||||
"zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'",
|
||||
"ls -hal /var/backup/postgresql/ >/dev/console",
|
||||
"stat -c '%a' ${backupFileBase}.sql.gz | grep 600",
|
||||
)
|
||||
with subtest("Backup service removes prev files"):
|
||||
machine.succeed(
|
||||
# Create dummy prev files.
|
||||
"touch ${backupFileBase}.prev.sql{,.gz,.zstd}",
|
||||
"chown postgres:postgres ${backupFileBase}.prev.sql{,.gz,.zstd}",
|
||||
|
||||
# Run backup.
|
||||
"systemctl start ${backupService}.service",
|
||||
"ls -hal /var/backup/postgresql/ >/dev/console",
|
||||
|
||||
# Since nothing has changed in the database, the cur and prev files
|
||||
# should match.
|
||||
"zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'",
|
||||
"cmp ${backupFileBase}.sql.gz ${backupFileBase}.prev.sql.gz",
|
||||
|
||||
# The prev files with unused suffix should be removed.
|
||||
"[ ! -f '${backupFileBase}.prev.sql' ]",
|
||||
"[ ! -f '${backupFileBase}.prev.sql.zstd' ]",
|
||||
|
||||
# Both cur and prev file should only be accessible by the postgres user.
|
||||
"stat -c '%a' ${backupFileBase}.sql.gz | grep 600",
|
||||
"stat -c '%a' '${backupFileBase}.prev.sql.gz' | grep 600",
|
||||
)
|
||||
with subtest("Backup service fails gracefully"):
|
||||
# Sabotage the backup process
|
||||
machine.succeed("rm /run/postgresql/.s.PGSQL.5432")
|
||||
machine.fail(
|
||||
"systemctl start ${backupService}.service",
|
||||
)
|
||||
machine.succeed(
|
||||
"ls -hal /var/backup/postgresql/ >/dev/console",
|
||||
"zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'",
|
||||
"stat ${backupFileBase}.in-progress.sql.gz",
|
||||
)
|
||||
# In a previous version, the second run would overwrite prev.sql.gz,
|
||||
# so we test a second run as well.
|
||||
machine.fail(
|
||||
"systemctl start ${backupService}.service",
|
||||
)
|
||||
machine.succeed(
|
||||
"stat ${backupFileBase}.in-progress.sql.gz",
|
||||
"zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'",
|
||||
)
|
||||
|
||||
|
||||
with subtest("Initdb works"):
|
||||
machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2")
|
||||
|
||||
machine.log(machine.execute("systemd-analyze security postgresql.service | grep -v ✓")[1])
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
|
||||
};
|
||||
|
||||
mk-ensure-clauses-test = postgresql-name: postgresql-package: makeTest {
|
||||
name = postgresql-name;
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ zagy ];
|
||||
};
|
||||
|
||||
nodes.machine = {...}:
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = postgresql-package;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "all-clauses";
|
||||
ensureClauses = {
|
||||
superuser = true;
|
||||
createdb = true;
|
||||
createrole = true;
|
||||
"inherit" = true;
|
||||
login = true;
|
||||
replication = true;
|
||||
bypassrls = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "default-clauses";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = let
|
||||
getClausesQuery = user: pkgs.lib.concatStringsSep " "
|
||||
[
|
||||
"SELECT row_to_json(row)"
|
||||
"FROM ("
|
||||
"SELECT"
|
||||
"rolsuper,"
|
||||
"rolinherit,"
|
||||
"rolcreaterole,"
|
||||
"rolcreatedb,"
|
||||
"rolcanlogin,"
|
||||
"rolreplication,"
|
||||
"rolbypassrls"
|
||||
"FROM pg_roles"
|
||||
"WHERE rolname = '${user}'"
|
||||
") row;"
|
||||
];
|
||||
in ''
|
||||
import json
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("All user permissions are set according to the ensureClauses attr"):
|
||||
clauses = json.loads(
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -tc \"${getClausesQuery "all-clauses"}\""
|
||||
)
|
||||
)
|
||||
print(clauses)
|
||||
assert clauses['rolsuper'], 'expected user with clauses to have superuser clause'
|
||||
assert clauses['rolinherit'], 'expected user with clauses to have inherit clause'
|
||||
assert clauses['rolcreaterole'], 'expected user with clauses to have create role clause'
|
||||
assert clauses['rolcreatedb'], 'expected user with clauses to have create db clause'
|
||||
assert clauses['rolcanlogin'], 'expected user with clauses to have login clause'
|
||||
assert clauses['rolreplication'], 'expected user with clauses to have replication clause'
|
||||
assert clauses['rolbypassrls'], 'expected user with clauses to have bypassrls clause'
|
||||
|
||||
with subtest("All user permissions default when ensureClauses is not provided"):
|
||||
clauses = json.loads(
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -tc \"${getClausesQuery "default-clauses"}\""
|
||||
)
|
||||
)
|
||||
assert not clauses['rolsuper'], 'expected user with no clauses set to have default superuser clause'
|
||||
assert clauses['rolinherit'], 'expected user with no clauses set to have default inherit clause'
|
||||
assert not clauses['rolcreaterole'], 'expected user with no clauses set to have default create role clause'
|
||||
assert not clauses['rolcreatedb'], 'expected user with no clauses set to have default create db clause'
|
||||
assert clauses['rolcanlogin'], 'expected user with no clauses set to have default login clause'
|
||||
assert not clauses['rolreplication'], 'expected user with no clauses set to have default replication clause'
|
||||
assert not clauses['rolbypassrls'], 'expected user with no clauses set to have default bypassrls clause'
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
concatMapAttrs (name: package: {
|
||||
${name} = make-postgresql-test name package false;
|
||||
${name + "-backup-all"} = make-postgresql-test "${name + "-backup-all"}" package true;
|
||||
${name + "-clauses"} = mk-ensure-clauses-test name package;
|
||||
}) postgresql-versions
|
||||
@@ -0,0 +1,116 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "postgresql_anonymizer-${package.name}";
|
||||
meta.maintainers = lib.teams.flyingcircus.members;
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [ pkgs.pg-dump-anon ];
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
extraPlugins = ps: [ ps.anonymizer ];
|
||||
settings.shared_preload_libraries = [ "anon" ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.wait_for_unit("postgresql.service")
|
||||
|
||||
with subtest("Setup"):
|
||||
machine.succeed("sudo -u postgres psql --command 'create database demo'")
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -d demo -f ${pkgs.writeText "init.sql" ''
|
||||
create extension anon cascade;
|
||||
select anon.init();
|
||||
create table player(id serial, name text, points int);
|
||||
insert into player(id,name,points) values (1,'Foo', 23);
|
||||
insert into player(id,name,points) values (2,'Bar',42);
|
||||
security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name();';
|
||||
security label for anon on column player.points is 'MASKED WITH VALUE NULL';
|
||||
''}"
|
||||
)
|
||||
|
||||
def get_player_table_contents():
|
||||
return [
|
||||
x.split(',') for x in machine.succeed("sudo -u postgres psql -d demo --csv --command 'select * from player'").splitlines()[1:]
|
||||
]
|
||||
|
||||
def check_anonymized_row(row, id, original_name):
|
||||
assert row[0] == id, f"Expected first row to have ID {id}, but got {row[0]}"
|
||||
assert row[1] != original_name, f"Expected first row to have a name other than {original_name}"
|
||||
assert not bool(row[2]), "Expected points to be NULL in first row"
|
||||
|
||||
def find_xsv_in_dump(dump, sep=','):
|
||||
"""
|
||||
Expecting to find a CSV (for pg_dump_anon) or TSV (for pg_dump) structure, looking like
|
||||
|
||||
COPY public.player ...
|
||||
1,Shields,
|
||||
2,Salazar,
|
||||
\.
|
||||
|
||||
in the given dump (the commas are tabs in case of pg_dump).
|
||||
Extract the CSV lines and split by `sep`.
|
||||
"""
|
||||
|
||||
try:
|
||||
from itertools import dropwhile, takewhile
|
||||
return [x.split(sep) for x in list(takewhile(
|
||||
lambda x: x != "\\.",
|
||||
dropwhile(
|
||||
lambda x: not x.startswith("COPY public.player"),
|
||||
dump.splitlines()
|
||||
)
|
||||
))[1:]]
|
||||
except:
|
||||
print(f"Dump to process: {dump}")
|
||||
raise
|
||||
|
||||
def check_original_data(output):
|
||||
assert output[0] == ['1','Foo','23'], f"Expected first row from player table to be 1,Foo,23; got {output[0]}"
|
||||
assert output[1] == ['2','Bar','42'], f"Expected first row from player table to be 2,Bar,42; got {output[1]}"
|
||||
|
||||
def check_anonymized_rows(output):
|
||||
check_anonymized_row(output[0], '1', 'Foo')
|
||||
check_anonymized_row(output[1], '2', 'Bar')
|
||||
|
||||
with subtest("Check initial state"):
|
||||
check_original_data(get_player_table_contents())
|
||||
|
||||
with subtest("Anonymous dumps"):
|
||||
check_original_data(find_xsv_in_dump(
|
||||
machine.succeed("sudo -u postgres pg_dump demo"),
|
||||
sep='\t'
|
||||
))
|
||||
check_anonymized_rows(find_xsv_in_dump(
|
||||
machine.succeed("sudo -u postgres pg_dump_anon -U postgres -h /run/postgresql -d demo"),
|
||||
sep=','
|
||||
))
|
||||
|
||||
with subtest("Anonymize"):
|
||||
machine.succeed("sudo -u postgres psql -d demo --command 'select anon.anonymize_database();'")
|
||||
check_anonymized_rows(get_player_table_contents())
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (_: p: !p.pkgs.anonymizer.meta.broken) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
system ? builtins.currentSystem,
|
||||
config ? { },
|
||||
pkgs ? import ../../.. { inherit system config; },
|
||||
}:
|
||||
|
||||
with import ../../lib/testing-python.nix { inherit system pkgs; };
|
||||
|
||||
let
|
||||
importWithArgs = path: import path { inherit pkgs makeTest; };
|
||||
in
|
||||
{
|
||||
# postgresql
|
||||
postgresql = importWithArgs ./postgresql.nix;
|
||||
postgresql-jit = importWithArgs ./postgresql-jit.nix;
|
||||
postgresql-wal-receiver = importWithArgs ./postgresql-wal-receiver.nix;
|
||||
postgresql-tls-client-cert = importWithArgs ./postgresql-tls-client-cert.nix;
|
||||
|
||||
# extensions
|
||||
anonymizer = importWithArgs ./anonymizer.nix;
|
||||
pgjwt = importWithArgs ./pgjwt.nix;
|
||||
pgvecto-rs = importWithArgs ./pgvecto-rs.nix;
|
||||
timescaledb = importWithArgs ./timescaledb.nix;
|
||||
tsja = importWithArgs ./tsja.nix;
|
||||
wal2json = importWithArgs ./wal2json.nix;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "pgjwt-${package.name}";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [
|
||||
spinus
|
||||
willibutz
|
||||
];
|
||||
};
|
||||
|
||||
nodes.master =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
extraPlugins =
|
||||
ps: with ps; [
|
||||
pgjwt
|
||||
pgtap
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
sqlSU = "${nodes.master.services.postgresql.superUser}";
|
||||
pgProve = "${pkgs.perlPackages.TAPParserSourceHandlerpgTAP}";
|
||||
inherit (nodes.master.services.postgresql.package.pkgs) pgjwt;
|
||||
in
|
||||
''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.succeed(
|
||||
"${pkgs.sudo}/bin/sudo -u ${sqlSU} ${pgProve}/bin/pg_prove -d postgres -v -f ${pgjwt.src}/test.sql"
|
||||
)
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (_: p: !p.pkgs.pgjwt.meta.broken) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,81 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
# Test cases from https://docs.pgvecto.rs/use-cases/hybrid-search.html
|
||||
test-sql = pkgs.writeText "postgresql-test" ''
|
||||
CREATE EXTENSION vectors;
|
||||
|
||||
CREATE TABLE items (
|
||||
id bigserial PRIMARY KEY,
|
||||
content text NOT NULL,
|
||||
embedding vectors.vector(3) NOT NULL -- 3 dimensions
|
||||
);
|
||||
|
||||
INSERT INTO items (content, embedding) VALUES
|
||||
('a fat cat sat on a mat and ate a fat rat', '[1, 2, 3]'),
|
||||
('a fat dog sat on a mat and ate a fat rat', '[4, 5, 6]'),
|
||||
('a thin cat sat on a mat and ate a thin rat', '[7, 8, 9]'),
|
||||
('a thin dog sat on a mat and ate a thin rat', '[10, 11, 12]');
|
||||
'';
|
||||
|
||||
makeTestFor =
|
||||
postgresqlPackage:
|
||||
makeTest {
|
||||
name = "pgvecto-rs-${postgresqlPackage.name}";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ diogotcorreia ];
|
||||
};
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = postgresqlPackage;
|
||||
extraPlugins =
|
||||
ps: with ps; [
|
||||
pgvecto-rs
|
||||
];
|
||||
settings.shared_preload_libraries = "vectors";
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
inherit (nodes.machine.services.postgresql.package.pkgs) pgvecto-rs;
|
||||
in
|
||||
''
|
||||
def check_count(statement, lines):
|
||||
return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
|
||||
statement, lines
|
||||
)
|
||||
|
||||
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("Postgresql with extension vectors is available just after unit start"):
|
||||
machine.succeed(check_count("SELECT * FROM pg_available_extensions WHERE name = 'vectors' AND default_version = '${pgvecto-rs.version}';", 1))
|
||||
|
||||
machine.succeed("sudo -u postgres psql -f ${test-sql}")
|
||||
|
||||
machine.succeed(check_count("SELECT content, embedding FROM items WHERE to_tsvector('english', content) @@ 'cat & rat'::tsquery;", 2))
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (_: p: !p.pkgs.pgvecto-rs.meta.broken) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "postgresql-jit-${package.name}";
|
||||
meta.maintainers = with lib.maintainers; [ ma27 ];
|
||||
|
||||
nodes.machine =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
enableJIT = true;
|
||||
initialScript = pkgs.writeText "init.sql" ''
|
||||
create table demo (id int);
|
||||
insert into demo (id) select generate_series(1, 5);
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql.service")
|
||||
|
||||
with subtest("JIT is enabled"):
|
||||
machine.succeed("sudo -u postgres psql <<<'show jit;' | grep 'on'")
|
||||
|
||||
with subtest("Test JIT works fine"):
|
||||
output = machine.succeed(
|
||||
"cat ${pkgs.writeText "test.sql" ''
|
||||
set jit_above_cost = 1;
|
||||
EXPLAIN ANALYZE SELECT CONCAT('jit result = ', SUM(id)) FROM demo;
|
||||
SELECT CONCAT('jit result = ', SUM(id)) from demo;
|
||||
''} | sudo -u postgres psql"
|
||||
)
|
||||
assert "JIT:" in output
|
||||
assert "jit result = 15" in output
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (n: _: lib.hasSuffix "_jit" n) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,135 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
runWithOpenSSL =
|
||||
file: cmd:
|
||||
pkgs.runCommand file {
|
||||
buildInputs = [ pkgs.openssl ];
|
||||
} cmd;
|
||||
caKey = runWithOpenSSL "ca.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
||||
caCert = runWithOpenSSL "ca.crt" ''
|
||||
openssl req -new -x509 -sha256 -key ${caKey} -out $out -subj "/CN=test.example" -days 36500
|
||||
'';
|
||||
serverKey = runWithOpenSSL "server.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
||||
serverKeyPath = "/var/lib/postgresql";
|
||||
serverCert = runWithOpenSSL "server.crt" ''
|
||||
openssl req -new -sha256 -key ${serverKey} -out server.csr -subj "/CN=db.test.example"
|
||||
openssl x509 -req -in server.csr -CA ${caCert} -CAkey ${caKey} \
|
||||
-CAcreateserial -out $out -days 36500 -sha256
|
||||
'';
|
||||
clientKey = runWithOpenSSL "client.key" "openssl ecparam -name prime256v1 -genkey -noout -out $out";
|
||||
clientCert = runWithOpenSSL "client.crt" ''
|
||||
openssl req -new -sha256 -key ${clientKey} -out client.csr -subj "/CN=test"
|
||||
openssl x509 -req -in client.csr -CA ${caCert} -CAkey ${caKey} \
|
||||
-CAcreateserial -out $out -days 36500 -sha256
|
||||
'';
|
||||
clientKeyPath = "/root";
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "postgresql-tls-client-cert-${package.name}";
|
||||
meta.maintainers = with lib.maintainers; [ erictapen ];
|
||||
|
||||
nodes.server =
|
||||
{ ... }:
|
||||
{
|
||||
system.activationScripts = {
|
||||
keyPlacement.text = ''
|
||||
mkdir -p '${serverKeyPath}'
|
||||
cp '${serverKey}' '${serverKeyPath}/server.key'
|
||||
chown postgres:postgres '${serverKeyPath}/server.key'
|
||||
chmod 600 '${serverKeyPath}/server.key'
|
||||
'';
|
||||
};
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
enableTCPIP = true;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "test";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
ensureDatabases = [ "test" ];
|
||||
settings = {
|
||||
ssl = "on";
|
||||
ssl_ca_file = toString caCert;
|
||||
ssl_cert_file = toString serverCert;
|
||||
ssl_key_file = "${serverKeyPath}/server.key";
|
||||
};
|
||||
authentication = ''
|
||||
hostssl test test ::/0 cert clientcert=verify-full
|
||||
'';
|
||||
};
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "fc00::1";
|
||||
prefixLength = 120;
|
||||
}
|
||||
];
|
||||
};
|
||||
firewall.allowedTCPPorts = [ 5432 ];
|
||||
};
|
||||
};
|
||||
|
||||
nodes.client =
|
||||
{ ... }:
|
||||
{
|
||||
system.activationScripts = {
|
||||
keyPlacement.text = ''
|
||||
mkdir -p '${clientKeyPath}'
|
||||
cp '${clientKey}' '${clientKeyPath}/client.key'
|
||||
chown root:root '${clientKeyPath}/client.key'
|
||||
chmod 600 '${clientKeyPath}/client.key'
|
||||
'';
|
||||
};
|
||||
environment = {
|
||||
variables = {
|
||||
PGHOST = "db.test.example";
|
||||
PGPORT = "5432";
|
||||
PGDATABASE = "test";
|
||||
PGUSER = "test";
|
||||
PGSSLMODE = "verify-full";
|
||||
PGSSLCERT = clientCert;
|
||||
PGSSLKEY = "${clientKeyPath}/client.key";
|
||||
PGSSLROOTCERT = caCert;
|
||||
};
|
||||
systemPackages = [ package ];
|
||||
};
|
||||
networking = {
|
||||
interfaces.eth1 = {
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "fc00::2";
|
||||
prefixLength = 120;
|
||||
}
|
||||
];
|
||||
};
|
||||
hosts = {
|
||||
"fc00::1" = [ "db.test.example" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
server.wait_for_unit("multi-user.target")
|
||||
client.wait_for_unit("multi-user.target")
|
||||
client.succeed("psql -c \"SELECT 1;\"")
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) pkgs.postgresqlVersions
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,115 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
let
|
||||
postgresqlDataDir = "/var/lib/postgresql/${package.psqlSchema}";
|
||||
replicationUser = "wal_receiver_user";
|
||||
replicationSlot = "wal_receiver_slot";
|
||||
replicationConn = "postgresql://${replicationUser}@localhost";
|
||||
baseBackupDir = "/var/cache/wals/pg_basebackup";
|
||||
walBackupDir = "/var/cache/wals/pg_wal";
|
||||
recoveryFile = pkgs.writeTextDir "recovery.signal" "";
|
||||
in
|
||||
makeTest {
|
||||
name = "postgresql-wal-receiver-${package.name}";
|
||||
meta.maintainers = with lib.maintainers; [ pacien ];
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/cache/wals 0750 postgres postgres - -"
|
||||
];
|
||||
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
settings = {
|
||||
max_replication_slots = 10;
|
||||
max_wal_senders = 10;
|
||||
recovery_end_command = "touch recovery.done";
|
||||
restore_command = "cp ${walBackupDir}/%f %p";
|
||||
wal_level = "archive"; # alias for replica on pg >= 9.6
|
||||
};
|
||||
authentication = ''
|
||||
host replication ${replicationUser} all trust
|
||||
'';
|
||||
initialScript = pkgs.writeText "init.sql" ''
|
||||
create user ${replicationUser} replication;
|
||||
select * from pg_create_physical_replication_slot('${replicationSlot}');
|
||||
'';
|
||||
};
|
||||
|
||||
services.postgresqlWalReceiver.receivers.main = {
|
||||
postgresqlPackage = package;
|
||||
connection = replicationConn;
|
||||
slot = replicationSlot;
|
||||
directory = walBackupDir;
|
||||
};
|
||||
# This is only to speedup test, it isn't time racing. Service is set to autorestart always,
|
||||
# default 60sec is fine for real system, but is too much for a test
|
||||
systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5;
|
||||
systemd.services.postgresql.serviceConfig.ReadWritePaths = [ "/var/cache/wals" ];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
# make an initial base backup
|
||||
machine.wait_for_unit("postgresql")
|
||||
machine.wait_for_unit("postgresql-wal-receiver-main")
|
||||
# WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other
|
||||
# required only for 9.4
|
||||
machine.sleep(5)
|
||||
machine.succeed(
|
||||
"${package}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}"
|
||||
)
|
||||
|
||||
# create a dummy table with 100 records
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'"
|
||||
)
|
||||
|
||||
# stop postgres and destroy data
|
||||
machine.systemctl("stop postgresql")
|
||||
machine.systemctl("stop postgresql-wal-receiver-main")
|
||||
machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}")
|
||||
|
||||
# restore the base backup
|
||||
machine.succeed(
|
||||
"cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}"
|
||||
)
|
||||
|
||||
# prepare WAL and recovery
|
||||
machine.succeed("chmod a+rX -R ${walBackupDir}")
|
||||
machine.execute(
|
||||
"for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done"
|
||||
) # make use of partial segments too
|
||||
machine.succeed(
|
||||
"cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*"
|
||||
)
|
||||
|
||||
# replay WAL
|
||||
machine.systemctl("start postgresql")
|
||||
machine.wait_for_file("${postgresqlDataDir}/recovery.done")
|
||||
machine.systemctl("restart postgresql")
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
# check that our records have been restored
|
||||
machine.succeed(
|
||||
"test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100"
|
||||
)
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) pkgs.postgresqlVersions
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,244 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
lib.recurseIntoAttrs {
|
||||
postgresql = makeTestForWithBackupAll package false;
|
||||
postgresql-backup-all = makeTestForWithBackupAll package true;
|
||||
postgresql-clauses = makeEnsureTestFor package;
|
||||
};
|
||||
|
||||
test-sql = pkgs.writeText "postgresql-test" ''
|
||||
CREATE EXTENSION pgcrypto; -- just to check if lib loading works
|
||||
CREATE TABLE sth (
|
||||
id int
|
||||
);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
INSERT INTO sth (id) VALUES (1);
|
||||
CREATE TABLE xmltest ( doc xml );
|
||||
INSERT INTO xmltest (doc) VALUES ('<test>ok</test>'); -- check if libxml2 enabled
|
||||
'';
|
||||
|
||||
makeTestForWithBackupAll =
|
||||
package: backupAll:
|
||||
makeTest {
|
||||
name = "postgresql${lib.optionalString backupAll "-backup-all"}-${package.name}";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ zagy ];
|
||||
};
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit (package) ;
|
||||
enable = true;
|
||||
};
|
||||
|
||||
services.postgresqlBackup = {
|
||||
enable = true;
|
||||
databases = lib.optional (!backupAll) "postgres";
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
let
|
||||
backupName = if backupAll then "all" else "postgres";
|
||||
backupService = if backupAll then "postgresqlBackup" else "postgresqlBackup-postgres";
|
||||
backupFileBase = "/var/backup/postgresql/${backupName}";
|
||||
in
|
||||
''
|
||||
def check_count(statement, lines):
|
||||
return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
|
||||
statement, lines
|
||||
)
|
||||
|
||||
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("Postgresql is available just after unit start"):
|
||||
machine.succeed(
|
||||
"cat ${test-sql} | sudo -u postgres psql"
|
||||
)
|
||||
|
||||
with subtest("Postgresql survives restart (bug #1735)"):
|
||||
machine.shutdown()
|
||||
import time
|
||||
time.sleep(2)
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
machine.fail(check_count("SELECT * FROM sth;", 3))
|
||||
machine.succeed(check_count("SELECT * FROM sth;", 5))
|
||||
machine.fail(check_count("SELECT * FROM sth;", 4))
|
||||
machine.succeed(check_count("SELECT xpath('/test/text()', doc) FROM xmltest;", 1))
|
||||
|
||||
with subtest("Backup service works"):
|
||||
machine.succeed(
|
||||
"systemctl start ${backupService}.service",
|
||||
"zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'",
|
||||
"ls -hal /var/backup/postgresql/ >/dev/console",
|
||||
"stat -c '%a' ${backupFileBase}.sql.gz | grep 600",
|
||||
)
|
||||
with subtest("Backup service removes prev files"):
|
||||
machine.succeed(
|
||||
# Create dummy prev files.
|
||||
"touch ${backupFileBase}.prev.sql{,.gz,.zstd}",
|
||||
"chown postgres:postgres ${backupFileBase}.prev.sql{,.gz,.zstd}",
|
||||
|
||||
# Run backup.
|
||||
"systemctl start ${backupService}.service",
|
||||
"ls -hal /var/backup/postgresql/ >/dev/console",
|
||||
|
||||
# Since nothing has changed in the database, the cur and prev files
|
||||
# should match.
|
||||
"zcat ${backupFileBase}.sql.gz | grep '<test>ok</test>'",
|
||||
"cmp ${backupFileBase}.sql.gz ${backupFileBase}.prev.sql.gz",
|
||||
|
||||
# The prev files with unused suffix should be removed.
|
||||
"[ ! -f '${backupFileBase}.prev.sql' ]",
|
||||
"[ ! -f '${backupFileBase}.prev.sql.zstd' ]",
|
||||
|
||||
# Both cur and prev file should only be accessible by the postgres user.
|
||||
"stat -c '%a' ${backupFileBase}.sql.gz | grep 600",
|
||||
"stat -c '%a' '${backupFileBase}.prev.sql.gz' | grep 600",
|
||||
)
|
||||
with subtest("Backup service fails gracefully"):
|
||||
# Sabotage the backup process
|
||||
machine.succeed("rm /run/postgresql/.s.PGSQL.5432")
|
||||
machine.fail(
|
||||
"systemctl start ${backupService}.service",
|
||||
)
|
||||
machine.succeed(
|
||||
"ls -hal /var/backup/postgresql/ >/dev/console",
|
||||
"zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'",
|
||||
"stat ${backupFileBase}.in-progress.sql.gz",
|
||||
)
|
||||
# In a previous version, the second run would overwrite prev.sql.gz,
|
||||
# so we test a second run as well.
|
||||
machine.fail(
|
||||
"systemctl start ${backupService}.service",
|
||||
)
|
||||
machine.succeed(
|
||||
"stat ${backupFileBase}.in-progress.sql.gz",
|
||||
"zcat ${backupFileBase}.prev.sql.gz | grep '<test>ok</test>'",
|
||||
)
|
||||
|
||||
|
||||
with subtest("Initdb works"):
|
||||
machine.succeed("sudo -u postgres initdb -D /tmp/testpostgres2")
|
||||
|
||||
machine.log(machine.execute("systemd-analyze security postgresql.service | grep -v ✓")[1])
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
|
||||
makeEnsureTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "postgresql-clauses-${package.name}";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ zagy ];
|
||||
};
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "all-clauses";
|
||||
ensureClauses = {
|
||||
superuser = true;
|
||||
createdb = true;
|
||||
createrole = true;
|
||||
"inherit" = true;
|
||||
login = true;
|
||||
replication = true;
|
||||
bypassrls = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
name = "default-clauses";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
testScript =
|
||||
let
|
||||
getClausesQuery =
|
||||
user:
|
||||
lib.concatStringsSep " " [
|
||||
"SELECT row_to_json(row)"
|
||||
"FROM ("
|
||||
"SELECT"
|
||||
"rolsuper,"
|
||||
"rolinherit,"
|
||||
"rolcreaterole,"
|
||||
"rolcreatedb,"
|
||||
"rolcanlogin,"
|
||||
"rolreplication,"
|
||||
"rolbypassrls"
|
||||
"FROM pg_roles"
|
||||
"WHERE rolname = '${user}'"
|
||||
") row;"
|
||||
];
|
||||
in
|
||||
''
|
||||
import json
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("All user permissions are set according to the ensureClauses attr"):
|
||||
clauses = json.loads(
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -tc \"${getClausesQuery "all-clauses"}\""
|
||||
)
|
||||
)
|
||||
print(clauses)
|
||||
assert clauses['rolsuper'], 'expected user with clauses to have superuser clause'
|
||||
assert clauses['rolinherit'], 'expected user with clauses to have inherit clause'
|
||||
assert clauses['rolcreaterole'], 'expected user with clauses to have create role clause'
|
||||
assert clauses['rolcreatedb'], 'expected user with clauses to have create db clause'
|
||||
assert clauses['rolcanlogin'], 'expected user with clauses to have login clause'
|
||||
assert clauses['rolreplication'], 'expected user with clauses to have replication clause'
|
||||
assert clauses['rolbypassrls'], 'expected user with clauses to have bypassrls clause'
|
||||
|
||||
with subtest("All user permissions default when ensureClauses is not provided"):
|
||||
clauses = json.loads(
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -tc \"${getClausesQuery "default-clauses"}\""
|
||||
)
|
||||
)
|
||||
assert not clauses['rolsuper'], 'expected user with no clauses set to have default superuser clause'
|
||||
assert clauses['rolinherit'], 'expected user with no clauses set to have default inherit clause'
|
||||
assert not clauses['rolcreaterole'], 'expected user with no clauses set to have default create role clause'
|
||||
assert not clauses['rolcreatedb'], 'expected user with no clauses set to have default create db clause'
|
||||
assert clauses['rolcanlogin'], 'expected user with no clauses set to have default login clause'
|
||||
assert not clauses['rolreplication'], 'expected user with no clauses set to have default replication clause'
|
||||
assert not clauses['rolbypassrls'], 'expected user with no clauses set to have default bypassrls clause'
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) pkgs.postgresqlVersions
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,100 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
test-sql = pkgs.writeText "postgresql-test" ''
|
||||
CREATE EXTENSION timescaledb;
|
||||
CREATE EXTENSION timescaledb_toolkit;
|
||||
|
||||
CREATE TABLE sth (
|
||||
time TIMESTAMPTZ NOT NULL,
|
||||
value DOUBLE PRECISION
|
||||
);
|
||||
|
||||
SELECT create_hypertable('sth', 'time');
|
||||
|
||||
INSERT INTO sth (time, value) VALUES
|
||||
('2003-04-12 04:05:06 America/New_York', 1.0),
|
||||
('2003-04-12 04:05:07 America/New_York', 2.0),
|
||||
('2003-04-12 04:05:08 America/New_York', 3.0),
|
||||
('2003-04-12 04:05:09 America/New_York', 4.0),
|
||||
('2003-04-12 04:05:10 America/New_York', 5.0)
|
||||
;
|
||||
|
||||
WITH t AS (
|
||||
SELECT
|
||||
time_bucket('1 day'::interval, time) AS dt,
|
||||
stats_agg(value) AS stats
|
||||
FROM sth
|
||||
GROUP BY time_bucket('1 day'::interval, time)
|
||||
)
|
||||
SELECT
|
||||
average(stats)
|
||||
FROM t;
|
||||
|
||||
SELECT * FROM sth;
|
||||
'';
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "timescaledb-${package.name}";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ typetetris ];
|
||||
};
|
||||
|
||||
nodes.machine =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
extraPlugins =
|
||||
ps: with ps; [
|
||||
timescaledb
|
||||
timescaledb_toolkit
|
||||
];
|
||||
settings = {
|
||||
shared_preload_libraries = "timescaledb, timescaledb_toolkit";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def check_count(statement, lines):
|
||||
return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
|
||||
statement, lines
|
||||
)
|
||||
|
||||
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("Postgresql with extensions timescaledb and timescaledb_toolkit is available just after unit start"):
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -f ${test-sql}"
|
||||
)
|
||||
|
||||
machine.fail(check_count("SELECT * FROM sth;", 3))
|
||||
machine.succeed(check_count("SELECT * FROM sth;", 5))
|
||||
machine.fail(check_count("SELECT * FROM sth;", 4))
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
};
|
||||
in
|
||||
# Not run by default, because this requires allowUnfree.
|
||||
# To run these tests:
|
||||
# NIXPKGS_ALLOW_UNFREE=1 nix-build -A nixosTests.postgresql.timescaledb
|
||||
lib.dontRecurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (_: p: !p.pkgs.timescaledb.meta.broken) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "tsja-${package.name}";
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ chayleaf ];
|
||||
};
|
||||
|
||||
nodes.master =
|
||||
{ ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
extraPlugins =
|
||||
ps: with ps; [
|
||||
tsja
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.succeed("sudo -u postgres psql -f /run/current-system/sw/share/postgresql/extension/libtsja_dbinit.sql")
|
||||
# make sure "日本語" is parsed as a separate lexeme
|
||||
master.succeed("""
|
||||
sudo -u postgres \\
|
||||
psql -c "SELECT * FROM ts_debug('japanese', 'PostgreSQLで日本語のテキスト検索ができます。')" \\
|
||||
| grep "{日本語}"
|
||||
""")
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (_: p: !p.pkgs.tsja.meta.broken) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
pkgs,
|
||||
makeTest,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
makeTestFor =
|
||||
package:
|
||||
makeTest {
|
||||
name = "wal2json-${package.name}";
|
||||
meta.maintainers = with pkgs.lib.maintainers; [ euank ];
|
||||
|
||||
nodes.machine = {
|
||||
services.postgresql = {
|
||||
inherit package;
|
||||
enable = true;
|
||||
extraPlugins = with package.pkgs; [ wal2json ];
|
||||
settings = {
|
||||
wal_level = "logical";
|
||||
max_replication_slots = "10";
|
||||
max_wal_senders = "10";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("postgresql")
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -qAt -f ${./wal2json/example2.sql} postgres > /tmp/example2.out"
|
||||
)
|
||||
machine.succeed(
|
||||
"diff ${./wal2json/example2.out} /tmp/example2.out"
|
||||
)
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -qAt -f ${./wal2json/example3.sql} postgres > /tmp/example3.out"
|
||||
)
|
||||
machine.succeed(
|
||||
"diff ${./wal2json/example3.out} /tmp/example3.out"
|
||||
)
|
||||
'';
|
||||
};
|
||||
in
|
||||
lib.recurseIntoAttrs (
|
||||
lib.concatMapAttrs (n: p: { ${n} = makeTestFor p; }) (
|
||||
lib.filterAttrs (_: p: !p.pkgs.wal2json.meta.broken) pkgs.postgresqlVersions
|
||||
)
|
||||
// {
|
||||
passthru.override = p: makeTestFor p;
|
||||
}
|
||||
)
|
||||
@@ -1,93 +0,0 @@
|
||||
# mostly copied from ./postgresql.nix as it seemed unapproriate to
|
||||
# test additional extensions for postgresql there.
|
||||
|
||||
{ system ? builtins.currentSystem
|
||||
, config ? { }
|
||||
, pkgs ? import ../.. { inherit system config; }
|
||||
}:
|
||||
|
||||
with import ../lib/testing-python.nix { inherit system pkgs; };
|
||||
with pkgs.lib;
|
||||
|
||||
let
|
||||
postgresql-versions = import ../../pkgs/servers/sql/postgresql pkgs;
|
||||
test-sql = pkgs.writeText "postgresql-test" ''
|
||||
CREATE EXTENSION timescaledb;
|
||||
CREATE EXTENSION timescaledb_toolkit;
|
||||
|
||||
CREATE TABLE sth (
|
||||
time TIMESTAMPTZ NOT NULL,
|
||||
value DOUBLE PRECISION
|
||||
);
|
||||
|
||||
SELECT create_hypertable('sth', 'time');
|
||||
|
||||
INSERT INTO sth (time, value) VALUES
|
||||
('2003-04-12 04:05:06 America/New_York', 1.0),
|
||||
('2003-04-12 04:05:07 America/New_York', 2.0),
|
||||
('2003-04-12 04:05:08 America/New_York', 3.0),
|
||||
('2003-04-12 04:05:09 America/New_York', 4.0),
|
||||
('2003-04-12 04:05:10 America/New_York', 5.0)
|
||||
;
|
||||
|
||||
WITH t AS (
|
||||
SELECT
|
||||
time_bucket('1 day'::interval, time) AS dt,
|
||||
stats_agg(value) AS stats
|
||||
FROM sth
|
||||
GROUP BY time_bucket('1 day'::interval, time)
|
||||
)
|
||||
SELECT
|
||||
average(stats)
|
||||
FROM t;
|
||||
'';
|
||||
make-postgresql-test = postgresql-name: postgresql-package: makeTest {
|
||||
name = postgresql-name;
|
||||
meta = with pkgs.lib.maintainers; {
|
||||
maintainers = [ typetetris ];
|
||||
};
|
||||
|
||||
nodes.machine = { ... }:
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = postgresql-package;
|
||||
extraPlugins = ps: with ps; [
|
||||
timescaledb
|
||||
timescaledb_toolkit
|
||||
];
|
||||
settings = { shared_preload_libraries = "timescaledb, timescaledb_toolkit"; };
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
def check_count(statement, lines):
|
||||
return 'test $(sudo -u postgres psql postgres -tAc "{}"|wc -l) -eq {}'.format(
|
||||
statement, lines
|
||||
)
|
||||
|
||||
|
||||
machine.start()
|
||||
machine.wait_for_unit("postgresql")
|
||||
|
||||
with subtest("Postgresql with extensions timescaledb and timescaledb_toolkit is available just after unit start"):
|
||||
machine.succeed(
|
||||
"sudo -u postgres psql -f ${test-sql}"
|
||||
)
|
||||
|
||||
machine.fail(check_count("SELECT * FROM sth;", 3))
|
||||
machine.succeed(check_count("SELECT * FROM sth;", 5))
|
||||
machine.fail(check_count("SELECT * FROM sth;", 4))
|
||||
|
||||
machine.shutdown()
|
||||
'';
|
||||
|
||||
};
|
||||
applicablePostgresqlVersions = filterAttrs (_: value: versionAtLeast value.version "14") postgresql-versions;
|
||||
in
|
||||
mapAttrs'
|
||||
(name: package: {
|
||||
inherit name;
|
||||
value = make-postgresql-test name package;
|
||||
})
|
||||
applicablePostgresqlVersions
|
||||
@@ -1,32 +0,0 @@
|
||||
import ./make-test-python.nix ({ pkgs, lib, ...} : {
|
||||
name = "tsja";
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ chayleaf ];
|
||||
};
|
||||
|
||||
nodes = {
|
||||
master =
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
extraPlugins = ps: with ps; [
|
||||
tsja
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
start_all()
|
||||
master.wait_for_unit("postgresql")
|
||||
master.succeed("sudo -u postgres psql -f /run/current-system/sw/share/postgresql/extension/libtsja_dbinit.sql")
|
||||
# make sure "日本語" is parsed as a separate lexeme
|
||||
master.succeed("""
|
||||
sudo -u postgres \\
|
||||
psql -c "SELECT * FROM ts_debug('japanese', 'PostgreSQLで日本語のテキスト検索ができます。')" \\
|
||||
| grep "{日本語}"
|
||||
""")
|
||||
'';
|
||||
})
|
||||
@@ -31,21 +31,30 @@ import ../make-test-python.nix (
|
||||
machine.succeed("curl --fail http://localhost:2283/")
|
||||
|
||||
machine.succeed("""
|
||||
curl -H 'Content-Type: application/json' --data '{ "email": "test@example.com", "name": "Admin", "password": "admin" }' -X POST http://localhost:2283/api/auth/admin-sign-up
|
||||
curl -f --json '{ "email": "test@example.com", "name": "Admin", "password": "admin" }' http://localhost:2283/api/auth/admin-sign-up
|
||||
""")
|
||||
res = machine.succeed("""
|
||||
curl -H 'Content-Type: application/json' --data '{ "email": "test@example.com", "password": "admin" }' -X POST http://localhost:2283/api/auth/login
|
||||
curl -f --json '{ "email": "test@example.com", "password": "admin" }' http://localhost:2283/api/auth/login
|
||||
""")
|
||||
token = json.loads(res)['accessToken']
|
||||
|
||||
res = machine.succeed("""
|
||||
curl -H 'Content-Type: application/json' -H 'Cookie: immich_access_token=%s' --data '{ "name": "API Key", "permissions": ["all"] }' -X POST http://localhost:2283/api/api-keys
|
||||
curl -f -H 'Cookie: immich_access_token=%s' --json '{ "name": "API Key", "permissions": ["all"] }' http://localhost:2283/api/api-keys
|
||||
""" % token)
|
||||
key = json.loads(res)['secret']
|
||||
|
||||
machine.succeed(f"immich login http://localhost:2283/api {key}")
|
||||
res = machine.succeed("immich server-info")
|
||||
print(res)
|
||||
|
||||
machine.succeed("""
|
||||
curl -f -X PUT -H 'Cookie: immich_access_token=%s' --json '{ "command": "start" }' http://localhost:2283/api/jobs/backupDatabase
|
||||
""" % token)
|
||||
res = machine.succeed("""
|
||||
curl -f -H 'Cookie: immich_access_token=%s' http://localhost:2283/api/jobs
|
||||
""" % token)
|
||||
assert json.loads(res)["backupDatabase"]["jobCounts"]["active"] == 1
|
||||
machine.wait_until_succeeds("ls /var/lib/immich/backups/*.sql.gz")
|
||||
'';
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "audacious";
|
||||
version = "4.4.1";
|
||||
version = "4.4.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "audacious-media-player";
|
||||
repo = "audacious";
|
||||
rev = "${pname}-${version}";
|
||||
hash = "sha256-Bz/OI38+IFTHlBH3p2NTzSj8YD/7Xd4JeWpHgCSpMXw=";
|
||||
hash = "sha256-Vh39uY15Pj2TbPk8gU55YykhFf5ytSUxN2gJ0VlC3tQ=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -46,13 +46,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "audacious-plugins";
|
||||
version = "4.4.1";
|
||||
version = "4.4.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "audacious-media-player";
|
||||
repo = "audacious-plugins";
|
||||
rev = "${pname}-${version}";
|
||||
hash = "sha256-F2kcGc6VCaBsL5Zx7qtZjPvqzaxmR87Q9LTFEU+nqmo=";
|
||||
hash = "sha256-fA7xB04WLlleLIBDEZOVqDQguKAXtTsJoedQ9A/ZHQg=";
|
||||
};
|
||||
|
||||
patches = [ ./0001-Set-plugindir-to-PREFIX-lib-audacious.patch ];
|
||||
|
||||
@@ -39,9 +39,9 @@ rustPlatform.buildRustPackage.override { inherit stdenv; } rec {
|
||||
# Use the stdenv default phases (./configure; make) instead of the
|
||||
# ones from buildRustPackage.
|
||||
configurePhase = "configurePhase";
|
||||
buildPhase = "buildPhase";
|
||||
checkPhase = "checkPhase";
|
||||
installPhase = "installPhase";
|
||||
dontCargoBuild = true;
|
||||
dontCargoCheck = true;
|
||||
dontCargoInstall = true;
|
||||
|
||||
postPatch = ''
|
||||
# Have to do this here instead of in preConfigure because
|
||||
|
||||
@@ -2,49 +2,63 @@
|
||||
#!nix-shell update-shell.nix -i python3
|
||||
|
||||
# format:
|
||||
# $ nix run nixpkgs.python3Packages.black -c black update.py
|
||||
# $ nix run nixpkgs#python3Packages.ruff -- update.py
|
||||
# type-check:
|
||||
# $ nix run nixpkgs.python3Packages.mypy -c mypy update.py
|
||||
# $ nix run nixpkgs#python3Packages.mypy -- update.py
|
||||
# linted:
|
||||
# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265,E402 update.py
|
||||
# $ nix run nixpkgs#python3Packages.flake8 -- --ignore E501,E265,E402 update.py
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
from typing import List, Tuple
|
||||
from pathlib import Path
|
||||
from typing import List, Tuple
|
||||
|
||||
# Import plugin update library from maintainers/scripts/pluginupdate.py
|
||||
ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) # type: ignore
|
||||
ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) # type: ignore
|
||||
sys.path.insert(
|
||||
0, os.path.join(ROOT.parent.parent.parent.parent.parent, "maintainers", "scripts")
|
||||
)
|
||||
import pluginupdate
|
||||
|
||||
GET_PLUGINS = f"""(with import <localpkgs> {{}};
|
||||
GET_PLUGINS = f"""(
|
||||
with import <localpkgs> {{ }};
|
||||
let
|
||||
inherit (kakouneUtils.override {{}}) buildKakounePluginFrom2Nix;
|
||||
inherit (kakouneUtils.override {{ }}) buildKakounePluginFrom2Nix;
|
||||
generated = callPackage {ROOT}/generated.nix {{
|
||||
inherit buildKakounePluginFrom2Nix;
|
||||
}};
|
||||
hasChecksum = value: lib.isAttrs value && lib.hasAttrByPath ["src" "outputHash"] value;
|
||||
getChecksum = name: value:
|
||||
if hasChecksum value then {{
|
||||
submodules = value.src.fetchSubmodules or false;
|
||||
sha256 = value.src.outputHash;
|
||||
rev = value.src.rev;
|
||||
}} else null;
|
||||
hasChecksum =
|
||||
value:
|
||||
lib.isAttrs value
|
||||
&& lib.hasAttrByPath [
|
||||
"src"
|
||||
"outputHash"
|
||||
] value;
|
||||
getChecksum =
|
||||
name: value:
|
||||
if hasChecksum value then
|
||||
{{
|
||||
submodules = value.src.fetchSubmodules or false;
|
||||
sha256 = value.src.outputHash;
|
||||
rev = value.src.rev;
|
||||
}}
|
||||
else
|
||||
null;
|
||||
checksums = lib.mapAttrs getChecksum generated;
|
||||
in lib.filterAttrs (n: v: v != null) checksums)"""
|
||||
in
|
||||
lib.filterAttrs (n: v: v != null) checksums
|
||||
)"""
|
||||
|
||||
HEADER = "# This file has been @generated by ./pkgs/applications/editors/kakoune/plugins/update.py. Do not edit!"
|
||||
|
||||
HEADER = "# This file has been generated by ./pkgs/applications/editors/kakoune/plugins/update.py. Do not edit!"
|
||||
|
||||
class KakouneEditor(pluginupdate.Editor):
|
||||
|
||||
|
||||
def generate_nix(self, plugins: List[Tuple[pluginupdate.PluginDesc, pluginupdate.Plugin]], outfile: str):
|
||||
sorted_plugins = sorted(plugins, key=lambda v: v[1].name.lower())
|
||||
|
||||
def generate_nix(
|
||||
self,
|
||||
plugins: List[Tuple[pluginupdate.PluginDesc, pluginupdate.Plugin]],
|
||||
outfile: str,
|
||||
):
|
||||
with open(outfile, "w+") as f:
|
||||
f.write(HEADER)
|
||||
f.write(
|
||||
@@ -54,7 +68,7 @@ let
|
||||
packages = ( self:
|
||||
{"""
|
||||
)
|
||||
for pluginDesc, plugin in sorted_plugins:
|
||||
for pluginDesc, plugin in plugins:
|
||||
f.write(
|
||||
f"""
|
||||
{plugin.normalized_name} = buildKakounePluginFrom2Nix {{
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, nix-update-script
|
||||
, rustPlatform
|
||||
, cmake
|
||||
, pkg-config
|
||||
, perl
|
||||
, python3
|
||||
, fontconfig
|
||||
, glib
|
||||
, gtk3
|
||||
, openssl
|
||||
, libGL
|
||||
, libobjc
|
||||
, libxkbcommon
|
||||
, Security
|
||||
, CoreServices
|
||||
, ApplicationServices
|
||||
, Carbon
|
||||
, AppKit
|
||||
, wrapGAppsHook3
|
||||
, wayland
|
||||
, gobject-introspection
|
||||
, xorg
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
nix-update-script,
|
||||
rustPlatform,
|
||||
cmake,
|
||||
pkg-config,
|
||||
perl,
|
||||
python3,
|
||||
fontconfig,
|
||||
glib,
|
||||
gtk3,
|
||||
openssl,
|
||||
libGL,
|
||||
libobjc,
|
||||
libxkbcommon,
|
||||
wrapGAppsHook3,
|
||||
wayland,
|
||||
gobject-introspection,
|
||||
xorg,
|
||||
apple-sdk_11,
|
||||
}:
|
||||
let
|
||||
rpathLibs = lib.optionals stdenv.hostPlatform.isLinux [
|
||||
@@ -85,33 +82,37 @@ rustPlatform.buildRustPackage rec {
|
||||
gobject-introspection
|
||||
];
|
||||
|
||||
buildInputs = rpathLibs ++ [
|
||||
glib
|
||||
gtk3
|
||||
openssl
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
fontconfig
|
||||
] ++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
libobjc
|
||||
Security
|
||||
CoreServices
|
||||
ApplicationServices
|
||||
Carbon
|
||||
AppKit
|
||||
];
|
||||
buildInputs =
|
||||
rpathLibs
|
||||
++ [
|
||||
glib
|
||||
gtk3
|
||||
openssl
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
fontconfig
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [
|
||||
libobjc
|
||||
apple-sdk_11
|
||||
];
|
||||
|
||||
postInstall = if stdenv.hostPlatform.isLinux then ''
|
||||
install -Dm0644 $src/extra/images/logo.svg $out/share/icons/hicolor/scalable/apps/dev.lapce.lapce.svg
|
||||
install -Dm0644 $src/extra/linux/dev.lapce.lapce.desktop $out/share/applications/lapce.desktop
|
||||
postInstall =
|
||||
if stdenv.hostPlatform.isLinux then
|
||||
''
|
||||
install -Dm0644 $src/extra/images/logo.svg $out/share/icons/hicolor/scalable/apps/dev.lapce.lapce.svg
|
||||
install -Dm0644 $src/extra/linux/dev.lapce.lapce.desktop $out/share/applications/lapce.desktop
|
||||
|
||||
$STRIP -S $out/bin/lapce
|
||||
$STRIP -S $out/bin/lapce
|
||||
|
||||
patchelf --add-rpath "${lib.makeLibraryPath rpathLibs}" $out/bin/lapce
|
||||
'' else ''
|
||||
mkdir $out/Applications
|
||||
cp -r extra/macos/Lapce.app $out/Applications
|
||||
ln -s $out/bin $out/Applications/Lapce.app/Contents/MacOS
|
||||
'';
|
||||
patchelf --add-rpath "${lib.makeLibraryPath rpathLibs}" $out/bin/lapce
|
||||
''
|
||||
else
|
||||
''
|
||||
mkdir $out/Applications
|
||||
cp -r extra/macos/Lapce.app $out/Applications
|
||||
ln -s $out/bin $out/Applications/Lapce.app/Contents/MacOS
|
||||
'';
|
||||
|
||||
dontPatchELF = true;
|
||||
|
||||
@@ -124,7 +125,5 @@ rustPlatform.buildRustPackage rec {
|
||||
license = with licenses; [ asl20 ];
|
||||
maintainers = with maintainers; [ elliot ];
|
||||
mainProgram = "lapce";
|
||||
# Undefined symbols for architecture x86_64: "_NSPasteboardTypeFileURL"
|
||||
broken = stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isx86_64;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "leo-editor";
|
||||
version = "6.8.1";
|
||||
version = "6.8.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "leo-editor";
|
||||
repo = "leo-editor";
|
||||
rev = version;
|
||||
sha256 = "sha256-YhZSmk2n/Tg0zx1xuy0LtABNiBB3LmXYlhXoK7/b2tQ=";
|
||||
sha256 = "sha256-LfeqQjzrWzqJ/iTuMOWLnxEZ+SNPVcutNPI+T3WEKnM=";
|
||||
};
|
||||
|
||||
dontBuild = true;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1532,6 +1532,13 @@ in
|
||||
dependencies = with self; [ ultisnips ];
|
||||
};
|
||||
|
||||
neoconf-nvim = super.neoconf-nvim.overrideAttrs {
|
||||
dependencies = with self; [ nvim-lspconfig ];
|
||||
|
||||
doInstallCheck = true;
|
||||
nvimRequireCheck = "neoconf";
|
||||
};
|
||||
|
||||
neogit = super.neogit.overrideAttrs {
|
||||
dependencies = with self; [ plenary-nvim ];
|
||||
nvimRequireCheck = "neogit";
|
||||
@@ -2261,6 +2268,16 @@ in
|
||||
dependencies = with self; [ telescope-nvim ];
|
||||
};
|
||||
|
||||
quarto-nvim = super.quarto-nvim.overrideAttrs {
|
||||
dependencies = with self; [
|
||||
nvim-lspconfig
|
||||
otter-nvim
|
||||
];
|
||||
|
||||
nvimRequireCheck = "quarto";
|
||||
doInstallCheck = true;
|
||||
};
|
||||
|
||||
telescope-zoxide = super.telescope-zoxide.overrideAttrs {
|
||||
dependencies = with self; [ telescope-nvim ];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# run with:
|
||||
# $ nix run .\#vimPluginsUpdater
|
||||
# format:
|
||||
# $ nix run nixpkgs#python3Packages.black -- update.py
|
||||
# $ nix run nixpkgs#python3Packages.ruff -- update.py
|
||||
# type-check:
|
||||
# $ nix run nixpkgs#python3Packages.mypy -- update.py
|
||||
# linted:
|
||||
@@ -19,30 +19,24 @@
|
||||
#
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import logging
|
||||
import textwrap
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from typing import List, Tuple
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
from typing import List, Tuple
|
||||
|
||||
log = logging.getLogger("vim-updater")
|
||||
|
||||
sh = logging.StreamHandler()
|
||||
formatter = logging.Formatter("%(name)s:%(levelname)s: %(message)s")
|
||||
sh.setFormatter(formatter)
|
||||
log.addHandler(sh)
|
||||
|
||||
# Import plugin update library from maintainers/scripts/pluginupdate.py
|
||||
ROOT = Path(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
|
||||
import pluginupdate
|
||||
import importlib
|
||||
from pluginupdate import run_nix_expr, PluginDesc
|
||||
|
||||
treesitter = importlib.import_module('nvim-treesitter.update')
|
||||
import pluginupdate
|
||||
from pluginupdate import PluginDesc, run_nix_expr
|
||||
|
||||
treesitter = importlib.import_module("nvim-treesitter.update")
|
||||
|
||||
|
||||
HEADER = (
|
||||
@@ -56,17 +50,14 @@ class VimEditor(pluginupdate.Editor):
|
||||
nvim_treesitter_updated = False
|
||||
|
||||
def generate_nix(
|
||||
self,
|
||||
plugins: List[Tuple[PluginDesc, pluginupdate.Plugin]],
|
||||
outfile: str
|
||||
self, plugins: List[Tuple[PluginDesc, pluginupdate.Plugin]], outfile: str
|
||||
):
|
||||
log.info("Generating nix code")
|
||||
sorted_plugins = sorted(plugins, key=lambda v: v[0].name.lower())
|
||||
log.debug("Loading nvim-treesitter revision from nix...")
|
||||
nvim_treesitter_rev = pluginupdate.run_nix_expr(
|
||||
"(import <localpkgs> { }).vimPlugins.nvim-treesitter.src.rev",
|
||||
self.nixpkgs,
|
||||
timeout=10
|
||||
timeout=10,
|
||||
)
|
||||
|
||||
GET_PLUGINS_LUA = """
|
||||
@@ -98,7 +89,7 @@ class VimEditor(pluginupdate.Editor):
|
||||
"""
|
||||
)
|
||||
)
|
||||
for pdesc, plugin in sorted_plugins:
|
||||
for pdesc, plugin in plugins:
|
||||
content = self.plugin2nix(pdesc, plugin, _isNeovimPlugin(plugin))
|
||||
f.write(content)
|
||||
if (
|
||||
@@ -109,8 +100,9 @@ class VimEditor(pluginupdate.Editor):
|
||||
f.write("\n}\n")
|
||||
print(f"updated {outfile}")
|
||||
|
||||
def plugin2nix(self, pdesc: PluginDesc, plugin: pluginupdate.Plugin, isNeovim: bool) -> str:
|
||||
|
||||
def plugin2nix(
|
||||
self, pdesc: PluginDesc, plugin: pluginupdate.Plugin, isNeovim: bool
|
||||
) -> str:
|
||||
repo = pdesc.repo
|
||||
|
||||
content = f" {plugin.normalized_name} = "
|
||||
@@ -138,19 +130,25 @@ class VimEditor(pluginupdate.Editor):
|
||||
if self.nvim_treesitter_updated:
|
||||
print("updating nvim-treesitter grammars")
|
||||
cmd = [
|
||||
"nix", "build",
|
||||
"vimPlugins.nvim-treesitter.src", "-f", self.nixpkgs
|
||||
, "--print-out-paths"
|
||||
"nix",
|
||||
"build",
|
||||
"vimPlugins.nvim-treesitter.src",
|
||||
"-f",
|
||||
self.nixpkgs,
|
||||
"--print-out-paths",
|
||||
]
|
||||
log.debug("Running command: %s", " ".join(cmd))
|
||||
nvim_treesitter_dir = subprocess.check_output(cmd, text=True, timeout=90).strip()
|
||||
nvim_treesitter_dir = subprocess.check_output(
|
||||
cmd, text=True, timeout=90
|
||||
).strip()
|
||||
|
||||
generated = treesitter.update_grammars(nvim_treesitter_dir)
|
||||
treesitter_generated_nix_path = os.path.join(
|
||||
NIXPKGS_NVIMTREESITTER_FOLDER,
|
||||
"generated.nix"
|
||||
NIXPKGS_NVIMTREESITTER_FOLDER, "generated.nix"
|
||||
)
|
||||
open(os.path.join(args.nixpkgs, treesitter_generated_nix_path), "w").write(
|
||||
generated
|
||||
)
|
||||
open(os.path.join(args.nixpkgs, treesitter_generated_nix_path), "w").write(generated)
|
||||
|
||||
if self.nixpkgs_repo:
|
||||
index = self.nixpkgs_repo.index
|
||||
|
||||
@@ -116,9 +116,10 @@ https://github.com/AndrewRadev/bufferize.vim/,HEAD,
|
||||
https://github.com/akinsho/bufferline.nvim/,,
|
||||
https://github.com/kwkarlwang/bufjump.nvim/,HEAD,
|
||||
https://github.com/bullets-vim/bullets.vim/,,
|
||||
https://github.com/mattn/calendar-vim/,,mattn-calendar-vim
|
||||
https://github.com/itchyny/calendar.vim/,,
|
||||
https://github.com/bkad/camelcasemotion/,,
|
||||
https://github.com/catppuccin/nvim/,,catppuccin-nvim
|
||||
https://github.com/catppuccin/vim/,HEAD,catppuccin-vim
|
||||
https://github.com/tyru/caw.vim/,,
|
||||
https://github.com/uga-rosa/ccc.nvim/,HEAD,
|
||||
https://github.com/Eandrju/cellular-automaton.nvim/,HEAD,
|
||||
@@ -299,6 +300,7 @@ https://github.com/direnv/direnv.vim/,,
|
||||
https://github.com/chipsenkbeil/distant.nvim/,HEAD,
|
||||
https://github.com/doki-theme/doki-theme-vim/,,
|
||||
https://github.com/NTBBloodbath/doom-one.nvim/,,
|
||||
https://github.com/dracula/vim/,,dracula-vim
|
||||
https://github.com/Mofiqul/dracula.nvim/,HEAD,
|
||||
https://github.com/stevearc/dressing.nvim/,,
|
||||
https://github.com/Bekaboo/dropbar.nvim/,HEAD,
|
||||
@@ -313,6 +315,7 @@ https://github.com/creativenull/efmls-configs-nvim/,,
|
||||
https://github.com/elixir-tools/elixir-tools.nvim/,HEAD,
|
||||
https://github.com/elmcast/elm-vim/,,
|
||||
https://github.com/dmix/elvish.vim/,,
|
||||
https://github.com/embark-theme/vim/,,embark-vim
|
||||
https://github.com/mattn/emmet-vim/,,
|
||||
https://github.com/vim-scripts/emodeline/,,
|
||||
https://github.com/vim-scripts/errormarker.vim/,,
|
||||
@@ -361,6 +364,7 @@ https://github.com/gfanto/fzf-lsp.nvim/,,
|
||||
https://github.com/ibhagwan/fzf-lua/,HEAD,
|
||||
https://github.com/junegunn/fzf.vim/,,
|
||||
https://github.com/NTBBloodbath/galaxyline.nvim/,,
|
||||
https://github.com/gbprod/nord.nvim/,,gbprod-nord
|
||||
https://github.com/jsfaint/gen_tags.vim/,,
|
||||
https://github.com/gentoo/gentoo-syntax/,,
|
||||
https://github.com/ndmitchell/ghcid/,,
|
||||
@@ -389,9 +393,9 @@ https://github.com/liuchengxu/graphviz.vim/,,
|
||||
https://github.com/cbochs/grapple.nvim/,HEAD,
|
||||
https://github.com/blazkowolf/gruber-darker.nvim/,,
|
||||
https://github.com/MagicDuck/grug-far.nvim/,,
|
||||
https://github.com/gruvbox-community/gruvbox/,,gruvbox-community
|
||||
https://github.com/morhetz/gruvbox/,,
|
||||
https://github.com/luisiacc/gruvbox-baby/,HEAD,
|
||||
https://github.com/gruvbox-community/gruvbox/,,gruvbox-community
|
||||
https://github.com/eddyekofo94/gruvbox-flat.nvim/,,
|
||||
https://github.com/sainnhe/gruvbox-material/,,
|
||||
https://github.com/f4z3r/gruvbox-material.nvim/,HEAD,
|
||||
@@ -404,8 +408,8 @@ https://github.com/junegunn/gv.vim/,,
|
||||
https://github.com/TheSnakeWitcher/hardhat.nvim/,HEAD,
|
||||
https://github.com/m4xshen/hardtime.nvim/,HEAD,
|
||||
https://git.sr.ht/~sircmpwn/hare.vim,HEAD,
|
||||
https://github.com/ThePrimeagen/harpoon/,harpoon2,harpoon2
|
||||
https://github.com/ThePrimeagen/harpoon/,master,
|
||||
https://github.com/ThePrimeagen/harpoon/,harpoon2,harpoon2
|
||||
https://github.com/kiyoon/haskell-scope-highlighting.nvim/,HEAD,
|
||||
https://github.com/mrcjkb/haskell-snippets.nvim/,HEAD,
|
||||
https://github.com/neovimhaskell/haskell-vim/,,
|
||||
@@ -434,7 +438,6 @@ https://github.com/idris-hackers/idris-vim/,,
|
||||
https://github.com/ShinKage/idris2-nvim/,,
|
||||
https://github.com/edwinb/idris2-vim/,,
|
||||
https://github.com/3rd/image.nvim/,HEAD,
|
||||
https://github.com/samodostal/image.nvim/,HEAD,samodostal-image-nvim
|
||||
https://github.com/HakonHarnes/img-clip.nvim/,HEAD,
|
||||
https://github.com/lewis6991/impatient.nvim/,,
|
||||
https://github.com/backdround/improved-search.nvim/,HEAD,
|
||||
@@ -447,7 +450,6 @@ https://github.com/Darazaki/indent-o-matic/,,
|
||||
https://github.com/Yggdroot/indentLine/,,
|
||||
https://github.com/ciaranm/inkpot/,,
|
||||
https://github.com/jbyuki/instant.nvim/,HEAD,
|
||||
https://github.com/jbyuki/one-small-step-for-vimkind/,HEAD,
|
||||
https://github.com/pta2002/intellitab.nvim/,HEAD,
|
||||
https://github.com/parsonsmatt/intero-neovim/,,
|
||||
https://github.com/keith/investigate.vim/,,
|
||||
@@ -544,6 +546,7 @@ https://github.com/williamboman/mason.nvim/,HEAD,
|
||||
https://github.com/vim-scripts/matchit.zip/,,
|
||||
https://github.com/marko-cerovac/material.nvim/,,
|
||||
https://github.com/kaicataldo/material.vim/,HEAD,
|
||||
https://github.com/mattn/calendar-vim/,,mattn-calendar-vim
|
||||
https://github.com/vim-scripts/mayansmoke/,,
|
||||
https://github.com/chikamichi/mediawiki.vim/,HEAD,
|
||||
https://github.com/savq/melange-nvim/,,
|
||||
@@ -602,7 +605,6 @@ https://github.com/miikanissi/modus-themes.nvim/,HEAD,
|
||||
https://github.com/tomasr/molokai/,,
|
||||
https://github.com/benlubas/molten-nvim/,HEAD,
|
||||
https://github.com/loctvl842/monokai-pro.nvim/,HEAD,
|
||||
https://github.com/shaunsingh/moonlight.nvim/,,pure-lua
|
||||
https://github.com/leafo/moonscript-vim/,HEAD,
|
||||
https://github.com/yegappan/mru/,,
|
||||
https://github.com/smoka7/multicursors.nvim/,HEAD,
|
||||
@@ -673,7 +675,6 @@ https://github.com/stevanmilic/neotest-scala/,HEAD,
|
||||
https://github.com/shunsambongi/neotest-testthat/,HEAD,
|
||||
https://github.com/marilari88/neotest-vitest/,HEAD,
|
||||
https://github.com/lawrence-laz/neotest-zig/,HEAD,
|
||||
https://github.com/rose-pine/neovim/,main,rose-pine
|
||||
https://github.com/Shatur/neovim-ayu/,,
|
||||
https://github.com/cloudhead/neovim-fuzzy/,,
|
||||
https://github.com/jeffkreeftmeijer/neovim-sensible/,,
|
||||
@@ -688,6 +689,7 @@ https://github.com/fiatjaf/neuron.vim/,,
|
||||
https://github.com/Olical/nfnl/,main,
|
||||
https://github.com/chr4/nginx.vim/,,
|
||||
https://github.com/oxfist/night-owl.nvim/,,
|
||||
https://github.com/bluz71/vim-nightfly-colors/,,nightfly
|
||||
https://github.com/EdenEast/nightfox.nvim/,,
|
||||
https://github.com/Alexis12119/nightly.nvim/,,
|
||||
https://github.com/zah/nim.vim/,,
|
||||
@@ -699,7 +701,7 @@ https://github.com/shortcuts/no-neck-pain.nvim/,HEAD,
|
||||
https://github.com/kartikp10/noctis.nvim/,,
|
||||
https://github.com/folke/noice.nvim/,HEAD,
|
||||
https://github.com/nvimtools/none-ls.nvim/,HEAD,
|
||||
https://github.com/gbprod/nord.nvim/,,gbprod-nord
|
||||
https://github.com/nordtheme/vim/,,nord-vim
|
||||
https://github.com/shaunsingh/nord.nvim/,,
|
||||
https://github.com/andersevenrud/nordic.nvim/,,
|
||||
https://github.com/vigoux/notifier.nvim/,HEAD,
|
||||
@@ -708,8 +710,8 @@ https://github.com/MunifTanjim/nui.nvim/,main,
|
||||
https://github.com/jose-elias-alvarez/null-ls.nvim/,,
|
||||
https://github.com/nacro90/numb.nvim/,,
|
||||
https://github.com/nvchad/nvchad/,HEAD,
|
||||
https://github.com/nvchad/ui/,HEAD,nvchad-ui
|
||||
https://github.com/ChristianChiarulli/nvcode-color-schemes.vim/,,
|
||||
https://github.com/catppuccin/nvim/,,catppuccin-nvim
|
||||
https://github.com/AckslD/nvim-FeMaco.lua/,HEAD,
|
||||
https://github.com/nathanmsmith/nvim-ale-diagnostic/,,
|
||||
https://github.com/windwp/nvim-autopairs/,,
|
||||
@@ -825,6 +827,7 @@ https://github.com/nomnivore/ollama.nvim/,HEAD,
|
||||
https://github.com/yonlu/omni.vim/,,
|
||||
https://github.com/Hoffs/omnisharp-extended-lsp.nvim/,HEAD,
|
||||
https://github.com/Th3Whit3Wolf/one-nvim/,,
|
||||
https://github.com/jbyuki/one-small-step-for-vimkind/,HEAD,
|
||||
https://github.com/navarasu/onedark.nvim/,,
|
||||
https://github.com/joshdick/onedark.vim/,,
|
||||
https://github.com/LunarVim/onedarker.nvim/,,
|
||||
@@ -854,6 +857,7 @@ https://github.com/olimorris/persisted.nvim/,HEAD,
|
||||
https://github.com/folke/persistence.nvim/,,
|
||||
https://github.com/pest-parser/pest.vim/,HEAD,
|
||||
https://github.com/lifepillar/pgsql.vim/,,
|
||||
https://github.com/phha/zenburn.nvim/,,phha-zenburn
|
||||
https://github.com/motus/pig.vim/,,
|
||||
https://github.com/weirongxu/plantuml-previewer.vim/,HEAD,
|
||||
https://github.com/aklt/plantuml-syntax/,,
|
||||
@@ -873,6 +877,7 @@ https://github.com/ahmedkhalf/project.nvim/,,
|
||||
https://github.com/kevinhwang91/promise-async/,HEAD,
|
||||
https://github.com/frigoeu/psc-ide-vim/,,
|
||||
https://github.com/Shougo/pum.vim/,HEAD,
|
||||
https://github.com/shaunsingh/moonlight.nvim/,,pure-lua
|
||||
https://github.com/purescript-contrib/purescript-vim/,,
|
||||
https://github.com/python-mode/python-mode/,,
|
||||
https://github.com/vim-python/python-syntax/,,
|
||||
@@ -905,6 +910,7 @@ https://github.com/gu-fan/riv.vim/,,
|
||||
https://github.com/kevinhwang91/rnvimr/,,
|
||||
https://github.com/mfukar/robotframework-vim/,,
|
||||
https://github.com/ron-rs/ron.vim/,,
|
||||
https://github.com/rose-pine/neovim/,main,rose-pine
|
||||
https://github.com/jmederosalvarado/roslyn.nvim/,HEAD,
|
||||
https://github.com/keith/rspec.vim/,,
|
||||
https://github.com/ccarpita/rtorrent-syntax-file/,,
|
||||
@@ -912,6 +918,7 @@ https://github.com/simrat39/rust-tools.nvim/,,
|
||||
https://github.com/rust-lang/rust.vim/,,
|
||||
https://github.com/hauleth/sad.vim/,,
|
||||
https://github.com/vmware-archive/salt-vim/,,
|
||||
https://github.com/samodostal/image.nvim/,HEAD,samodostal-image-nvim
|
||||
https://github.com/lewis6991/satellite.nvim/,HEAD,
|
||||
https://github.com/davidgranstrom/scnvim/,HEAD,
|
||||
https://github.com/tiagovla/scope.nvim/,HEAD,
|
||||
@@ -935,8 +942,8 @@ https://github.com/mrjones2014/smart-splits.nvim/,,
|
||||
https://github.com/m4xshen/smartcolumn.nvim/,,
|
||||
https://github.com/gorkunov/smartpairs.vim/,,
|
||||
https://github.com/ibhagwan/smartyank.nvim/,,
|
||||
https://github.com/camspiers/snap/,,
|
||||
https://github.com/folke/snacks.nvim/,HEAD,
|
||||
https://github.com/camspiers/snap/,,
|
||||
https://github.com/norcalli/snippets.nvim/,,
|
||||
https://github.com/shaunsingh/solarized.nvim/,HEAD,
|
||||
https://github.com/sainnhe/sonokai/,,
|
||||
@@ -1068,7 +1075,6 @@ https://github.com/jose-elias-alvarez/typescript.nvim/,,
|
||||
https://github.com/MrPicklePinosaur/typst-conceal.vim/,HEAD,
|
||||
https://github.com/chomosuke/typst-preview.nvim/,HEAD,
|
||||
https://github.com/kaarmu/typst.vim/,HEAD,
|
||||
https://github.com/nvchad/ui/,HEAD,nvchad-ui
|
||||
https://github.com/altermo/ultimate-autopair.nvim/,HEAD,
|
||||
https://github.com/SirVer/ultisnips/,,
|
||||
https://github.com/mbbill/undotree/,,
|
||||
@@ -1084,11 +1090,6 @@ https://github.com/junegunn/vader.vim/,,
|
||||
https://github.com/jbyuki/venn.nvim/,,
|
||||
https://github.com/vhda/verilog_systemverilog.vim/,,
|
||||
https://github.com/vifm/vifm.vim/,,
|
||||
https://github.com/catppuccin/vim/,HEAD,catppuccin-vim
|
||||
https://github.com/dracula/vim/,,dracula-vim
|
||||
https://github.com/embark-theme/vim/,,embark-vim
|
||||
https://github.com/nordtheme/vim/,,nord-vim
|
||||
https://github.com/inkarkat/vim-AdvancedSorters/,,vim-advanced-sorters
|
||||
https://github.com/Konfekt/vim-CtrlXA/,,
|
||||
https://github.com/konfekt/vim-DetectSpellLang/,,
|
||||
https://github.com/dpelle/vim-LanguageTool/,,
|
||||
@@ -1115,6 +1116,7 @@ https://github.com/MarcWeber/vim-addon-sql/,,
|
||||
https://github.com/MarcWeber/vim-addon-syntax-checker/,,
|
||||
https://github.com/MarcWeber/vim-addon-toggle-buffer/,,
|
||||
https://github.com/MarcWeber/vim-addon-xdebug/,,
|
||||
https://github.com/inkarkat/vim-AdvancedSorters/,,vim-advanced-sorters
|
||||
https://github.com/junegunn/vim-after-object/,,
|
||||
https://github.com/danilo-augusto/vim-afterglow/,HEAD,
|
||||
https://github.com/msuperdock/vim-agda/,HEAD,
|
||||
@@ -1191,6 +1193,7 @@ https://github.com/kristijanhusak/vim-dirvish-git/,,
|
||||
https://github.com/tpope/vim-dispatch/,,
|
||||
https://github.com/radenling/vim-dispatch-neovim/,,
|
||||
https://github.com/jhradilek/vim-docbk/,,
|
||||
https://github.com/jhradilek/vim-snippets/,,vim-docbk-snippets
|
||||
https://github.com/tpope/vim-dotenv/,,
|
||||
https://github.com/junegunn/vim-easy-align/,,
|
||||
https://github.com/zhou13/vim-easyescape/,,
|
||||
@@ -1344,7 +1347,6 @@ https://github.com/jistr/vim-nerdtree-tabs/,,
|
||||
https://github.com/nfnty/vim-nftables/,,
|
||||
https://github.com/kana/vim-niceblock/,,
|
||||
https://github.com/nickel-lang/vim-nickel/,main,
|
||||
https://github.com/bluz71/vim-nightfly-colors/,,nightfly
|
||||
https://github.com/tommcdo/vim-ninja-feet/,,
|
||||
https://github.com/LnL7/vim-nix/,,
|
||||
https://github.com/symphorien/vim-nixhash/,,
|
||||
@@ -1436,7 +1438,6 @@ https://github.com/bohlender/vim-smt2/,,
|
||||
https://github.com/justinmk/vim-sneak/,,
|
||||
https://github.com/garbas/vim-snipmate/,,
|
||||
https://github.com/honza/vim-snippets/,,
|
||||
https://github.com/jhradilek/vim-snippets/,,vim-docbk-snippets
|
||||
https://github.com/lifepillar/vim-solarized8/,HEAD,
|
||||
https://github.com/tomlion/vim-solidity/,,
|
||||
https://github.com/christoomey/vim-sort-motion/,,
|
||||
@@ -1565,7 +1566,6 @@ https://github.com/Lilja/zellij.nvim/,HEAD,
|
||||
https://github.com/folke/zen-mode.nvim/,,
|
||||
https://github.com/zenbones-theme/zenbones.nvim/,HEAD,
|
||||
https://github.com/jnurmine/zenburn/,,
|
||||
https://github.com/phha/zenburn.nvim/,,phha-zenburn
|
||||
https://github.com/nvimdev/zephyr-nvim/,,
|
||||
https://github.com/ziglang/zig.vim/,,
|
||||
https://github.com/zk-org/zk-nvim/,HEAD,
|
||||
|
||||
@@ -1049,26 +1049,26 @@ let
|
||||
sources = {
|
||||
"x86_64-linux" = {
|
||||
arch = "linux-x64";
|
||||
hash = "sha256-X6Oszc88F0ENABwX63uwxbJ4VPQOQzZbJA87znVg5d8=";
|
||||
hash = "sha256-+/0ZQkRS6AD8u5+t2hiPwQxzwhEc+n2F0GVk1s0n74U=";
|
||||
};
|
||||
"x86_64-darwin" = {
|
||||
arch = "darwin-x64";
|
||||
hash = "sha256-NH3kGmNZpKofNplw+FRJFvV3m36HRuIqGR3zt6X5x60=";
|
||||
hash = "sha256-FZbTBPn12pv9bQWqfWwPapFLTpp5nclp0RH/WZc6/r4=";
|
||||
};
|
||||
"aarch64-linux" = {
|
||||
arch = "linux-arm64";
|
||||
hash = "sha256-hlFAMz17cl2/1CK7/dgrLktcPZYAcccIWIpkAVdwpkI=";
|
||||
hash = "sha256-e6zfflFgxVuikWwQuU6ImEuVk8xgi2HyY8uZwBoQiLU=";
|
||||
};
|
||||
"aarch64-darwin" = {
|
||||
arch = "darwin-arm64";
|
||||
hash = "sha256-oVkmdw0sHv5Y+ysT4zWW6qFDh/h4/TcgSAauh1KrE1c=";
|
||||
hash = "sha256-SfA9wkvYT2Vb3GpJRjWE6lzZAXdFCnEKoKl0hjT0Llw=";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
name = "continue";
|
||||
publisher = "Continue";
|
||||
version = "0.8.44";
|
||||
version = "0.8.54";
|
||||
}
|
||||
// sources.${stdenv.system};
|
||||
nativeBuildInputs = lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
|
||||
@@ -1740,8 +1740,8 @@ let
|
||||
mktplcRef = {
|
||||
name = "prettier-vscode";
|
||||
publisher = "esbenp";
|
||||
version = "10.4.0";
|
||||
hash = "sha256-8+90cZpqyH+wBgPFaX5GaU6E02yBWUoB+T9C2z2Ix8c=";
|
||||
version = "11.0.0";
|
||||
hash = "sha256-pNjkJhof19cuK0PsXJ/Q/Zb2H7eoIkfXJMLZJ4lDn7k=";
|
||||
};
|
||||
meta = {
|
||||
changelog = "https://marketplace.visualstudio.com/items/esbenp.prettier-vscode/changelog";
|
||||
@@ -3627,8 +3627,14 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
ms-vscode-remote.vscode-remote-extensionpack =
|
||||
callPackage ./ms-vscode-remote.vscode-remote-extensionpack
|
||||
{ };
|
||||
|
||||
ms-vsliveshare.vsliveshare = callPackage ./ms-vsliveshare.vsliveshare { };
|
||||
|
||||
ms-windows-ai-studio.windows-ai-studio = callPackage ./ms-windows-ai-studio.windows-ai-studio { };
|
||||
|
||||
mshr-h.veriloghdl = buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "veriloghdl";
|
||||
@@ -4151,6 +4157,23 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
sainnhe.gruvbox-material = buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "gruvbox-material";
|
||||
publisher = "sainnhe";
|
||||
version = "6.5.2";
|
||||
hash = "sha256-D+SZEQQwjZeuyENOYBJGn8tqS3cJiWbEkmEqhNRY/i4=";
|
||||
};
|
||||
meta = {
|
||||
changelog = "https://marketplace.visualstudio.com/items/sainnhe.gruvbox-material/changelog";
|
||||
description = "Gruvbox Material theme VSCode extension with Material palette";
|
||||
downloadPage = "https://marketplace.visualstudio.com/items?itemName=sainnhe.gruvbox-material";
|
||||
homepage = "https://github.com/sainnhe/gruvbox-material-vscode";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [ thtrf ];
|
||||
};
|
||||
};
|
||||
|
||||
samuelcolvin.jinjahtml = buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "jinjahtml";
|
||||
@@ -4301,8 +4324,8 @@ let
|
||||
mktplcRef = {
|
||||
publisher = "shd101wyy";
|
||||
name = "markdown-preview-enhanced";
|
||||
version = "0.8.14";
|
||||
hash = "sha256-vCuuPB/GTkM2xCBn1UF3CZwP49Ge/8eelHhg67EG7tQ=";
|
||||
version = "0.8.15";
|
||||
hash = "sha256-aW2Ri73xIl/1q/Yoi5qg25fjx7l55QfXAn+M+JuoN+A=";
|
||||
};
|
||||
meta = {
|
||||
description = "Provides a live preview of markdown using either markdown-it or pandoc";
|
||||
@@ -4531,8 +4554,8 @@ let
|
||||
mktplcRef = {
|
||||
name = "code-spell-checker";
|
||||
publisher = "streetsidesoftware";
|
||||
version = "4.0.14";
|
||||
hash = "sha256-b87sBCprMMfxsP8lyMM3yI82YvKZd5Jc+Z/x7uflnL0=";
|
||||
version = "4.0.15";
|
||||
hash = "sha256-Zow0laXwORa3V5Hy40pWDa/+Xq7kQbgn/Ia6PrJxI6E=";
|
||||
};
|
||||
meta = {
|
||||
changelog = "https://marketplace.visualstudio.com/items/streetsidesoftware.code-spell-checker/changelog";
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
lib,
|
||||
vscode-utils,
|
||||
}:
|
||||
|
||||
vscode-utils.buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "vscode-remote-extensionpack";
|
||||
publisher = "ms-vscode-remote";
|
||||
version = "0.26.0";
|
||||
hash = "sha256-YUo0QbJILa9BzWub6Wi6cDD/Zsy/H8LZ8j+9H+5pVHY=";
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "A Visual Studio Code extension pack that lets you open any folder in a container, on a remote machine, or in WSL and take advantage of VS Code's full feature set";
|
||||
homepage = "https://github.com/Microsoft/vscode-remote-release";
|
||||
license = lib.licenses.unfree;
|
||||
maintainers = with lib.maintainers; [ drupol ];
|
||||
};
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
lib,
|
||||
vscode-utils,
|
||||
}:
|
||||
|
||||
vscode-utils.buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "windows-ai-studio";
|
||||
publisher = "ms-windows-ai-studio";
|
||||
version = "0.6.1";
|
||||
hash = "sha256-BAA7wSfyJ4y8how+NnaGdCf/BCU6aOmI8ew8qpcQCnY=";
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "A Visual Studio Code an extension to help developers and AI engineers to easily build AI apps through developing and testing with generative AI models locally or in the cloud";
|
||||
homepage = "https://github.com/Microsoft/windows-ai-studio";
|
||||
license = lib.licenses.unfree;
|
||||
maintainers = with lib.maintainers; [ drupol ];
|
||||
};
|
||||
}
|
||||
@@ -10,8 +10,8 @@ vscode-utils.buildVscodeMarketplaceExtension {
|
||||
mktplcRef = {
|
||||
name = "sourcery";
|
||||
publisher = "sourcery";
|
||||
version = "1.23.0";
|
||||
hash = "sha256-wMky9whajltZYD3PUG+LCzuK9S5t55+3tRjTyA8kFcY=";
|
||||
version = "1.24.0";
|
||||
hash = "sha256-T2AbGxBytHXWP/ZKBhglRRbvPZ6px90XnSadwZTe/BM=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
, cmake
|
||||
, wrapQtAppsHook
|
||||
, qtbase
|
||||
, qtsvg
|
||||
, bluez
|
||||
, ffmpeg
|
||||
, libao
|
||||
@@ -48,13 +49,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "dolphin-emu-primehack";
|
||||
version = "1.0.6a";
|
||||
version = "1.0.7a";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "shiiion";
|
||||
repo = "dolphin";
|
||||
rev = version;
|
||||
hash = "sha256-gc4+ofoLKR+cvm+SaWEnGaKrSjWMKq7pF6pEIi75Rtk=";
|
||||
hash = "sha256-vuTSXQHnR4HxAGGiPg5tUzfiXROU3+E9kyjH+T6zVmc=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
@@ -93,6 +94,7 @@ stdenv.mkDerivation rec {
|
||||
fmt
|
||||
xz
|
||||
qtbase
|
||||
qtsvg
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
bluez
|
||||
udev
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
diff --git a/intern/smoke/intern/WAVELET_NOISE.h b/intern/smoke/intern/WAVELET_NOISE.h
|
||||
index fce901b..1f73c5e 100644
|
||||
--- a/intern/smoke/intern/WAVELET_NOISE.h
|
||||
+++ b/intern/smoke/intern/WAVELET_NOISE.h
|
||||
@@ -43,6 +43,7 @@
|
||||
#ifndef WAVELET_NOISE_H
|
||||
#define WAVELET_NOISE_H
|
||||
|
||||
+#include <string.h>
|
||||
#include <MERSENNETWISTER.h>
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "cotp";
|
||||
version = "1.9.1";
|
||||
version = "1.9.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "replydev";
|
||||
repo = "cotp";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-U5x8szvouoxJ+DZUlrn5wtXt+6vs62tzcWICQW3B21U=";
|
||||
hash = "sha256-5wVIjh16AYwrzjbPgvjsQhihu/vwdQfzU2kZS6eSTWs=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-o9LRXbx77EXXO7rEmpBrx2nommJgG0ikw1YzdeB0Gug=";
|
||||
cargoHash = "sha256-DMswC+Qp6w7Dcp5YYV4EGWUylv/ouG0ukAdCdDnOA/8=";
|
||||
|
||||
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ libxcb ]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ AppKit ];
|
||||
|
||||
@@ -208,7 +208,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
description = "G-code generator for 3D printer";
|
||||
homepage = "https://github.com/prusa3d/PrusaSlicer";
|
||||
license = licenses.agpl3Plus;
|
||||
maintainers = with maintainers; [ moredread tweber tmarkus ];
|
||||
maintainers = with maintainers; [ tweber tmarkus ];
|
||||
platforms = platforms.unix;
|
||||
} // lib.optionalAttrs (stdenv.hostPlatform.isDarwin) {
|
||||
mainProgram = "PrusaSlicer";
|
||||
|
||||
@@ -88,7 +88,7 @@ let
|
||||
inherit description;
|
||||
homepage = "https://github.com/supermerill/SuperSlicer";
|
||||
license = licenses.agpl3Plus;
|
||||
maintainers = with maintainers; [ cab404 moredread tmarkus ];
|
||||
maintainers = with maintainers; [ cab404 tmarkus ];
|
||||
mainProgram = "superslicer";
|
||||
};
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
From 9dd8048e28b65da0b904dfbace482f70ae768fd8 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Date: Tue, 5 Mar 2024 04:12:28 +0100
|
||||
Subject: [PATCH] Bug 1882291. Switch to stdarch_arm_neon_intrinsics feature on
|
||||
rust >=1.78. r=glandium
|
||||
|
||||
We only need this on ARM32 because the ARM64 intrinsics are stable.
|
||||
|
||||
stdarch_arm_neon_intrinsics was split out from stdsimd here:
|
||||
https://github.com/rust-lang/stdarch/pull/1486
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D203039
|
||||
---
|
||||
Cargo.lock | 1 +
|
||||
gfx/qcms/Cargo.toml | 3 +++
|
||||
gfx/qcms/build.rs | 7 +++++++
|
||||
gfx/qcms/src/lib.rs | 6 ++++--
|
||||
4 files changed, 15 insertions(+), 2 deletions(-)
|
||||
create mode 100644 gfx/qcms/build.rs
|
||||
|
||||
diff --git a/Cargo.lock b/Cargo.lock
|
||||
index aba397832e..8f0a879a87 100644
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -4276,6 +4276,7 @@ name = "qcms"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
+ "version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
diff --git a/gfx/qcms/Cargo.toml b/gfx/qcms/Cargo.toml
|
||||
index e976054a7b..f50d6623a1 100644
|
||||
--- a/gfx/qcms/Cargo.toml
|
||||
+++ b/gfx/qcms/Cargo.toml
|
||||
@@ -20,3 +20,6 @@ cmyk = []
|
||||
|
||||
[dependencies]
|
||||
libc = {version = "0.2", optional = true }
|
||||
+
|
||||
+[build-dependencies]
|
||||
+version_check = "0.9"
|
||||
diff --git a/gfx/qcms/build.rs b/gfx/qcms/build.rs
|
||||
new file mode 100644
|
||||
index 0000000000..6810a8828e
|
||||
--- /dev/null
|
||||
+++ b/gfx/qcms/build.rs
|
||||
@@ -0,0 +1,7 @@
|
||||
+extern crate version_check as rustc;
|
||||
+
|
||||
+fn main() {
|
||||
+ if rustc::is_min_version("1.78.0").unwrap_or(false) {
|
||||
+ println!("cargo:rustc-cfg=stdsimd_split");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/gfx/qcms/src/lib.rs b/gfx/qcms/src/lib.rs
|
||||
index c311964ee3..fc496816a8 100644
|
||||
--- a/gfx/qcms/src/lib.rs
|
||||
+++ b/gfx/qcms/src/lib.rs
|
||||
@@ -7,9 +7,11 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
// These are needed for the neon SIMD code and can be removed once the MSRV supports the
|
||||
// instrinsics we use
|
||||
-#![cfg_attr(feature = "neon", feature(stdsimd))]
|
||||
+#![cfg_attr(all(stdsimd_split, target_arch = "arm", feature = "neon"), feature(stdarch_arm_neon_intrinsics))]
|
||||
+#![cfg_attr(all(stdsimd_split, target_arch = "arm", feature = "neon"), feature(stdarch_arm_feature_detection))]
|
||||
+#![cfg_attr(all(not(stdsimd_split), target_arch = "arm", feature = "neon"), feature(stdsimd))]
|
||||
#![cfg_attr(
|
||||
- feature = "neon",
|
||||
+ all(target_arch = "arm", feature = "neon"),
|
||||
feature(arm_target_feature, raw_ref_op)
|
||||
|
||||
)]
|
||||
--
|
||||
2.44.0
|
||||
|
||||
@@ -27,6 +27,12 @@ let
|
||||
|
||||
nativeBuildInputs = [ installShellFiles ];
|
||||
|
||||
ldflags = [
|
||||
"-X github.com/hashicorp/nomad/version.Version=${version}"
|
||||
"-X github.com/hashicorp/nomad/version.VersionPrerelease="
|
||||
"-X github.com/hashicorp/nomad/version.BuildDate=1970-01-01T00:00:00Z"
|
||||
];
|
||||
|
||||
# ui:
|
||||
# Nomad release commits include the compiled version of the UI, but the file
|
||||
# is only included if we build with the ui tag.
|
||||
@@ -89,9 +95,9 @@ rec {
|
||||
|
||||
nomad_1_9 = generic {
|
||||
buildGoModule = buildGo123Module;
|
||||
version = "1.9.0";
|
||||
sha256 = "sha256-MJNPYSH3KsRmGQeOcWw4VvDeFGinfsyGSo4q3OdOZo8=";
|
||||
vendorHash = "sha256-Ss/qwQ14VUu40nXaIgTfNuj95ekTTVrY+zcStFDSCyI=";
|
||||
version = "1.9.2";
|
||||
sha256 = "sha256-HIyRzujAGwhB2anbxidhq5UpWYHkigyyHfxIUwMF5X8=";
|
||||
vendorHash = "sha256-YIOTdD+oRDdEHkBzQCUuKCz7Wbj4mFjrZY0J3Cte400=";
|
||||
license = lib.licenses.bsl11;
|
||||
passthru.tests.nomad = nixosTests.nomad;
|
||||
preCheck = ''
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/Cargo.lock
|
||||
+++ b/Cargo.lock
|
||||
@@ -1535,7 +1535,7 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
|
||||
|
||||
[[package]]
|
||||
name = "tiny"
|
||||
-version = "0.10.0"
|
||||
+version = "0.11.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"dirs",
|
||||
@@ -69,8 +69,8 @@ in rec {
|
||||
thunderbird-esr = thunderbird-128;
|
||||
|
||||
thunderbird-128 = common {
|
||||
version = "128.4.0esr";
|
||||
sha512 = "ad031b3a9b738598358cead23cf8438435016222cd9a474c31892dc1b3db43d2d5d3a10c9639df770dc76eb3c0bc9db8be8beab84828d54ee50fc1e03f0da0a5";
|
||||
version = "128.4.2esr";
|
||||
sha512 = "4e37b77eb4652bc36585656bd3fe5416053f6a1a96ed1ca64c17d8d73031c746cb3832fd275d25f1283d20e18aa3e7b1df6d67864ced21b5f73042a42767cb45";
|
||||
|
||||
updateScript = callPackage ./update.nix {
|
||||
attrPath = "thunderbirdPackages.thunderbird-128";
|
||||
|
||||
@@ -548,7 +548,9 @@ in stdenv.mkDerivation (finalAttrs: {
|
||||
|
||||
buildTargets = [ "build-nocheck" ];
|
||||
|
||||
doCheck = true;
|
||||
# Disable tests for the Qt5 build, as they seem even more flaky
|
||||
# than usual, and we will drop the Qt5 build after 24.11 anyway.
|
||||
doCheck = !(kdeIntegration && qtMajor == "5");
|
||||
|
||||
preCheck = ''
|
||||
export HOME=$(pwd)
|
||||
|
||||
+36
-36
@@ -105,11 +105,11 @@
|
||||
md5name = "89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7-cppunit-1.15.1.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "curl-8.9.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/curl-8.9.0.tar.xz";
|
||||
sha256 = "ff09b2791ca56d25fd5c3f3a4927dce7c8a9dc4182200c487ca889fba1fdd412";
|
||||
name = "curl-8.10.1.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/curl-8.10.1.tar.xz";
|
||||
sha256 = "73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee";
|
||||
md5 = "";
|
||||
md5name = "ff09b2791ca56d25fd5c3f3a4927dce7c8a9dc4182200c487ca889fba1fdd412-curl-8.9.0.tar.xz";
|
||||
md5name = "73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee-curl-8.10.1.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "libe-book-0.1.3.tar.xz";
|
||||
@@ -147,11 +147,11 @@
|
||||
md5name = "b430435a6e8487888b761dc848b7981626eb814884963ffe25eb26a139301e9a-libetonyek-0.1.10.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "expat-2.6.2.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/expat-2.6.2.tar.xz";
|
||||
sha256 = "ee14b4c5d8908b1bec37ad937607eab183d4d9806a08adee472c3c3121d27364";
|
||||
name = "expat-2.6.3.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/expat-2.6.3.tar.xz";
|
||||
sha256 = "274db254a6979bde5aad404763a704956940e465843f2a9bd9ed7af22e2c0efc";
|
||||
md5 = "";
|
||||
md5name = "ee14b4c5d8908b1bec37ad937607eab183d4d9806a08adee472c3c3121d27364-expat-2.6.2.tar.xz";
|
||||
md5name = "274db254a6979bde5aad404763a704956940e465843f2a9bd9ed7af22e2c0efc-expat-2.6.3.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "Firebird-3.0.7.33374-0.tar.bz2";
|
||||
@@ -658,11 +658,11 @@
|
||||
md5name = "bb2dc4898180bea79863d5487e5f9c7c34297414bad54bcd0f0852aee9cfdb87-lxml-5.2.2.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "mariadb-connector-c-3.3.8-src.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.3.8-src.tar.gz";
|
||||
sha256 = "f9f076b4aa9fb22cc94b24f82c80f9ef063805ecd6533a2eb5d5060cf93833e8";
|
||||
name = "mariadb-connector-c-3.3.11-src.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.3.11-src.tar.gz";
|
||||
sha256 = "f7ba02f70aa2ae2b13e9ee5acc78423f6bede38998afb91326a62be46cf5956a";
|
||||
md5 = "";
|
||||
md5name = "f9f076b4aa9fb22cc94b24f82c80f9ef063805ecd6533a2eb5d5060cf93833e8-mariadb-connector-c-3.3.8-src.tar.gz";
|
||||
md5name = "f7ba02f70aa2ae2b13e9ee5acc78423f6bede38998afb91326a62be46cf5956a-mariadb-connector-c-3.3.11-src.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "mdds-2.1.1.tar.xz";
|
||||
@@ -742,11 +742,11 @@
|
||||
md5name = "48969323e94e3be3b03c6a132942dcba7ef8d545f2ad35401709019f696c3c4e-openldap-2.6.8.tgz";
|
||||
}
|
||||
{
|
||||
name = "openssl-3.0.14.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/openssl-3.0.14.tar.gz";
|
||||
sha256 = "eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca";
|
||||
name = "openssl-3.0.15.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/openssl-3.0.15.tar.gz";
|
||||
sha256 = "23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533";
|
||||
md5 = "";
|
||||
md5name = "eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca-openssl-3.0.14.tar.gz";
|
||||
md5name = "23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533-openssl-3.0.15.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "liborcus-0.19.2.tar.xz";
|
||||
@@ -777,25 +777,25 @@
|
||||
md5name = "ea1480efada2fd948bc75366f7c349e1c96d3297d09a3fe62626e38e234a625e-pixman-0.42.2.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "libpng-1.6.43.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/libpng-1.6.43.tar.xz";
|
||||
sha256 = "6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c";
|
||||
name = "libpng-1.6.44.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/libpng-1.6.44.tar.xz";
|
||||
sha256 = "60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e";
|
||||
md5 = "";
|
||||
md5name = "6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c-libpng-1.6.43.tar.xz";
|
||||
md5name = "60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e-libpng-1.6.44.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "tiff-4.6.0t.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/tiff-4.6.0t.tar.xz";
|
||||
sha256 = "d6da35c9986a4ec845eb96258b3693f8df515f7eb4c1e597ceb03e22788f305b";
|
||||
name = "tiff-4.7.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/tiff-4.7.0.tar.xz";
|
||||
sha256 = "273a0a73b1f0bed640afee4a5df0337357ced5b53d3d5d1c405b936501f71017";
|
||||
md5 = "";
|
||||
md5name = "d6da35c9986a4ec845eb96258b3693f8df515f7eb4c1e597ceb03e22788f305b-tiff-4.6.0t.tar.xz";
|
||||
md5name = "273a0a73b1f0bed640afee4a5df0337357ced5b53d3d5d1c405b936501f71017-tiff-4.7.0.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "poppler-24.06.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/poppler-24.06.0.tar.xz";
|
||||
sha256 = "0cdabd495cada11f6ee9e75c793f80daf46367b66c25a63ee8c26d0f9ec40c76";
|
||||
name = "poppler-24.08.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/poppler-24.08.0.tar.xz";
|
||||
sha256 = "97453fbddf0c9a9eafa0ea45ac710d3d49bcf23a62e864585385d3c0b4403174";
|
||||
md5 = "";
|
||||
md5name = "0cdabd495cada11f6ee9e75c793f80daf46367b66c25a63ee8c26d0f9ec40c76-poppler-24.06.0.tar.xz";
|
||||
md5name = "97453fbddf0c9a9eafa0ea45ac710d3d49bcf23a62e864585385d3c0b4403174-poppler-24.08.0.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "poppler-data-0.4.12.tar.gz";
|
||||
@@ -805,18 +805,18 @@
|
||||
md5name = "c835b640a40ce357e1b83666aabd95edffa24ddddd49b8daff63adb851cdab74-poppler-data-0.4.12.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "postgresql-13.15.tar.bz2";
|
||||
url = "https://dev-www.libreoffice.org/src/postgresql-13.15.tar.bz2";
|
||||
sha256 = "42edd415446d33b8c242be76d1ad057531b2264b2e86939339b7075c6e4ec925";
|
||||
name = "postgresql-13.16.tar.bz2";
|
||||
url = "https://dev-www.libreoffice.org/src/postgresql-13.16.tar.bz2";
|
||||
sha256 = "c9cbbb6129f02328204828066bb3785c00a85c8ca8fd329c2a8a53c1f5cd8865";
|
||||
md5 = "";
|
||||
md5name = "42edd415446d33b8c242be76d1ad057531b2264b2e86939339b7075c6e4ec925-postgresql-13.15.tar.bz2";
|
||||
md5name = "c9cbbb6129f02328204828066bb3785c00a85c8ca8fd329c2a8a53c1f5cd8865-postgresql-13.16.tar.bz2";
|
||||
}
|
||||
{
|
||||
name = "Python-3.9.19.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/Python-3.9.19.tar.xz";
|
||||
sha256 = "d4892cd1618f6458cb851208c030df1482779609d0f3939991bd38184f8c679e";
|
||||
name = "Python-3.9.20.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/Python-3.9.20.tar.xz";
|
||||
sha256 = "6b281279efd85294d2d6993e173983a57464c0133956fbbb5536ec9646beaf0c";
|
||||
md5 = "";
|
||||
md5name = "d4892cd1618f6458cb851208c030df1482779609d0f3939991bd38184f8c679e-Python-3.9.19.tar.xz";
|
||||
md5name = "6b281279efd85294d2d6993e173983a57464c0133956fbbb5536ec9646beaf0c-Python-3.9.20.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "libqxp-0.0.2.tar.xz";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchurl, ... }:
|
||||
fetchurl {
|
||||
sha256 = "1vbi2qbap3ccychc0sfn32z46klyzjh0hhk4in0sd7qkl97y6lvn";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.8.0/libreoffice-help-24.8.0.3.tar.xz";
|
||||
sha256 = "1xlfs1380h9axqx37kp9nwq4bwlg08rm136ayzglaz57vx87vxsg";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.8.2/libreoffice-help-24.8.2.1.tar.xz";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchurl, ... }:
|
||||
fetchurl {
|
||||
sha256 = "1hbqgpgih3j9ic1dljxz3mz0rsjf0iyws7qm7g1hb35ns664c4av";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.8.0/libreoffice-24.8.0.3.tar.xz";
|
||||
sha256 = "1ky4ph9g7x9k68px6x4dgfnf5wqbxqabkp75pjhsj521nsp1nc5b";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.8.2/libreoffice-24.8.2.1.tar.xz";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchurl, ... }:
|
||||
fetchurl {
|
||||
sha256 = "0p75xijrmp44kcda33xg5dr06xl1fcxwhxgvlcj396rkn2k0c9sy";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.8.0/libreoffice-translations-24.8.0.3.tar.xz";
|
||||
sha256 = "1yvfcwj9dr2216b9fyi89849jy4lw3jg2yqrx4dm30qdn07jqf3j";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.8.2/libreoffice-translations-24.8.2.1.tar.xz";
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
"24.8.0.3"
|
||||
"24.8.2.1"
|
||||
|
||||
+44
-44
@@ -105,11 +105,11 @@
|
||||
md5name = "89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7-cppunit-1.15.1.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "curl-8.7.1.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/curl-8.7.1.tar.xz";
|
||||
sha256 = "6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd";
|
||||
name = "curl-8.10.1.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/curl-8.10.1.tar.xz";
|
||||
sha256 = "73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee";
|
||||
md5 = "";
|
||||
md5name = "6fea2aac6a4610fbd0400afb0bcddbe7258a64c63f1f68e5855ebc0c659710cd-curl-8.7.1.tar.xz";
|
||||
md5name = "73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee-curl-8.10.1.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "libe-book-0.1.3.tar.xz";
|
||||
@@ -147,11 +147,11 @@
|
||||
md5name = "b430435a6e8487888b761dc848b7981626eb814884963ffe25eb26a139301e9a-libetonyek-0.1.10.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "expat-2.6.2.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/expat-2.6.2.tar.xz";
|
||||
sha256 = "ee14b4c5d8908b1bec37ad937607eab183d4d9806a08adee472c3c3121d27364";
|
||||
name = "expat-2.6.3.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/expat-2.6.3.tar.xz";
|
||||
sha256 = "274db254a6979bde5aad404763a704956940e465843f2a9bd9ed7af22e2c0efc";
|
||||
md5 = "";
|
||||
md5name = "ee14b4c5d8908b1bec37ad937607eab183d4d9806a08adee472c3c3121d27364-expat-2.6.2.tar.xz";
|
||||
md5name = "274db254a6979bde5aad404763a704956940e465843f2a9bd9ed7af22e2c0efc-expat-2.6.3.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "Firebird-3.0.7.33374-0.tar.bz2";
|
||||
@@ -630,11 +630,11 @@
|
||||
md5name = "4003c56b3d356d21b1db7775318540fad6bfedaf5f117e8f7c010811219be3cf-xmlsec1-1.3.2.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "libxml2-2.12.8.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/libxml2-2.12.8.tar.xz";
|
||||
sha256 = "43ad877b018bc63deb2468d71f95219c2fac196876ef36d1bee51d226173ec93";
|
||||
name = "libxml2-2.12.9.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/libxml2-2.12.9.tar.xz";
|
||||
sha256 = "59912db536ab56a3996489ea0299768c7bcffe57169f0235e7f962a91f483590";
|
||||
md5 = "";
|
||||
md5name = "43ad877b018bc63deb2468d71f95219c2fac196876ef36d1bee51d226173ec93-libxml2-2.12.8.tar.xz";
|
||||
md5name = "59912db536ab56a3996489ea0299768c7bcffe57169f0235e7f962a91f483590-libxml2-2.12.9.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "libxslt-1.1.39.tar.xz";
|
||||
@@ -658,11 +658,11 @@
|
||||
md5name = "2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67-lxml-4.9.2.tgz";
|
||||
}
|
||||
{
|
||||
name = "mariadb-connector-c-3.3.8-src.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.3.8-src.tar.gz";
|
||||
sha256 = "f9f076b4aa9fb22cc94b24f82c80f9ef063805ecd6533a2eb5d5060cf93833e8";
|
||||
name = "mariadb-connector-c-3.3.11-src.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.3.11-src.tar.gz";
|
||||
sha256 = "f7ba02f70aa2ae2b13e9ee5acc78423f6bede38998afb91326a62be46cf5956a";
|
||||
md5 = "";
|
||||
md5name = "f9f076b4aa9fb22cc94b24f82c80f9ef063805ecd6533a2eb5d5060cf93833e8-mariadb-connector-c-3.3.8-src.tar.gz";
|
||||
md5name = "f7ba02f70aa2ae2b13e9ee5acc78423f6bede38998afb91326a62be46cf5956a-mariadb-connector-c-3.3.11-src.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "mdds-2.1.1.tar.xz";
|
||||
@@ -700,11 +700,11 @@
|
||||
md5name = "19279f70707bbe5ffa619f2dc319f888cec0c4a8d339dc0a21330517bd6f521d-mythes-1.2.5.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "nss-3.99-with-nspr-4.35.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/nss-3.99-with-nspr-4.35.tar.gz";
|
||||
sha256 = "5f29fea64b3234b33a615b6df40469e239a4168ac0909106bd00e6490b274c31";
|
||||
name = "nss-3.101.2-with-nspr-4.35.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/nss-3.101.2-with-nspr-4.35.tar.gz";
|
||||
sha256 = "ff602c1fa86a4f841b27109918dfff60f41582e1caf6dbd651cfa72bdc8a64aa";
|
||||
md5 = "";
|
||||
md5name = "5f29fea64b3234b33a615b6df40469e239a4168ac0909106bd00e6490b274c31-nss-3.99-with-nspr-4.35.tar.gz";
|
||||
md5name = "ff602c1fa86a4f841b27109918dfff60f41582e1caf6dbd651cfa72bdc8a64aa-nss-3.101.2-with-nspr-4.35.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "libodfgen-0.1.8.tar.xz";
|
||||
@@ -742,11 +742,11 @@
|
||||
md5name = "cd775f625c944ed78a3da18a03b03b08eea73c8aabc97b41bb336e9a10954930-openldap-2.6.7.tgz";
|
||||
}
|
||||
{
|
||||
name = "openssl-3.0.14.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/openssl-3.0.14.tar.gz";
|
||||
sha256 = "eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca";
|
||||
name = "openssl-3.0.15.tar.gz";
|
||||
url = "https://dev-www.libreoffice.org/src/openssl-3.0.15.tar.gz";
|
||||
sha256 = "23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533";
|
||||
md5 = "";
|
||||
md5name = "eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca-openssl-3.0.14.tar.gz";
|
||||
md5name = "23c666d0edf20f14249b3d8f0368acaee9ab585b09e1de82107c66e1f3ec9533-openssl-3.0.15.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "liborcus-0.19.2.tar.xz";
|
||||
@@ -777,25 +777,25 @@
|
||||
md5name = "ea1480efada2fd948bc75366f7c349e1c96d3297d09a3fe62626e38e234a625e-pixman-0.42.2.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "libpng-1.6.43.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/libpng-1.6.43.tar.xz";
|
||||
sha256 = "6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c";
|
||||
name = "libpng-1.6.44.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/libpng-1.6.44.tar.xz";
|
||||
sha256 = "60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e";
|
||||
md5 = "";
|
||||
md5name = "6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c-libpng-1.6.43.tar.xz";
|
||||
md5name = "60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e-libpng-1.6.44.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "tiff-4.6.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/tiff-4.6.0.tar.xz";
|
||||
sha256 = "e178649607d1e22b51cf361dd20a3753f244f022eefab1f2f218fc62ebaf87d2";
|
||||
name = "tiff-4.7.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/tiff-4.7.0.tar.xz";
|
||||
sha256 = "273a0a73b1f0bed640afee4a5df0337357ced5b53d3d5d1c405b936501f71017";
|
||||
md5 = "";
|
||||
md5name = "e178649607d1e22b51cf361dd20a3753f244f022eefab1f2f218fc62ebaf87d2-tiff-4.6.0.tar.xz";
|
||||
md5name = "273a0a73b1f0bed640afee4a5df0337357ced5b53d3d5d1c405b936501f71017-tiff-4.7.0.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "poppler-23.09.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/poppler-23.09.0.tar.xz";
|
||||
sha256 = "80d1d44dd8bdf4ac1a47d56c5065075eb9991790974b1ed7d14b972acde88e55";
|
||||
name = "poppler-24.08.0.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/poppler-24.08.0.tar.xz";
|
||||
sha256 = "97453fbddf0c9a9eafa0ea45ac710d3d49bcf23a62e864585385d3c0b4403174";
|
||||
md5 = "";
|
||||
md5name = "80d1d44dd8bdf4ac1a47d56c5065075eb9991790974b1ed7d14b972acde88e55-poppler-23.09.0.tar.xz";
|
||||
md5name = "97453fbddf0c9a9eafa0ea45ac710d3d49bcf23a62e864585385d3c0b4403174-poppler-24.08.0.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "poppler-data-0.4.12.tar.gz";
|
||||
@@ -805,18 +805,18 @@
|
||||
md5name = "c835b640a40ce357e1b83666aabd95edffa24ddddd49b8daff63adb851cdab74-poppler-data-0.4.12.tar.gz";
|
||||
}
|
||||
{
|
||||
name = "postgresql-13.14.tar.bz2";
|
||||
url = "https://dev-www.libreoffice.org/src/postgresql-13.14.tar.bz2";
|
||||
sha256 = "b8df078551898960bd500dc5d38a177e9905376df81fe7f2b660a1407fa6a5ed";
|
||||
name = "postgresql-13.16.tar.bz2";
|
||||
url = "https://dev-www.libreoffice.org/src/postgresql-13.16.tar.bz2";
|
||||
sha256 = "c9cbbb6129f02328204828066bb3785c00a85c8ca8fd329c2a8a53c1f5cd8865";
|
||||
md5 = "";
|
||||
md5name = "b8df078551898960bd500dc5d38a177e9905376df81fe7f2b660a1407fa6a5ed-postgresql-13.14.tar.bz2";
|
||||
md5name = "c9cbbb6129f02328204828066bb3785c00a85c8ca8fd329c2a8a53c1f5cd8865-postgresql-13.16.tar.bz2";
|
||||
}
|
||||
{
|
||||
name = "Python-3.8.19.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/Python-3.8.19.tar.xz";
|
||||
sha256 = "d2807ac69f69b84fd46a0b93bbd02a4fa48d3e70f4b2835ff0f72a2885040076";
|
||||
name = "Python-3.8.20.tar.xz";
|
||||
url = "https://dev-www.libreoffice.org/src/Python-3.8.20.tar.xz";
|
||||
sha256 = "6fb89a7124201c61125c0ab4cf7f6894df339a40c02833bfd28ab4d7691fafb4";
|
||||
md5 = "";
|
||||
md5name = "d2807ac69f69b84fd46a0b93bbd02a4fa48d3e70f4b2835ff0f72a2885040076-Python-3.8.19.tar.xz";
|
||||
md5name = "6fb89a7124201c61125c0ab4cf7f6894df339a40c02833bfd28ab4d7691fafb4-Python-3.8.20.tar.xz";
|
||||
}
|
||||
{
|
||||
name = "libqxp-0.0.2.tar.xz";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchurl, ... }:
|
||||
fetchurl {
|
||||
sha256 = "090pi8dnj5izpvng94hgmjid14n7xvy3rlqqvang3pqdn35xnpsl";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.2.5/libreoffice-help-24.2.5.2.tar.xz";
|
||||
sha256 = "0g31xfmmxjd5c1xg203gflzvq2d2jlgfi9gmg1wxl18l9gjk4hds";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.2.7/libreoffice-help-24.2.7.2.tar.xz";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchurl, ... }:
|
||||
fetchurl {
|
||||
sha256 = "03halzc9w4z8pfs8krpswp2qzrqq9rhnmms8v8ny88am87vy85lw";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.2.5/libreoffice-24.2.5.2.tar.xz";
|
||||
sha256 = "1r8h8g5fs7z0fvf7f6fq44rw90q4v2z23kkwzdh1s8gaxlnb3sgm";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.2.7/libreoffice-24.2.7.2.tar.xz";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ fetchurl, ... }:
|
||||
fetchurl {
|
||||
sha256 = "0fri41y59zhm8lq0kh6hvf5rpdjdqx0lg1sl40mhh1d6lf1izc1w";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.2.5/libreoffice-translations-24.2.5.2.tar.xz";
|
||||
sha256 = "0g2wp8s3gxhy3l685jv3h63gzaljfclgcah437922dl60kpm9yjq";
|
||||
url = "https://download.documentfoundation.org/libreoffice/src/24.2.7/libreoffice-translations-24.2.7.2.tar.xz";
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
"24.2.5.2"
|
||||
"24.2.7.2"
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
let
|
||||
pname = "qownnotes";
|
||||
appname = "QOwnNotes";
|
||||
version = "24.9.8";
|
||||
version = "24.11.1";
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
inherit pname version;
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/pbek/QOwnNotes/releases/download/v${version}/qownnotes-${version}.tar.xz";
|
||||
hash = "sha256-G5PLz1GzjfPM5tj3rtwJt4hR3v+oSq2bVr/llTSFbNk=";
|
||||
hash = "sha256-OQ6p5VCdQZ2P1UFiCPtK+HogIgaoBQKdKO1tEDCA/5I=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
diff --git c/src/cgraphicsscene.cpp i/src/cgraphicsscene.cpp
|
||||
index ac2929a..c399706 100644
|
||||
--- c/src/cgraphicsscene.cpp
|
||||
+++ i/src/cgraphicsscene.cpp
|
||||
@@ -1436,7 +1436,7 @@ namespace Caneda
|
||||
QPointF newPos = m_currentWiringWire->mapFromScene(pos);
|
||||
QPointF refPos = m_currentWiringWire->port1()->pos();
|
||||
|
||||
- if( abs(refPos.x()-newPos.x()) > abs(refPos.y()-newPos.y()) ) {
|
||||
+ if( (refPos.x()-newPos.x()) > (refPos.y()-newPos.y()) ) {
|
||||
m_currentWiringWire->movePort2(QPointF(newPos.x(), refPos.y()));
|
||||
}
|
||||
else {
|
||||
@@ -1,6 +1,20 @@
|
||||
{ lib, stdenv, fetchurl, libxml2, freetype, libGLU, libGL, glew
|
||||
, qtbase, wrapQtAppsHook, autoPatchelfHook, python3
|
||||
, cmake, libjpeg, llvmPackages }:
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
libxml2,
|
||||
freetype,
|
||||
libGLU,
|
||||
libGL,
|
||||
glew,
|
||||
qtbase,
|
||||
wrapQtAppsHook,
|
||||
autoPatchelfHook,
|
||||
python3,
|
||||
cmake,
|
||||
libjpeg,
|
||||
llvmPackages,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "tulip";
|
||||
@@ -11,21 +25,37 @@ stdenv.mkDerivation rec {
|
||||
hash = "sha256-7z21WkPi1v2AGishDmXZPAedMjgXPRnpUiHTzEnc5LY=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake wrapQtAppsHook ]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
wrapQtAppsHook
|
||||
] ++ lib.optionals stdenv.hostPlatform.isLinux [ autoPatchelfHook ];
|
||||
|
||||
buildInputs = [ libxml2 freetype glew libjpeg qtbase python3 ]
|
||||
buildInputs =
|
||||
[
|
||||
libxml2
|
||||
freetype
|
||||
glew
|
||||
libjpeg
|
||||
qtbase
|
||||
python3
|
||||
]
|
||||
++ lib.optionals stdenv.hostPlatform.isDarwin [ llvmPackages.openmp ]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [ libGLU libGL ];
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
libGLU
|
||||
libGL
|
||||
];
|
||||
|
||||
qtWrapperArgs = [ ''--prefix PATH : ${lib.makeBinPath [ python3 ]}'' ];
|
||||
|
||||
env.NIX_CFLAGS_COMPILE = lib.optionalString stdenv.hostPlatform.isDarwin (toString [
|
||||
# fatal error: 'Python.h' file not found
|
||||
"-I${python3}/include/${python3.libPrefix}"
|
||||
# error: format string is not a string literal (potentially insecure)
|
||||
"-Wno-format-security"
|
||||
]);
|
||||
env.NIX_CFLAGS_COMPILE =
|
||||
# error: invalid conversion from 'unsigned char*' to 'char*'
|
||||
"-fpermissive "
|
||||
+ (lib.optionalString stdenv.hostPlatform.isDarwin (toString [
|
||||
# fatal error: 'Python.h' file not found
|
||||
"-I${python3}/include/${python3.libPrefix}"
|
||||
# error: format string is not a string literal (potentially insecure)
|
||||
"-Wno-format-security"
|
||||
]));
|
||||
|
||||
# FIXME: "make check" needs Docbook's DTD 4.4, among other things.
|
||||
doCheck = false;
|
||||
|
||||
@@ -97,6 +97,7 @@ python3.pkgs.buildPythonApplication rec {
|
||||
"test_misc_nonpredicatble_generate"
|
||||
"test_disk_dir_searchable" # does something strange with permissions
|
||||
"testCLI0001virt_install_many_devices" # expects /var to exist
|
||||
"testCLI0263virt_xml" # depends on a specific libvirt version
|
||||
];
|
||||
|
||||
preCheck = ''
|
||||
|
||||
@@ -87,7 +87,7 @@ let
|
||||
destination = "/etc/profile";
|
||||
text = ''
|
||||
export PS1='${name}-fhsenv:\u@\h:\w\$ '
|
||||
export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive'
|
||||
export LOCALE_ARCHIVE="''${LOCALE_ARCHIVE:-/usr/lib/locale/locale-archive}"
|
||||
export PATH="/run/wrappers/bin:/usr/bin:/usr/sbin:$PATH"
|
||||
export TZDIR='/etc/zoneinfo'
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user