Merge master into staging-next
This commit is contained in:
commit
89ec09c858
102
nixos/modules/services/networking/mosquitto.md
Normal file
102
nixos/modules/services/networking/mosquitto.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Mosquitto {#module-services-mosquitto}
|
||||
|
||||
Mosquitto is a MQTT broker often used for IoT or home automation data transport.
|
||||
|
||||
## Quickstart {#module-services-mosquitto-quickstart}
|
||||
|
||||
A minimal configuration for Mosquitto is
|
||||
|
||||
```nix
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [ {
|
||||
acl = [ "pattern readwrite #" ];
|
||||
omitPasswordAuth = true;
|
||||
settings.allow_anonymous = true;
|
||||
} ];
|
||||
};
|
||||
```
|
||||
|
||||
This will start a broker on port 1883, listening on all interfaces of the machine, allowing
|
||||
read/write access to all topics to any user without password requirements.
|
||||
|
||||
User authentication can be configured with the `users` key of listeners. A config that gives
|
||||
full read access to a user `monitor` and restricted write access to a user `service` could look
|
||||
like
|
||||
|
||||
```nix
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [ {
|
||||
users = {
|
||||
monitor = {
|
||||
acl = [ "read #" ];
|
||||
password = "monitor";
|
||||
};
|
||||
service = {
|
||||
acl = [ "write service/#" ];
|
||||
password = "service";
|
||||
};
|
||||
};
|
||||
} ];
|
||||
};
|
||||
```
|
||||
|
||||
TLS authentication is configured by setting TLS-related options of the listener:
|
||||
|
||||
```nix
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [ {
|
||||
port = 8883; # port change is not required, but helpful to avoid mistakes
|
||||
# ...
|
||||
settings = {
|
||||
cafile = "/path/to/mqtt.ca.pem";
|
||||
certfile = "/path/to/mqtt.pem";
|
||||
keyfile = "/path/to/mqtt.key";
|
||||
};
|
||||
} ];
|
||||
```
|
||||
|
||||
## Configuration {#module-services-mosquitto-config}
|
||||
|
||||
The Mosquitto configuration has four distinct types of settings:
|
||||
the global settings of the daemon, listeners, plugins, and bridges.
|
||||
Bridges and listeners are part of the global configuration, plugins are part of listeners.
|
||||
Users of the broker are configured as parts of listeners rather than globally, allowing
|
||||
configurations in which a given user is only allowed to log in to the broker using specific
|
||||
listeners (eg to configure an admin user with full access to all topics, but restricted to
|
||||
localhost).
|
||||
|
||||
Almost all options of Mosquitto are available for configuration at their appropriate levels, some
|
||||
as NixOS options written in camel case, the remainders under `settings` with their exact names in
|
||||
the Mosquitto config file. The exceptions are `acl_file` (which is always set according to the
|
||||
`acl` attributes of a listener and its users) and `per_listener_settings` (which is always set to
|
||||
`true`).
|
||||
|
||||
### Password authentication {#module-services-mosquitto-config-passwords}
|
||||
|
||||
Mosquitto can be run in two modes, with a password file or without. Each listener has its own
|
||||
password file, and different listeners may use different password files. Password file generation
|
||||
can be disabled by setting `omitPasswordAuth = true` for a listener; in this case it is necessary
|
||||
to either set `settings.allow_anonymous = true` to allow all logins, or to configure other
|
||||
authentication methods like TLS client certificates with `settings.use_identity_as_username = true`.
|
||||
|
||||
The default is to generate a password file for each listener from the users configured to that
|
||||
listener. Users with no configured password will not be added to the password file and thus
|
||||
will not be able to use the broker.
|
||||
|
||||
### ACL format {#module-services-mosquitto-config-acl}
|
||||
|
||||
Every listener has a Mosquitto `acl_file` attached to it. This ACL is configured via two
|
||||
attributes of the config:
|
||||
|
||||
* the `acl` attribute of the listener configures pattern ACL entries and topic ACL entries
|
||||
for anonymous users. Each entry must be prefixed with `pattern` or `topic` to distinguish
|
||||
between these two cases.
|
||||
* the `acl` attribute of every user configures in the listener configured the ACL for that
|
||||
given user. Only topic ACLs are supported by Mosquitto in this setting, so no prefix is
|
||||
required or allowed.
|
||||
|
||||
The default ACL for a listener is empty, disallowing all accesses from all clients. To configure
|
||||
a completely open ACL, set `acl = [ "pattern readwrite #" ]` in the listener.
|
@ -257,18 +257,28 @@ let
|
||||
|
||||
users = mkOption {
|
||||
type = attrsOf userOptions;
|
||||
example = { john = { password = "123456"; acl = [ "topic readwrite john/#" ]; }; };
|
||||
example = { john = { password = "123456"; acl = [ "readwrite john/#" ]; }; };
|
||||
description = ''
|
||||
A set of users and their passwords and ACLs.
|
||||
'';
|
||||
default = {};
|
||||
};
|
||||
|
||||
omitPasswordAuth = mkOption {
|
||||
type = bool;
|
||||
description = ''
|
||||
Omits password checking, allowing anyone to log in with any user name unless
|
||||
other mandatory authentication methods (eg TLS client certificates) are configured.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
|
||||
acl = mkOption {
|
||||
type = listOf str;
|
||||
description = ''
|
||||
Additional ACL items to prepend to the generated ACL file.
|
||||
'';
|
||||
example = [ "pattern read #" "topic readwrite anon/report/#" ];
|
||||
default = [];
|
||||
};
|
||||
|
||||
@ -294,9 +304,9 @@ let
|
||||
formatListener = idx: listener:
|
||||
[
|
||||
"listener ${toString listener.port} ${toString listener.address}"
|
||||
"password_file ${cfg.dataDir}/passwd-${toString idx}"
|
||||
"acl_file ${makeACLFile idx listener.users listener.acl}"
|
||||
]
|
||||
++ optional (! listener.omitPasswordAuth) "password_file ${cfg.dataDir}/passwd-${toString idx}"
|
||||
++ formatFreeform {} listener.settings
|
||||
++ concatMap formatAuthPlugin listener.authPlugins;
|
||||
|
||||
@ -645,5 +655,10 @@ in
|
||||
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ pennae ];
|
||||
meta = {
|
||||
maintainers = with lib.maintainers; [ pennae ];
|
||||
# Don't edit the docbook xml directly, edit the md and generate it:
|
||||
# `pandoc mosquitto.md -t docbook --top-level-division=chapter --extract-media=media -f markdown+smart > mosquitto.xml`
|
||||
doc = ./mosquitto.xml;
|
||||
};
|
||||
}
|
||||
|
147
nixos/modules/services/networking/mosquitto.xml
Normal file
147
nixos/modules/services/networking/mosquitto.xml
Normal file
@ -0,0 +1,147 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="module-services-mosquitto">
|
||||
<title>Mosquitto</title>
|
||||
<para>
|
||||
Mosquitto is a MQTT broker often used for IoT or home automation
|
||||
data transport.
|
||||
</para>
|
||||
<section xml:id="module-services-mosquitto-quickstart">
|
||||
<title>Quickstart</title>
|
||||
<para>
|
||||
A minimal configuration for Mosquitto is
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [ {
|
||||
acl = [ "pattern readwrite #" ];
|
||||
omitPasswordAuth = true;
|
||||
settings.allow_anonymous = true;
|
||||
} ];
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
This will start a broker on port 1883, listening on all interfaces
|
||||
of the machine, allowing read/write access to all topics to any
|
||||
user without password requirements.
|
||||
</para>
|
||||
<para>
|
||||
User authentication can be configured with the
|
||||
<literal>users</literal> key of listeners. A config that gives
|
||||
full read access to a user <literal>monitor</literal> and
|
||||
restricted write access to a user <literal>service</literal> could
|
||||
look like
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [ {
|
||||
users = {
|
||||
monitor = {
|
||||
acl = [ "read #" ];
|
||||
password = "monitor";
|
||||
};
|
||||
service = {
|
||||
acl = [ "write service/#" ];
|
||||
password = "service";
|
||||
};
|
||||
};
|
||||
} ];
|
||||
};
|
||||
</programlisting>
|
||||
<para>
|
||||
TLS authentication is configured by setting TLS-related options of
|
||||
the listener:
|
||||
</para>
|
||||
<programlisting language="bash">
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
listeners = [ {
|
||||
port = 8883; # port change is not required, but helpful to avoid mistakes
|
||||
# ...
|
||||
settings = {
|
||||
cafile = "/path/to/mqtt.ca.pem";
|
||||
certfile = "/path/to/mqtt.pem";
|
||||
keyfile = "/path/to/mqtt.key";
|
||||
};
|
||||
} ];
|
||||
</programlisting>
|
||||
</section>
|
||||
<section xml:id="module-services-mosquitto-config">
|
||||
<title>Configuration</title>
|
||||
<para>
|
||||
The Mosquitto configuration has four distinct types of settings:
|
||||
the global settings of the daemon, listeners, plugins, and
|
||||
bridges. Bridges and listeners are part of the global
|
||||
configuration, plugins are part of listeners. Users of the broker
|
||||
are configured as parts of listeners rather than globally,
|
||||
allowing configurations in which a given user is only allowed to
|
||||
log in to the broker using specific listeners (eg to configure an
|
||||
admin user with full access to all topics, but restricted to
|
||||
localhost).
|
||||
</para>
|
||||
<para>
|
||||
Almost all options of Mosquitto are available for configuration at
|
||||
their appropriate levels, some as NixOS options written in camel
|
||||
case, the remainders under <literal>settings</literal> with their
|
||||
exact names in the Mosquitto config file. The exceptions are
|
||||
<literal>acl_file</literal> (which is always set according to the
|
||||
<literal>acl</literal> attributes of a listener and its users) and
|
||||
<literal>per_listener_settings</literal> (which is always set to
|
||||
<literal>true</literal>).
|
||||
</para>
|
||||
<section xml:id="module-services-mosquitto-config-passwords">
|
||||
<title>Password authentication</title>
|
||||
<para>
|
||||
Mosquitto can be run in two modes, with a password file or
|
||||
without. Each listener has its own password file, and different
|
||||
listeners may use different password files. Password file
|
||||
generation can be disabled by setting
|
||||
<literal>omitPasswordAuth = true</literal> for a listener; in
|
||||
this case it is necessary to either set
|
||||
<literal>settings.allow_anonymous = true</literal> to allow all
|
||||
logins, or to configure other authentication methods like TLS
|
||||
client certificates with
|
||||
<literal>settings.use_identity_as_username = true</literal>.
|
||||
</para>
|
||||
<para>
|
||||
The default is to generate a password file for each listener
|
||||
from the users configured to that listener. Users with no
|
||||
configured password will not be added to the password file and
|
||||
thus will not be able to use the broker.
|
||||
</para>
|
||||
</section>
|
||||
<section xml:id="module-services-mosquitto-config-acl">
|
||||
<title>ACL format</title>
|
||||
<para>
|
||||
Every listener has a Mosquitto <literal>acl_file</literal>
|
||||
attached to it. This ACL is configured via two attributes of the
|
||||
config:
|
||||
</para>
|
||||
<itemizedlist spacing="compact">
|
||||
<listitem>
|
||||
<para>
|
||||
the <literal>acl</literal> attribute of the listener
|
||||
configures pattern ACL entries and topic ACL entries for
|
||||
anonymous users. Each entry must be prefixed with
|
||||
<literal>pattern</literal> or <literal>topic</literal> to
|
||||
distinguish between these two cases.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
the <literal>acl</literal> attribute of every user
|
||||
configures in the listener configured the ACL for that given
|
||||
user. Only topic ACLs are supported by Mosquitto in this
|
||||
setting, so no prefix is required or allowed.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
The default ACL for a listener is empty, disallowing all
|
||||
accesses from all clients. To configure a completely open ACL,
|
||||
set <literal>acl = [ "pattern readwrite #" ]</literal>
|
||||
in the listener.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
@ -254,7 +254,7 @@ in
|
||||
"allow ${e}")
|
||||
cfg.allowedBridges;
|
||||
systemPackages = with pkgs; [ libressl.nc iptables cfg.package cfg.qemu.package ];
|
||||
etc.ethertypes.source = "${pkgs.ebtables}/etc/ethertypes";
|
||||
etc.ethertypes.source = "${pkgs.iptables}/etc/ethertypes";
|
||||
};
|
||||
|
||||
boot.kernelModules = [ "tun" ];
|
||||
|
@ -3,6 +3,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }:
|
||||
let
|
||||
port = 1888;
|
||||
tlsPort = 1889;
|
||||
anonPort = 1890;
|
||||
password = "VERY_secret";
|
||||
hashedPassword = "$7$101$/WJc4Mp+I+uYE9sR$o7z9rD1EYXHPwEP5GqQj6A7k4W1yVbePlb8TqNcuOLV9WNCiDgwHOB0JHC1WCtdkssqTBduBNUnUGd6kmZvDSw==";
|
||||
topic = "test/foo";
|
||||
@ -63,7 +64,7 @@ in {
|
||||
};
|
||||
in {
|
||||
server = { pkgs, ... }: {
|
||||
networking.firewall.allowedTCPPorts = [ port tlsPort ];
|
||||
networking.firewall.allowedTCPPorts = [ port tlsPort anonPort ];
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
settings = {
|
||||
@ -112,6 +113,18 @@ in {
|
||||
use_identity_as_username = true;
|
||||
};
|
||||
}
|
||||
{
|
||||
port = anonPort;
|
||||
omitPasswordAuth = true;
|
||||
settings.allow_anonymous = true;
|
||||
acl = [ "pattern read #" ];
|
||||
users = {
|
||||
anonWriter = {
|
||||
password = "<ignored>" + password;
|
||||
acl = [ "write ${topic}" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
@ -136,9 +149,8 @@ in {
|
||||
def publish(args, user, topic="${topic}", port=${toString port}):
|
||||
return "{} {}".format(mosquitto_cmd("pub", user, topic, port), args)
|
||||
|
||||
|
||||
def subscribe(args, user, topic="${topic}", port=${toString port}):
|
||||
return "{} -C 1 {}".format(mosquitto_cmd("sub", user, topic, port), args)
|
||||
return "{} -W 5 -C 1 {}".format(mosquitto_cmd("sub", user, topic, port), args)
|
||||
|
||||
def parallel(*fns):
|
||||
from threading import Thread
|
||||
@ -150,17 +162,15 @@ in {
|
||||
start_all()
|
||||
server.wait_for_unit("mosquitto.service")
|
||||
|
||||
def check_passwords():
|
||||
with subtest("check passwords"):
|
||||
client1.succeed(publish("-m test", "password_store"))
|
||||
client1.succeed(publish("-m test", "password_file"))
|
||||
client1.succeed(publish("-m test", "hashed_store"))
|
||||
client1.succeed(publish("-m test", "hashed_file"))
|
||||
|
||||
check_passwords()
|
||||
|
||||
def check_acl():
|
||||
with subtest("check acl"):
|
||||
client1.succeed(subscribe("", "reader", topic="$SYS/#"))
|
||||
client1.fail(subscribe("-W 5", "writer", topic="$SYS/#"))
|
||||
client1.fail(subscribe("", "writer", topic="$SYS/#"))
|
||||
|
||||
parallel(
|
||||
lambda: client1.succeed(subscribe("-i 3688cdd7-aa07-42a4-be22-cb9352917e40", "reader")),
|
||||
@ -170,15 +180,13 @@ in {
|
||||
])
|
||||
|
||||
parallel(
|
||||
lambda: client1.fail(subscribe("-W 5 -i 24ff16a2-ae33-4a51-9098-1b417153c712", "reader")),
|
||||
lambda: client1.fail(subscribe("-i 24ff16a2-ae33-4a51-9098-1b417153c712", "reader")),
|
||||
lambda: [
|
||||
server.wait_for_console_text("24ff16a2-ae33-4a51-9098-1b417153c712"),
|
||||
client2.succeed(publish("-m test", "reader"))
|
||||
])
|
||||
|
||||
check_acl()
|
||||
|
||||
def check_tls():
|
||||
with subtest("check tls"):
|
||||
client1.succeed(
|
||||
subscribe(
|
||||
"--cafile ${snakeOil}/ca.crt "
|
||||
@ -188,6 +196,13 @@ in {
|
||||
port=${toString tlsPort},
|
||||
user="no_such_user"))
|
||||
|
||||
check_tls()
|
||||
with subtest("check omitPasswordAuth"):
|
||||
parallel(
|
||||
lambda: client1.succeed(subscribe("-i fd56032c-d9cb-4813-a3b4-6be0e04c8fc3",
|
||||
"anonReader", port=${toString anonPort})),
|
||||
lambda: [
|
||||
server.wait_for_console_text("fd56032c-d9cb-4813-a3b4-6be0e04c8fc3"),
|
||||
client2.succeed(publish("-m test", "anonWriter", port=${toString anonPort}))
|
||||
])
|
||||
'';
|
||||
})
|
||||
|
@ -1,5 +1,6 @@
|
||||
{ lib, stdenv
|
||||
, fetchurl
|
||||
, fetchpatch
|
||||
, pkg-config
|
||||
, alsa-lib
|
||||
, audiofile
|
||||
@ -28,6 +29,16 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "1m7njfjdb7sqf0lhgc4swihgdr4snkg8v02wcly08wb5ar2fr2s6";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Pull patch pending upstream inclusion for ncurses-6.3:
|
||||
# https://sourceforge.net/p/ecasound/bugs/54/
|
||||
(fetchpatch {
|
||||
name = "ncursdes-6.3.patch";
|
||||
url = "https://sourceforge.net/p/ecasound/bugs/54/attachment/0001-ecasignalview.cpp-always-use-s-style-format-for-prin.patch";
|
||||
sha256 = "1x1gsjzd43lh19mhpmwrbq269h56s8bxgyv0yfi5yf0sqjf9vaq0";
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
];
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ lib, stdenv, fetchurl, zlib, ncurses }:
|
||||
{ lib, stdenv, fetchurl, fetchpatch, zlib, ncurses }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "aewan";
|
||||
@ -9,6 +9,17 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "5266dec5e185e530b792522821c97dfa5f9e3892d0dca5e881d0c30ceac21817";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Pull patch pending upstream inclusion:
|
||||
# https://sourceforge.net/p/aewan/bugs/13/
|
||||
(fetchpatch {
|
||||
url = "https://sourceforge.net/p/aewan/bugs/13/attachment/aewan-cvs-ncurses-6.3.patch";
|
||||
sha256 = "0pgpk1l3d6d5y37lvvavipwnmv9gmpfdy21jkz6baxhlkgf43r4p";
|
||||
# patch is in CVS diff format, add 'a/' prefix
|
||||
extraPrefix = "";
|
||||
})
|
||||
];
|
||||
|
||||
buildInputs = [ zlib ncurses ];
|
||||
|
||||
meta = {
|
||||
|
@ -6,6 +6,7 @@
|
||||
, qttools
|
||||
, qtscript
|
||||
, qtdeclarative
|
||||
, qtnetworkauth
|
||||
, qtbase
|
||||
, autogen
|
||||
, automake
|
||||
@ -17,15 +18,16 @@
|
||||
, rsync
|
||||
, typescript
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "imgbrd-grabber";
|
||||
version = "7.5.1";
|
||||
|
||||
version = "7.3.2";
|
||||
src = fetchFromGitHub {
|
||||
owner = "Bionus";
|
||||
repo = "imgbrd-grabber";
|
||||
rev = "v${version}";
|
||||
sha256 = "053rwvcr88fcba0447a6r115cgnqsm9rl066z8d5jacqnhdij58k";
|
||||
sha256 = "sha256-40JCdtRhAQpz2lBGmYh2MgA9rRzHmOZx7lWW0IbfjP4=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
@ -41,6 +43,7 @@ stdenv.mkDerivation rec {
|
||||
qtbase
|
||||
qtdeclarative
|
||||
qttools
|
||||
qtnetworkauth
|
||||
nodejs
|
||||
cmake
|
||||
wrapQtAppsHook
|
||||
@ -67,6 +70,8 @@ stdenv.mkDerivation rec {
|
||||
|
||||
# link the catch2 sources from nixpkgs
|
||||
ln -sf ${catch2.src} tests/src/vendor/catch
|
||||
|
||||
sed "s|strict\": true|strict\": false|g" -i ./sites/tsconfig.json
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ stdenv, lib, fetchFromGitHub, cairo, libxkbcommon
|
||||
{ stdenv, lib, fetchFromGitHub, fetchpatch, cairo, libxkbcommon
|
||||
, pango, fribidi, harfbuzz, pcre, pkg-config
|
||||
, ncursesSupport ? true, ncurses ? null
|
||||
, waylandSupport ? true, wayland ? null, wayland-protocols ? null
|
||||
@ -20,6 +20,15 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "sha256-U4IMfDvQ0rfEJhE3Uext2c/Cs0mjy1tw+k8uk441Ag8=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Pull upstream fix for build against ncurses-6.3
|
||||
(fetchpatch {
|
||||
name = "ncurses-6.3.patch";
|
||||
url = "https://github.com/Cloudef/bemenu/commit/d31164db756989579468946aba62969e42c7ed28.patch";
|
||||
sha256 = "sha256-oyndQI7SaR8cK0IO5wIIxMpmakhfUzwUqLIKRbPkEdw=";
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [ pkg-config pcre ];
|
||||
|
||||
makeFlags = ["PREFIX=$(out)"];
|
||||
|
@ -43,12 +43,11 @@
|
||||
|
||||
# Hardening
|
||||
, graphene-hardened-malloc
|
||||
# crashes with intel driver
|
||||
, useHardenedMalloc ? false
|
||||
# Whether to use graphene-hardened-malloc
|
||||
, useHardenedMalloc ? true
|
||||
|
||||
# Whether to disable multiprocess support to work around crashing tabs
|
||||
# TODO: fix the underlying problem instead of this terrible work-around
|
||||
, disableContentSandbox ? true
|
||||
# Whether to disable multiprocess support
|
||||
, disableContentSandbox ? false
|
||||
|
||||
# Extra preferences
|
||||
, extraPrefs ? ""
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ lib, stdenv, fetchurl, openssl, ncurses, pkg-config, glib, loudmouth, libotr
|
||||
{ lib, stdenv, fetchurl, fetchpatch, openssl, ncurses, pkg-config, glib, loudmouth, libotr
|
||||
, gpgme
|
||||
}:
|
||||
|
||||
@ -11,6 +11,16 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "0q1i5acyghsmzas88qswvki8kkk2nfpr8zapgnxbcd3lwcxl38f4";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Pull upstream patch for ncurses-6.3.
|
||||
(fetchpatch {
|
||||
name = "ncurses-6.3.patch";
|
||||
url = "https://github.com/McKael/mcabber/commit/5a0893d69023b77b7671731defbdca5d47731130.patch";
|
||||
sha256 = "01bc23z0mva9l9jv587sq2r9w3diachgkmb9ad99hlzgj02fmq4v";
|
||||
stripLen = 1;
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
buildInputs = [ openssl ncurses glib loudmouth libotr gpgme ];
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ lib, stdenv, fetchFromGitHub, libsodium, ncurses, curl
|
||||
{ lib, stdenv, fetchFromGitHub, fetchpatch, libsodium, ncurses, curl
|
||||
, libtoxcore, openal, libvpx, freealut, libconfig, pkg-config, libopus
|
||||
, qrencode, gdk-pixbuf, libnotify }:
|
||||
|
||||
@ -13,6 +13,15 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "sha256-5jLXXI+IMrYa7ZtdMjJrah1zB5TJ3GdHfvcMd1TYE4E=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Pending for upstream inclusion fix for ncurses-6.3 compatibility.
|
||||
(fetchpatch {
|
||||
name = "ncurses-6.3.patch";
|
||||
url = "https://github.com/JFreegman/toxic/commit/41e93adbdbd56db065166af5a6676a7996e9e451.patch";
|
||||
sha256 = "sha256-LYEseB5FmXFNifa1RZUxhkXeWlkEEMm3ASD55IoUPa0=";
|
||||
})
|
||||
];
|
||||
|
||||
makeFlags = [ "PREFIX=$(out)"];
|
||||
installFlags = [ "PREFIX=$(out)"];
|
||||
|
||||
|
136
pkgs/applications/science/electronics/picoscope/default.nix
Normal file
136
pkgs/applications/science/electronics/picoscope/default.nix
Normal file
@ -0,0 +1,136 @@
|
||||
{ stdenv, lib, fetchurl, dpkg, makeWrapper , mono, gtk-sharp-3_0
|
||||
, glib, libusb1 , zlib, gtk3-x11, callPackage
|
||||
, scopes ? [
|
||||
"picocv"
|
||||
"ps2000"
|
||||
"ps2000a"
|
||||
"ps3000"
|
||||
"ps3000a"
|
||||
"ps4000"
|
||||
"ps4000a"
|
||||
"ps5000"
|
||||
"ps5000a"
|
||||
"ps6000"
|
||||
"ps6000a"
|
||||
] }:
|
||||
|
||||
let
|
||||
shared_meta = lib:
|
||||
with lib; {
|
||||
homepage = "https://www.picotech.com/downloads/linux";
|
||||
maintainers = with maintainers; [ expipiplus1 yorickvp wirew0rm ];
|
||||
platforms = [ "x86_64-linux" ];
|
||||
license = licenses.unfree;
|
||||
};
|
||||
|
||||
libpicoipp = callPackage ({ stdenv, lib, fetchurl, autoPatchelfHook, dpkg }:
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "libpicoipp";
|
||||
inherit (sources.libpicoipp) version;
|
||||
src = fetchurl { inherit (sources.libpicoipp) url sha256; };
|
||||
nativeBuildInputs = [ dpkg autoPatchelfHook ];
|
||||
buildInputs = [ stdenv.cc.cc.lib ];
|
||||
sourceRoot = ".";
|
||||
unpackCmd = "dpkg-deb -x $src .";
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/lib
|
||||
cp -d opt/picoscope/lib/* $out/lib
|
||||
install -Dt $out/usr/share/doc/libpicoipp usr/share/doc/libpicoipp/copyright
|
||||
runHook postInstall
|
||||
'';
|
||||
meta = with lib;
|
||||
shared_meta lib // {
|
||||
description = "library for picotech oscilloscope software";
|
||||
};
|
||||
}) { };
|
||||
|
||||
# If we don't have a platform available, put a dummy version here, so at
|
||||
# least evaluation succeeds.
|
||||
sources =
|
||||
(lib.importJSON ./sources.json).${stdenv.system} or { picoscope.version = "unknown"; };
|
||||
|
||||
scopePkg = name:
|
||||
{ url, version, sha256 }:
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "lib${name}";
|
||||
inherit version;
|
||||
src = fetchurl { inherit url sha256; };
|
||||
# picoscope does a signature check, so we can't patchelf these
|
||||
nativeBuildInputs = [ dpkg ];
|
||||
sourceRoot = ".";
|
||||
unpackCmd = "dpkg-deb -x $src .";
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/lib
|
||||
cp -d opt/picoscope/lib/* $out/lib
|
||||
runHook postInstall
|
||||
'';
|
||||
meta = with lib;
|
||||
shared_meta lib // {
|
||||
description = "library for picotech oscilloscope ${name} series";
|
||||
};
|
||||
};
|
||||
|
||||
scopePkgs = lib.mapAttrs scopePkg sources;
|
||||
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "picoscope";
|
||||
inherit (sources.picoscope) version;
|
||||
|
||||
src = fetchurl { inherit (sources.picoscope) url sha256; };
|
||||
|
||||
nativeBuildInputs = [ dpkg makeWrapper ];
|
||||
buildInputs = [ gtk-sharp-3_0 mono glib libusb1 zlib ];
|
||||
|
||||
unpackCmd = "dpkg-deb -x $src .";
|
||||
sourceRoot = ".";
|
||||
scopeLibs = lib.attrVals (map (x: "lib${x}") scopes) scopePkgs;
|
||||
MONO_PATH = "${gtk-sharp-3_0}/lib/mono/gtk-sharp-3.0:" + (lib.makeLibraryPath
|
||||
([
|
||||
glib
|
||||
gtk3-x11
|
||||
gtk-sharp-3_0
|
||||
libusb1
|
||||
zlib
|
||||
libpicoipp
|
||||
] ++ scopeLibs));
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/
|
||||
cp -dr usr/share $out/share
|
||||
cp -dr opt/picoscope/* $out/
|
||||
makeWrapper "$(command -v mono)" $out/bin/picoscope \
|
||||
--add-flags $out/lib/PicoScope.GTK.exe \
|
||||
--prefix MONO_PATH : "$MONO_PATH" \
|
||||
--prefix LD_LIBRARY_PATH : "$MONO_PATH"
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
# usage:
|
||||
# services.udev.packages = [ pkgs.picoscope.rules ];
|
||||
# users.groups.pico = {};
|
||||
# users.users.you.extraGroups = [ "pico" ];
|
||||
passthru.rules = lib.writeTextDir "lib/udev/rules.d/95-pico.rules" ''
|
||||
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0ce9", MODE="664",GROUP="pico"
|
||||
'';
|
||||
|
||||
meta = with lib;
|
||||
shared_meta lib // {
|
||||
description =
|
||||
"Oscilloscope application that works with all PicoScope models";
|
||||
longDescription = ''
|
||||
PicoScope for Linux is a powerful oscilloscope application that works
|
||||
with all PicoScope models. The most important features from PicoScope
|
||||
for Windows are included—scope, spectrum analyzer, advanced triggers,
|
||||
automated measurements, interactive zoom, persistence modes and signal
|
||||
generator control. More features are being added all the time.
|
||||
|
||||
Waveform captures can be saved for off-line analysis, and shared with
|
||||
PicoScope for Linux, PicoScope for macOS and PicoScope for Windows
|
||||
users, or exported in text, CSV and MathWorks MATLAB 4 formats.
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
69
pkgs/applications/science/electronics/picoscope/sources.json
Normal file
69
pkgs/applications/science/electronics/picoscope/sources.json
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"x86_64-linux": {
|
||||
"libpicocv": {
|
||||
"sha256": "c2e74c2b0679df0226993d063b38d0eda5b05ff59f29bbfa12ded5226df37024",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libpicocv/libpicocv_1.1.27-1r153_amd64.deb",
|
||||
"version": "1.1.27-1r153"
|
||||
},
|
||||
"libpicoipp": {
|
||||
"sha256": "87ae49cd5e8dda4a73a835b95ea13e4c3fc4d1c4c9d6495c9affdf6fa6b1b4aa",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libpicoipp/libpicoipp_1.3.0-4r121_amd64.deb",
|
||||
"version": "1.3.0-4r121"
|
||||
},
|
||||
"libps2000": {
|
||||
"sha256": "792e506c08cebbd617e833e1547d3e5a13a186f93cea3f84608b7ed9451fb077",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps2000/libps2000_3.0.75-3r2957_amd64.deb",
|
||||
"version": "3.0.75-3r2957"
|
||||
},
|
||||
"libps2000a": {
|
||||
"sha256": "f31b3a8e9c6af14a59e348e4b302f12f582cdb08a47a3c04d8a6a612b4630305",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps2000a/libps2000a_2.1.75-5r2957_amd64.deb",
|
||||
"version": "2.1.75-5r2957"
|
||||
},
|
||||
"libps3000": {
|
||||
"sha256": "27dce3c924bb0169768a4964ce567b4a18ce74079537ca1fcba61e9234691580",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps3000/libps3000_4.0.75-3r2957_amd64.deb",
|
||||
"version": "4.0.75-3r2957"
|
||||
},
|
||||
"libps3000a": {
|
||||
"sha256": "31cf00ce136526af6e8b211a44a56b221d137de6eaec4d6fd7f31593b4245d62",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps3000a/libps3000a_2.1.75-6r2957_amd64.deb",
|
||||
"version": "2.1.75-6r2957"
|
||||
},
|
||||
"libps4000": {
|
||||
"sha256": "c976f09647f1fd2c980aafd1efe7f557bfc7c283fb9c135725c38dd59cc297e9",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps4000/libps4000_2.1.75-2r2957_amd64.deb",
|
||||
"version": "2.1.75-2r2957"
|
||||
},
|
||||
"libps4000a": {
|
||||
"sha256": "727f24fa74759385902d41d52a26a4636b3e3f08a8743901d15cc49622207b97",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps4000a/libps4000a_2.1.75-2r2957_amd64.deb",
|
||||
"version": "2.1.75-2r2957"
|
||||
},
|
||||
"libps5000": {
|
||||
"sha256": "3237c1dfdb384079b7039d2b4a8e0b0126e804830b29d60e89ae018182667edb",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps5000/libps5000_2.1.75-3r2957_amd64.deb",
|
||||
"version": "2.1.75-3r2957"
|
||||
},
|
||||
"libps5000a": {
|
||||
"sha256": "27947f8461a16cf59d64cd23d7a78ddd27826e38dfe9fca3902e3b553591fb19",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps5000a/libps5000a_2.1.75-5r2957_amd64.deb",
|
||||
"version": "2.1.75-5r2957"
|
||||
},
|
||||
"libps6000": {
|
||||
"sha256": "d65e923db969e306fb9f3f3892229a297d6187574d901dde44375270cc1e1404",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps6000/libps6000_2.1.75-6r2957_amd64.deb",
|
||||
"version": "2.1.75-6r2957"
|
||||
},
|
||||
"libps6000a": {
|
||||
"sha256": "eff8644ad44f9cc1cf9052e27786a1480a4ab599766c1c01e370fef40a76b224",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/libp/libps6000a/libps6000a_1.0.75-0r2957_amd64.deb",
|
||||
"version": "1.0.75-0r2957"
|
||||
},
|
||||
"picoscope": {
|
||||
"sha256": "3d2a0e360c8143fc03c29b394c16bfc2387164e33099a46b6905af992cfab440",
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/pool/main/p/picoscope/picoscope_7.0.83-1r9320_amd64.deb",
|
||||
"version": "7.0.83-1r9320"
|
||||
}
|
||||
}
|
||||
}
|
44
pkgs/applications/science/electronics/picoscope/update.py
Executable file
44
pkgs/applications/science/electronics/picoscope/update.py
Executable file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell --pure -i python3 -p "python3.withPackages (ps: with ps; [ requests ])"
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
import sys
|
||||
|
||||
def parse_packages(text):
|
||||
res = []
|
||||
for package in resp.text.split("\n\n"):
|
||||
if not package: continue
|
||||
pkg = {}
|
||||
for field in package.split("\n"):
|
||||
if field.startswith(" "): # multiline string
|
||||
pkg[k] += "\n" + field[1:]
|
||||
else:
|
||||
[k, v] = field.split(": ", 1)
|
||||
pkg[k] = v
|
||||
res.append(pkg)
|
||||
return res
|
||||
|
||||
def generate_sources(packages):
|
||||
sources_spec = {}
|
||||
for pkg in pkgs:
|
||||
sources_spec[pkg['Package']] = {
|
||||
"url": "https://labs.picotech.com/rc/picoscope7/debian/" + pkg["Filename"],
|
||||
"sha256": pkg["SHA256"],
|
||||
"version": pkg["Version"]
|
||||
}
|
||||
return sources_spec
|
||||
|
||||
out = {}
|
||||
for nix_system, release in {"x86_64-linux": "amd64"}.items():
|
||||
resp = requests.get("https://labs.picotech.com/rc/picoscope7/debian//dists/picoscope/main/binary-"+release+"/Packages")
|
||||
if resp.status_code != 200:
|
||||
print("error: could not fetch data for release {} (code {})".format(release, resp.code), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
pkgs = parse_packages(resp.text)
|
||||
out[nix_system] = generate_sources(pkgs)
|
||||
|
||||
with open(os.path.dirname(__file__) + "/sources.json", "w") as f:
|
||||
json.dump(out, f, indent=2, sort_keys=True)
|
||||
f.write('\n')
|
||||
|
@ -1,26 +1,50 @@
|
||||
{ lib, buildPythonPackage, fetchPypi, mailman, mock }:
|
||||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchPypi
|
||||
, mailman
|
||||
, mock
|
||||
, nose2
|
||||
, python
|
||||
, requests
|
||||
, zope_interface
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "mailman-hyperkitty";
|
||||
version = "1.1.0";
|
||||
format = "setuptools";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "1lfqa9admhvdv71f528jmz2wl0i5cv77v6l64px2pm4zqr9ckkjx";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [ mailman ];
|
||||
checkInputs = [ mock ];
|
||||
propagatedBuildInputs = [
|
||||
mailman
|
||||
requests
|
||||
zope_interface
|
||||
];
|
||||
|
||||
checkInputs = [
|
||||
mock
|
||||
nose2
|
||||
];
|
||||
|
||||
checkPhase = ''
|
||||
python -m nose2 -v
|
||||
${python.interpreter} -m nose2 -v
|
||||
'';
|
||||
|
||||
# There is an AssertionError
|
||||
doCheck = false;
|
||||
|
||||
pythonImportsCheck = [
|
||||
"mailman_hyperkitty"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Mailman archiver plugin for HyperKitty";
|
||||
homepage = "https://gitlab.com/mailman/mailman-hyperkitty";
|
||||
license = licenses.gpl3;
|
||||
license = licenses.gpl3Plus;
|
||||
maintainers = with maintainers; [ globin qyliss ];
|
||||
};
|
||||
}
|
||||
|
@ -8,13 +8,13 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "mypy-boto3-s3";
|
||||
version = "1.19.8";
|
||||
version = "1.19.12";
|
||||
|
||||
disabled = pythonOlder "3.6";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "60481cae38e01273d09a6159e4ff8c36d5d7e335319117a16cdb3d887928a7b4";
|
||||
sha256 = "sha256-xgcGbWcrdFwFPQLJHmgRdY2XbwAiInZxmw6RiFVJ5F4=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
|
@ -28,8 +28,15 @@ buildPythonPackage rec {
|
||||
pydot
|
||||
];
|
||||
|
||||
# Multiple tests are out-dated and failing
|
||||
doCheck = false;
|
||||
|
||||
pythonImportsCheck = [
|
||||
"prov"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "A Python library for W3C Provenance Data Model (PROV)";
|
||||
description = "Python library for W3C Provenance Data Model (PROV)";
|
||||
homepage = "https://github.com/trungdong/prov";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ ashgillman ];
|
||||
|
@ -1,36 +1,62 @@
|
||||
{ buildPythonPackage
|
||||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchPypi
|
||||
, isodate
|
||||
, html5lib
|
||||
, SPARQLWrapper
|
||||
, isodate
|
||||
, networkx
|
||||
, nose
|
||||
, python
|
||||
, pyparsing
|
||||
, tabulate
|
||||
, pandas
|
||||
, pytestCheckHook
|
||||
, pythonOlder
|
||||
, SPARQLWrapper
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "rdflib";
|
||||
version = "6.0.1";
|
||||
version = "6.0.2";
|
||||
format = "setuptools";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "f071caff0b68634e4a7bd1d66ea3416ac98f1cc3b915938147ea899c32608728";
|
||||
sha256 = "sha256-YTauBWABR07ir/X8W5VuYqEcOpxmuw89nAqqX7tWhU4=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [isodate html5lib SPARQLWrapper ];
|
||||
propagatedBuildInputs = [
|
||||
isodate
|
||||
html5lib
|
||||
pyparsing
|
||||
SPARQLWrapper
|
||||
];
|
||||
|
||||
checkInputs = [ networkx nose ];
|
||||
checkInputs = [
|
||||
networkx
|
||||
pandas
|
||||
nose
|
||||
tabulate
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
# Python 2 syntax
|
||||
# Failing doctest
|
||||
doCheck = false;
|
||||
disabledTests = [
|
||||
# Requires network access
|
||||
"api_key"
|
||||
"BerkeleyDBTestCase"
|
||||
"test_bad_password"
|
||||
"test_service"
|
||||
"testGuessFormatForParse"
|
||||
];
|
||||
|
||||
checkPhase = ''
|
||||
${python.interpreter} run_tests.py
|
||||
'';
|
||||
pythonImportsCheck = [
|
||||
"rdflib"
|
||||
];
|
||||
|
||||
meta = {
|
||||
description = "A Python library for working with RDF, a simple yet powerful language for representing information";
|
||||
homepage = "http://www.rdflib.net/";
|
||||
meta = with lib; {
|
||||
description = "Python library for working with RDF";
|
||||
homepage = "https://rdflib.readthedocs.io";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ ];
|
||||
};
|
||||
}
|
||||
|
@ -12,14 +12,14 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "smbprotocol";
|
||||
version = "1.8.1";
|
||||
version = "1.8.2";
|
||||
disabled = pythonOlder "3.6";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jborean93";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-HhyOGRwDnLwrXPjvF04MlgSxGZc0w3nDek9Mnv49cG4=";
|
||||
sha256 = "sha256-NBwfWW02lzR4Xk+7qodQX+eIXMTtdy9WOtLzsf30d4c=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
|
@ -6,13 +6,13 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "starkbank-ecdsa";
|
||||
version = "2.0.0";
|
||||
version = "2.0.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "starkbank";
|
||||
repo = "ecdsa-python";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-MTd9aeX6UavRua0hnuy5qY5kltzSoyvv+LcL5EvU5Sc=";
|
||||
sha256 = "sha256-TYp8eIzO8Bn1hgye7PpIywVEV0tQtJ3HaYjCnn4/57w=";
|
||||
};
|
||||
|
||||
checkInputs = [
|
||||
|
@ -56,7 +56,7 @@ with py.pkgs;
|
||||
|
||||
buildPythonApplication rec {
|
||||
pname = "checkov";
|
||||
version = "2.0.528";
|
||||
version = "2.0.549";
|
||||
|
||||
disabled = python3.pythonOlder "3.7";
|
||||
|
||||
@ -64,7 +64,7 @@ buildPythonApplication rec {
|
||||
owner = "bridgecrewio";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "sha256-RcQVm3ppe3c4G/32Dgf6UhwtxJyQWgS4vD5wMYIfwKY=";
|
||||
sha256 = "sha256-nxvUxjqzBUPbOkMhdQhkdlMRGFj6vhMU3BjXpSwBb8s=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = with py.pkgs; [
|
||||
|
@ -65,24 +65,21 @@ rec {
|
||||
|
||||
gradle_latest = gradle_7;
|
||||
|
||||
gradle_7 = gradleGen (gradleSpec {
|
||||
version = "7.2";
|
||||
nativeVersion = "0.22-milestone-21";
|
||||
sha256 = "1pg6w5czysywsgdvmll5bwd2p6y99cn5sn3gw69cps9mkjd710gm";
|
||||
});
|
||||
# NOTE: 7.3 is a candidate.
|
||||
gradle_7 = gradle_7_2;
|
||||
|
||||
gradle_6_8 = gradleGen (gradleSpec {
|
||||
version = "6.8.3";
|
||||
nativeVersion = "0.22-milestone-9";
|
||||
sha256 = "01fjrk5nfdp6mldyblfmnkq2gv1rz1818kzgr0k2i1wzfsc73akz";
|
||||
});
|
||||
gradle_7_3 = gradleGen (gradleSpec (import ./gradle-7.3-rc-3-spec.nix));
|
||||
gradle_7_2 = gradleGen (gradleSpec (import ./gradle-7.2-spec.nix));
|
||||
gradle_6_9 = gradleGen (gradleSpec (import ./gradle-6.9.1-spec.nix));
|
||||
|
||||
# NOTE: No GitHub Release for this release, so update.sh does not work.
|
||||
gradle_5_6 = gradleGen (gradleSpec {
|
||||
version = "5.6.4";
|
||||
nativeVersion = "0.18";
|
||||
sha256 = "1f3067073041bc44554d0efe5d402a33bc3d3c93cc39ab684f308586d732a80d";
|
||||
sha256 = "03d86bbqd19h9xlanffcjcy3vg1k5905vzhf9mal9g21603nfc0z";
|
||||
});
|
||||
|
||||
# NOTE: No GitHub Release for this release, so update.sh does not work.
|
||||
gradle_4_10 = gradleGen (gradleSpec {
|
||||
version = "4.10.3";
|
||||
nativeVersion = "0.14";
|
||||
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
version = "6.9.1";
|
||||
nativeVersion = "0.22-milestone-20";
|
||||
sha256 = "1zmjfwlh34b65rdx9izgavw3qwqqwm39h5siyj2bf0m55111a4lc";
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
version = "7.2";
|
||||
nativeVersion = "0.22-milestone-21";
|
||||
sha256 = "1pg6w5czysywsgdvmll5bwd2p6y99cn5sn3gw69cps9mkjd710gm";
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
{
|
||||
version = "7.3-rc-3";
|
||||
nativeVersion = "0.22-milestone-21";
|
||||
sha256 = "0401q4qpl36a2vnlrlsblflfiiy3b95gyj2wj62hzc1x00hbfznm";
|
||||
}
|
57
pkgs/development/tools/build-managers/gradle/update.sh
Executable file
57
pkgs/development/tools/build-managers/gradle/update.sh
Executable file
@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p nix-prefetch curl jq
|
||||
|
||||
# Generates Gradle release specs from GitHub Releases.
|
||||
#
|
||||
# As of 2021-11, this script has very poor error handling,
|
||||
# it is expected to be run by maintainers as one-off job
|
||||
# only.
|
||||
#
|
||||
# NOTE: The earliest Gradle release that has a
|
||||
# corresponding entry as GitHub Release is 6.8-rc-1.
|
||||
|
||||
for v in $(curl -s "https://api.github.com/repos/gradle/gradle/releases" | jq -r '.[].tag_name' | sort -n -r)
|
||||
do
|
||||
# Tag names and download filenames are not the same,
|
||||
# we modify the tag name slightly to translate it
|
||||
# to the naming scheme of download filenames.
|
||||
# This translation assumes a tag naming scheme.
|
||||
# As of 2021-11 it works from 6.8-rc-1 to 7.3-rc-3.
|
||||
|
||||
# Remove first letter (assumed to be "v").
|
||||
v=${v:1}
|
||||
|
||||
# To lower case.
|
||||
v=${v,,}
|
||||
|
||||
# Add dash after "rc".
|
||||
v=${v/-rc/-rc-}
|
||||
|
||||
# Remove trailing ".0"
|
||||
v=${v%.0}
|
||||
|
||||
# Remove trailing ".0" for release candidates.
|
||||
v=${v/.0-rc/-rc}
|
||||
|
||||
f="gradle-${v}-spec.nix"
|
||||
|
||||
if [ -f "$f" ]
|
||||
then
|
||||
echo "$v SKIP"
|
||||
continue
|
||||
fi
|
||||
|
||||
url="https://services.gradle.org/distributions/gradle-${v}-bin.zip"
|
||||
read -d "\n" gradle_hash gradle_path < <(nix-prefetch-url --print-path $url)
|
||||
|
||||
# Prefix and suffix for "native-platform" dependency.
|
||||
gradle_native_prefix="gradle-$v/lib/native-native-"
|
||||
gradle_native_suffix=".jar"
|
||||
gradle_native=$(zipinfo -1 "$gradle_path" "$gradle_native_prefix*$gradle_native_suffix" | head -n1)
|
||||
gradle_native=${gradle_native#"$gradle_native_prefix"}
|
||||
gradle_native=${gradle_native%"$gradle_native_suffix"}
|
||||
|
||||
echo -e "{\\n version = \"$v\";\\n nativeVersion = \"$gradle_native\";\\n sha256 = \"$gradle_hash\";\\n}" > $f
|
||||
|
||||
echo "$v DONE"
|
||||
done
|
@ -1,6 +1,6 @@
|
||||
{ lib, stdenv, fetchFromGitHub, jdk11, gradleGen, makeDesktopItem, copyDesktopItems, perl, writeText, runtimeShell, makeWrapper, glib, wrapGAppsHook }:
|
||||
let
|
||||
gradle = (gradleGen.override (old: { java = jdk11; })).gradle_6_8;
|
||||
gradle = (gradleGen.override (old: { java = jdk11; })).gradle_6_9;
|
||||
|
||||
pname = "scenebuilder";
|
||||
version = "15.0.1";
|
||||
|
@ -18,6 +18,14 @@ stdenv.mkDerivation rec {
|
||||
url = "https://github.com/fph/bastet/commit/0e03f8d4d6bc6949cf1c447e632ce0d1b98c4be1.patch";
|
||||
sha256 = "1475hisbm44jirsrhdlnddppsyn83xmvcx09gfkm9drcix05alzj";
|
||||
})
|
||||
|
||||
# Fix pending upstream inclusion for ncurses-6.3:
|
||||
# https://github.com/fph/bastet/pull/21
|
||||
(fetchpatch {
|
||||
name = "ncurses-6.3.patch";
|
||||
url = "https://github.com/fph/bastet/commit/54a6d127351ea2c62f50efafe97c5b02e23e86a7.patch";
|
||||
sha256 = "14v95b0m16m6ycd82i3wpp81kbmj6qz029b1m5483dkk6mwz98iy";
|
||||
})
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
|
@ -88,7 +88,7 @@ let
|
||||
'';
|
||||
|
||||
# The default one still uses jdk8 (#89731)
|
||||
gradle_6 = (gradleGen.override (old: { java = jdk; })).gradle_6_8;
|
||||
gradle_6 = (gradleGen.override (old: { java = jdk; })).gradle_6_9;
|
||||
|
||||
# fake build to pre-download deps into fixed-output derivation
|
||||
deps = stdenv.mkDerivation {
|
||||
|
@ -1,11 +1,14 @@
|
||||
{ lib
|
||||
, python3Packages
|
||||
, python3
|
||||
, fetchFromGitHub
|
||||
}:
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "pyLODE";
|
||||
python3.pkgs.buildPythonApplication rec {
|
||||
pname = "pylode";
|
||||
version = "2.12.0";
|
||||
format = "setuptools";
|
||||
|
||||
disabled = python3.pythonOlder "3.6";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "RDFLib";
|
||||
@ -14,22 +17,32 @@ python3Packages.buildPythonApplication rec {
|
||||
sha256 = "sha256-X/YiJduAJNiceIrlCFwD2PFiMn3HVlzr9NzyDvYcql8=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with python3Packages; [
|
||||
python-dateutil
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
beautifulsoup4
|
||||
falcon
|
||||
gunicorn
|
||||
isodate
|
||||
jinja2
|
||||
markdown
|
||||
python-dateutil
|
||||
rdflib
|
||||
requests
|
||||
six
|
||||
beautifulsoup4
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace requirements.txt \
|
||||
--replace "rdflib==6.0.0" "rdflib"
|
||||
'';
|
||||
|
||||
# Path issues with the tests
|
||||
doCheck = false;
|
||||
|
||||
pythonImportsCheck = [
|
||||
"pylode"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "An OWL ontology documentation tool using Python and templating, based on LODE";
|
||||
description = "OWL ontology documentation tool using Python and templating, based on LODE";
|
||||
homepage = "https://github.com/RDFLib/pyLODE";
|
||||
# Next release will move to BSD3
|
||||
license = licenses.gpl3Only;
|
||||
maintainers = with maintainers; [ koslambrou ];
|
||||
};
|
||||
|
@ -320,6 +320,7 @@ in with py.pkgs; buildPythonApplication rec {
|
||||
"ecobee"
|
||||
"econet"
|
||||
"ee_brightbox"
|
||||
"efergy"
|
||||
"elgato"
|
||||
"elkm1"
|
||||
"emonitor"
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "riemann-c-client";
|
||||
version = "1.10.4";
|
||||
version = "1.10.5";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "algernon";
|
||||
repo = "riemann-c-client";
|
||||
rev = "riemann-c-client-${version}";
|
||||
sha256 = "01gzqxqm1xvki2vd78c7my2kgp4fyhkcf5j5fmy8z0l93lgj82rr";
|
||||
sha256 = "sha256-LuI9XFDPx0qw/+kkpXd0FOMESERAp31R1+ttkGuJnPA=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ autoreconfHook pkg-config ];
|
||||
|
@ -2,6 +2,7 @@
|
||||
, stdenv
|
||||
, autoreconfHook
|
||||
, fetchurl
|
||||
, fetchpatch
|
||||
, ncurses
|
||||
}:
|
||||
|
||||
@ -14,6 +15,17 @@ stdenv.mkDerivation rec {
|
||||
sha256 = "0ikzyvnb73msm9n7ripg1dsw9av1i0c7q2hi2173xsj8zyv559f1";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# Pull upstream fix for ncurses-6.3 support.
|
||||
(fetchpatch {
|
||||
name = "ncurses-6.3.patch";
|
||||
url = "https://github.com/vgropp/bwm-ng/commit/6a2087db6cc7ac5b5f667fcd17c262c079e8dcf2.patch";
|
||||
sha256 = "1l5dii9d52v0x0sq458ybw7m9p8aan2vl94gwx5s8mgxsnbcmzzx";
|
||||
# accidentally committed changes
|
||||
excludes = [ "config.h.in~" "configure.in" "configure~" ];
|
||||
})
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
autoreconfHook
|
||||
];
|
||||
|
@ -1,4 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "metasploit-framework", git: "https://github.com/rapid7/metasploit-framework", ref: "refs/tags/6.1.12"
|
||||
gem "metasploit-framework", git: "https://github.com/rapid7/metasploit-framework", ref: "refs/tags/6.1.13"
|
||||
|
@ -1,9 +1,9 @@
|
||||
GIT
|
||||
remote: https://github.com/rapid7/metasploit-framework
|
||||
revision: bde342fd8293e49a45ba837ca9a1fdea505bc919
|
||||
ref: refs/tags/6.1.12
|
||||
revision: 643afb56f7f86a858e3da144fd367575a2f0b2c6
|
||||
ref: refs/tags/6.1.13
|
||||
specs:
|
||||
metasploit-framework (6.1.12)
|
||||
metasploit-framework (6.1.13)
|
||||
actionpack (~> 6.0)
|
||||
activerecord (~> 6.0)
|
||||
activesupport (~> 6.0)
|
||||
@ -31,7 +31,7 @@ GIT
|
||||
metasploit-concern
|
||||
metasploit-credential
|
||||
metasploit-model
|
||||
metasploit-payloads (= 2.0.58)
|
||||
metasploit-payloads (= 2.0.60)
|
||||
metasploit_data_models
|
||||
metasploit_payloads-mettle (= 1.0.15)
|
||||
mqtt
|
||||
@ -128,23 +128,23 @@ GEM
|
||||
arel-helpers (2.12.1)
|
||||
activerecord (>= 3.1.0, < 7)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.521.0)
|
||||
aws-sdk-core (3.121.5)
|
||||
aws-partitions (1.525.0)
|
||||
aws-sdk-core (3.122.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.520.1)
|
||||
aws-partitions (~> 1, >= 1.525.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-ec2 (1.275.0)
|
||||
aws-sdk-core (~> 3, >= 3.121.2)
|
||||
aws-sdk-ec2 (1.277.0)
|
||||
aws-sdk-core (~> 3, >= 3.122.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-iam (1.62.0)
|
||||
aws-sdk-core (~> 3, >= 3.121.2)
|
||||
aws-sdk-iam (1.63.0)
|
||||
aws-sdk-core (~> 3, >= 3.122.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-kms (1.50.0)
|
||||
aws-sdk-core (~> 3, >= 3.121.2)
|
||||
aws-sdk-kms (1.51.0)
|
||||
aws-sdk-core (~> 3, >= 3.122.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.104.0)
|
||||
aws-sdk-core (~> 3, >= 3.121.2)
|
||||
aws-sdk-s3 (1.105.1)
|
||||
aws-sdk-core (~> 3, >= 3.122.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
aws-sigv4 (1.4.0)
|
||||
@ -212,7 +212,7 @@ GEM
|
||||
domain_name (~> 0.5)
|
||||
http_parser.rb (0.8.0)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.8.10)
|
||||
i18n (1.8.11)
|
||||
concurrent-ruby (~> 1.0)
|
||||
io-console (0.5.9)
|
||||
irb (1.3.6)
|
||||
@ -247,7 +247,7 @@ GEM
|
||||
activemodel (~> 6.0)
|
||||
activesupport (~> 6.0)
|
||||
railties (~> 6.0)
|
||||
metasploit-payloads (2.0.58)
|
||||
metasploit-payloads (2.0.60)
|
||||
metasploit_data_models (5.0.4)
|
||||
activerecord (~> 6.0)
|
||||
activesupport (~> 6.0)
|
||||
|
@ -14,13 +14,13 @@ let
|
||||
};
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "metasploit-framework";
|
||||
version = "6.1.12";
|
||||
version = "6.1.13";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "rapid7";
|
||||
repo = "metasploit-framework";
|
||||
rev = version;
|
||||
sha256 = "sha256-I7wk8DBN7i4zE4bEIMVGcZi4OMIsbh0Ay2RsAh0VRrw=";
|
||||
sha256 = "sha256-ncmLizpX1yEtr8biUoWVVK4Ziv3QMiKWsj694yubA1M=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
@ -104,60 +104,60 @@
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "0zfwynw6d4lbq63lwk94insrjmgxwfp1lic4913a9ik00wnf90wd";
|
||||
sha256 = "181a2xf9zs0hz77jkpmxidvkjzs65vsyqv1a31fcali7f0kvh4h9";
|
||||
type = "gem";
|
||||
};
|
||||
version = "1.521.0";
|
||||
version = "1.525.0";
|
||||
};
|
||||
aws-sdk-core = {
|
||||
groups = ["default"];
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "0akv0jyr4crs4r5vdzc18j5drqgpcckm0gnpgi0bzpqyyk6m16hq";
|
||||
sha256 = "0krx8cfajc72gv6mpyb67vnhd2m2iya19846jgipgfris194gjm2";
|
||||
type = "gem";
|
||||
};
|
||||
version = "3.121.5";
|
||||
version = "3.122.0";
|
||||
};
|
||||
aws-sdk-ec2 = {
|
||||
groups = ["default"];
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "13kbrl8r9cm7i9cb6w5ayji1vqaca6h0inxpyx8bhbrwkscrbh2s";
|
||||
sha256 = "0qy318swkl3393gl5031n634z8msb7rghhp7zdnawvs39c0fbmxd";
|
||||
type = "gem";
|
||||
};
|
||||
version = "1.275.0";
|
||||
version = "1.277.0";
|
||||
};
|
||||
aws-sdk-iam = {
|
||||
groups = ["default"];
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "0vnhcgr5pjkkplh4z2lbwp4w13kbwp236p0y1b1qiia28ra2isxv";
|
||||
sha256 = "0ms76yn9iprmvjw1ijrgasss70398i8wmkwmgpghn5wc37z59x2s";
|
||||
type = "gem";
|
||||
};
|
||||
version = "1.62.0";
|
||||
version = "1.63.0";
|
||||
};
|
||||
aws-sdk-kms = {
|
||||
groups = ["default"];
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "0prj048lcbkmxc6k2p7vibn3vw7cy1104dljqjvmwz12h9ds1qlf";
|
||||
sha256 = "0qac9dd6qriz6ldghkr8ga74zz28jl109kmvhvag74a3qf7k9dwj";
|
||||
type = "gem";
|
||||
};
|
||||
version = "1.50.0";
|
||||
version = "1.51.0";
|
||||
};
|
||||
aws-sdk-s3 = {
|
||||
groups = ["default"];
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "1h8yzrzinckrfs8ahzqg7fs356vs1ksi5bva1bpfp0i65fjh9mw0";
|
||||
sha256 = "12j7i6l52b6hsnj59grn0m1s9pn6l38zmra6ad8i12vdsvd185w7";
|
||||
type = "gem";
|
||||
};
|
||||
version = "1.104.0";
|
||||
version = "1.105.1";
|
||||
};
|
||||
aws-sigv4 = {
|
||||
groups = ["default"];
|
||||
@ -544,10 +544,10 @@
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "0g2fnag935zn2ggm5cn6k4s4xvv53v2givj1j90szmvavlpya96a";
|
||||
sha256 = "0vdd1kii40qhbr9n8qx71k2gskq6rkl8ygy8hw5hfj8bb5a364xf";
|
||||
type = "gem";
|
||||
};
|
||||
version = "1.8.10";
|
||||
version = "1.8.11";
|
||||
};
|
||||
io-console = {
|
||||
groups = ["default"];
|
||||
@ -664,12 +664,12 @@
|
||||
platforms = [];
|
||||
source = {
|
||||
fetchSubmodules = false;
|
||||
rev = "bde342fd8293e49a45ba837ca9a1fdea505bc919";
|
||||
sha256 = "1g262lfh4v34rc01svicq8wbi63i8v2j1i462crjxvjd63q29g13";
|
||||
rev = "643afb56f7f86a858e3da144fd367575a2f0b2c6";
|
||||
sha256 = "0lq3kcmy7g9ynab24cnhzn51kbjljn2m5qn6mwnj3msp7a5qpjcx";
|
||||
type = "git";
|
||||
url = "https://github.com/rapid7/metasploit-framework";
|
||||
};
|
||||
version = "6.1.12";
|
||||
version = "6.1.13";
|
||||
};
|
||||
metasploit-model = {
|
||||
groups = ["default"];
|
||||
@ -686,10 +686,10 @@
|
||||
platforms = [];
|
||||
source = {
|
||||
remotes = ["https://rubygems.org"];
|
||||
sha256 = "05z0lqa2w6n1nqw3k2s0cxfbqa7bf1p199gccfahjyxjn9xzhcf7";
|
||||
sha256 = "1rg11gjy590cixfy6lmwgd76ai0s2gs4w8m379bkkx2f12lkibhn";
|
||||
type = "gem";
|
||||
};
|
||||
version = "2.0.58";
|
||||
version = "2.0.60";
|
||||
};
|
||||
metasploit_data_models = {
|
||||
groups = ["default"];
|
||||
|
@ -4512,6 +4512,8 @@ with pkgs;
|
||||
tk = tk-8_5;
|
||||
};
|
||||
|
||||
picoscope = callPackage ../applications/science/electronics/picoscope { };
|
||||
|
||||
picotts = callPackage ../tools/audio/picotts { };
|
||||
|
||||
wgetpaste = callPackage ../tools/text/wgetpaste { };
|
||||
@ -14550,7 +14552,7 @@ with pkgs;
|
||||
gradle_4_10 = res.gradleGen.gradle_4_10;
|
||||
gradle_4 = gradle_4_10;
|
||||
gradle_5 = res.gradleGen.gradle_5_6;
|
||||
gradle_6 = res.gradleGen.gradle_6_8;
|
||||
gradle_6 = res.gradleGen.gradle_6_9;
|
||||
gradle_7 = res.gradleGen.gradle_7;
|
||||
|
||||
gperf = callPackage ../development/tools/misc/gperf { };
|
||||
@ -33028,7 +33030,7 @@ with pkgs;
|
||||
inherit wineBuild;
|
||||
|
||||
inherit (callPackage ./wine-packages.nix {})
|
||||
minimal base full stable unstable staging fonts;
|
||||
minimal base full stable stableFull unstable unstableFull staging stagingFull fonts;
|
||||
});
|
||||
|
||||
winePackages = recurseIntoAttrs (winePackagesFor (config.wine.build or "wine32"));
|
||||
|
@ -51,6 +51,11 @@ rec {
|
||||
};
|
||||
|
||||
stable = base.override { wineRelease = "stable"; };
|
||||
stableFull = full.override { wineRelease = "stable"; };
|
||||
|
||||
unstable = base.override { wineRelease = "unstable"; };
|
||||
unstableFull = full.override { wineRelease = "unstable"; };
|
||||
|
||||
staging = base.override { wineRelease = "staging"; };
|
||||
stagingFull = full.override { wineRelease = "staging"; };
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user