Merge branch 'staging-next' into staging
Conflicts: pkgs/development/libraries/log4cplus/default.nix
This commit is contained in:
commit
07a8ae0c5a
6
.github/CODEOWNERS
vendored
6
.github/CODEOWNERS
vendored
@ -39,7 +39,7 @@
|
||||
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
|
||||
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
|
||||
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
|
||||
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
|
||||
/pkgs/stdenv/generic @Ericson2314 @matthewbauer @cab404
|
||||
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
|
||||
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
|
||||
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
|
||||
@ -219,9 +219,9 @@
|
||||
# Podman, CRI-O modules and related
|
||||
/nixos/modules/virtualisation/containers.nix @NixOS/podman @zowoq @adisbladis
|
||||
/nixos/modules/virtualisation/cri-o.nix @NixOS/podman @zowoq @adisbladis
|
||||
/nixos/modules/virtualisation/podman.nix @NixOS/podman @zowoq @adisbladis
|
||||
/nixos/modules/virtualisation/podman @NixOS/podman @zowoq @adisbladis
|
||||
/nixos/tests/cri-o.nix @NixOS/podman @zowoq @adisbladis
|
||||
/nixos/tests/podman.nix @NixOS/podman @zowoq @adisbladis
|
||||
/nixos/tests/podman @NixOS/podman @zowoq @adisbladis
|
||||
|
||||
# Docker tools
|
||||
/pkgs/build-support/docker @roberth @utdemir
|
||||
|
@ -1633,3 +1633,25 @@ would be:
|
||||
```ShellSession
|
||||
$ maintainers/scripts/update-python-libraries --target minor --commit --use-pkgs-prefix pkgs/development/python-modules/**/default.nix
|
||||
```
|
||||
|
||||
## CPython Update Schedule
|
||||
|
||||
With [PEP 602](https://www.python.org/dev/peps/pep-0602/), CPython now
|
||||
follows a yearly release cadence. In nixpkgs, all supported interpreters
|
||||
are made available, but only the most recent two
|
||||
interpreters package sets are built; this is a compromise between being
|
||||
the latest interpreter, and what the majority of the Python packages support.
|
||||
|
||||
New CPython interpreters are released in October. Generally, it takes some
|
||||
time for the majority of active Python projects to support the latest stable
|
||||
interpreter. To help ease the migration for Nixpkgs users
|
||||
between Python interpreters the schedule below will be used:
|
||||
|
||||
| When | Event |
|
||||
| --- | --- |
|
||||
| After YY.11 Release | Bump CPython package set window. The latest and previous latest stable should now be built. |
|
||||
| After YY.05 Release | Bump default CPython interpreter to latest stable. |
|
||||
|
||||
In practice, this means that the Python community will have had a stable interpreter
|
||||
for ~2 months before attempting to update the package set. And this will
|
||||
allow for ~7 months for Python applications to support the latest interpreter.
|
||||
|
@ -201,6 +201,19 @@ $ nix-shell --run 'ruby -rpg -e "puts PG.library_version"'
|
||||
|
||||
Of course for this use-case one could also use overlays since the configuration for `pg` depends on the `postgresql` alias, but for demonstration purposes this has to suffice.
|
||||
|
||||
### Platform-specific gems
|
||||
|
||||
Right now, bundix has some issues with pre-built, platform-specific gems: [bundix PR #68](https://github.com/nix-community/bundix/pull/68).
|
||||
Until this is solved, you can tell bundler to not use platform-specific gems and instead build them from source each time:
|
||||
- globally (will be set in `~/.config/.bundle/config`):
|
||||
```shell
|
||||
$ bundle config set force_ruby_platform true
|
||||
```
|
||||
- locally (will be set in `<project-root>/.bundle/config`):
|
||||
```shell
|
||||
$ bundle config set --local force_ruby_platform true
|
||||
```
|
||||
|
||||
### Adding a gem to the default gemset {#adding-a-gem-to-the-default-gemset}
|
||||
|
||||
Now that you know how to get a working Ruby environment with Nix, it's time to go forward and start actually developing with Ruby. We will first have a look at how Ruby gems are packaged on Nix. Then, we will look at how you can use development mode with your code.
|
||||
|
@ -796,7 +796,7 @@ The standard environment provides a number of useful functions.
|
||||
|
||||
### `makeWrapper` \<executable\> \<wrapperfile\> \<args\> {#fun-makeWrapper}
|
||||
|
||||
Constructs a wrapper for a program with various possible arguments. For example:
|
||||
Constructs a wrapper for a program with various possible arguments. It is defined as part of 2 setup-hooks named `makeWrapper` and `makeBinaryWrapper` that implement the same bash functions. Hence, to use it you have to add `makeWrapper` to your `nativeBuildInputs`. Here's an example usage:
|
||||
|
||||
```bash
|
||||
# adds `FOOBAR=baz` to `$out/bin/foo`’s environment
|
||||
@ -808,9 +808,11 @@ makeWrapper $out/bin/foo $wrapperfile --set FOOBAR baz
|
||||
makeWrapper $out/bin/foo $wrapperfile --prefix PATH : ${lib.makeBinPath [ hello git ]}
|
||||
```
|
||||
|
||||
There’s many more kinds of arguments, they are documented in `nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh`.
|
||||
There’s many more kinds of arguments, they are documented in `nixpkgs/pkgs/build-support/setup-hooks/make-wrapper.sh` for the `makeWrapper` implementation and in `nixpkgs/pkgs/build-support/setup-hooks/make-binary-wrapper.sh` for the `makeBinaryWrapper` implementation.
|
||||
|
||||
`wrapProgram` is a convenience function you probably want to use most of the time.
|
||||
`wrapProgram` is a convenience function you probably want to use most of the time, implemented by both `makeWrapper` and `makeBinaryWrapper`.
|
||||
|
||||
Using the `makeBinaryWrapper` implementation is usually preferred, as it creates a tiny _compiled_ wrapper executable, that can be used as a shebang interpreter. This is needed mostly on Darwin, where shebangs cannot point to scripts, [due to a limitation with the `execve`-syscall](https://stackoverflow.com/questions/67100831/macos-shebang-with-absolute-path-not-working). Compiled wrappers generated by `makeBinaryWrapper` can be inspected with `less <path-to-wrapper>` - by scrolling past the binary data you should be able to see the shell command that generated the executable and there see the environment variables that were injected into the wrapper.
|
||||
|
||||
### `substitute` \<infile\> \<outfile\> \<subs\> {#fun-substitute}
|
||||
|
||||
@ -885,9 +887,9 @@ someVar=$(stripHash $name)
|
||||
|
||||
### `wrapProgram` \<executable\> \<makeWrapperArgs\> {#fun-wrapProgram}
|
||||
|
||||
Convenience function for `makeWrapper` that automatically creates a sane wrapper file. It takes all the same arguments as `makeWrapper`, except for `--argv0`.
|
||||
Convenience function for `makeWrapper` that replaces `<\executable\>` with a wrapper that executes the original program. It takes all the same arguments as `makeWrapper`, except for `--inherit-argv0` (used by the `makeBinaryWrapper` implementation) and `--argv0` (used by both `makeWrapper` and `makeBinaryWrapper` wrapper implementations).
|
||||
|
||||
It cannot be applied multiple times, since it will overwrite the wrapper file.
|
||||
If you will apply it multiple times, it will overwrite the wrapper file and you will end up with double wrapping, which should be avoided.
|
||||
|
||||
## Package setup hooks {#ssec-setup-hooks}
|
||||
|
||||
|
@ -39,8 +39,8 @@ let
|
||||
"riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd"
|
||||
|
||||
# none
|
||||
"aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none"
|
||||
"msp430-none" "or1k-none" "m68k-none" "powerpc-none"
|
||||
"aarch64_be-none" "aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none"
|
||||
"msp430-none" "or1k-none" "m68k-none" "powerpc-none" "powerpcle-none"
|
||||
"riscv32-none" "riscv64-none" "s390-none" "s390x-none" "vc4-none"
|
||||
"x86_64-none"
|
||||
|
||||
|
@ -290,6 +290,7 @@ rec {
|
||||
libc = "nblibc";
|
||||
};
|
||||
|
||||
# this is broken and never worked fully
|
||||
x86_64-netbsd-llvm = {
|
||||
config = "x86_64-unknown-netbsd";
|
||||
libc = "nblibc";
|
||||
|
@ -1414,6 +1414,12 @@
|
||||
githubId = 251106;
|
||||
name = "Daniel Bergey";
|
||||
};
|
||||
bergkvist = {
|
||||
email = "tobias@bergkv.ist";
|
||||
github = "bergkvist";
|
||||
githubId = 410028;
|
||||
name = "Tobias Bergkvist";
|
||||
};
|
||||
betaboon = {
|
||||
email = "betaboon@0x80.ninja";
|
||||
github = "betaboon";
|
||||
@ -3689,6 +3695,7 @@
|
||||
};
|
||||
evils = {
|
||||
email = "evils.devils@protonmail.com";
|
||||
matrix = "@evils:nixos.dev";
|
||||
github = "evils";
|
||||
githubId = 30512529;
|
||||
name = "Evils";
|
||||
@ -13389,4 +13396,10 @@
|
||||
github = "vdot0x23";
|
||||
githubId = 40716069;
|
||||
};
|
||||
jpagex = {
|
||||
name = "Jérémy Pagé";
|
||||
email = "contact@jeremypage.me";
|
||||
github = "jpagex";
|
||||
githubId = 635768;
|
||||
};
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ def check_results(
|
||||
sys.exit(1)
|
||||
|
||||
def parse_plugin_line(line: str) -> PluginDesc:
|
||||
branch = "master"
|
||||
branch = "HEAD"
|
||||
alias = None
|
||||
name, repo = line.split("/")
|
||||
if " as " in repo:
|
||||
|
@ -259,4 +259,11 @@ with lib.maintainers; {
|
||||
];
|
||||
scope = "coqui-ai TTS (formerly Mozilla TTS) and leaf packages";
|
||||
};
|
||||
|
||||
xfce = {
|
||||
members = [
|
||||
romildo
|
||||
];
|
||||
scope = "Maintain Xfce desktop environment and related packages.";
|
||||
};
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ let
|
||||
in rec {
|
||||
inherit generatedSources;
|
||||
|
||||
inherit (optionsDoc) optionsJSON optionsXML optionsDocBook;
|
||||
inherit (optionsDoc) optionsJSON optionsDocBook;
|
||||
|
||||
# Generate the NixOS manual.
|
||||
manualHTML = runCommand "nixos-manual-html"
|
||||
|
@ -53,12 +53,12 @@ let
|
||||
};
|
||||
|
||||
withWarnings = x:
|
||||
lib.warnIf (evalConfigArgs?args) "The extraArgs argument to eval-config.nix is deprecated. Please set config._module.args instead."
|
||||
lib.warnIf (evalConfigArgs?extraArgs) "The extraArgs argument to eval-config.nix is deprecated. Please set config._module.args instead."
|
||||
lib.warnIf (evalConfigArgs?check) "The check argument to eval-config.nix is deprecated. Please set config._module.check instead."
|
||||
x;
|
||||
|
||||
legacyModules =
|
||||
lib.optional (evalConfigArgs?args) {
|
||||
lib.optional (evalConfigArgs?extraArgs) {
|
||||
config = {
|
||||
_module.args = extraArgs;
|
||||
};
|
||||
|
@ -24,18 +24,25 @@
|
||||
}:
|
||||
|
||||
let
|
||||
# Replace functions by the string <function>
|
||||
substFunction = x:
|
||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||
else if builtins.isList x then map substFunction x
|
||||
# Make a value safe for JSON. Functions are replaced by the string "<function>",
|
||||
# derivations are replaced with an attrset
|
||||
# { _type = "derivation"; name = <name of that derivation>; }.
|
||||
# We need to handle derivations specially because consumers want to know about them,
|
||||
# but we can't easily use the type,name subset of keys (since type is often used as
|
||||
# a module option and might cause confusion). Use _type,name instead to the same
|
||||
# effect, since _type is already used by the module system.
|
||||
substSpecial = x:
|
||||
if lib.isDerivation x then { _type = "derivation"; name = x.name; }
|
||||
else if builtins.isAttrs x then lib.mapAttrs (name: substSpecial) x
|
||||
else if builtins.isList x then map substSpecial x
|
||||
else if lib.isFunction x then "<function>"
|
||||
else x;
|
||||
|
||||
optionsListDesc = lib.flip map optionsListVisible
|
||||
optionsList = lib.flip map optionsListVisible
|
||||
(opt: transformOptions opt
|
||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
||||
// lib.optionalAttrs (opt ? example) { example = substSpecial opt.example; }
|
||||
// lib.optionalAttrs (opt ? default) { default = substSpecial opt.default; }
|
||||
// lib.optionalAttrs (opt ? type) { type = substSpecial opt.type; }
|
||||
// lib.optionalAttrs (opt ? relatedPackages && opt.relatedPackages != []) { relatedPackages = genRelatedPackages opt.relatedPackages opt.name; }
|
||||
);
|
||||
|
||||
@ -69,96 +76,25 @@ let
|
||||
+ "</listitem>";
|
||||
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
|
||||
|
||||
# Custom "less" that pushes up all the things ending in ".enable*"
|
||||
# and ".package*"
|
||||
optionLess = a: b:
|
||||
let
|
||||
ise = lib.hasPrefix "enable";
|
||||
isp = lib.hasPrefix "package";
|
||||
cmp = lib.splitByAndCompare ise lib.compare
|
||||
(lib.splitByAndCompare isp lib.compare lib.compare);
|
||||
in lib.compareLists cmp a.loc b.loc < 0;
|
||||
|
||||
# Remove invisible and internal options.
|
||||
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
||||
|
||||
# Customly sort option list for the man page.
|
||||
# Always ensure that the sort order matches sortXML.py!
|
||||
optionsList = lib.sort optionLess optionsListDesc;
|
||||
|
||||
# Convert the list of options into an XML file.
|
||||
# This file is *not* sorted sorted to save on eval time, since the docbook XML
|
||||
# and the manpage depend on it and thus we evaluate this on every system rebuild.
|
||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsListDesc);
|
||||
|
||||
optionsNix = builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList);
|
||||
|
||||
# TODO: declarations: link to github
|
||||
singleAsciiDoc = name: value: ''
|
||||
== ${name}
|
||||
|
||||
${value.description}
|
||||
|
||||
[discrete]
|
||||
=== details
|
||||
|
||||
Type:: ${value.type}
|
||||
${ if lib.hasAttr "default" value
|
||||
then ''
|
||||
Default::
|
||||
+
|
||||
----
|
||||
${builtins.toJSON value.default}
|
||||
----
|
||||
''
|
||||
else "No Default:: {blank}"
|
||||
}
|
||||
${ if value.readOnly
|
||||
then "Read Only:: {blank}"
|
||||
else ""
|
||||
}
|
||||
${ if lib.hasAttr "example" value
|
||||
then ''
|
||||
Example::
|
||||
+
|
||||
----
|
||||
${builtins.toJSON value.example}
|
||||
----
|
||||
''
|
||||
else "No Example:: {blank}"
|
||||
}
|
||||
'';
|
||||
|
||||
singleMDDoc = name: value: ''
|
||||
## ${lib.escape [ "<" ">" ] name}
|
||||
${value.description}
|
||||
|
||||
${lib.optionalString (value ? type) ''
|
||||
*_Type_*:
|
||||
${value.type}
|
||||
''}
|
||||
|
||||
${lib.optionalString (value ? default) ''
|
||||
*_Default_*
|
||||
```
|
||||
${builtins.toJSON value.default}
|
||||
```
|
||||
''}
|
||||
|
||||
${lib.optionalString (value ? example) ''
|
||||
*_Example_*
|
||||
```
|
||||
${builtins.toJSON value.example}
|
||||
```
|
||||
''}
|
||||
'';
|
||||
|
||||
in {
|
||||
in rec {
|
||||
inherit optionsNix;
|
||||
|
||||
optionsAsciiDoc = lib.concatStringsSep "\n" (lib.mapAttrsToList singleAsciiDoc optionsNix);
|
||||
optionsAsciiDoc = pkgs.runCommand "options.adoc" {} ''
|
||||
${pkgs.python3Minimal}/bin/python ${./generateAsciiDoc.py} \
|
||||
< ${optionsJSON}/share/doc/nixos/options.json \
|
||||
> $out
|
||||
'';
|
||||
|
||||
optionsMDDoc = lib.concatStringsSep "\n" (lib.mapAttrsToList singleMDDoc optionsNix);
|
||||
optionsCommonMark = pkgs.runCommand "options.md" {} ''
|
||||
${pkgs.python3Minimal}/bin/python ${./generateCommonMark.py} \
|
||||
< ${optionsJSON}/share/doc/nixos/options.json \
|
||||
> $out
|
||||
'';
|
||||
|
||||
optionsJSON = pkgs.runCommand "options.json"
|
||||
{ meta.description = "List of NixOS options in JSON format";
|
||||
@ -176,7 +112,18 @@ in {
|
||||
mkdir -p $out/nix-support
|
||||
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
|
||||
echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products
|
||||
''; # */
|
||||
'';
|
||||
|
||||
# Convert options.json into an XML file.
|
||||
# The actual generation of the xml file is done in nix purely for the convenience
|
||||
# of not having to generate the xml some other way
|
||||
optionsXML = pkgs.runCommand "options.xml" {} ''
|
||||
${pkgs.nix}/bin/nix-instantiate \
|
||||
--store dummy:// \
|
||||
--eval --xml --strict ${./optionsJSONtoXML.nix} \
|
||||
--argstr file ${optionsJSON}/share/doc/nixos/options.json \
|
||||
> "$out"
|
||||
'';
|
||||
|
||||
optionsDocBook = pkgs.runCommand "options-docbook.xml" {} ''
|
||||
optionsXML=${optionsXML}
|
||||
|
37
nixos/lib/make-options-doc/generateAsciiDoc.py
Normal file
37
nixos/lib/make-options-doc/generateAsciiDoc.py
Normal file
@ -0,0 +1,37 @@
|
||||
import json
|
||||
import sys
|
||||
|
||||
options = json.load(sys.stdin)
|
||||
# TODO: declarations: link to github
|
||||
for (name, value) in options.items():
|
||||
print(f'== {name}')
|
||||
print()
|
||||
print(value['description'])
|
||||
print()
|
||||
print('[discrete]')
|
||||
print('=== details')
|
||||
print()
|
||||
print(f'Type:: {value["type"]}')
|
||||
if 'default' in value:
|
||||
print('Default::')
|
||||
print('+')
|
||||
print('----')
|
||||
print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':')))
|
||||
print('----')
|
||||
print()
|
||||
else:
|
||||
print('No Default:: {blank}')
|
||||
if value['readOnly']:
|
||||
print('Read Only:: {blank}')
|
||||
else:
|
||||
print()
|
||||
if 'example' in value:
|
||||
print('Example::')
|
||||
print('+')
|
||||
print('----')
|
||||
print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':')))
|
||||
print('----')
|
||||
print()
|
||||
else:
|
||||
print('No Example:: {blank}')
|
||||
print()
|
27
nixos/lib/make-options-doc/generateCommonMark.py
Normal file
27
nixos/lib/make-options-doc/generateCommonMark.py
Normal file
@ -0,0 +1,27 @@
|
||||
import json
|
||||
import sys
|
||||
|
||||
options = json.load(sys.stdin)
|
||||
for (name, value) in options.items():
|
||||
print('##', name.replace('<', '\\<').replace('>', '\\>'))
|
||||
print(value['description'])
|
||||
print()
|
||||
if 'type' in value:
|
||||
print('*_Type_*:')
|
||||
print(value['type'])
|
||||
print()
|
||||
print()
|
||||
if 'default' in value:
|
||||
print('*_Default_*')
|
||||
print('```')
|
||||
print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':')))
|
||||
print('```')
|
||||
print()
|
||||
print()
|
||||
if 'example' in value:
|
||||
print('*_Example_*')
|
||||
print('```')
|
||||
print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':')))
|
||||
print('```')
|
||||
print()
|
||||
print()
|
@ -189,7 +189,7 @@
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="derivation">
|
||||
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'derivation']]]">
|
||||
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
|
||||
</xsl:template>
|
||||
|
||||
|
6
nixos/lib/make-options-doc/optionsJSONtoXML.nix
Normal file
6
nixos/lib/make-options-doc/optionsJSONtoXML.nix
Normal file
@ -0,0 +1,6 @@
|
||||
{ file }:
|
||||
|
||||
builtins.attrValues
|
||||
(builtins.mapAttrs
|
||||
(name: def: def // { inherit name; })
|
||||
(builtins.fromJSON (builtins.readFile file)))
|
@ -19,7 +19,6 @@ def sortKey(opt):
|
||||
for p in opt.findall('attr[@name="loc"]/list/string')
|
||||
]
|
||||
|
||||
# always ensure that the sort order matches the order used in the nix expression!
|
||||
options.sort(key=sortKey)
|
||||
|
||||
doc = ET.Element("expr")
|
||||
|
@ -21,8 +21,15 @@ stdenv.mkDerivation {
|
||||
# for nix-store --load-db.
|
||||
cp $closureInfo/registration nix-path-registration
|
||||
|
||||
# 64 cores on i686 does not work
|
||||
# fails with FATAL ERROR: mangle2:: xz compress failed with error code 5
|
||||
if ((NIX_BUILD_CORES > 48)); then
|
||||
NIX_BUILD_CORES=48
|
||||
fi
|
||||
|
||||
# Generate the squashfs image.
|
||||
mksquashfs nix-path-registration $(cat $closureInfo/store-paths) $out \
|
||||
-no-hardlinks -keep-as-directory -all-root -b 1048576 -comp ${comp}
|
||||
-no-hardlinks -keep-as-directory -all-root -b 1048576 -comp ${comp} \
|
||||
-processors $NIX_BUILD_CORES
|
||||
'';
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{ config, lib }:
|
||||
{ lib, systemdUtils }:
|
||||
|
||||
with systemdUtils.lib;
|
||||
with lib;
|
||||
with import ./systemd-lib.nix { inherit config lib pkgs; };
|
||||
|
||||
let
|
||||
checkService = checkUnitConfig "Service" [
|
32
nixos/lib/test-driver/default.nix
Normal file
32
nixos/lib/test-driver/default.nix
Normal file
@ -0,0 +1,32 @@
|
||||
{ lib
|
||||
, python3Packages
|
||||
, enableOCR ? false
|
||||
, qemu_pkg ? qemu_test
|
||||
, coreutils
|
||||
, imagemagick_light
|
||||
, libtiff
|
||||
, netpbm
|
||||
, qemu_test
|
||||
, socat
|
||||
, tesseract4
|
||||
, vde2
|
||||
}:
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "nixos-test-driver";
|
||||
version = "1.0";
|
||||
src = ./.;
|
||||
|
||||
propagatedBuildInputs = [ coreutils netpbm python3Packages.colorama python3Packages.ptpython qemu_pkg socat vde2 ]
|
||||
++ (lib.optionals enableOCR [ imagemagick_light tesseract4 ]);
|
||||
|
||||
doCheck = true;
|
||||
checkInputs = with python3Packages; [ mypy pylint black ];
|
||||
checkPhase = ''
|
||||
mypy --disallow-untyped-defs \
|
||||
--no-implicit-optional \
|
||||
--ignore-missing-imports ${src}/test_driver
|
||||
pylint --errors-only ${src}/test_driver
|
||||
black --check --diff ${src}/test_driver
|
||||
'';
|
||||
}
|
13
nixos/lib/test-driver/setup.py
Normal file
13
nixos/lib/test-driver/setup.py
Normal file
@ -0,0 +1,13 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="nixos-test-driver",
|
||||
version='1.0',
|
||||
packages=find_packages(),
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"nixos-test-driver=test_driver:main",
|
||||
"generate-driver-symbols=test_driver:generate_driver_symbols"
|
||||
]
|
||||
},
|
||||
)
|
100
nixos/lib/test-driver/test_driver/__init__.py
Executable file
100
nixos/lib/test-driver/test_driver/__init__.py
Executable file
@ -0,0 +1,100 @@
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import ptpython.repl
|
||||
import os
|
||||
import time
|
||||
|
||||
from test_driver.logger import rootlog
|
||||
from test_driver.driver import Driver
|
||||
|
||||
|
||||
class EnvDefault(argparse.Action):
|
||||
"""An argpars Action that takes values from the specified
|
||||
environment variable as the flags default value.
|
||||
"""
|
||||
|
||||
def __init__(self, envvar, required=False, default=None, nargs=None, **kwargs): # type: ignore
|
||||
if not default and envvar:
|
||||
if envvar in os.environ:
|
||||
if nargs is not None and (nargs.isdigit() or nargs in ["*", "+"]):
|
||||
default = os.environ[envvar].split()
|
||||
else:
|
||||
default = os.environ[envvar]
|
||||
kwargs["help"] = (
|
||||
kwargs["help"] + f" (default from environment: {default})"
|
||||
)
|
||||
if required and default:
|
||||
required = False
|
||||
super(EnvDefault, self).__init__(
|
||||
default=default, required=required, nargs=nargs, **kwargs
|
||||
)
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None): # type: ignore
|
||||
setattr(namespace, self.dest, values)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
arg_parser = argparse.ArgumentParser(prog="nixos-test-driver")
|
||||
arg_parser.add_argument(
|
||||
"-K",
|
||||
"--keep-vm-state",
|
||||
help="re-use a VM state coming from a previous run",
|
||||
action="store_true",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"-I",
|
||||
"--interactive",
|
||||
help="drop into a python repl and run the tests interactively",
|
||||
action="store_true",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--start-scripts",
|
||||
metavar="START-SCRIPT",
|
||||
action=EnvDefault,
|
||||
envvar="startScripts",
|
||||
nargs="*",
|
||||
help="start scripts for participating virtual machines",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--vlans",
|
||||
metavar="VLAN",
|
||||
action=EnvDefault,
|
||||
envvar="vlans",
|
||||
nargs="*",
|
||||
help="vlans to span by the driver",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"testscript",
|
||||
action=EnvDefault,
|
||||
envvar="testScript",
|
||||
help="the test script to run",
|
||||
type=Path,
|
||||
)
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
if not args.keep_vm_state:
|
||||
rootlog.info("Machine state will be reset. To keep it, pass --keep-vm-state")
|
||||
|
||||
with Driver(
|
||||
args.start_scripts, args.vlans, args.testscript.read_text(), args.keep_vm_state
|
||||
) as driver:
|
||||
if args.interactive:
|
||||
ptpython.repl.embed(driver.test_symbols(), {})
|
||||
else:
|
||||
tic = time.time()
|
||||
driver.run_tests()
|
||||
toc = time.time()
|
||||
rootlog.info(f"test script finished in {(toc-tic):.2f}s")
|
||||
|
||||
|
||||
def generate_driver_symbols() -> None:
|
||||
"""
|
||||
This generates a file with symbols of the test-driver code that can be used
|
||||
in user's test scripts. That list is then used by pyflakes to lint those
|
||||
scripts.
|
||||
"""
|
||||
d = Driver([], [], "")
|
||||
test_symbols = d.test_symbols()
|
||||
with open("driver-symbols", "w") as fp:
|
||||
fp.write(",".join(test_symbols.keys()))
|
161
nixos/lib/test-driver/test_driver/driver.py
Normal file
161
nixos/lib/test-driver/test_driver/driver.py
Normal file
@ -0,0 +1,161 @@
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Iterator, List
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from test_driver.logger import rootlog
|
||||
from test_driver.machine import Machine, NixStartScript, retry
|
||||
from test_driver.vlan import VLan
|
||||
|
||||
|
||||
class Driver:
|
||||
"""A handle to the driver that sets up the environment
|
||||
and runs the tests"""
|
||||
|
||||
tests: str
|
||||
vlans: List[VLan]
|
||||
machines: List[Machine]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
start_scripts: List[str],
|
||||
vlans: List[int],
|
||||
tests: str,
|
||||
keep_vm_state: bool = False,
|
||||
):
|
||||
self.tests = tests
|
||||
|
||||
tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
|
||||
tmp_dir.mkdir(mode=0o700, exist_ok=True)
|
||||
|
||||
with rootlog.nested("start all VLans"):
|
||||
self.vlans = [VLan(nr, tmp_dir) for nr in vlans]
|
||||
|
||||
def cmd(scripts: List[str]) -> Iterator[NixStartScript]:
|
||||
for s in scripts:
|
||||
yield NixStartScript(s)
|
||||
|
||||
self.machines = [
|
||||
Machine(
|
||||
start_command=cmd,
|
||||
keep_vm_state=keep_vm_state,
|
||||
name=cmd.machine_name,
|
||||
tmp_dir=tmp_dir,
|
||||
)
|
||||
for cmd in cmd(start_scripts)
|
||||
]
|
||||
|
||||
def __enter__(self) -> "Driver":
|
||||
return self
|
||||
|
||||
def __exit__(self, *_: Any) -> None:
|
||||
with rootlog.nested("cleanup"):
|
||||
for machine in self.machines:
|
||||
machine.release()
|
||||
|
||||
def subtest(self, name: str) -> Iterator[None]:
|
||||
"""Group logs under a given test name"""
|
||||
with rootlog.nested(name):
|
||||
try:
|
||||
yield
|
||||
return True
|
||||
except Exception as e:
|
||||
rootlog.error(f'Test "{name}" failed with error: "{e}"')
|
||||
raise e
|
||||
|
||||
def test_symbols(self) -> Dict[str, Any]:
|
||||
@contextmanager
|
||||
def subtest(name: str) -> Iterator[None]:
|
||||
return self.subtest(name)
|
||||
|
||||
general_symbols = dict(
|
||||
start_all=self.start_all,
|
||||
test_script=self.test_script,
|
||||
machines=self.machines,
|
||||
vlans=self.vlans,
|
||||
driver=self,
|
||||
log=rootlog,
|
||||
os=os,
|
||||
create_machine=self.create_machine,
|
||||
subtest=subtest,
|
||||
run_tests=self.run_tests,
|
||||
join_all=self.join_all,
|
||||
retry=retry,
|
||||
serial_stdout_off=self.serial_stdout_off,
|
||||
serial_stdout_on=self.serial_stdout_on,
|
||||
Machine=Machine, # for typing
|
||||
)
|
||||
machine_symbols = {m.name: m for m in self.machines}
|
||||
# If there's exactly one machine, make it available under the name
|
||||
# "machine", even if it's not called that.
|
||||
if len(self.machines) == 1:
|
||||
(machine_symbols["machine"],) = self.machines
|
||||
vlan_symbols = {
|
||||
f"vlan{v.nr}": self.vlans[idx] for idx, v in enumerate(self.vlans)
|
||||
}
|
||||
print(
|
||||
"additionally exposed symbols:\n "
|
||||
+ ", ".join(map(lambda m: m.name, self.machines))
|
||||
+ ",\n "
|
||||
+ ", ".join(map(lambda v: f"vlan{v.nr}", self.vlans))
|
||||
+ ",\n "
|
||||
+ ", ".join(list(general_symbols.keys()))
|
||||
)
|
||||
return {**general_symbols, **machine_symbols, **vlan_symbols}
|
||||
|
||||
def test_script(self) -> None:
|
||||
"""Run the test script"""
|
||||
with rootlog.nested("run the VM test script"):
|
||||
symbols = self.test_symbols() # call eagerly
|
||||
exec(self.tests, symbols, None)
|
||||
|
||||
def run_tests(self) -> None:
|
||||
"""Run the test script (for non-interactive test runs)"""
|
||||
self.test_script()
|
||||
# TODO: Collect coverage data
|
||||
for machine in self.machines:
|
||||
if machine.is_up():
|
||||
machine.execute("sync")
|
||||
|
||||
def start_all(self) -> None:
|
||||
"""Start all machines"""
|
||||
with rootlog.nested("start all VMs"):
|
||||
for machine in self.machines:
|
||||
machine.start()
|
||||
|
||||
def join_all(self) -> None:
|
||||
"""Wait for all machines to shut down"""
|
||||
with rootlog.nested("wait for all VMs to finish"):
|
||||
for machine in self.machines:
|
||||
machine.wait_for_shutdown()
|
||||
|
||||
def create_machine(self, args: Dict[str, Any]) -> Machine:
|
||||
rootlog.warning(
|
||||
"Using legacy create_machine(), please instantiate the"
|
||||
"Machine class directly, instead"
|
||||
)
|
||||
tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
|
||||
tmp_dir.mkdir(mode=0o700, exist_ok=True)
|
||||
|
||||
if args.get("startCommand"):
|
||||
start_command: str = args.get("startCommand", "")
|
||||
cmd = NixStartScript(start_command)
|
||||
name = args.get("name", cmd.machine_name)
|
||||
else:
|
||||
cmd = Machine.create_startcommand(args) # type: ignore
|
||||
name = args.get("name", "machine")
|
||||
|
||||
return Machine(
|
||||
tmp_dir=tmp_dir,
|
||||
start_command=cmd,
|
||||
name=name,
|
||||
keep_vm_state=args.get("keep_vm_state", False),
|
||||
allow_reboot=args.get("allow_reboot", False),
|
||||
)
|
||||
|
||||
def serial_stdout_on(self) -> None:
|
||||
rootlog._print_serial_logs = True
|
||||
|
||||
def serial_stdout_off(self) -> None:
|
||||
rootlog._print_serial_logs = False
|
101
nixos/lib/test-driver/test_driver/logger.py
Normal file
101
nixos/lib/test-driver/test_driver/logger.py
Normal file
@ -0,0 +1,101 @@
|
||||
from colorama import Style
|
||||
from contextlib import contextmanager
|
||||
from typing import Any, Dict, Iterator
|
||||
from queue import Queue, Empty
|
||||
from xml.sax.saxutils import XMLGenerator
|
||||
import codecs
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import unicodedata
|
||||
|
||||
|
||||
class Logger:
|
||||
def __init__(self) -> None:
|
||||
self.logfile = os.environ.get("LOGFILE", "/dev/null")
|
||||
self.logfile_handle = codecs.open(self.logfile, "wb")
|
||||
self.xml = XMLGenerator(self.logfile_handle, encoding="utf-8")
|
||||
self.queue: "Queue[Dict[str, str]]" = Queue()
|
||||
|
||||
self.xml.startDocument()
|
||||
self.xml.startElement("logfile", attrs={})
|
||||
|
||||
self._print_serial_logs = True
|
||||
|
||||
@staticmethod
|
||||
def _eprint(*args: object, **kwargs: Any) -> None:
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
def close(self) -> None:
|
||||
self.xml.endElement("logfile")
|
||||
self.xml.endDocument()
|
||||
self.logfile_handle.close()
|
||||
|
||||
def sanitise(self, message: str) -> str:
|
||||
return "".join(ch for ch in message if unicodedata.category(ch)[0] != "C")
|
||||
|
||||
def maybe_prefix(self, message: str, attributes: Dict[str, str]) -> str:
|
||||
if "machine" in attributes:
|
||||
return "{}: {}".format(attributes["machine"], message)
|
||||
return message
|
||||
|
||||
def log_line(self, message: str, attributes: Dict[str, str]) -> None:
|
||||
self.xml.startElement("line", attributes)
|
||||
self.xml.characters(message)
|
||||
self.xml.endElement("line")
|
||||
|
||||
def info(self, *args, **kwargs) -> None: # type: ignore
|
||||
self.log(*args, **kwargs)
|
||||
|
||||
def warning(self, *args, **kwargs) -> None: # type: ignore
|
||||
self.log(*args, **kwargs)
|
||||
|
||||
def error(self, *args, **kwargs) -> None: # type: ignore
|
||||
self.log(*args, **kwargs)
|
||||
sys.exit(1)
|
||||
|
||||
def log(self, message: str, attributes: Dict[str, str] = {}) -> None:
|
||||
self._eprint(self.maybe_prefix(message, attributes))
|
||||
self.drain_log_queue()
|
||||
self.log_line(message, attributes)
|
||||
|
||||
def log_serial(self, message: str, machine: str) -> None:
|
||||
self.enqueue({"msg": message, "machine": machine, "type": "serial"})
|
||||
if self._print_serial_logs:
|
||||
self._eprint(
|
||||
Style.DIM + "{} # {}".format(machine, message) + Style.RESET_ALL
|
||||
)
|
||||
|
||||
def enqueue(self, item: Dict[str, str]) -> None:
|
||||
self.queue.put(item)
|
||||
|
||||
def drain_log_queue(self) -> None:
|
||||
try:
|
||||
while True:
|
||||
item = self.queue.get_nowait()
|
||||
msg = self.sanitise(item["msg"])
|
||||
del item["msg"]
|
||||
self.log_line(msg, item)
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
@contextmanager
|
||||
def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]:
|
||||
self._eprint(self.maybe_prefix(message, attributes))
|
||||
|
||||
self.xml.startElement("nest", attrs={})
|
||||
self.xml.startElement("head", attributes)
|
||||
self.xml.characters(message)
|
||||
self.xml.endElement("head")
|
||||
|
||||
tic = time.time()
|
||||
self.drain_log_queue()
|
||||
yield
|
||||
self.drain_log_queue()
|
||||
toc = time.time()
|
||||
self.log("(finished: {}, in {:.2f} seconds)".format(message, toc - tic))
|
||||
|
||||
self.xml.endElement("nest")
|
||||
|
||||
|
||||
rootlog = Logger()
|
424
nixos/lib/test-driver/test-driver.py → nixos/lib/test-driver/test_driver/machine.py
Executable file → Normal file
424
nixos/lib/test-driver/test-driver.py → nixos/lib/test-driver/test_driver/machine.py
Executable file → Normal file
@ -1,19 +1,11 @@
|
||||
#! /somewhere/python3
|
||||
from contextlib import contextmanager, _GeneratorContextManager
|
||||
from queue import Queue, Empty
|
||||
from typing import Tuple, Any, Callable, Dict, Iterator, Optional, List, Iterable
|
||||
from xml.sax.saxutils import XMLGenerator
|
||||
from colorama import Style
|
||||
from contextlib import _GeneratorContextManager
|
||||
from pathlib import Path
|
||||
import queue
|
||||
import io
|
||||
import threading
|
||||
import argparse
|
||||
from queue import Queue
|
||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
|
||||
import base64
|
||||
import codecs
|
||||
import io
|
||||
import os
|
||||
import ptpython.repl
|
||||
import pty
|
||||
import queue
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
@ -21,8 +13,10 @@ import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import unicodedata
|
||||
|
||||
from test_driver.logger import rootlog
|
||||
|
||||
CHAR_TO_KEY = {
|
||||
"A": "shift-a",
|
||||
@ -88,115 +82,10 @@ CHAR_TO_KEY = {
|
||||
}
|
||||
|
||||
|
||||
class Logger:
|
||||
def __init__(self) -> None:
|
||||
self.logfile = os.environ.get("LOGFILE", "/dev/null")
|
||||
self.logfile_handle = codecs.open(self.logfile, "wb")
|
||||
self.xml = XMLGenerator(self.logfile_handle, encoding="utf-8")
|
||||
self.queue: "Queue[Dict[str, str]]" = Queue()
|
||||
|
||||
self.xml.startDocument()
|
||||
self.xml.startElement("logfile", attrs={})
|
||||
|
||||
self._print_serial_logs = True
|
||||
|
||||
@staticmethod
|
||||
def _eprint(*args: object, **kwargs: Any) -> None:
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
def close(self) -> None:
|
||||
self.xml.endElement("logfile")
|
||||
self.xml.endDocument()
|
||||
self.logfile_handle.close()
|
||||
|
||||
def sanitise(self, message: str) -> str:
|
||||
return "".join(ch for ch in message if unicodedata.category(ch)[0] != "C")
|
||||
|
||||
def maybe_prefix(self, message: str, attributes: Dict[str, str]) -> str:
|
||||
if "machine" in attributes:
|
||||
return "{}: {}".format(attributes["machine"], message)
|
||||
return message
|
||||
|
||||
def log_line(self, message: str, attributes: Dict[str, str]) -> None:
|
||||
self.xml.startElement("line", attributes)
|
||||
self.xml.characters(message)
|
||||
self.xml.endElement("line")
|
||||
|
||||
def info(self, *args, **kwargs) -> None: # type: ignore
|
||||
self.log(*args, **kwargs)
|
||||
|
||||
def warning(self, *args, **kwargs) -> None: # type: ignore
|
||||
self.log(*args, **kwargs)
|
||||
|
||||
def error(self, *args, **kwargs) -> None: # type: ignore
|
||||
self.log(*args, **kwargs)
|
||||
sys.exit(1)
|
||||
|
||||
def log(self, message: str, attributes: Dict[str, str] = {}) -> None:
|
||||
self._eprint(self.maybe_prefix(message, attributes))
|
||||
self.drain_log_queue()
|
||||
self.log_line(message, attributes)
|
||||
|
||||
def log_serial(self, message: str, machine: str) -> None:
|
||||
self.enqueue({"msg": message, "machine": machine, "type": "serial"})
|
||||
if self._print_serial_logs:
|
||||
self._eprint(
|
||||
Style.DIM + "{} # {}".format(machine, message) + Style.RESET_ALL
|
||||
)
|
||||
|
||||
def enqueue(self, item: Dict[str, str]) -> None:
|
||||
self.queue.put(item)
|
||||
|
||||
def drain_log_queue(self) -> None:
|
||||
try:
|
||||
while True:
|
||||
item = self.queue.get_nowait()
|
||||
msg = self.sanitise(item["msg"])
|
||||
del item["msg"]
|
||||
self.log_line(msg, item)
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
@contextmanager
|
||||
def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]:
|
||||
self._eprint(self.maybe_prefix(message, attributes))
|
||||
|
||||
self.xml.startElement("nest", attrs={})
|
||||
self.xml.startElement("head", attributes)
|
||||
self.xml.characters(message)
|
||||
self.xml.endElement("head")
|
||||
|
||||
tic = time.time()
|
||||
self.drain_log_queue()
|
||||
yield
|
||||
self.drain_log_queue()
|
||||
toc = time.time()
|
||||
self.log("(finished: {}, in {:.2f} seconds)".format(message, toc - tic))
|
||||
|
||||
self.xml.endElement("nest")
|
||||
|
||||
|
||||
rootlog = Logger()
|
||||
|
||||
|
||||
def make_command(args: list) -> str:
|
||||
return " ".join(map(shlex.quote, (map(str, args))))
|
||||
|
||||
|
||||
def retry(fn: Callable, timeout: int = 900) -> None:
|
||||
"""Call the given function repeatedly, with 1 second intervals,
|
||||
until it returns True or a timeout is reached.
|
||||
"""
|
||||
|
||||
for _ in range(timeout):
|
||||
if fn(False):
|
||||
return
|
||||
time.sleep(1)
|
||||
|
||||
if not fn(True):
|
||||
raise Exception(f"action timed out after {timeout} seconds")
|
||||
|
||||
|
||||
def _perform_ocr_on_screenshot(
|
||||
screenshot_path: str, model_ids: Iterable[int]
|
||||
) -> List[str]:
|
||||
@ -228,6 +117,20 @@ def _perform_ocr_on_screenshot(
|
||||
return model_results
|
||||
|
||||
|
||||
def retry(fn: Callable, timeout: int = 900) -> None:
|
||||
"""Call the given function repeatedly, with 1 second intervals,
|
||||
until it returns True or a timeout is reached.
|
||||
"""
|
||||
|
||||
for _ in range(timeout):
|
||||
if fn(False):
|
||||
return
|
||||
time.sleep(1)
|
||||
|
||||
if not fn(True):
|
||||
raise Exception(f"action timed out after {timeout} seconds")
|
||||
|
||||
|
||||
class StartCommand:
|
||||
"""The Base Start Command knows how to append the necesary
|
||||
runtime qemu options as determined by a particular test driver
|
||||
@ -1066,286 +969,3 @@ class Machine:
|
||||
self.shell.close()
|
||||
self.monitor.close()
|
||||
self.serial_thread.join()
|
||||
|
||||
|
||||
class VLan:
|
||||
"""This class handles a VLAN that the run-vm scripts identify via its
|
||||
number handles. The network's lifetime equals the object's lifetime.
|
||||
"""
|
||||
|
||||
nr: int
|
||||
socket_dir: Path
|
||||
|
||||
process: subprocess.Popen
|
||||
pid: int
|
||||
fd: io.TextIOBase
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Vlan Nr. {self.nr}>"
|
||||
|
||||
def __init__(self, nr: int, tmp_dir: Path):
|
||||
self.nr = nr
|
||||
self.socket_dir = tmp_dir / f"vde{self.nr}.ctl"
|
||||
|
||||
# TODO: don't side-effect environment here
|
||||
os.environ[f"QEMU_VDE_SOCKET_{self.nr}"] = str(self.socket_dir)
|
||||
|
||||
rootlog.info("start vlan")
|
||||
pty_master, pty_slave = pty.openpty()
|
||||
|
||||
self.process = subprocess.Popen(
|
||||
["vde_switch", "-s", self.socket_dir, "--dirmode", "0700"],
|
||||
stdin=pty_slave,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=False,
|
||||
)
|
||||
self.pid = self.process.pid
|
||||
self.fd = os.fdopen(pty_master, "w")
|
||||
self.fd.write("version\n")
|
||||
|
||||
# TODO: perl version checks if this can be read from
|
||||
# an if not, dies. we could hang here forever. Fix it.
|
||||
assert self.process.stdout is not None
|
||||
self.process.stdout.readline()
|
||||
if not (self.socket_dir / "ctl").exists():
|
||||
rootlog.error("cannot start vde_switch")
|
||||
|
||||
rootlog.info(f"running vlan (pid {self.pid})")
|
||||
|
||||
def __del__(self) -> None:
|
||||
rootlog.info(f"kill vlan (pid {self.pid})")
|
||||
self.fd.close()
|
||||
self.process.terminate()
|
||||
|
||||
|
||||
class Driver:
|
||||
"""A handle to the driver that sets up the environment
|
||||
and runs the tests"""
|
||||
|
||||
tests: str
|
||||
vlans: List[VLan]
|
||||
machines: List[Machine]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
start_scripts: List[str],
|
||||
vlans: List[int],
|
||||
tests: str,
|
||||
keep_vm_state: bool = False,
|
||||
):
|
||||
self.tests = tests
|
||||
|
||||
tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
|
||||
tmp_dir.mkdir(mode=0o700, exist_ok=True)
|
||||
|
||||
with rootlog.nested("start all VLans"):
|
||||
self.vlans = [VLan(nr, tmp_dir) for nr in vlans]
|
||||
|
||||
def cmd(scripts: List[str]) -> Iterator[NixStartScript]:
|
||||
for s in scripts:
|
||||
yield NixStartScript(s)
|
||||
|
||||
self.machines = [
|
||||
Machine(
|
||||
start_command=cmd,
|
||||
keep_vm_state=keep_vm_state,
|
||||
name=cmd.machine_name,
|
||||
tmp_dir=tmp_dir,
|
||||
)
|
||||
for cmd in cmd(start_scripts)
|
||||
]
|
||||
|
||||
def __enter__(self) -> "Driver":
|
||||
return self
|
||||
|
||||
def __exit__(self, *_: Any) -> None:
|
||||
with rootlog.nested("cleanup"):
|
||||
for machine in self.machines:
|
||||
machine.release()
|
||||
|
||||
def subtest(self, name: str) -> Iterator[None]:
|
||||
"""Group logs under a given test name"""
|
||||
with rootlog.nested(name):
|
||||
try:
|
||||
yield
|
||||
return True
|
||||
except Exception as e:
|
||||
rootlog.error(f'Test "{name}" failed with error: "{e}"')
|
||||
raise e
|
||||
|
||||
def test_symbols(self) -> Dict[str, Any]:
|
||||
@contextmanager
|
||||
def subtest(name: str) -> Iterator[None]:
|
||||
return self.subtest(name)
|
||||
|
||||
general_symbols = dict(
|
||||
start_all=self.start_all,
|
||||
test_script=self.test_script,
|
||||
machines=self.machines,
|
||||
vlans=self.vlans,
|
||||
driver=self,
|
||||
log=rootlog,
|
||||
os=os,
|
||||
create_machine=self.create_machine,
|
||||
subtest=subtest,
|
||||
run_tests=self.run_tests,
|
||||
join_all=self.join_all,
|
||||
retry=retry,
|
||||
serial_stdout_off=self.serial_stdout_off,
|
||||
serial_stdout_on=self.serial_stdout_on,
|
||||
Machine=Machine, # for typing
|
||||
)
|
||||
machine_symbols = {m.name: m for m in self.machines}
|
||||
# If there's exactly one machine, make it available under the name
|
||||
# "machine", even if it's not called that.
|
||||
if len(self.machines) == 1:
|
||||
(machine_symbols["machine"],) = self.machines
|
||||
vlan_symbols = {
|
||||
f"vlan{v.nr}": self.vlans[idx] for idx, v in enumerate(self.vlans)
|
||||
}
|
||||
print(
|
||||
"additionally exposed symbols:\n "
|
||||
+ ", ".join(map(lambda m: m.name, self.machines))
|
||||
+ ",\n "
|
||||
+ ", ".join(map(lambda v: f"vlan{v.nr}", self.vlans))
|
||||
+ ",\n "
|
||||
+ ", ".join(list(general_symbols.keys()))
|
||||
)
|
||||
return {**general_symbols, **machine_symbols, **vlan_symbols}
|
||||
|
||||
def test_script(self) -> None:
|
||||
"""Run the test script"""
|
||||
with rootlog.nested("run the VM test script"):
|
||||
symbols = self.test_symbols() # call eagerly
|
||||
exec(self.tests, symbols, None)
|
||||
|
||||
def run_tests(self) -> None:
|
||||
"""Run the test script (for non-interactive test runs)"""
|
||||
self.test_script()
|
||||
# TODO: Collect coverage data
|
||||
for machine in self.machines:
|
||||
if machine.is_up():
|
||||
machine.execute("sync")
|
||||
|
||||
def start_all(self) -> None:
|
||||
"""Start all machines"""
|
||||
with rootlog.nested("start all VMs"):
|
||||
for machine in self.machines:
|
||||
machine.start()
|
||||
|
||||
def join_all(self) -> None:
|
||||
"""Wait for all machines to shut down"""
|
||||
with rootlog.nested("wait for all VMs to finish"):
|
||||
for machine in self.machines:
|
||||
machine.wait_for_shutdown()
|
||||
|
||||
def create_machine(self, args: Dict[str, Any]) -> Machine:
|
||||
rootlog.warning(
|
||||
"Using legacy create_machine(), please instantiate the"
|
||||
"Machine class directly, instead"
|
||||
)
|
||||
tmp_dir = Path(os.environ.get("TMPDIR", tempfile.gettempdir()))
|
||||
tmp_dir.mkdir(mode=0o700, exist_ok=True)
|
||||
|
||||
if args.get("startCommand"):
|
||||
start_command: str = args.get("startCommand", "")
|
||||
cmd = NixStartScript(start_command)
|
||||
name = args.get("name", cmd.machine_name)
|
||||
else:
|
||||
cmd = Machine.create_startcommand(args) # type: ignore
|
||||
name = args.get("name", "machine")
|
||||
|
||||
return Machine(
|
||||
tmp_dir=tmp_dir,
|
||||
start_command=cmd,
|
||||
name=name,
|
||||
keep_vm_state=args.get("keep_vm_state", False),
|
||||
allow_reboot=args.get("allow_reboot", False),
|
||||
)
|
||||
|
||||
def serial_stdout_on(self) -> None:
|
||||
rootlog._print_serial_logs = True
|
||||
|
||||
def serial_stdout_off(self) -> None:
|
||||
rootlog._print_serial_logs = False
|
||||
|
||||
|
||||
class EnvDefault(argparse.Action):
|
||||
"""An argpars Action that takes values from the specified
|
||||
environment variable as the flags default value.
|
||||
"""
|
||||
|
||||
def __init__(self, envvar, required=False, default=None, nargs=None, **kwargs): # type: ignore
|
||||
if not default and envvar:
|
||||
if envvar in os.environ:
|
||||
if nargs is not None and (nargs.isdigit() or nargs in ["*", "+"]):
|
||||
default = os.environ[envvar].split()
|
||||
else:
|
||||
default = os.environ[envvar]
|
||||
kwargs["help"] = (
|
||||
kwargs["help"] + f" (default from environment: {default})"
|
||||
)
|
||||
if required and default:
|
||||
required = False
|
||||
super(EnvDefault, self).__init__(
|
||||
default=default, required=required, nargs=nargs, **kwargs
|
||||
)
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None): # type: ignore
|
||||
setattr(namespace, self.dest, values)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
arg_parser = argparse.ArgumentParser(prog="nixos-test-driver")
|
||||
arg_parser.add_argument(
|
||||
"-K",
|
||||
"--keep-vm-state",
|
||||
help="re-use a VM state coming from a previous run",
|
||||
action="store_true",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"-I",
|
||||
"--interactive",
|
||||
help="drop into a python repl and run the tests interactively",
|
||||
action="store_true",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--start-scripts",
|
||||
metavar="START-SCRIPT",
|
||||
action=EnvDefault,
|
||||
envvar="startScripts",
|
||||
nargs="*",
|
||||
help="start scripts for participating virtual machines",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"--vlans",
|
||||
metavar="VLAN",
|
||||
action=EnvDefault,
|
||||
envvar="vlans",
|
||||
nargs="*",
|
||||
help="vlans to span by the driver",
|
||||
)
|
||||
arg_parser.add_argument(
|
||||
"testscript",
|
||||
action=EnvDefault,
|
||||
envvar="testScript",
|
||||
help="the test script to run",
|
||||
type=Path,
|
||||
)
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
if not args.keep_vm_state:
|
||||
rootlog.info("Machine state will be reset. To keep it, pass --keep-vm-state")
|
||||
|
||||
with Driver(
|
||||
args.start_scripts, args.vlans, args.testscript.read_text(), args.keep_vm_state
|
||||
) as driver:
|
||||
if args.interactive:
|
||||
ptpython.repl.embed(driver.test_symbols(), {})
|
||||
else:
|
||||
tic = time.time()
|
||||
driver.run_tests()
|
||||
toc = time.time()
|
||||
rootlog.info(f"test script finished in {(toc-tic):.2f}s")
|
58
nixos/lib/test-driver/test_driver/vlan.py
Normal file
58
nixos/lib/test-driver/test_driver/vlan.py
Normal file
@ -0,0 +1,58 @@
|
||||
from pathlib import Path
|
||||
import io
|
||||
import os
|
||||
import pty
|
||||
import subprocess
|
||||
|
||||
from test_driver.logger import rootlog
|
||||
|
||||
|
||||
class VLan:
|
||||
"""This class handles a VLAN that the run-vm scripts identify via its
|
||||
number handles. The network's lifetime equals the object's lifetime.
|
||||
"""
|
||||
|
||||
nr: int
|
||||
socket_dir: Path
|
||||
|
||||
process: subprocess.Popen
|
||||
pid: int
|
||||
fd: io.TextIOBase
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Vlan Nr. {self.nr}>"
|
||||
|
||||
def __init__(self, nr: int, tmp_dir: Path):
|
||||
self.nr = nr
|
||||
self.socket_dir = tmp_dir / f"vde{self.nr}.ctl"
|
||||
|
||||
# TODO: don't side-effect environment here
|
||||
os.environ[f"QEMU_VDE_SOCKET_{self.nr}"] = str(self.socket_dir)
|
||||
|
||||
rootlog.info("start vlan")
|
||||
pty_master, pty_slave = pty.openpty()
|
||||
|
||||
self.process = subprocess.Popen(
|
||||
["vde_switch", "-s", self.socket_dir, "--dirmode", "0700"],
|
||||
stdin=pty_slave,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=False,
|
||||
)
|
||||
self.pid = self.process.pid
|
||||
self.fd = os.fdopen(pty_master, "w")
|
||||
self.fd.write("version\n")
|
||||
|
||||
# TODO: perl version checks if this can be read from
|
||||
# an if not, dies. we could hang here forever. Fix it.
|
||||
assert self.process.stdout is not None
|
||||
self.process.stdout.readline()
|
||||
if not (self.socket_dir / "ctl").exists():
|
||||
rootlog.error("cannot start vde_switch")
|
||||
|
||||
rootlog.info(f"running vlan (pid {self.pid})")
|
||||
|
||||
def __del__(self) -> None:
|
||||
rootlog.info(f"kill vlan (pid {self.pid})")
|
||||
self.fd.close()
|
||||
self.process.terminate()
|
@ -16,65 +16,6 @@ rec {
|
||||
|
||||
inherit pkgs;
|
||||
|
||||
# Reifies and correctly wraps the python test driver for
|
||||
# the respective qemu version and with or without ocr support
|
||||
pythonTestDriver = {
|
||||
qemu_pkg ? pkgs.qemu_test
|
||||
, enableOCR ? false
|
||||
}:
|
||||
let
|
||||
name = "nixos-test-driver";
|
||||
testDriverScript = ./test-driver/test-driver.py;
|
||||
ocrProg = tesseract4.override { enableLanguages = [ "eng" ]; };
|
||||
imagemagick_tiff = imagemagick_light.override { inherit libtiff; };
|
||||
in stdenv.mkDerivation {
|
||||
inherit name;
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
buildInputs = [ (python3.withPackages (p: [ p.ptpython p.colorama ])) ];
|
||||
checkInputs = with python3Packages; [ pylint black mypy ];
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
preferLocalBuild = true;
|
||||
|
||||
buildPhase = ''
|
||||
python <<EOF
|
||||
from pydoc import importfile
|
||||
with open('driver-symbols', 'w') as fp:
|
||||
t = importfile('${testDriverScript}')
|
||||
d = t.Driver([],[],"")
|
||||
test_symbols = d.test_symbols()
|
||||
fp.write(','.join(test_symbols.keys()))
|
||||
EOF
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
mypy --disallow-untyped-defs \
|
||||
--no-implicit-optional \
|
||||
--ignore-missing-imports ${testDriverScript}
|
||||
pylint --errors-only ${testDriverScript}
|
||||
black --check --diff ${testDriverScript}
|
||||
'';
|
||||
|
||||
installPhase =
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
cp ${testDriverScript} $out/bin/nixos-test-driver
|
||||
chmod u+x $out/bin/nixos-test-driver
|
||||
# TODO: copy user script part into this file (append)
|
||||
|
||||
wrapProgram $out/bin/nixos-test-driver \
|
||||
--argv0 ${name} \
|
||||
--prefix PATH : "${lib.makeBinPath [ qemu_pkg vde2 netpbm coreutils socat ]}" \
|
||||
${lib.optionalString enableOCR
|
||||
"--prefix PATH : '${ocrProg}/bin:${imagemagick_tiff}/bin'"} \
|
||||
|
||||
install -m 0644 -vD driver-symbols $out/nix-support/driver-symbols
|
||||
'';
|
||||
};
|
||||
|
||||
# Run an automated test suite in the given virtual network.
|
||||
runTests = { driver, pos }:
|
||||
stdenv.mkDerivation {
|
||||
@ -112,8 +53,15 @@ rec {
|
||||
, passthru ? {}
|
||||
}:
|
||||
let
|
||||
# FIXME: get this pkg from the module system
|
||||
testDriver = pythonTestDriver { inherit qemu_pkg enableOCR;};
|
||||
# Reifies and correctly wraps the python test driver for
|
||||
# the respective qemu version and with or without ocr support
|
||||
testDriver = pkgs.callPackage ./test-driver {
|
||||
inherit enableOCR;
|
||||
qemu_pkg = qemu_test;
|
||||
imagemagick_light = imagemagick_light.override { inherit libtiff; };
|
||||
tesseract4 = tesseract4.override { enableLanguages = [ "eng" ]; };
|
||||
};
|
||||
|
||||
|
||||
testDriverName =
|
||||
let
|
||||
@ -178,10 +126,11 @@ rec {
|
||||
echo -n "$testScript" > $out/test-script
|
||||
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
|
||||
|
||||
${testDriver}/bin/generate-driver-symbols
|
||||
${lib.optionalString (!skipLint) ''
|
||||
PYFLAKES_BUILTINS="$(
|
||||
echo -n ${lib.escapeShellArg (lib.concatStringsSep "," nodeHostNames)},
|
||||
< ${lib.escapeShellArg "${testDriver}/nix-support/driver-symbols"}
|
||||
< ${lib.escapeShellArg "driver-symbols"}
|
||||
)" ${python3Packages.pyflakes}/bin/pyflakes $out/test-script
|
||||
''}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
pkgs: with pkgs.lib;
|
||||
{ lib, config, pkgs }: with lib;
|
||||
|
||||
rec {
|
||||
|
||||
@ -165,4 +165,9 @@ rec {
|
||||
${builtins.toJSON set}
|
||||
EOF
|
||||
'';
|
||||
|
||||
systemdUtils = {
|
||||
lib = import ./systemd-lib.nix { inherit lib config pkgs; };
|
||||
unitOptions = import ./systemd-unit-options.nix { inherit lib systemdUtils; };
|
||||
};
|
||||
}
|
||||
|
37
nixos/modules/hardware/gpgsmartcards.nix
Normal file
37
nixos/modules/hardware/gpgsmartcards.nix
Normal file
@ -0,0 +1,37 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
# gnupg's manual describes how to setup ccid udev rules:
|
||||
# https://www.gnupg.org/howtos/card-howto/en/ch02s03.html
|
||||
# gnupg folks advised me (https://dev.gnupg.org/T5409) to look at debian's rules:
|
||||
# https://salsa.debian.org/debian/gnupg2/-/blob/debian/main/debian/scdaemon.udev
|
||||
|
||||
# the latest rev of the entire debian gnupg2 repo as of 2021-04-28
|
||||
# the scdaemon.udev file was last commited on 2021-01-05 (7817a03):
|
||||
scdaemonUdevRev = "01898735a015541e3ffb43c7245ac1e612f40836";
|
||||
|
||||
scdaemonRules = pkgs.fetchurl {
|
||||
url = "https://salsa.debian.org/debian/gnupg2/-/raw/${scdaemonUdevRev}/debian/scdaemon.udev";
|
||||
sha256 = "08v0vp6950bz7galvc92zdss89y9vcwbinmbfcdldy8x72w6rqr3";
|
||||
};
|
||||
|
||||
# per debian's udev deb hook (https://man7.org/linux/man-pages/man1/dh_installudev.1.html)
|
||||
destination = "60-scdaemon.rules";
|
||||
|
||||
scdaemonUdevRulesPkg = pkgs.runCommandNoCC "scdaemon-udev-rules" {} ''
|
||||
loc="$out/lib/udev/rules.d/"
|
||||
mkdir -p "''${loc}"
|
||||
cp "${scdaemonRules}" "''${loc}/${destination}"
|
||||
'';
|
||||
|
||||
cfg = config.hardware.gpgSmartcards;
|
||||
in {
|
||||
options.hardware.gpgSmartcards = {
|
||||
enable = mkEnableOption "udev rules for gnupg smart cards";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.udev.packages = [ scdaemonUdevRulesPkg ];
|
||||
};
|
||||
}
|
@ -5,7 +5,6 @@ let
|
||||
cfg = config.hardware.keyboard.zsa;
|
||||
in
|
||||
{
|
||||
# TODO: make group configurable like in https://github.com/NixOS/nixpkgs/blob/0b2b4b8c4e729535a61db56468809c5c2d3d175c/pkgs/tools/security/nitrokey-app/udev-rules.nix ?
|
||||
options.hardware.keyboard.zsa = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
@ -14,7 +13,6 @@ in
|
||||
Enables udev rules for keyboards from ZSA like the ErgoDox EZ, Planck EZ and Moonlander Mark I.
|
||||
You need it when you want to flash a new configuration on the keyboard
|
||||
or use their live training in the browser.
|
||||
Access to the keyboard is granted to users in the "plugdev" group.
|
||||
You may want to install the wally-cli package.
|
||||
'';
|
||||
};
|
||||
@ -22,6 +20,5 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.udev.packages = [ pkgs.zsa-udev-rules ];
|
||||
users.groups.plugdev = {};
|
||||
};
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ in
|
||||
|
||||
config = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
description = ''
|
||||
Path to the configuration file which maps the memory, IRQs
|
||||
and ports used by the PCMCIA hardware.
|
||||
|
@ -1,7 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
{ lib, config, pkgs, ... }:
|
||||
|
||||
{
|
||||
_module.args = {
|
||||
utils = import ../../lib/utils.nix pkgs;
|
||||
utils = import ../../lib/utils.nix { inherit lib config pkgs; };
|
||||
};
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
./hardware/device-tree.nix
|
||||
./hardware/gkraken.nix
|
||||
./hardware/flirc.nix
|
||||
./hardware/gpgsmartcards.nix
|
||||
./hardware/i2c.nix
|
||||
./hardware/sensor/hddtemp.nix
|
||||
./hardware/sensor/iio.nix
|
||||
@ -1192,8 +1193,7 @@
|
||||
./virtualisation/kvmgt.nix
|
||||
./virtualisation/openvswitch.nix
|
||||
./virtualisation/parallels-guest.nix
|
||||
./virtualisation/podman.nix
|
||||
./virtualisation/podman-network-socket-ghostunnel.nix
|
||||
./virtualisation/podman/default.nix
|
||||
./virtualisation/qemu-guest-agent.nix
|
||||
./virtualisation/railcar.nix
|
||||
./virtualisation/spice-usb-redirection.nix
|
||||
|
@ -60,7 +60,7 @@ in
|
||||
environment.systemPackages = [ pkgs.dconf ];
|
||||
|
||||
# Needed for unwrapped applications
|
||||
environment.sessionVariables.GIO_EXTRA_MODULES = mkIf cfg.enable [ "${pkgs.dconf.lib}/lib/gio/modules" ];
|
||||
environment.variables.GIO_EXTRA_MODULES = mkIf cfg.enable [ "${pkgs.dconf.lib}/lib/gio/modules" ];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -295,9 +295,14 @@ let
|
||||
};
|
||||
|
||||
limits = mkOption {
|
||||
default = [];
|
||||
type = limitsType;
|
||||
description = ''
|
||||
Attribute set describing resource limits. Defaults to the
|
||||
value of <option>security.pam.loginLimits</option>.
|
||||
The meaning of the values is explained in <citerefentry>
|
||||
<refentrytitle>limits.conf</refentrytitle><manvolnum>5</manvolnum>
|
||||
</citerefentry>.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -648,6 +653,51 @@ let
|
||||
"${domain} ${type} ${item} ${toString value}\n")
|
||||
limits);
|
||||
|
||||
limitsType = with lib.types; listOf (submodule ({ ... }: {
|
||||
options = {
|
||||
domain = mkOption {
|
||||
description = "Username, groupname, or wildcard this limit applies to";
|
||||
example = "@wheel";
|
||||
type = str;
|
||||
};
|
||||
|
||||
type = mkOption {
|
||||
description = "Type of this limit";
|
||||
type = enum [ "-" "hard" "soft" ];
|
||||
default = "-";
|
||||
};
|
||||
|
||||
item = mkOption {
|
||||
description = "Item this limit applies to";
|
||||
type = enum [
|
||||
"core"
|
||||
"data"
|
||||
"fsize"
|
||||
"memlock"
|
||||
"nofile"
|
||||
"rss"
|
||||
"stack"
|
||||
"cpu"
|
||||
"nproc"
|
||||
"as"
|
||||
"maxlogins"
|
||||
"maxsyslogins"
|
||||
"priority"
|
||||
"locks"
|
||||
"sigpending"
|
||||
"msgqueue"
|
||||
"nice"
|
||||
"rtprio"
|
||||
];
|
||||
};
|
||||
|
||||
value = mkOption {
|
||||
description = "Value of this limit";
|
||||
type = oneOf [ str int ];
|
||||
};
|
||||
};
|
||||
}));
|
||||
|
||||
motd = pkgs.writeText "motd" config.users.motd;
|
||||
|
||||
makePAMService = name: service:
|
||||
@ -669,6 +719,7 @@ in
|
||||
|
||||
security.pam.loginLimits = mkOption {
|
||||
default = [];
|
||||
type = limitsType;
|
||||
example =
|
||||
[ { domain = "ftp";
|
||||
type = "hard";
|
||||
@ -688,7 +739,8 @@ in
|
||||
<varname>domain</varname>, <varname>type</varname>,
|
||||
<varname>item</varname>, and <varname>value</varname>
|
||||
attribute. The syntax and semantics of these attributes
|
||||
must be that described in the limits.conf(5) man page.
|
||||
must be that described in <citerefentry><refentrytitle>limits.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum></citerefentry>.
|
||||
|
||||
Note that these limits do not apply to systemd services,
|
||||
whose limits can be changed via <option>systemd.extraConfig</option>
|
||||
|
@ -1,11 +1,9 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
{ config, pkgs, lib, utils, ... }:
|
||||
|
||||
let
|
||||
toplevelConfig = config;
|
||||
inherit (lib) types;
|
||||
inherit (import ../system/boot/systemd-lib.nix {
|
||||
inherit config pkgs lib;
|
||||
}) mkPathSafeName;
|
||||
inherit (utils.systemdUtils.lib) mkPathSafeName;
|
||||
in {
|
||||
options.systemd.services = lib.mkOption {
|
||||
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
||||
|
@ -1,10 +1,10 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
|
||||
unitOption = (import ../../system/boot/systemd-unit-options.nix { inherit config lib; }).unitOption;
|
||||
inherit (utils.systemdUtils.unitOptions) unitOption;
|
||||
in
|
||||
{
|
||||
options.services.restic.backups = mkOption {
|
||||
|
@ -38,7 +38,7 @@ with lib;
|
||||
|
||||
systemd.packages = [ pkgs.glib-networking ];
|
||||
|
||||
environment.sessionVariables.GIO_EXTRA_MODULES = [ "${pkgs.glib-networking.out}/lib/gio/modules" ];
|
||||
environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.glib-networking.out}/lib/gio/modules" ];
|
||||
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ in
|
||||
services.udev.packages = [ pkgs.libmtp.bin ];
|
||||
|
||||
# Needed for unwrapped applications
|
||||
environment.sessionVariables.GIO_EXTRA_MODULES = [ "${cfg.package}/lib/gio/modules" ];
|
||||
environment.variables.GIO_EXTRA_MODULES = [ "${cfg.package}/lib/gio/modules" ];
|
||||
|
||||
};
|
||||
|
||||
|
@ -40,6 +40,7 @@ in {
|
||||
|
||||
haskellPackages = mkOption {
|
||||
description = "Which haskell package set to use.";
|
||||
type = types.attrs;
|
||||
default = pkgs.haskellPackages;
|
||||
defaultText = literalExpression "pkgs.haskellPackages";
|
||||
};
|
||||
|
@ -137,7 +137,6 @@ in
|
||||
description = "the RAS logging daemon";
|
||||
documentation = [ "man:rasdaemon(1)" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "syslog.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
StateDirectory = optionalString (cfg.record) "rasdaemon";
|
||||
|
@ -104,31 +104,37 @@ in
|
||||
properties = mkOption {
|
||||
description = "An attribute set in which each attribute represents a machine property. Optionally, these values can be shell substitutions.";
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
containers = mkOption {
|
||||
description = "An attribute set in which each key represents a container and each value an attribute set providing its configuration properties";
|
||||
default = {};
|
||||
type = types.attrsOf types.attrs;
|
||||
};
|
||||
|
||||
components = mkOption {
|
||||
description = "An atttribute set in which each key represents a container and each value an attribute set in which each key represents a component and each value a derivation constructing its initial state";
|
||||
default = {};
|
||||
type = types.attrsOf types.attrs;
|
||||
};
|
||||
|
||||
extraContainerProperties = mkOption {
|
||||
description = "An attribute set providing additional container settings in addition to the default properties";
|
||||
default = {};
|
||||
type = types.attrs;
|
||||
};
|
||||
|
||||
extraContainerPaths = mkOption {
|
||||
description = "A list of paths containing additional container configurations that are added to the search folders";
|
||||
default = [];
|
||||
type = types.listOf types.path;
|
||||
};
|
||||
|
||||
extraModulePaths = mkOption {
|
||||
description = "A list of paths containing additional modules that are added to the search folders";
|
||||
default = [];
|
||||
type = types.listOf types.path;
|
||||
};
|
||||
|
||||
enableLegacyModules = mkOption {
|
||||
|
@ -192,15 +192,28 @@ in
|
||||
example = "batch";
|
||||
description = ''
|
||||
Nix daemon process CPU scheduling policy. This policy propagates to
|
||||
build processes. other is the default scheduling policy for regular
|
||||
tasks. The batch policy is similar to other, but optimised for
|
||||
non-interactive tasks. idle is for extremely low-priority tasks
|
||||
that should only be run when no other task requires CPU time.
|
||||
build processes. <literal>other</literal> is the default scheduling
|
||||
policy for regular tasks. The <literal>batch</literal> policy is
|
||||
similar to <literal>other</literal>, but optimised for
|
||||
non-interactive tasks. <literal>idle</literal> is for extremely
|
||||
low-priority tasks that should only be run when no other task
|
||||
requires CPU time.
|
||||
|
||||
Please note that while using the idle policy may greatly improve
|
||||
responsiveness of a system performing expensive builds, it may also
|
||||
slow down and potentially starve crucial configuration updates
|
||||
during load.
|
||||
Please note that while using the <literal>idle</literal> policy may
|
||||
greatly improve responsiveness of a system performing expensive
|
||||
builds, it may also slow down and potentially starve crucial
|
||||
configuration updates during load.
|
||||
|
||||
<literal>idle</literal> may therefore be a sensible policy for
|
||||
systems that experience only intermittent phases of high CPU load,
|
||||
such as desktop or portable computers used interactively. Other
|
||||
systems should use the <literal>other</literal> or
|
||||
<literal>batch</literal> policy instead.
|
||||
|
||||
For more fine-grained resource control, please refer to
|
||||
<citerefentry><refentrytitle>systemd.resource-control
|
||||
</refentrytitle><manvolnum>5</manvolnum></citerefentry> and adjust
|
||||
<option>systemd.services.nix-daemon</option> directly.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -210,13 +223,20 @@ in
|
||||
example = "idle";
|
||||
description = ''
|
||||
Nix daemon process I/O scheduling class. This class propagates to
|
||||
build processes. best-effort is the default class for regular tasks.
|
||||
The idle class is for extremely low-priority tasks that should only
|
||||
perform I/O when no other task does.
|
||||
build processes. <literal>best-effort</literal> is the default
|
||||
class for regular tasks. The <literal>idle</literal> class is for
|
||||
extremely low-priority tasks that should only perform I/O when no
|
||||
other task does.
|
||||
|
||||
Please note that while using the idle scheduling class can improve
|
||||
responsiveness of a system performing expensive builds, it might also
|
||||
slow down or starve crucial configuration updates during load.
|
||||
Please note that while using the <literal>idle</literal> scheduling
|
||||
class can improve responsiveness of a system performing expensive
|
||||
builds, it might also slow down or starve crucial configuration
|
||||
updates during load.
|
||||
|
||||
<literal>idle</literal> may therefore be a sensible class for
|
||||
systems that experience only intermittent phases of high I/O load,
|
||||
such as desktop or portable computers used interactively. Other
|
||||
systems should use the <literal>best-effort</literal> class.
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -217,6 +217,8 @@ in
|
||||
"-Dnet.java.sip.communicator.SC_HOME_DIR_NAME" = "videobridge";
|
||||
"-Djava.util.logging.config.file" = "/etc/jitsi/videobridge/logging.properties";
|
||||
"-Dconfig.file" = pkgs.writeText "jvb.conf" (toHOCON jvbConfig);
|
||||
# Mitigate CVE-2021-44228
|
||||
"-Dlog4j2.formatMsgNoLookups" = true;
|
||||
} // (mapAttrs' (k: v: nameValuePair "-D${k}" v) cfg.extraProperties);
|
||||
in
|
||||
{
|
||||
|
@ -97,6 +97,11 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
confDir = mkOption {
|
||||
type = types.path;
|
||||
default = confDir;
|
||||
description = "The location of the config files for xrdp.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@ -149,7 +154,7 @@ in
|
||||
User = "xrdp";
|
||||
Group = "xrdp";
|
||||
PermissionsStartOnly = true;
|
||||
ExecStart = "${cfg.package}/bin/xrdp --nodaemon --port ${toString cfg.port} --config ${confDir}/xrdp.ini";
|
||||
ExecStart = "${cfg.package}/bin/xrdp --nodaemon --port ${toString cfg.port} --config ${cfg.confDir}/xrdp.ini";
|
||||
};
|
||||
};
|
||||
|
||||
@ -159,7 +164,7 @@ in
|
||||
description = "xrdp session manager";
|
||||
restartIfChanged = false; # do not restart on "nixos-rebuild switch". like "display-manager", it can have many interactive programs as children
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/xrdp-sesman --nodaemon --config ${confDir}/sesman.ini";
|
||||
ExecStart = "${cfg.package}/bin/xrdp-sesman --nodaemon --config ${cfg.confDir}/sesman.ini";
|
||||
ExecStop = "${pkgs.coreutils}/bin/kill -INT $MAINPID";
|
||||
};
|
||||
};
|
||||
|
@ -621,12 +621,13 @@ in
|
||||
|
||||
max_user_api_reqs_per_minute = 20;
|
||||
max_user_api_reqs_per_day = 2880;
|
||||
max_admin_api_reqs_per_key_per_minute = 60;
|
||||
max_admin_api_reqs_per_minute = 60;
|
||||
max_reqs_per_ip_per_minute = 200;
|
||||
max_reqs_per_ip_per_10_seconds = 50;
|
||||
max_asset_reqs_per_ip_per_10_seconds = 200;
|
||||
max_reqs_per_ip_mode = "block";
|
||||
max_reqs_rate_limit_on_private = false;
|
||||
skip_per_ip_rate_limit_trust_level = 1;
|
||||
force_anonymous_min_queue_seconds = 1;
|
||||
force_anonymous_min_per_10_seconds = 3;
|
||||
background_requests_max_queue_length = 0.5;
|
||||
@ -646,6 +647,9 @@ in
|
||||
enable_email_sync_demon = false;
|
||||
max_digests_enqueued_per_30_mins_per_site = 10000;
|
||||
cluster_name = null;
|
||||
multisite_config_path = "config/multisite.yml";
|
||||
enable_long_polling = null;
|
||||
long_polling_interval = null;
|
||||
};
|
||||
|
||||
services.redis.enable = lib.mkDefault (cfg.redis.host == "localhost");
|
||||
@ -825,7 +829,7 @@ in
|
||||
|
||||
appendHttpConfig = ''
|
||||
# inactive means we keep stuff around for 1440m minutes regardless of last access (1 week)
|
||||
# levels means it is a 2 deep heirarchy cause we can have lots of files
|
||||
# levels means it is a 2 deep hierarchy cause we can have lots of files
|
||||
# max_size limits the size of the cache
|
||||
proxy_cache_path /var/cache/nginx inactive=1440m levels=1:2 keys_zone=discourse:10m max_size=600m;
|
||||
|
||||
@ -837,7 +841,7 @@ in
|
||||
inherit (cfg) sslCertificate sslCertificateKey enableACME;
|
||||
forceSSL = lib.mkDefault tlsEnabled;
|
||||
|
||||
root = "/run/discourse/public";
|
||||
root = "${cfg.package}/share/discourse/public";
|
||||
|
||||
locations =
|
||||
let
|
||||
@ -889,7 +893,7 @@ in
|
||||
"~ ^/uploads/" = proxy {
|
||||
extraConfig = cache_1y + ''
|
||||
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
|
||||
proxy_set_header X-Accel-Mapping /run/discourse/public/=/downloads/;
|
||||
proxy_set_header X-Accel-Mapping ${cfg.package}/share/discourse/public/=/downloads/;
|
||||
|
||||
# custom CSS
|
||||
location ~ /stylesheet-cache/ {
|
||||
@ -911,7 +915,7 @@ in
|
||||
"~ ^/admin/backups/" = proxy {
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
|
||||
proxy_set_header X-Accel-Mapping /run/discourse/public/=/downloads/;
|
||||
proxy_set_header X-Accel-Mapping ${cfg.package}/share/discourse/public/=/downloads/;
|
||||
'';
|
||||
};
|
||||
"~ ^/(svg-sprite/|letter_avatar/|letter_avatar_proxy/|user_avatar|highlight-js|stylesheets|theme-javascripts|favicon/proxied|service-worker)" = proxy {
|
||||
@ -938,7 +942,7 @@ in
|
||||
};
|
||||
"/downloads/".extraConfig = ''
|
||||
internal;
|
||||
alias /run/discourse/public/;
|
||||
alias ${cfg.package}/share/discourse/public/;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
@ -297,7 +297,7 @@ services.discourse = {
|
||||
the script:
|
||||
<programlisting language="bash">
|
||||
./update.py update-plugins
|
||||
</programlisting>.
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -308,6 +308,9 @@ in
|
||||
inherit user;
|
||||
group = webserver.group;
|
||||
|
||||
# Not yet compatible with php 8 https://www.dokuwiki.org/requirements
|
||||
# https://github.com/splitbrain/dokuwiki/issues/3545
|
||||
phpPackage = pkgs.php74;
|
||||
phpEnv = {
|
||||
DOKUWIKI_LOCAL_CONFIG = "${dokuwikiLocalConfig hostName cfg}";
|
||||
DOKUWIKI_PLUGINS_LOCAL_CONFIG = "${dokuwikiPluginsLocalConfig hostName cfg}";
|
||||
@ -446,5 +449,6 @@ in
|
||||
meta.maintainers = with maintainers; [
|
||||
_1000101
|
||||
onny
|
||||
dandellion
|
||||
];
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ in
|
||||
{
|
||||
|
||||
meta = {
|
||||
maintainers = with maintainers; [ ];
|
||||
maintainers = teams.xfce.members;
|
||||
};
|
||||
|
||||
imports = [
|
||||
|
@ -39,10 +39,12 @@ in {
|
||||
options = {
|
||||
services.xserver.windowManager.xmonad = {
|
||||
enable = mkEnableOption "xmonad";
|
||||
|
||||
haskellPackages = mkOption {
|
||||
default = pkgs.haskellPackages;
|
||||
defaultText = literalExpression "pkgs.haskellPackages";
|
||||
example = literalExpression "pkgs.haskell.packages.ghc784";
|
||||
type = types.attrs;
|
||||
description = ''
|
||||
haskellPackages used to build Xmonad and other packages.
|
||||
This can be used to change the GHC version used to build
|
||||
|
@ -351,8 +351,14 @@ foreach my $device (keys %$prevSwaps) {
|
||||
|
||||
# Should we have systemd re-exec itself?
|
||||
my $prevSystemd = abs_path("/proc/1/exe") // "/unknown";
|
||||
my $prevSystemdSystemConfig = abs_path("/etc/systemd/system.conf") // "/unknown";
|
||||
my $newSystemd = abs_path("@systemd@/lib/systemd/systemd") or die;
|
||||
my $newSystemdSystemConfig = abs_path("$out/etc/systemd/system.conf") // "/unknown";
|
||||
|
||||
my $restartSystemd = $prevSystemd ne $newSystemd;
|
||||
if ($prevSystemdSystemConfig ne $newSystemdSystemConfig) {
|
||||
$restartSystemd = 1;
|
||||
}
|
||||
|
||||
|
||||
sub filterUnits {
|
||||
|
@ -1,8 +1,8 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with utils.systemdUtils.unitOptions;
|
||||
with utils.systemdUtils.lib;
|
||||
with lib;
|
||||
with import ./systemd-unit-options.nix { inherit config lib; };
|
||||
with import ./systemd-lib.nix { inherit config lib pkgs; };
|
||||
|
||||
let
|
||||
|
||||
@ -823,6 +823,16 @@ let
|
||||
(assertValueOneOf "OnLink" boolValues)
|
||||
];
|
||||
|
||||
sectionDHCPServerStaticLease = checkUnitConfig "DHCPServerStaticLease" [
|
||||
(assertOnlyFields [
|
||||
"MACAddress"
|
||||
"Address"
|
||||
])
|
||||
(assertHasField "MACAddress")
|
||||
(assertHasField "Address")
|
||||
(assertMacAddress "MACAddress")
|
||||
];
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -1163,6 +1173,25 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
dhcpServerStaticLeaseOptions = {
|
||||
options = {
|
||||
dhcpServerStaticLeaseConfig = mkOption {
|
||||
default = {};
|
||||
example = { MACAddress = "65:43:4a:5b:d8:5f"; Address = "192.168.1.42"; };
|
||||
type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPServerStaticLease;
|
||||
description = ''
|
||||
Each attribute in this set specifies an option in the
|
||||
<literal>[DHCPServerStaticLease]</literal> section of the unit. See
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle>
|
||||
<manvolnum>5</manvolnum></citerefentry> for details.
|
||||
|
||||
Make sure to configure the corresponding client interface to use
|
||||
<literal>ClientIdentifier=mac</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networkOptions = commonNetworkOptions // {
|
||||
|
||||
linkConfig = mkOption {
|
||||
@ -1275,6 +1304,17 @@ let
|
||||
'';
|
||||
};
|
||||
|
||||
dhcpServerStaticLeases = mkOption {
|
||||
default = [];
|
||||
example = [ { MACAddress = "65:43:4a:5b:d8:5f"; Address = "192.168.1.42"; } ];
|
||||
type = with types; listOf (submodule dhcpServerStaticLeaseOptions);
|
||||
description = ''
|
||||
A list of DHCPServerStaticLease sections to be added to the unit. See
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle>
|
||||
<manvolnum>5</manvolnum></citerefentry> for details.
|
||||
'';
|
||||
};
|
||||
|
||||
ipv6Prefixes = mkOption {
|
||||
default = [];
|
||||
example = [ { AddressAutoconfiguration = true; OnLink = true; } ];
|
||||
@ -1646,6 +1686,10 @@ let
|
||||
[IPv6Prefix]
|
||||
${attrsToSection x.ipv6PrefixConfig}
|
||||
'')
|
||||
+ flip concatMapStrings def.dhcpServerStaticLeases (x: ''
|
||||
[DHCPServerStaticLease]
|
||||
${attrsToSection x.dhcpServerStaticLeaseConfig}
|
||||
'')
|
||||
+ def.extraConfig;
|
||||
};
|
||||
|
||||
|
@ -119,6 +119,18 @@ specialMount() {
|
||||
}
|
||||
source @earlyMountScript@
|
||||
|
||||
# Copy initrd secrets from /.initrd-secrets to their actual destinations
|
||||
if [ -d "/.initrd-secrets" ]; then
|
||||
#
|
||||
# Secrets are named by their full destination pathname and stored
|
||||
# under /.initrd-secrets/
|
||||
#
|
||||
for secret in $(cd "/.initrd-secrets"; find . -type f); do
|
||||
mkdir -p $(dirname "/$secret")
|
||||
cp "/.initrd-secrets/$secret" "$secret"
|
||||
done
|
||||
fi
|
||||
|
||||
# Log the script output to /dev/kmsg or /run/log/stage-1-init.log.
|
||||
mkdir -p /tmp
|
||||
mkfifo /tmp/stage-1-init.log.fifo
|
||||
|
@ -411,8 +411,8 @@ let
|
||||
${lib.concatStringsSep "\n" (mapAttrsToList (dest: source:
|
||||
let source' = if source == null then dest else toString source; in
|
||||
''
|
||||
mkdir -p $(dirname "$tmp/${dest}")
|
||||
cp -a ${source'} "$tmp/${dest}"
|
||||
mkdir -p $(dirname "$tmp/.initrd-secrets/${dest}")
|
||||
cp -a ${source'} "$tmp/.initrd-secrets/${dest}"
|
||||
''
|
||||
) config.boot.initrd.secrets)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{ config, lib , pkgs, ...}:
|
||||
{ config, lib, pkgs, utils, ...}:
|
||||
|
||||
with utils.systemdUtils.unitOptions;
|
||||
with utils.systemdUtils.lib;
|
||||
with lib;
|
||||
with import ./systemd-unit-options.nix { inherit config lib; };
|
||||
with import ./systemd-lib.nix { inherit config lib pkgs; };
|
||||
|
||||
let
|
||||
cfg = config.systemd.nspawn;
|
||||
|
@ -1,9 +1,9 @@
|
||||
{ config, lib, pkgs, utils, ... }:
|
||||
|
||||
with utils;
|
||||
with systemdUtils.unitOptions;
|
||||
with systemdUtils.lib;
|
||||
with lib;
|
||||
with import ./systemd-unit-options.nix { inherit config lib; };
|
||||
with import ./systemd-lib.nix { inherit config lib pkgs; };
|
||||
|
||||
let
|
||||
|
||||
|
@ -207,7 +207,7 @@ in
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = "@system-service";
|
||||
SystemCallErrorNumber = "EPERM";
|
||||
CapabilityBoundingSet = "CAP_DAC_OVERRIDE" ++
|
||||
CapabilityBoundingSet = "CAP_DAC_OVERRIDE" +
|
||||
lib.optionalString cfg.touchBeforeSync " CAP_FOWNER";
|
||||
|
||||
ProtectSystem = "strict";
|
||||
|
@ -39,8 +39,8 @@ let
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./podman-dnsname.nix
|
||||
./podman-network-socket.nix
|
||||
./dnsname.nix
|
||||
./network-socket.nix
|
||||
(lib.mkRenamedOptionModule [ "virtualisation" "podman" "libpod" ] [ "virtualisation" "containers" "containersConf" ])
|
||||
];
|
||||
|
@ -9,6 +9,10 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./network-socket-ghostunnel.nix
|
||||
];
|
||||
|
||||
options.virtualisation.podman.networkSocket = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
@ -835,6 +835,7 @@ in
|
||||
|
||||
# FIXME: Consolidate this one day.
|
||||
virtualisation.qemu.options = mkMerge [
|
||||
[ "-device virtio-keyboard" ]
|
||||
(mkIf pkgs.stdenv.hostPlatform.isx86 [
|
||||
"-usb" "-device usb-tablet,bus=usb-bus.0"
|
||||
])
|
||||
|
@ -369,9 +369,9 @@ in
|
||||
plikd = handleTest ./plikd.nix {};
|
||||
plotinus = handleTest ./plotinus.nix {};
|
||||
podgrab = handleTest ./podgrab.nix {};
|
||||
podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
|
||||
podman-dnsname = handleTestOn ["x86_64-linux"] ./podman-dnsname.nix {};
|
||||
podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman-tls-ghostunnel.nix {};
|
||||
podman = handleTestOn ["x86_64-linux"] ./podman/default.nix {};
|
||||
podman-dnsname = handleTestOn ["x86_64-linux"] ./podman/dnsname.nix {};
|
||||
podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman/tls-ghostunnel.nix {};
|
||||
pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {};
|
||||
postfix = handleTest ./postfix.nix {};
|
||||
postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
|
||||
@ -454,6 +454,7 @@ in
|
||||
systemd-journal = handleTest ./systemd-journal.nix {};
|
||||
systemd-networkd = handleTest ./systemd-networkd.nix {};
|
||||
systemd-networkd-dhcpserver = handleTest ./systemd-networkd-dhcpserver.nix {};
|
||||
systemd-networkd-dhcpserver-static-leases = handleTest ./systemd-networkd-dhcpserver-static-leases.nix {};
|
||||
systemd-networkd-ipv6-prefix-delegation = handleTest ./systemd-networkd-ipv6-prefix-delegation.nix {};
|
||||
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};
|
||||
systemd-nspawn = handleTest ./systemd-nspawn.nix {};
|
||||
|
@ -23,6 +23,7 @@ import ./make-test-python.nix ({ pkgs, ...} : {
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import re
|
||||
# sane loads libsane-brother5.so.1 successfully, and scanimage doesn't die
|
||||
strace = machine.succeed('strace scanimage -L 2>&1').split("\n")
|
||||
regexp = 'openat\(.*libsane-brother5.so.1", O_RDONLY|O_CLOEXEC\) = \d\d*$'
|
||||
|
@ -13,7 +13,12 @@ let
|
||||
|
||||
machine = { ... }: {
|
||||
virtualisation.useBootLoader = true;
|
||||
boot.initrd.secrets."/test" = secretInStore;
|
||||
boot.initrd.secrets = {
|
||||
"/test" = secretInStore;
|
||||
|
||||
# This should *not* need to be copied in postMountCommands
|
||||
"/run/keys/test" = secretInStore;
|
||||
};
|
||||
boot.initrd.postMountCommands = ''
|
||||
cp /test /mnt-root/secret-from-initramfs
|
||||
'';
|
||||
@ -26,7 +31,8 @@ let
|
||||
start_all()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
machine.succeed(
|
||||
"cmp ${secretInStore} /secret-from-initramfs"
|
||||
"cmp ${secretInStore} /secret-from-initramfs",
|
||||
"cmp ${secretInStore} /run/keys/test",
|
||||
)
|
||||
'';
|
||||
};
|
||||
|
@ -53,12 +53,12 @@ let
|
||||
};
|
||||
# /etc/nixos/configuration.nix for the vm
|
||||
configFile = pkgs.writeText "configuration.nix" ''
|
||||
{config, pkgs, ...}: ({
|
||||
{config, pkgs, lib, ...}: ({
|
||||
imports =
|
||||
[ ./hardware-configuration.nix
|
||||
<nixpkgs/nixos/modules/testing/test-instrumentation.nix>
|
||||
];
|
||||
} // pkgs.lib.importJSON ${
|
||||
} // lib.importJSON ${
|
||||
pkgs.writeText "simpleConfig.json" (builtins.toJSON simpleConfig)
|
||||
})
|
||||
'';
|
||||
@ -114,7 +114,7 @@ in {
|
||||
"${configFile}",
|
||||
"/etc/nixos/configuration.nix",
|
||||
)
|
||||
machine.succeed("nixos-rebuild boot >&2")
|
||||
machine.succeed("nixos-rebuild boot --show-trace >&2")
|
||||
|
||||
machine.succeed("egrep 'menuentry.*debian' /boot/grub/grub.cfg")
|
||||
'';
|
||||
|
@ -1,6 +1,6 @@
|
||||
# This test runs podman and checks if simple container starts
|
||||
|
||||
import ./make-test-python.nix (
|
||||
import ../make-test-python.nix (
|
||||
{ pkgs, lib, ... }: {
|
||||
name = "podman";
|
||||
meta = {
|
||||
@ -48,7 +48,7 @@ import ./make-test-python.nix (
|
||||
start_all()
|
||||
|
||||
with subtest("Run container as root with runc"):
|
||||
podman.succeed("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg")
|
||||
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
|
||||
podman.succeed(
|
||||
"podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
)
|
||||
@ -57,7 +57,7 @@ import ./make-test-python.nix (
|
||||
podman.succeed("podman rm sleeping")
|
||||
|
||||
with subtest("Run container as root with crun"):
|
||||
podman.succeed("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg")
|
||||
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
|
||||
podman.succeed(
|
||||
"podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
)
|
||||
@ -66,7 +66,7 @@ import ./make-test-python.nix (
|
||||
podman.succeed("podman rm sleeping")
|
||||
|
||||
with subtest("Run container as root with the default backend"):
|
||||
podman.succeed("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg")
|
||||
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
|
||||
podman.succeed(
|
||||
"podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
)
|
||||
@ -78,7 +78,7 @@ import ./make-test-python.nix (
|
||||
podman.succeed("loginctl enable-linger alice")
|
||||
|
||||
with subtest("Run container rootless with runc"):
|
||||
podman.succeed(su_cmd("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg"))
|
||||
podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
|
||||
podman.succeed(
|
||||
su_cmd(
|
||||
"podman run --runtime=runc -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
@ -89,7 +89,7 @@ import ./make-test-python.nix (
|
||||
podman.succeed(su_cmd("podman rm sleeping"))
|
||||
|
||||
with subtest("Run container rootless with crun"):
|
||||
podman.succeed(su_cmd("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg"))
|
||||
podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
|
||||
podman.succeed(
|
||||
su_cmd(
|
||||
"podman run --runtime=crun -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
@ -100,7 +100,7 @@ import ./make-test-python.nix (
|
||||
podman.succeed(su_cmd("podman rm sleeping"))
|
||||
|
||||
with subtest("Run container rootless with the default backend"):
|
||||
podman.succeed(su_cmd("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg"))
|
||||
podman.succeed(su_cmd("tar cv --files-from /dev/null | podman import - scratchimg"))
|
||||
podman.succeed(
|
||||
su_cmd(
|
||||
"podman run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
@ -112,7 +112,7 @@ import ./make-test-python.nix (
|
||||
|
||||
with subtest("Run container with init"):
|
||||
podman.succeed(
|
||||
"tar cvf busybox.tar -C ${pkgs.pkgsStatic.busybox} . && podman import busybox.tar busybox"
|
||||
"tar cv -C ${pkgs.pkgsStatic.busybox} . | podman import - busybox"
|
||||
)
|
||||
pid = podman.succeed("podman run --rm busybox readlink /proc/self").strip()
|
||||
assert pid == "1"
|
||||
@ -124,7 +124,7 @@ import ./make-test-python.nix (
|
||||
|
||||
with subtest("Run container via docker cli"):
|
||||
podman.succeed("docker network create default")
|
||||
podman.succeed("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg")
|
||||
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
|
||||
podman.succeed(
|
||||
"docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
||||
)
|
@ -1,4 +1,4 @@
|
||||
import ./make-test-python.nix (
|
||||
import ../make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
inherit (pkgs) writeTextDir python3 curl;
|
||||
@ -21,7 +21,7 @@ import ./make-test-python.nix (
|
||||
podman.wait_for_unit("sockets.target")
|
||||
|
||||
with subtest("DNS works"): # also tests inter-container tcp routing
|
||||
podman.succeed("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg")
|
||||
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
|
||||
podman.succeed(
|
||||
"podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${webroot} scratchimg ${python3}/bin/python -m http.server 8000"
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
This test runs podman as a backend for the Docker CLI.
|
||||
*/
|
||||
import ./make-test-python.nix (
|
||||
import ../make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
|
||||
let gen-ca = pkgs.writeScript "gen-ca" ''
|
||||
@ -126,7 +126,7 @@ import ./make-test-python.nix (
|
||||
client.succeed("docker version")
|
||||
|
||||
# via socket would be nicer
|
||||
podman.succeed("tar cvf scratchimg.tar --files-from /dev/null && podman import scratchimg.tar scratchimg")
|
||||
podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
|
||||
|
||||
client.succeed(
|
||||
"docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
|
81
nixos/tests/systemd-networkd-dhcpserver-static-leases.nix
Normal file
81
nixos/tests/systemd-networkd-dhcpserver-static-leases.nix
Normal file
@ -0,0 +1,81 @@
|
||||
# In contrast to systemd-networkd-dhcpserver, this test configures
|
||||
# the router with a static DHCP lease for the client's MAC address.
|
||||
import ./make-test-python.nix ({ lib, ... }: {
|
||||
name = "systemd-networkd-dhcpserver-static-leases";
|
||||
meta = with lib.maintainers; {
|
||||
maintainers = [ veehaitch tomfitzhenry ];
|
||||
};
|
||||
nodes = {
|
||||
router = {
|
||||
virtualisation.vlans = [ 1 ];
|
||||
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
networking = {
|
||||
useNetworkd = true;
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
};
|
||||
systemd.network = {
|
||||
networks = {
|
||||
# systemd-networkd will load the first network unit file
|
||||
# that matches, ordered lexiographically by filename.
|
||||
# /etc/systemd/network/{40-eth1,99-main}.network already
|
||||
# exists. This network unit must be loaded for the test,
|
||||
# however, hence why this network is named such.
|
||||
"01-eth1" = {
|
||||
name = "eth1";
|
||||
networkConfig = {
|
||||
DHCPServer = true;
|
||||
Address = "10.0.0.1/24";
|
||||
};
|
||||
dhcpServerStaticLeases = [{
|
||||
dhcpServerStaticLeaseConfig = {
|
||||
MACAddress = "02:de:ad:be:ef:01";
|
||||
Address = "10.0.0.10";
|
||||
};
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
client = {
|
||||
virtualisation.vlans = [ 1 ];
|
||||
systemd.services.systemd-networkd.environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
networking = {
|
||||
useNetworkd = true;
|
||||
useDHCP = false;
|
||||
firewall.enable = false;
|
||||
interfaces.eth1 = {
|
||||
useDHCP = true;
|
||||
macAddress = "02:de:ad:be:ef:01";
|
||||
};
|
||||
};
|
||||
|
||||
# This setting is important to have the router assign the
|
||||
# configured lease based on the client's MAC address. Also see:
|
||||
# https://github.com/systemd/systemd/issues/21368#issuecomment-982193546
|
||||
systemd.network.networks."40-eth1".dhcpV4Config.ClientIdentifier = "mac";
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
start_all()
|
||||
|
||||
with subtest("check router network configuration"):
|
||||
router.wait_for_unit("systemd-networkd-wait-online.service")
|
||||
eth1_status = router.succeed("networkctl status eth1")
|
||||
assert "Network File: /etc/systemd/network/01-eth1.network" in eth1_status, \
|
||||
"The router interface eth1 is not using the expected network file"
|
||||
assert "10.0.0.1" in eth1_status, "Did not find expected router IPv4"
|
||||
|
||||
with subtest("check client network configuration"):
|
||||
client.wait_for_unit("systemd-networkd-wait-online.service")
|
||||
eth1_status = client.succeed("networkctl status eth1")
|
||||
assert "Network File: /etc/systemd/network/40-eth1.network" in eth1_status, \
|
||||
"The client interface eth1 is not using the expected network file"
|
||||
assert "10.0.0.10" in eth1_status, "Did not find expected client IPv4"
|
||||
|
||||
with subtest("router and client can reach each other"):
|
||||
client.wait_until_succeeds("ping -c 5 10.0.0.1")
|
||||
router.wait_until_succeeds("ping -c 5 10.0.0.10")
|
||||
'';
|
||||
})
|
@ -6,11 +6,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "bitwig-studio";
|
||||
version = "4.1";
|
||||
version = "4.1.1";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://downloads.bitwig.com/stable/${version}/${pname}-${version}.deb";
|
||||
sha256 = "sha256-h6TNlfKgN7CPhtY8DxESrydtEsdVPT+Uf+VKcqKVuXw=";
|
||||
sha256 = "sha256-bhd3Ij4y1r5pHrpQkbHuMTNl8Z3w0HsbCkr1C0CVFvQ=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ dpkg makeWrapper wrapGAppsHook ];
|
||||
|
@ -21,20 +21,20 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "gnome-podcasts";
|
||||
version = "0.4.9";
|
||||
version = "0.5.0";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
domain = "gitlab.gnome.org";
|
||||
owner = "World";
|
||||
repo = "podcasts";
|
||||
rev = version;
|
||||
sha256 = "1ah59ac3xm3sqai8zhil8ar30pviw83cm8in1n4id77rv24xkvgm";
|
||||
hash = "sha256-Jk++/QrQt/fjOz2OaEIr1Imq2DmqTjcormCebjO4/Kk=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoTarball {
|
||||
inherit src;
|
||||
name = "${pname}-${version}";
|
||||
sha256 = "1iihpfvkli09ysn46cnif53xizkwzk0m91bljmlzsygp3ip5i5yw";
|
||||
hash = "sha256-jlXpeVabc1h2GU1j9Ff6GZJec+JgFyOdJzsOtdkrEWI=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -5,14 +5,14 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "helio-workstation";
|
||||
version = "3.6";
|
||||
version = "3.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "helio-fm";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
fetchSubmodules = true;
|
||||
sha256 = "sha256-qW39g6rQ5VPQ3Hx9NmwLbpZiITnzFZDZlcLkE+pJKPc=";
|
||||
sha256 = "sha256-uwRSOJ5WvDH4mfL9pCTCGzuSRT8SIBrI+Wsbumzejv0=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
@ -30,13 +30,13 @@ stdenv.mkDerivation rec {
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
install -Dm755 build/Helio $out/bin
|
||||
wrapProgram $out/bin/Helio --prefix PATH ":" ${gnome.zenity}/bin
|
||||
install -Dm755 build/helio $out/bin
|
||||
wrapProgram $out/bin/helio --prefix PATH ":" ${gnome.zenity}/bin
|
||||
|
||||
mkdir -p $out/share
|
||||
cp -r ../Deployment/Linux/Debian/x64/usr/share/* $out/share
|
||||
substituteInPlace $out/share/applications/Helio.desktop \
|
||||
--replace "/usr/bin/helio" "$out/bin/Helio"
|
||||
--replace "/usr/bin/helio" "$out/bin/helio"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "jamulus";
|
||||
version = "3.8.0";
|
||||
version = "3.8.1";
|
||||
src = fetchFromGitHub {
|
||||
owner = "jamulussoftware";
|
||||
repo = "jamulus";
|
||||
rev = "r${lib.replaceStrings [ "." ] [ "_" ] version}";
|
||||
sha256 = "sha256-Ni6N7XW34OFNuEkqBEgMcYGmIqb+UZ0uhLt/shRkWRs=";
|
||||
sha256 = "sha256-QtlvcKVqKgRAO/leHy4CgvjNW49HAyZLI2JtKERP7HQ=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config qmake ];
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "JMusicBot";
|
||||
version = "0.3.4";
|
||||
version = "0.3.6";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/jagrosh/MusicBot/releases/download/${version}/JMusicBot-${version}.jar";
|
||||
sha256 = "sha256-++/ot9k74pkN9Wl7IEjiMIv/q5zklIEdU6uFjam0tmU=";
|
||||
sha256 = "sha256-Hc3dsOADC+jVZScY19OYDkHimntMjdw/BoB3EUS/d0k=";
|
||||
};
|
||||
|
||||
dontUnpack = true;
|
||||
|
@ -1,37 +0,0 @@
|
||||
{ lib, stdenv, fetchurl, makeWrapper, pkg-config, MMA, libjack2, libsmf, python2Packages }:
|
||||
|
||||
let
|
||||
inherit (python2Packages) pyGtkGlade pygtksourceview python;
|
||||
in stdenv.mkDerivation rec {
|
||||
version = "12.02.1";
|
||||
pname = "linuxband";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://linuxband.org/assets/sources/${pname}-${version}.tar.gz";
|
||||
sha256 = "1r71h4yg775m4gax4irrvygmrsclgn503ykmc2qwjsxa42ri4n2n";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ pkg-config makeWrapper ];
|
||||
buildInputs = [ MMA libjack2 libsmf python pyGtkGlade pygtksourceview ];
|
||||
|
||||
patchPhase = ''
|
||||
sed -i 's@/usr/@${MMA}/@g' src/main/config/linuxband.rc.in
|
||||
cat src/main/config/linuxband.rc.in
|
||||
'';
|
||||
|
||||
postFixup = ''
|
||||
PYTHONPATH=$pyGtkGlade/share/:pygtksourceview/share/:$PYTHONPATH
|
||||
for f in $out/bin/*; do
|
||||
wrapProgram $f \
|
||||
--prefix PYTHONPATH : $PYTHONPATH
|
||||
done
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "A GUI front-end for MMA: Type in the chords, choose the groove and it will play an accompaniment";
|
||||
homepage = "https://linuxband.org/";
|
||||
license = lib.licenses.gpl2;
|
||||
maintainers = [ lib.maintainers.magnetophon ];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
@ -1,18 +1,19 @@
|
||||
{ lib, stdenv, fetchFromGitHub, lv2 }:
|
||||
{ lib, stdenv, fetchFromGitHub, lv2, cairo, pkg-config }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
|
||||
pname = "molot-lite";
|
||||
version = "1.0.0";
|
||||
version = "1.1.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "magnetophon";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "0xbvicfk1rgp01nlg6hlym9bnygry0nrbv88mv7w6hnacvl63ba4";
|
||||
sha256 = "sha256-0tmobsdCNon6udbkbQw7+EYQKBg2oaXlHIgNEf9U3XE=";
|
||||
};
|
||||
|
||||
buildInputs = [ lv2 ];
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ lv2 cairo ];
|
||||
|
||||
makeFlags = [ "INSTALL_DIR=$out/lib/lv2" ];
|
||||
|
||||
|
@ -11,13 +11,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "mpc";
|
||||
version = "0.33";
|
||||
version = "0.34";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "MusicPlayerDaemon";
|
||||
repo = "mpc";
|
||||
rev = "v${version}";
|
||||
sha256 = "1qbi0i9cq54rj8z2kapk8x8g1jkw2jz781niwb9i7kw4xfhvy5zx";
|
||||
sha256 = "sha256-2FjYBfak0IjibuU+CNQ0y9Ei8hTZhynS/BK2DNerhVw=";
|
||||
};
|
||||
|
||||
buildInputs = [ libmpdclient ] ++ lib.optionals stdenv.isDarwin [ libiconv ];
|
||||
|
@ -18,13 +18,13 @@ assert pcreSupport -> pcre != null;
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ncmpc";
|
||||
version = "0.45";
|
||||
version = "0.46";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "MusicPlayerDaemon";
|
||||
repo = "ncmpc";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-KDSHbEZ2PJLEIlXqPvBQ2ZPWno+IoajTjkl9faAXIko=";
|
||||
sha256 = "sha256-FyuN0jkHaJLXqcVbW+OggHkNBjmqH7bS7W/QXUoDjJk=";
|
||||
};
|
||||
|
||||
buildInputs = [ glib ncurses libmpdclient boost ]
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "padthv1";
|
||||
version = "0.9.18";
|
||||
version = "0.9.23";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://sourceforge/padthv1/${pname}-${version}.tar.gz";
|
||||
sha256 = "1karrprb3ijrbiwpr43rl3nxnzc33lnmwrd1832psgr3flnr9fp5";
|
||||
sha256 = "sha256-9yFfvlskOYnGraou2S3Qffl8RoYJqE0wnDlOP8mxQgg=";
|
||||
};
|
||||
|
||||
buildInputs = [ libjack2 alsa-lib libsndfile liblo lv2 qt5.qtbase qt5.qttools fftwFloat ];
|
||||
|
@ -7,13 +7,13 @@ let
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
name = "${pname}-${version}";
|
||||
version = "1.69";
|
||||
version = "1.70";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "graysky2";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-5WRhVIQlSwWuyvkzrnNW0rdVet9ZzM47gISJpznM8mU=";
|
||||
sha256 = "sha256-ZB1jrr31PF7+vNB+Xo5CATJmYbuDAPwewpDxCVnAowY=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
@ -21,14 +21,14 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "deja-dup";
|
||||
version = "42.7";
|
||||
version = "42.8";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
domain = "gitlab.gnome.org";
|
||||
owner = "World";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "1q66wccnph78cp1r5mln2iq4bcqdrrchxq3c1pjrzkmzwc6l93gz";
|
||||
sha256 = "sha256-DkRqZAj47wzt4lDvhAbO0PYcRA7oHEo2k69IMLOD3Ps=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
@ -24,11 +24,11 @@
|
||||
with lib;
|
||||
stdenv.mkDerivation rec {
|
||||
pname = if withGui then "elements" else "elementsd";
|
||||
version = "0.21.0";
|
||||
version = "0.21.0.1";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/ElementsProject/elements/archive/elements-${version}.tar.gz";
|
||||
sha256 = "0d9mcb0nw9qqhv0jhpddi9i4iry3w7b5jifsl5kpcw82qrkvgfgj";
|
||||
sha256 = "00a2lrn77mfmr5dvrqwplk20gaxxq4cd9gcx667hgmfmmz1v6r6b";
|
||||
};
|
||||
|
||||
nativeBuildInputs =
|
||||
|
@ -9,17 +9,17 @@ let
|
||||
|
||||
in buildGoModule rec {
|
||||
pname = "go-ethereum";
|
||||
version = "1.10.8";
|
||||
version = "1.10.11";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "ethereum";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-r4ifLa4CMZvp0MaCkxWo5rWLEnFdX//mYlC08hndXhQ=";
|
||||
sha256 = "sha256-8kPaa2wRKUQBn4LFDnc7tEbLR62f99NS1HIVDeHHzto=";
|
||||
};
|
||||
|
||||
runVend = true;
|
||||
vendorSha256 = "sha256-e8aKQMVEEf0BzpdljkOBxznj5P1Go/6EbY9mdhDLyrw=";
|
||||
vendorSha256 = "sha256-i2FOAN1ng3WNOWaFowiSSuYR4LA1Bo3tjkvgcClBXSU=";
|
||||
|
||||
doCheck = false;
|
||||
|
||||
|
@ -9,13 +9,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "monero-cli";
|
||||
version = "0.17.2.3";
|
||||
version = "0.17.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "monero-project";
|
||||
repo = "monero";
|
||||
rev = "v${version}";
|
||||
sha256 = "0nax991fshfh51grhh2ryfrwwws35k16gzl1l3niva28zff2xmq6";
|
||||
sha256 = "1spsf7m3x4psp9s7mivr6x4886jnbq4i8ll2dl8bv5bsdhcd3pjm";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -1,14 +1,17 @@
|
||||
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
|
||||
index a8916a7d0..39ec7747b 100644
|
||||
index 5b7f69a56..5536debe8 100644
|
||||
--- a/external/CMakeLists.txt
|
||||
+++ b/external/CMakeLists.txt
|
||||
@@ -37,34 +37,16 @@
|
||||
@@ -36,22 +36,9 @@
|
||||
# others.
|
||||
|
||||
find_package(Miniupnpc REQUIRED)
|
||||
|
||||
-
|
||||
-message(STATUS "Using in-tree miniupnpc")
|
||||
-set(UPNPC_NO_INSTALL TRUE CACHE BOOL "Disable miniupnp installation" FORCE)
|
||||
-add_subdirectory(miniupnp/miniupnpc)
|
||||
-set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
|
||||
-set_property(TARGET libminiupnpc-static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
-if(MSVC)
|
||||
- set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
-elseif(NOT MSVC)
|
||||
@ -25,36 +28,16 @@ index a8916a7d0..39ec7747b 100644
|
||||
|
||||
find_package(Unbound)
|
||||
|
||||
if(NOT UNBOUND_INCLUDE_DIR OR STATIC)
|
||||
- # NOTE: If STATIC is true, CMAKE_FIND_LIBRARY_SUFFIXES has been reordered.
|
||||
- # unbound has config tests which used OpenSSL libraries, so -ldl may need to
|
||||
- # be set in this case.
|
||||
- # The unbound CMakeLists.txt can set it, since it's also needed for the
|
||||
- # static OpenSSL libraries set up there after with target_link_libraries.
|
||||
- add_subdirectory(unbound)
|
||||
-
|
||||
- set(UNBOUND_STATIC true PARENT_SCOPE)
|
||||
- set(UNBOUND_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/unbound/libunbound" PARENT_SCOPE)
|
||||
- set(UNBOUND_LIBRARY "unbound" PARENT_SCOPE)
|
||||
- set(UNBOUND_LIBRARY_DIRS "${LIBEVENT2_LIBDIR}" PARENT_SCOPE)
|
||||
+ set(UNBOUND_STATIC false PARENT_SCOPE)
|
||||
+ set(UPNP_INCLUDE ${MINIUPNP_INCLUDE_DIR} PARENT_SCOPE)
|
||||
+ set(UPNP_LIBRARIES ${MINIUPNP_LIBRARY} PARENT_SCOPE)
|
||||
else()
|
||||
message(STATUS "Found libunbound include (unbound.h) in ${UNBOUND_INCLUDE_DIR}")
|
||||
if(UNBOUND_LIBRARIES)
|
||||
@@ -81,4 +63,5 @@ endif()
|
||||
@@ -69,4 +56,3 @@ endif()
|
||||
add_subdirectory(db_drivers)
|
||||
add_subdirectory(easylogging++)
|
||||
add_subdirectory(qrcodegen)
|
||||
-add_subdirectory(randomx EXCLUDE_FROM_ALL)
|
||||
+
|
||||
+find_library(RANDOMX_LIBRARIES NAMES RandomX)
|
||||
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
|
||||
index 175741146..088b582f7 100644
|
||||
index d4b39869c..13071d898 100644
|
||||
--- a/src/p2p/net_node.inl
|
||||
+++ b/src/p2p/net_node.inl
|
||||
@@ -60,9 +60,9 @@
|
||||
@@ -61,9 +61,9 @@
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#include "net/parse.h"
|
||||
|
||||
|
@ -14,13 +14,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "monero-gui";
|
||||
version = "0.17.2.3";
|
||||
version = "0.17.3.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "monero-project";
|
||||
repo = "monero-gui";
|
||||
rev = "v${version}";
|
||||
sha256 = "1d8y5yqyw0db2jdv9mwkczwm2qcwhzyslvq994yq5rvs4vkd8xjg";
|
||||
sha256 = "0rc1p0k16icgfhc7yvkvb8p6570zz0cvigs648l05fcm3mf787rp";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
let
|
||||
pname = "trezor-suite";
|
||||
version = "21.11.2";
|
||||
version = "21.12.2";
|
||||
name = "${pname}-${version}";
|
||||
|
||||
suffix = {
|
||||
@ -19,8 +19,8 @@ let
|
||||
src = fetchurl {
|
||||
url = "https://github.com/trezor/${pname}/releases/download/v${version}/Trezor-Suite-${version}-${suffix}.AppImage";
|
||||
sha512 = { # curl -Lfs https://github.com/trezor/trezor-suite/releases/latest/download/latest-linux{-arm64,}.yml | grep ^sha512 | sed 's/: /-/'
|
||||
aarch64-linux = "sha512-QX5Ak2F1aD846BuGNcP1K/2c77Ut3LK3UiXsUPqiSBGZ9YRgdzROqdGjCVnTBBhxeCfGYQDhWmpuOpNbLr4eYg==";
|
||||
x86_64-linux = "sha512-ckMlZoLEq3aLzyhoWf2rRE3XxNQhqo6rUHF2NKoV08sXz+Zth2Lk+P3te1vwFQl+Efryl84RTwVGWKmloZ8k9A==";
|
||||
aarch64-linux = "sha512-LzcTFSNN/loYaTDt+QpW8QpSgOTw2097IYdc7mC57Mn4NR/X2hycYZ9ZfZjBh9QFfVu/4R3UN2sA177v6Inomg==";
|
||||
x86_64-linux = "sha512-W/voBZrXaJVDN4eSUDD6lyBR9BqboD2k2/azI1pWm1NFUmDZFM+OGzyiPB3n+6SziAhca32Ot5Wy27sfmIjh3g==";
|
||||
}.${stdenv.hostPlatform.system} or (throw "Unsupported system: ${stdenv.hostPlatform.system}");
|
||||
};
|
||||
|
||||
|
40
pkgs/applications/editors/cpeditor/default.nix
Normal file
40
pkgs/applications/editors/cpeditor/default.nix
Normal file
@ -0,0 +1,40 @@
|
||||
{ lib
|
||||
, stdenv
|
||||
, fetchFromGitHub
|
||||
, pkg-config
|
||||
, qtbase
|
||||
, qttools
|
||||
, wrapQtAppsHook
|
||||
, cmake
|
||||
, ninja
|
||||
, python3
|
||||
, runtimeShell
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "cpeditor";
|
||||
version = "6.10.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "cpeditor";
|
||||
repo = "cpeditor";
|
||||
rev = version;
|
||||
sha256 = "sha256-SIREoOapaZTLtqi0Z07lKmNqF9a9qIpgGxuhqaY3yfU=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake ninja pkg-config wrapQtAppsHook python3 ];
|
||||
buildInputs = [ qtbase qttools ];
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace src/Core/Runner.cpp --replace "/bin/bash" "${runtimeShell}"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "An IDE specially designed for competitive programming";
|
||||
homepage = "https://cpeditor.org";
|
||||
license = licenses.gpl3Plus;
|
||||
platforms = platforms.linux;
|
||||
maintainers = with maintainers; [ rewine ];
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@ stdenv.mkDerivation rec {
|
||||
version = "27.2";
|
||||
|
||||
emacsName = "emacs-${version}";
|
||||
macportVersion = "8.2";
|
||||
macportVersion = "8.3";
|
||||
name = "emacs-mac-${version}-${macportVersion}";
|
||||
|
||||
src = fetchurl {
|
||||
@ -18,7 +18,8 @@ stdenv.mkDerivation rec {
|
||||
|
||||
macportSrc = fetchurl {
|
||||
url = "ftp://ftp.math.s.chiba-u.ac.jp/emacs/${emacsName}-mac-${macportVersion}.tar.gz";
|
||||
sha256 = "1bgm2g3ky7rkj1l27wnmyzqsqxzjng7y9bf72ym37wiyhyi2a9za";
|
||||
sha256 = "0q4lbk3nb8rz1ibmf23plgsh8sx2wvhry5bf5mivgz4m4b6s2yij";
|
||||
name = "${emacsName}-mac-${macportVersion}.tar.xz"; # It's actually compressed with xz, not gz
|
||||
};
|
||||
|
||||
hiresSrc = fetchurl {
|
||||
@ -37,11 +38,11 @@ stdenv.mkDerivation rec {
|
||||
|
||||
postUnpack = ''
|
||||
mv $sourceRoot $name
|
||||
tar xzf $macportSrc -C $name --strip-components=1
|
||||
tar xf $macportSrc -C $name --strip-components=1
|
||||
mv $name $sourceRoot
|
||||
|
||||
# extract retina image resources
|
||||
tar xzfv $hiresSrc --strip 1 -C $sourceRoot
|
||||
tar xfv $hiresSrc --strip 1 -C $sourceRoot
|
||||
'';
|
||||
|
||||
postPatch = ''
|
||||
|
@ -1,20 +1,24 @@
|
||||
{ pkgs, fetchurl, python2Packages }:
|
||||
{ pkgs, fetchFromGitHub, python3Packages }:
|
||||
|
||||
let
|
||||
pythonPackages = python2Packages;
|
||||
pythonPackages = python3Packages;
|
||||
in pythonPackages.buildPythonApplication rec {
|
||||
version = "0.9.7";
|
||||
version = "2.1.0";
|
||||
pname = "nvpy";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/cpbotha/nvpy/archive/v${version}.tar.gz";
|
||||
sha256 = "1rd3vlaqkg16iz6qcw6rkbq0jmyvc0843wa3brnvn1nz0kla243f";
|
||||
src = fetchFromGitHub {
|
||||
owner = "cpbotha";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "02njvybd8yaqdnc5ghwrm8225z57gg4w7rhmx3w5jqzh16ld4mhh";
|
||||
};
|
||||
|
||||
|
||||
propagatedBuildInputs = with pythonPackages; [
|
||||
markdown
|
||||
tkinter
|
||||
docutils
|
||||
simplenote
|
||||
tkinter
|
||||
];
|
||||
|
||||
# No tests
|
||||
|
@ -118,7 +118,7 @@ let
|
||||
packed="resources/app/node_modules.asar"
|
||||
unpacked="resources/app/node_modules"
|
||||
${nodePackages.asar}/bin/asar extract "$packed" "$unpacked"
|
||||
substituteInPlace $unpacked/sudo-prompt/index.js \
|
||||
substituteInPlace $unpacked/@vscode/sudo-prompt/index.js \
|
||||
--replace "/usr/bin/pkexec" "/run/wrappers/bin/pkexec" \
|
||||
--replace "/bin/bash" "${bash}/bin/bash"
|
||||
rm -rf "$packed"
|
||||
|
@ -14,17 +14,17 @@ let
|
||||
archive_fmt = if stdenv.isDarwin then "zip" else "tar.gz";
|
||||
|
||||
sha256 = {
|
||||
x86_64-linux = "0wf8bmzag49n81kjb46kj2nkksimm8f7cf4ihpqcw8k5iwasn3j9";
|
||||
x86_64-darwin = "1s7i5087bvckg66mcb32krv12vxhaw7ii9vm3i6p72wr0sv7dddh";
|
||||
aarch64-linux = "0yzh5javinvas3zz0lliyc77vbcs1jrmxbkr7nic4snscg6wjhcd";
|
||||
aarch64-darwin = "13l6ymz7v18s7ikxbwvkwb0f5ff2j82j5pfj04yy75kq9b5gh0vx";
|
||||
armv7l-linux = "129wffj9cidk9ysjpq3p0ddn6liwkmrkxhxgz7bqzj8sdhwyq8pz";
|
||||
x86_64-linux = "1w28rmb9fi45s85rrlzzh6r826dnyisd6lh3j8ir4hx6d34cawsf";
|
||||
x86_64-darwin = "1fyg3ygqk0z3jcj5bskgprlq8k9j134y75xq06z4xbv1dhgwhswj";
|
||||
aarch64-linux = "0hha9ksbj51zmq0p3d1fwni4jd0yp0wab0w19carmbhnydhrgh22";
|
||||
aarch64-darwin = "1cmrh621z7ddl4qh95hm0nwzazshl71a43c6113jf4w6b1kvy5m5";
|
||||
armv7l-linux = "1kipvqc5hrpgsfw7x2ab5jydf7zksdd3q8qr2mg20kjsdi4skwy4";
|
||||
}.${system};
|
||||
in
|
||||
callPackage ./generic.nix rec {
|
||||
# Please backport all compatible updates to the stable release.
|
||||
# This is important for the extension ecosystem.
|
||||
version = "1.62.3";
|
||||
version = "1.63.0";
|
||||
pname = "vscode";
|
||||
|
||||
executableName = "code" + lib.optionalString isInsiders "-insiders";
|
||||
|
@ -13,10 +13,10 @@ let
|
||||
archive_fmt = if system == "x86_64-darwin" then "zip" else "tar.gz";
|
||||
|
||||
sha256 = {
|
||||
x86_64-linux = "0g1c88i0nkg4hys00vhqp0i2n3kjl395fd2rimi2p49y042b5c9g";
|
||||
x86_64-darwin = "1521aqrv9zx2r5cy8h2011iz3v5lvayizlgv8j7j8qi272mmvx5k";
|
||||
aarch64-linux = "1kk0jrhqx6q325zmfg553pqmk6v9cx3a99bsh9rzvdlca94nmpj0";
|
||||
armv7l-linux = "08hy61a9pp18b1x7lnsc7b9y3bvnjmavazz7qkhp5qxl2gs802wm";
|
||||
x86_64-linux = "17kck7pkklhifm6hpsd93wmnyk06vi9sa55gp62m3diymp1b129z";
|
||||
x86_64-darwin = "1japc6yyvw07rll53pf2jfg89m2g9jqj5daghg10v1gqk98j7r3x";
|
||||
aarch64-linux = "0zg05q0hyldnw5g8b9zdf0ls4s07fixib7v830wa5dyi2sjcv149";
|
||||
armv7l-linux = "0mky66cyxhx3cfm35sa4vlwh8m1878rc80jml9mqxdhlrpnxgdiy";
|
||||
}.${system};
|
||||
|
||||
sourceRoot = {
|
||||
@ -31,7 +31,7 @@ in
|
||||
|
||||
# Please backport all compatible updates to the stable release.
|
||||
# This is important for the extension ecosystem.
|
||||
version = "1.62.3";
|
||||
version = "1.63.0";
|
||||
pname = "vscodium";
|
||||
|
||||
executableName = "codium";
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "your-editor";
|
||||
version = "1206";
|
||||
version = "1303";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "kammerdienerb";
|
||||
owner = "your-editor";
|
||||
repo = "yed";
|
||||
rev = "6cdd99fe1359899b26d8967bd376fd5caa5451eb";
|
||||
sha256 = "0XECSolW/xPXd1v3sv9HbJMWuHGnwCOwmHoPNCUsE+w=";
|
||||
rev = version;
|
||||
sha256 = "BWy/icQs8hVtNeM/mCi6LOah1UG0elU/DgCmfaIPD64=";
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
@ -21,8 +21,9 @@ stdenv.mkDerivation rec {
|
||||
meta = with lib; {
|
||||
description = "Your-editor (yed) is a small and simple terminal editor core that is meant to be extended through a powerful plugin architecture";
|
||||
homepage = "https://your-editor.org/";
|
||||
changelog = "https://github.com/your-editor/yed/blob/${version}/CHANGELOG.md";
|
||||
license = with licenses; [ mit ];
|
||||
platforms = platforms.linux;
|
||||
platforms = platforms.unix;
|
||||
maintainers = with maintainers; [ uniquepointer ];
|
||||
mainProgram = "yed";
|
||||
};
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "dcw-gmt";
|
||||
version = "1.1.4";
|
||||
version = "2.0.1";
|
||||
src = fetchurl {
|
||||
url = "ftp://ftp.soest.hawaii.edu/gmt/dcw-gmt-${version}.tar.gz";
|
||||
sha256 = "8d47402abcd7f54a0f711365cd022e4eaea7da324edac83611ca035ea443aad3";
|
||||
sha256 = "sha256-XJCylo9Alc9epEo1TcnY+d0bj+VRTgM4/4W0jgNUeiU=";
|
||||
};
|
||||
|
||||
installPhase = ''
|
||||
|
@ -1,13 +1,13 @@
|
||||
{ lib, stdenv, mkDerivation, fetchFromGitLab, qmake, qtbase, qttools, qtserialport, libGLU }:
|
||||
mkDerivation rec {
|
||||
pname = "OSCAR";
|
||||
version = "1.2.0";
|
||||
version = "1.3.0";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "pholy";
|
||||
repo = "OSCAR-code";
|
||||
rev = "v${version}";
|
||||
sha256 = "10r37d8c2avr167n2s9lhld1c9hmckm444fq163z1jsy9jpid6mg";
|
||||
sha256 = "sha256-oKKwX5HiT8RACiqzZegOxH6IHQn/u0N4ih/ubH6YYjg=";
|
||||
};
|
||||
|
||||
buildInputs = [ qtbase qttools qtserialport libGLU ];
|
||||
|
@ -27,14 +27,14 @@
|
||||
|
||||
mkDerivation rec {
|
||||
pname = "calibre";
|
||||
version = "5.31.1";
|
||||
version = "5.33.2";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://download.calibre-ebook.com/${version}/${pname}-${version}.tar.xz";
|
||||
sha256 = "sha256-3LGEWuHms54ji9GWSyLl8cFWIRBqHY1Jf/CNPJOywrU=";
|
||||
sha256 = "sha256-wtt3ucCaFq9wLk79CeCz20tMM6AbLtZ4Ln6TxOx0dvI=";
|
||||
};
|
||||
|
||||
# https://sources.debian.org/patches/calibre/5.31.1+dfsg-1
|
||||
# https://sources.debian.org/patches/calibre/5.33.2+dfsg-1
|
||||
patches = [
|
||||
# allow for plugin update check, but no calibre version check
|
||||
(fetchpatch {
|
||||
|
@ -34,8 +34,8 @@ let
|
||||
qonlinetranslator = fetchFromGitHub {
|
||||
owner = "crow-translate";
|
||||
repo = "QOnlineTranslator";
|
||||
rev = "df89083d2f680a8f856b1df00b8846f995cf1fae";
|
||||
sha256 = "sha256-I64KGInnYd/QdI5kANJERsF95wMvRlr8kgQhUqXXN/0=";
|
||||
rev = "1.5.2";
|
||||
sha256 = "sha256-iGi25aKwff2hNNx6o4kHZV8gVbEQcMgpTTvop3CoLjM=";
|
||||
};
|
||||
circleflags = fetchFromGitHub {
|
||||
owner = "HatScripts";
|
||||
@ -52,13 +52,13 @@ let
|
||||
in
|
||||
mkDerivation rec {
|
||||
pname = "crow-translate";
|
||||
version = "2.8.7";
|
||||
version = "2.9.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "crow-translate";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "sha256-0bq9itbFyzdOhdNuUtdCYLTCIhc91MM+YRhJgXC5PPw=";
|
||||
sha256 = "sha256-7Zb6PZO8eLeGPEZD37ja+LZydIQdsgy5gMAMtlS4k5Y=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user