Merge master into staging-next
This commit is contained in:
@@ -15768,6 +15768,12 @@
|
||||
githubId = 110892040;
|
||||
name = "Mykyta Polchanov";
|
||||
};
|
||||
mzabani = {
|
||||
email = "mzabani@gmail.com";
|
||||
github = "mzabani";
|
||||
githubId = 4662691;
|
||||
name = "Marcelo Zabani";
|
||||
};
|
||||
mzacho = {
|
||||
email = "nixpkgs@martinzacho.net";
|
||||
github = "mzacho";
|
||||
|
||||
@@ -95,6 +95,8 @@
|
||||
|
||||
- [InputPlumber](https://github.com/ShadowBlip/InputPlumber/), an open source input router and remapper daemon for Linux. Available as [services.inputplumber](#opt-services.inputplumber.enable).
|
||||
|
||||
- [echoip](https://github.com/mpolden/echoip), a simple service for looking up your IP address. Available as [services.echoip](#opt-services.echoip.enable).
|
||||
|
||||
- [Buffyboard](https://gitlab.postmarketos.org/postmarketOS/buffybox/-/tree/master/buffyboard), a framebuffer on-screen keyboard. Available as [services.buffyboard](option.html#opt-services.buffyboard).
|
||||
|
||||
- [KanBoard](https://github.com/kanboard/kanboard), a project management tool that focuses on the Kanban methodology. Available as [services.kanboard](#opt-services.kanboard.enable).
|
||||
|
||||
@@ -571,7 +571,13 @@
|
||||
./services/editors/emacs.nix
|
||||
./services/editors/haste.nix
|
||||
./services/editors/infinoted.nix
|
||||
./services/finance/libeufin/bank.nix
|
||||
./services/finance/libeufin/module.nix
|
||||
./services/finance/libeufin/nexus.nix
|
||||
./services/finance/odoo.nix
|
||||
./services/finance/taler/exchange.nix
|
||||
./services/finance/taler/merchant.nix
|
||||
./services/finance/taler/module.nix
|
||||
./services/games/archisteamfarm.nix
|
||||
./services/games/armagetronad.nix
|
||||
./services/games/crossfire-server.nix
|
||||
@@ -1459,6 +1465,7 @@
|
||||
./services/web-apps/documize.nix
|
||||
./services/web-apps/dokuwiki.nix
|
||||
./services/web-apps/dolibarr.nix
|
||||
./services/web-apps/echoip.nix
|
||||
./services/web-apps/eintopf.nix
|
||||
./services/web-apps/engelsystem.nix
|
||||
./services/web-apps/ethercalc.nix
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
options,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [ (import ./common.nix "bank") ];
|
||||
|
||||
options.services.libeufin.bank = {
|
||||
initialAccounts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
description = ''
|
||||
Accounts to enable before the bank service starts.
|
||||
|
||||
This is mainly needed for the nexus currency conversion
|
||||
since the exchange's bank account is expected to be already
|
||||
registered.
|
||||
|
||||
Don't forget to change the account passwords afterwards.
|
||||
'';
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration options for the libeufin bank system config file.
|
||||
|
||||
For a list of all possible options, please see the man page [`libeufin-bank.conf(5)`](https://docs.taler.net/manpages/libeufin-bank.conf.5.html)
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
inherit (options.services.libeufin.settings.type.nestedTypes) freeformType;
|
||||
options = {
|
||||
libeufin-bank = {
|
||||
CURRENCY = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The currency under which the libeufin-bank should operate.
|
||||
|
||||
This defaults to the GNU taler module's currency for convenience
|
||||
but if you run libeufin-bank separately from taler, you must set
|
||||
this yourself.
|
||||
'';
|
||||
};
|
||||
PORT = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8082;
|
||||
description = ''
|
||||
The port on which libeufin-bank should listen.
|
||||
'';
|
||||
};
|
||||
SUGGESTED_WITHDRAWAL_EXCHANGE = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "https://exchange.demo.taler.net/";
|
||||
description = ''
|
||||
Exchange that is suggested to wallets when withdrawing.
|
||||
|
||||
Note that, in order for withdrawals to work, your libeufin-bank
|
||||
must be able to communicate with and send money etc. to the bank
|
||||
at which the exchange used for withdrawals has its bank account.
|
||||
|
||||
If you also have your own bank and taler exchange network, you
|
||||
probably want to set one of your exchange's url here instead of
|
||||
the demo exchange.
|
||||
|
||||
This setting must always be set in order for the Android app to
|
||||
not crash during the withdrawal process but the exchange to be
|
||||
used can always be changed in the app.
|
||||
'';
|
||||
};
|
||||
};
|
||||
libeufin-bankdb-postgres = {
|
||||
CONFIG = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The database connection string for the libeufin-bank database.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
services.libeufin.bank.settings.libeufin-bank.CURRENCY = lib.mkIf (
|
||||
config.services.taler.enable && (config.services.taler.settings.taler ? CURRENCY)
|
||||
) config.services.taler.settings.taler.CURRENCY;
|
||||
|
||||
services.libeufin.bank.settings.libeufin-bankdb-postgres.CONFIG = lib.mkIf config.services.libeufin.bank.createLocalDatabase "postgresql:///libeufin-bank";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
# TODO: create a common module generator for Taler and Libeufin?
|
||||
libeufinComponent:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.services.libeufin.${libeufinComponent} = {
|
||||
enable = lib.mkEnableOption "libeufin core banking system and web interface";
|
||||
package = lib.mkPackageOption pkgs "libeufin" { };
|
||||
debug = lib.mkEnableOption "debug logging";
|
||||
createLocalDatabase = lib.mkEnableOption "automatic creation of a local postgres database";
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open ports in the firewall";
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
cfg = cfgMain.${libeufinComponent};
|
||||
cfgMain = config.services.libeufin;
|
||||
|
||||
configFile = config.environment.etc."libeufin/libeufin.conf".source;
|
||||
serviceName = "libeufin-${libeufinComponent}";
|
||||
isNexus = libeufinComponent == "nexus";
|
||||
|
||||
# get database name from config
|
||||
# TODO: should this always be the same db? In which case, should this be an option directly under `services.libeufin`?
|
||||
dbName =
|
||||
lib.removePrefix "postgresql:///"
|
||||
cfg.settings."libeufin-${libeufinComponent}db-postgres".CONFIG;
|
||||
|
||||
bankPort = cfg.settings."${if isNexus then "nexus-httpd" else "libeufin-bank"}".PORT;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
services.libeufin.settings = cfg.settings;
|
||||
|
||||
# TODO add system-libeufin.slice?
|
||||
systemd.services = {
|
||||
# Main service
|
||||
"${serviceName}" = {
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
ExecStart =
|
||||
let
|
||||
args = lib.cli.toGNUCommandLineShell { } {
|
||||
c = configFile;
|
||||
L = if cfg.debug then "debug" else null;
|
||||
};
|
||||
in
|
||||
"${lib.getExe' cfg.package "libeufin-${libeufinComponent}"} serve ${args}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
requires = [ "libeufin-dbinit.service" ];
|
||||
after = [ "libeufin-dbinit.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
# Database Initialisation
|
||||
libeufin-dbinit =
|
||||
let
|
||||
dbScript = pkgs.writers.writeText "libeufin-db-permissions.sql" ''
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA libeufin_bank TO "${serviceName}";
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA libeufin_nexus TO "${serviceName}";
|
||||
GRANT USAGE ON SCHEMA libeufin_bank TO "${serviceName}";
|
||||
GRANT USAGE ON SCHEMA libeufin_nexus TO "${serviceName}";
|
||||
'';
|
||||
|
||||
# Accounts to be created after the bank database initialization.
|
||||
#
|
||||
# For example, if the bank's currency conversion is enabled, it's
|
||||
# required that the exchange account is registered before the
|
||||
# service starts.
|
||||
initialAccountRegistration = lib.concatMapStringsSep "\n" (
|
||||
account:
|
||||
let
|
||||
args = lib.cli.toGNUCommandLineShell { } {
|
||||
c = configFile;
|
||||
inherit (account) username password name;
|
||||
payto_uri = "payto://x-taler-bank/bank:${toString bankPort}/${account.username}?receiver-name=${account.name}";
|
||||
exchange = lib.toLower account.username == "exchange";
|
||||
};
|
||||
in
|
||||
"${lib.getExe' cfg.package "libeufin-bank"} create-account ${args}"
|
||||
) cfg.initialAccounts;
|
||||
|
||||
args = lib.cli.toGNUCommandLineShell { } {
|
||||
c = configFile;
|
||||
L = if cfg.debug then "debug" else null;
|
||||
};
|
||||
in
|
||||
{
|
||||
path = [ config.services.postgresql.package ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
DynamicUser = true;
|
||||
StateDirectory = "libeufin-dbinit";
|
||||
StateDirectoryMode = "0750";
|
||||
User = dbName;
|
||||
};
|
||||
script = lib.optionalString cfg.enable ''
|
||||
${lib.getExe' cfg.package "libeufin-${libeufinComponent}"} dbinit ${args}
|
||||
'';
|
||||
# Grant DB permissions after schemas have been created
|
||||
postStart =
|
||||
''
|
||||
psql -U "${dbName}" -f "${dbScript}"
|
||||
''
|
||||
+ lib.optionalString ((!isNexus) && (cfg.initialAccounts != [ ])) ''
|
||||
# only register initial accounts once
|
||||
if [ ! -e /var/lib/libeufin-dbinit/init ]; then
|
||||
${initialAccountRegistration}
|
||||
|
||||
touch /var/lib/libeufin-dbinit/init
|
||||
echo "Bank initialisation complete"
|
||||
fi
|
||||
'';
|
||||
requires = lib.optionals cfg.createLocalDatabase [ "postgresql.service" ];
|
||||
after = [ "network.target" ] ++ lib.optionals cfg.createLocalDatabase [ "postgresql.service" ];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [
|
||||
bankPort
|
||||
];
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
services.postgresql = lib.mkIf cfg.createLocalDatabase {
|
||||
enable = true;
|
||||
ensureDatabases = [ dbName ];
|
||||
ensureUsers = [
|
||||
{ name = serviceName; }
|
||||
{
|
||||
name = dbName;
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
cfg.createLocalDatabase || (cfg.settings."libeufin-${libeufinComponent}db-postgres" ? CONFIG);
|
||||
message = "Libeufin ${libeufinComponent} database is not configured.";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.libeufin;
|
||||
settingsFormat = pkgs.formats.ini { };
|
||||
configFile = settingsFormat.generate "generated-libeufin.conf" cfg.settings;
|
||||
in
|
||||
|
||||
{
|
||||
options.services.libeufin = {
|
||||
settings = lib.mkOption {
|
||||
description = "Global configuration options for the libeufin bank system config file.";
|
||||
type = lib.types.submodule { freeformType = settingsFormat.type; };
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (cfg.bank.enable || cfg.nexus.enable) {
|
||||
environment.etc."libeufin/libeufin.conf".source = configFile;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
options,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [ (import ./common.nix "nexus") ];
|
||||
|
||||
options.services.libeufin.nexus.settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration options for the libeufin nexus config file.
|
||||
|
||||
For a list of all possible options, please see the man page [`libeufin-nexus.conf(5)`](https://docs.taler.net/manpages/libeufin-nexus.conf.5.html)
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
inherit (options.services.libeufin.settings.type.nestedTypes) freeformType;
|
||||
options = {
|
||||
nexus-ebics = {
|
||||
# Mandatory configuration values
|
||||
# https://docs.taler.net/libeufin/nexus-manual.html#setting-up-the-ebics-subscriber
|
||||
# https://docs.taler.net/libeufin/setup-ebics-at-postfinance.html
|
||||
CURRENCY = lib.mkOption {
|
||||
description = "Name of the fiat currency.";
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "CHF";
|
||||
};
|
||||
HOST_BASE_URL = lib.mkOption {
|
||||
description = "URL of the EBICS server.";
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "https://ebics.postfinance.ch/ebics/ebics.aspx";
|
||||
};
|
||||
BANK_DIALECT = lib.mkOption {
|
||||
description = ''
|
||||
Name of the following combination: EBICS version and ISO20022
|
||||
recommendations that Nexus would honor in the communication with the
|
||||
bank.
|
||||
|
||||
Currently only the "postfinance" or "gls" value is supported.
|
||||
'';
|
||||
type = lib.types.enum [
|
||||
"postfinance"
|
||||
"gls"
|
||||
];
|
||||
example = "postfinance";
|
||||
};
|
||||
HOST_ID = lib.mkOption {
|
||||
description = "Name of the EBICS host.";
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "PFEBICS";
|
||||
};
|
||||
USER_ID = lib.mkOption {
|
||||
description = ''
|
||||
User ID of the EBICS subscriber.
|
||||
|
||||
This value must be assigned by the bank after having activated a new EBICS subscriber.
|
||||
'';
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "PFC00563";
|
||||
};
|
||||
PARTNER_ID = lib.mkOption {
|
||||
description = ''
|
||||
Partner ID of the EBICS subscriber.
|
||||
|
||||
This value must be assigned by the bank after having activated a new EBICS subscriber.
|
||||
'';
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "PFC00563";
|
||||
};
|
||||
IBAN = lib.mkOption {
|
||||
description = "IBAN of the bank account that is associated with the EBICS subscriber.";
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "CH7789144474425692816";
|
||||
};
|
||||
BIC = lib.mkOption {
|
||||
description = "BIC of the bank account that is associated with the EBICS subscriber.";
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "POFICHBEXXX";
|
||||
};
|
||||
NAME = lib.mkOption {
|
||||
description = "Legal entity that is associated with the EBICS subscriber.";
|
||||
type = lib.types.nonEmptyStr;
|
||||
example = "John Smith S.A.";
|
||||
};
|
||||
BANK_PUBLIC_KEYS_FILE = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/libeufin-nexus/bank-ebics-keys.json";
|
||||
description = ''
|
||||
Filesystem location where Nexus should store the bank public keys.
|
||||
'';
|
||||
};
|
||||
CLIENT_PRIVATE_KEYS_FILE = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "/var/lib/libeufin-nexus/client-ebics-keys.json";
|
||||
description = ''
|
||||
Filesystem location where Nexus should store the subscriber private keys.
|
||||
'';
|
||||
};
|
||||
};
|
||||
nexus-httpd = {
|
||||
PORT = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8084;
|
||||
description = ''
|
||||
The port on which libeufin-bank should listen.
|
||||
'';
|
||||
};
|
||||
};
|
||||
libeufin-nexusdb-postgres = {
|
||||
CONFIG = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The database connection string for the libeufin-nexus database.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
cfgMain = config.services.libeufin;
|
||||
cfg = config.services.libeufin.nexus;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
services.libeufin.nexus.settings.libeufin-nexusdb-postgres.CONFIG = lib.mkIf (
|
||||
cfgMain.bank.enable && cfgMain.bank.createLocalDatabase
|
||||
) "postgresql:///libeufin-bank";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
# TODO: create a common module generator for Taler and Libeufin?
|
||||
{
|
||||
talerComponent ? "",
|
||||
servicesDB ? [ ],
|
||||
servicesNoDB ? [ ],
|
||||
...
|
||||
}:
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = cfgTaler.${talerComponent};
|
||||
cfgTaler = config.services.taler;
|
||||
|
||||
settingsFormat = pkgs.formats.ini { };
|
||||
|
||||
configFile = config.environment.etc."taler/taler.conf".source;
|
||||
componentConfigFile = settingsFormat.generate "generated-taler-${talerComponent}.conf" cfg.settings;
|
||||
|
||||
services = servicesDB ++ servicesNoDB;
|
||||
|
||||
dbName = "taler-${talerComponent}-httpd";
|
||||
groupName = "taler-${talerComponent}-services";
|
||||
|
||||
inherit (cfgTaler) runtimeDir;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.taler.${talerComponent} = {
|
||||
enable = lib.mkEnableOption "the GNU Taler ${talerComponent}";
|
||||
package = lib.mkPackageOption pkgs "taler-${talerComponent}" { };
|
||||
# TODO: make option accept multiple debugging levels?
|
||||
debug = lib.mkEnableOption "debug logging";
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open ports in the firewall";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.taler.enable = cfg.enable;
|
||||
services.taler.includes = [ componentConfigFile ];
|
||||
|
||||
systemd.services = lib.mergeAttrsList [
|
||||
# Main services
|
||||
(lib.genAttrs (map (n: "taler-${talerComponent}-${n}") services) (name: {
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
User = name;
|
||||
Group = groupName;
|
||||
ExecStart = toString [
|
||||
(lib.getExe' cfg.package name)
|
||||
"-c ${configFile}"
|
||||
(lib.optionalString cfg.debug " -L debug")
|
||||
];
|
||||
RuntimeDirectory = name;
|
||||
StateDirectory = name;
|
||||
CacheDirectory = name;
|
||||
ReadWritePaths = [ runtimeDir ];
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
requires = [ "taler-${talerComponent}-dbinit.service" ];
|
||||
after = [ "taler-${talerComponent}-dbinit.service" ];
|
||||
wantedBy = [ "multi-user.target" ]; # TODO slice?
|
||||
}))
|
||||
# Database Initialisation
|
||||
{
|
||||
"taler-${talerComponent}-dbinit" = {
|
||||
path = [ config.services.postgresql.package ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
DynamicUser = true;
|
||||
User = dbName;
|
||||
Restart = "on-failure";
|
||||
RestartSec = "5s";
|
||||
};
|
||||
requires = [ "postgresql.service" ];
|
||||
after = [ "postgresql.service" ];
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
users.groups.${groupName} = { };
|
||||
systemd.tmpfiles.settings = {
|
||||
"10-taler-${talerComponent}" = {
|
||||
"${runtimeDir}" = {
|
||||
d = {
|
||||
group = groupName;
|
||||
user = "nobody";
|
||||
mode = "070";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ cfg.settings."${talerComponent}".PORT ];
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ dbName ];
|
||||
ensureUsers = map (service: { name = "taler-${talerComponent}-${service}"; }) servicesDB ++ [
|
||||
{
|
||||
name = dbName;
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = cfgTaler.exchange;
|
||||
cfgTaler = config.services.taler;
|
||||
|
||||
talerComponent = "exchange";
|
||||
|
||||
# https://docs.taler.net/taler-exchange-manual.html#services-users-groups-and-file-system-hierarchy
|
||||
servicesDB = [
|
||||
"httpd"
|
||||
"aggregator"
|
||||
"closer"
|
||||
"wirewatch"
|
||||
];
|
||||
|
||||
servicesNoDB = [
|
||||
"secmod-cs"
|
||||
"secmod-eddsa"
|
||||
"secmod-rsa"
|
||||
];
|
||||
in
|
||||
|
||||
{
|
||||
imports = [
|
||||
(import ./common.nix { inherit talerComponent servicesDB servicesNoDB; })
|
||||
];
|
||||
|
||||
options.services.taler.exchange = {
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration options for the taler exchange config file.
|
||||
|
||||
For a list of all possible options, please see the man page [`taler-exchange.conf(5)`](https://docs.taler.net/manpages/taler-exchange.conf.5.html)
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
inherit (options.services.taler.settings.type.nestedTypes) freeformType;
|
||||
options = {
|
||||
# TODO: do we want this to be a sub-attribute or only define the exchange set of options here
|
||||
exchange = {
|
||||
AML_THRESHOLD = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${cfgTaler.settings.taler.CURRENCY}:1000000";
|
||||
defaultText = "1000000 in {option}`CURRENCY`";
|
||||
description = "Monthly transaction volume until an account is considered suspicious and flagged for AML review.";
|
||||
};
|
||||
DB = lib.mkOption {
|
||||
type = lib.types.enum [ "postgres" ];
|
||||
default = "postgres";
|
||||
description = "Plugin to use for the database.";
|
||||
};
|
||||
MASTER_PUBLIC_KEY = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "Used by the exchange to verify information signed by the offline system.";
|
||||
};
|
||||
PORT = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8081;
|
||||
description = "Port on which the HTTP server listens.";
|
||||
};
|
||||
};
|
||||
exchangedb-postgres = {
|
||||
CONFIG = lib.mkOption {
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "postgres:///taler-exchange-httpd";
|
||||
description = "Database connection URI.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
denominationConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
defaultText = "None, you must set this yourself.";
|
||||
example = ''
|
||||
[COIN-KUDOS-n1-t1718140083]
|
||||
VALUE = KUDOS:0.1
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0.1
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
'';
|
||||
description = ''
|
||||
This option configures the cash denomination for the coins that the exchange offers.
|
||||
For more information, consult the [upstream docs](https://docs.taler.net/taler-exchange-manual.html#coins-denomination-keys).
|
||||
|
||||
You can either write these manually or you can use the `taler-harness deployment gen-coin-config`
|
||||
command to generate it.
|
||||
|
||||
Warning: Do not modify existing denominations after deployment.
|
||||
Please see the upstream docs for how to safely do that.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = cfg.settings.exchange.MASTER_PUBLIC_KEY != "";
|
||||
message = ''
|
||||
You must provide `config.services.taler.exchange.settings.exchange.MASTER_PUBLIC_KEY` with the
|
||||
public part of your master key.
|
||||
|
||||
This will be used by the auditor service to get information about the exchange.
|
||||
For more information, see https://docs.taler.net/taler-auditor-manual.html#initial-configuration
|
||||
|
||||
To generate this key, you must run `taler-exchange-offline setup`, which will print the public key.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
services.taler.includes = [
|
||||
(pkgs.writers.writeText "exchange-denominations.conf" cfg.denominationConfig)
|
||||
];
|
||||
|
||||
systemd.services.taler-exchange-wirewatch = {
|
||||
requires = [ "taler-exchange-httpd.service" ];
|
||||
after = [ "taler-exchange-httpd.service" ];
|
||||
};
|
||||
|
||||
# Taken from https://docs.taler.net/taler-exchange-manual.html#exchange-database-setup
|
||||
# TODO: Why does aggregator need DELETE?
|
||||
systemd.services."taler-${talerComponent}-dbinit".script =
|
||||
let
|
||||
deletePerm = name: lib.optionalString (name == "aggregator") ",DELETE";
|
||||
dbScript = pkgs.writers.writeText "taler-exchange-db-permissions.sql" (
|
||||
lib.pipe servicesDB [
|
||||
(map (name: ''
|
||||
GRANT SELECT,INSERT,UPDATE${deletePerm name} ON ALL TABLES IN SCHEMA exchange TO "taler-exchange-${name}";
|
||||
GRANT USAGE ON SCHEMA exchange TO "taler-exchange-${name}";
|
||||
''))
|
||||
lib.concatStrings
|
||||
]
|
||||
);
|
||||
in
|
||||
''
|
||||
${lib.getExe' cfg.package "taler-exchange-dbinit"}
|
||||
psql -U taler-exchange-httpd -f ${dbScript}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
options,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = cfgTaler.merchant;
|
||||
cfgTaler = config.services.taler;
|
||||
|
||||
talerComponent = "merchant";
|
||||
|
||||
# https://docs.taler.net/taler-merchant-manual.html#launching-the-backend
|
||||
servicesDB = [
|
||||
"httpd"
|
||||
"webhook"
|
||||
"wirewatch"
|
||||
"depositcheck"
|
||||
"exchange"
|
||||
];
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(import ./common.nix { inherit talerComponent servicesDB; })
|
||||
];
|
||||
|
||||
options.services.taler.merchant = {
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration options for the taler merchant config file.
|
||||
|
||||
For a list of all possible options, please see the man page [`taler-merchant.conf(5)`](https://docs.taler.net/manpages/taler-merchant.conf.5.html)
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
inherit (options.services.taler.settings.type.nestedTypes) freeformType;
|
||||
options = {
|
||||
merchant = {
|
||||
DB = lib.mkOption {
|
||||
type = lib.types.enum [ "postgres" ];
|
||||
default = "postgres";
|
||||
description = "Plugin to use for the database.";
|
||||
};
|
||||
PORT = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8083;
|
||||
description = "Port on which the HTTP server listens.";
|
||||
};
|
||||
SERVE = lib.mkOption {
|
||||
type = lib.types.enum [
|
||||
"tcp"
|
||||
"unix"
|
||||
];
|
||||
default = "tcp";
|
||||
description = ''
|
||||
Whether the HTTP server should listen on a UNIX domain socket ("unix") or on a TCP socket ("tcp").
|
||||
'';
|
||||
};
|
||||
LEGAL_PRESERVATION = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "10 years";
|
||||
description = "How long to keep data in the database for tax audits after the transaction has completed.";
|
||||
};
|
||||
};
|
||||
merchantdb-postgres = {
|
||||
CONFIG = lib.mkOption {
|
||||
type = lib.types.nonEmptyStr;
|
||||
default = "postgres:///taler-merchant-httpd";
|
||||
description = "Database connection URI.";
|
||||
};
|
||||
SQL_DIR = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
internal = true;
|
||||
default = "${cfg.package}/share/taler/sql/merchant/";
|
||||
description = "The location for the SQL files to setup the database tables.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.taler-merchant-depositcheck = {
|
||||
# taler-merchant-depositcheck needs its executable is in the PATH
|
||||
# NOTE: couldn't use `lib.getExe` to only get that single executable
|
||||
path = [ cfg.package ];
|
||||
};
|
||||
|
||||
systemd.services."taler-${talerComponent}-dbinit".script =
|
||||
let
|
||||
# NOTE: not documented, but is necessary
|
||||
dbScript = pkgs.writers.writeText "taler-merchant-db-permissions.sql" (
|
||||
lib.concatStrings (
|
||||
map (name: ''
|
||||
GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA merchant TO "taler-merchant-${name}";
|
||||
GRANT USAGE ON SCHEMA merchant TO "taler-merchant-${name}";
|
||||
'') servicesDB
|
||||
)
|
||||
);
|
||||
in
|
||||
''
|
||||
${lib.getExe' cfg.package "taler-merchant-dbinit"}
|
||||
psql -U taler-${talerComponent}-httpd -f ${dbScript}
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.taler;
|
||||
settingsFormat = pkgs.formats.ini { };
|
||||
in
|
||||
|
||||
{
|
||||
# TODO turn this into a generic taler-like service thingy?
|
||||
options.services.taler = {
|
||||
enable = lib.mkEnableOption "the GNU Taler system" // lib.mkOption { internal = true; };
|
||||
includes = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [ ];
|
||||
description = ''
|
||||
Files to include into the config file using Taler's `@inline@` directive.
|
||||
|
||||
This allows including arbitrary INI files, including imperatively managed ones.
|
||||
'';
|
||||
};
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Global configuration options for the taler config file.
|
||||
|
||||
For a list of all possible options, please see the man page [`taler.conf(5)`](https://docs.taler.net/manpages/taler.conf.5.html)
|
||||
'';
|
||||
type = lib.types.submodule {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
taler = {
|
||||
CURRENCY = lib.mkOption {
|
||||
type = lib.types.nonEmptyStr;
|
||||
description = ''
|
||||
The currency which taler services will operate with. This cannot be changed later.
|
||||
'';
|
||||
};
|
||||
CURRENCY_ROUND_UNIT = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${cfg.settings.taler.CURRENCY}:0.01";
|
||||
defaultText = lib.literalExpression ''
|
||||
"''${config.services.taler.settings.taler.CURRENCY}:0.01"
|
||||
'';
|
||||
description = ''
|
||||
Smallest amount in this currency that can be transferred using the underlying RTGS.
|
||||
|
||||
You should probably not touch this.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
runtimeDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/run/taler-system-runtime/";
|
||||
description = ''
|
||||
Runtime directory shared between the taler services.
|
||||
|
||||
Crypto helpers put their sockets here for instance and the httpd
|
||||
connects to them.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.taler.settings.PATHS = {
|
||||
TALER_DATA_HOME = "\${STATE_DIRECTORY}/";
|
||||
TALER_CACHE_HOME = "\${CACHE_DIRECTORY}/";
|
||||
TALER_RUNTIME_DIR = cfg.runtimeDir;
|
||||
};
|
||||
|
||||
environment.etc."taler/taler.conf".source =
|
||||
let
|
||||
includes = pkgs.writers.writeText "includes.conf" (
|
||||
lib.concatStringsSep "\n" (map (include: "@inline@ ${include}") cfg.includes)
|
||||
);
|
||||
generatedConfig = settingsFormat.generate "generated-taler.conf" cfg.settings;
|
||||
in
|
||||
pkgs.runCommand "taler.conf" { } ''
|
||||
cat ${includes} > $out
|
||||
echo >> $out
|
||||
echo >> $out
|
||||
cat ${generatedConfig} >> $out
|
||||
'';
|
||||
|
||||
};
|
||||
}
|
||||
@@ -138,9 +138,10 @@ in
|
||||
|
||||
script = ''
|
||||
${lib.concatStringsSep "\n" (
|
||||
builtins.map (name: "export ${name}=$(systemd-creds cat 'SECRET-${name}')") (
|
||||
lib.attrNames cfg.credentials
|
||||
)
|
||||
builtins.map (name: ''
|
||||
${name}="$(systemd-creds cat 'SECRET-${name}')"
|
||||
export ${name}
|
||||
'') (lib.attrNames cfg.credentials)
|
||||
)}
|
||||
exec ${lib.escapeShellArg (lib.getExe cfg.package)}
|
||||
'';
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.echoip;
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ defelo ];
|
||||
|
||||
options.services.echoip = {
|
||||
enable = lib.mkEnableOption "echoip";
|
||||
|
||||
package = lib.mkPackageOption pkgs "echoip" { };
|
||||
|
||||
virtualHost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
Name of the nginx virtual host to use and setup. If null, do not setup anything.
|
||||
'';
|
||||
default = null;
|
||||
};
|
||||
|
||||
extraArgs = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
description = "Extra command line arguments to pass to echoip. See <https://github.com/mpolden/echoip> for details.";
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
listenAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "The address echoip should listen on";
|
||||
default = ":8080";
|
||||
example = "127.0.0.1:8000";
|
||||
};
|
||||
|
||||
enablePortLookup = lib.mkEnableOption "port lookup";
|
||||
|
||||
enableReverseHostnameLookups = lib.mkEnableOption "reverse hostname lookups";
|
||||
|
||||
remoteIpHeader = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = "Header to trust for remote IP, if present";
|
||||
default = null;
|
||||
example = "X-Real-IP";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.echoip = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
wants = [ "network-online.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
User = "echoip";
|
||||
Group = "echoip";
|
||||
DynamicUser = true;
|
||||
ExecStart = lib.escapeShellArgs (
|
||||
[
|
||||
(lib.getExe cfg.package)
|
||||
"-l"
|
||||
cfg.listenAddress
|
||||
]
|
||||
++ lib.optional cfg.enablePortLookup "-p"
|
||||
++ lib.optional cfg.enableReverseHostnameLookups "-r"
|
||||
++ lib.optionals (cfg.remoteIpHeader != null) [
|
||||
"-H"
|
||||
cfg.remoteIpHeader
|
||||
]
|
||||
++ cfg.extraArgs
|
||||
);
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = [ "" ];
|
||||
DeviceAllow = [ "" ];
|
||||
LockPersonality = true;
|
||||
PrivateDevices = true;
|
||||
PrivateTmp = true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = lib.mkIf (cfg.virtualHost != null) {
|
||||
enable = true;
|
||||
virtualHosts.${cfg.virtualHost} = {
|
||||
locations."/" = {
|
||||
proxyPass = "http://${cfg.listenAddress}";
|
||||
recommendedProxySettings = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.echoip = lib.mkIf (cfg.virtualHost != null) {
|
||||
listenAddress = lib.mkDefault "127.0.0.1:8080";
|
||||
remoteIpHeader = "X-Real-IP";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -192,7 +192,7 @@ let
|
||||
script =
|
||||
''
|
||||
state="/run/nixos/network/addresses/${i.name}"
|
||||
mkdir -p $(dirname "$state")
|
||||
mkdir -p "$(dirname "$state")"
|
||||
|
||||
ip link set dev "${i.name}" up
|
||||
|
||||
@@ -206,14 +206,14 @@ let
|
||||
if out=$(ip addr replace "${cidr}" dev "${i.name}" 2>&1); then
|
||||
echo "done"
|
||||
else
|
||||
echo "'ip addr replace "${cidr}" dev "${i.name}"' failed: $out"
|
||||
echo "'ip addr replace \"${cidr}\" dev \"${i.name}\"' failed: $out"
|
||||
exit 1
|
||||
fi
|
||||
''
|
||||
)}
|
||||
|
||||
state="/run/nixos/network/routes/${i.name}"
|
||||
mkdir -p $(dirname "$state")
|
||||
mkdir -p "$(dirname "$state")"
|
||||
|
||||
${flip concatMapStrings (i.ipv4.routes ++ i.ipv6.routes) (route:
|
||||
let
|
||||
@@ -228,7 +228,7 @@ let
|
||||
if out=$(ip route add ${type} "${cidr}" ${options} ${via} dev "${i.name}" proto static 2>&1); then
|
||||
echo "done"
|
||||
elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
|
||||
echo "'ip route add ${type} "${cidr}" ${options} ${via} dev "${i.name}"' failed: $out"
|
||||
echo "'ip route add ${type} \"${cidr}\" ${options} ${via} dev \"${i.name}\"' failed: $out"
|
||||
exit 1
|
||||
fi
|
||||
''
|
||||
|
||||
@@ -19,8 +19,19 @@ let
|
||||
export HOME=/root
|
||||
export DISPLAY=:0.0
|
||||
|
||||
# Determine if this script is ran with nounset
|
||||
strict="false"
|
||||
if set -o | grep --quiet --perl-regexp "nounset\s+on"; then
|
||||
strict="true"
|
||||
fi
|
||||
|
||||
if [[ -e /etc/profile ]]; then
|
||||
# TODO: Currently shell profiles are not checked at build time,
|
||||
# so we need to unset stricter options to source them
|
||||
set +o nounset
|
||||
# shellcheck disable=SC1091
|
||||
source /etc/profile
|
||||
[ "$strict" = "true" ] && set -o nounset
|
||||
fi
|
||||
|
||||
# Don't use a pager when executing backdoor
|
||||
@@ -45,7 +56,7 @@ let
|
||||
# we can also run non-NixOS guests during tests. This, however, is
|
||||
# mostly futureproofing as the test instrumentation is still very
|
||||
# tightly coupled to NixOS.
|
||||
PS1= exec ${pkgs.coreutils}/bin/env bash --norc /dev/hvc0
|
||||
PS1="" exec ${pkgs.coreutils}/bin/env bash --norc /dev/hvc0
|
||||
'';
|
||||
serviceConfig.KillSignal = "SIGHUP";
|
||||
};
|
||||
|
||||
@@ -294,6 +294,7 @@ in {
|
||||
early-mount-options = handleTest ./early-mount-options.nix {};
|
||||
ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
|
||||
ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {};
|
||||
echoip = handleTest ./echoip.nix {};
|
||||
ecryptfs = handleTest ./ecryptfs.nix {};
|
||||
fscrypt = handleTest ./fscrypt.nix {};
|
||||
fastnetmon-advanced = runTest ./fastnetmon-advanced.nix;
|
||||
@@ -1064,6 +1065,7 @@ in {
|
||||
systemd-userdbd = handleTest ./systemd-userdbd.nix {};
|
||||
systemd-homed = handleTest ./systemd-homed.nix {};
|
||||
systemtap = handleTest ./systemtap.nix {};
|
||||
taler = handleTest ./taler {};
|
||||
tandoor-recipes = handleTest ./tandoor-recipes.nix {};
|
||||
tandoor-recipes-script-name = handleTest ./tandoor-recipes-script-name.nix {};
|
||||
tang = handleTest ./tang.nix {};
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import ./make-test-python.nix (
|
||||
{ lib, ... }:
|
||||
{
|
||||
name = "echoip";
|
||||
meta.maintainers = with lib.maintainers; [ defelo ];
|
||||
|
||||
nodes.machine = {
|
||||
services.echoip = {
|
||||
enable = true;
|
||||
virtualHost = "echoip.local";
|
||||
};
|
||||
|
||||
networking.hosts = {
|
||||
"127.0.0.1" = [ "echoip.local" ];
|
||||
"::1" = [ "echoip.local" ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.wait_for_unit("echoip.service")
|
||||
machine.wait_for_open_port(8080)
|
||||
|
||||
resp = machine.succeed("curl -4 http://echoip.local/ip")
|
||||
assert resp.strip() == "127.0.0.1"
|
||||
resp = machine.succeed("curl -6 http://echoip.local/ip")
|
||||
assert resp.strip() == "::1"
|
||||
'';
|
||||
}
|
||||
)
|
||||
@@ -52,6 +52,16 @@ import ./make-test-python.nix (
|
||||
];
|
||||
};
|
||||
immutable = makeMattermost {
|
||||
package = pkgs.mattermost.overrideAttrs (prev: {
|
||||
webapp = prev.webapp.overrideAttrs (prevWebapp: {
|
||||
# Ensure that users can add patches.
|
||||
postPatch =
|
||||
prevWebapp.postPatch or ""
|
||||
+ ''
|
||||
substituteInPlace channels/src/root.html --replace-fail "Mattermost" "Patched Mattermost"
|
||||
'';
|
||||
});
|
||||
});
|
||||
mutableConfig = false;
|
||||
extraConfig.SupportSettings.HelpLink = "https://search.nixos.org";
|
||||
};
|
||||
@@ -94,6 +104,8 @@ import ./make-test-python.nix (
|
||||
## Mutable node tests ##
|
||||
mutable.wait_for_unit("mattermost.service")
|
||||
mutable.wait_for_open_port(8065)
|
||||
mutable.succeed("curl -L http://localhost:8065/index.html | grep '${siteName}'")
|
||||
mutable.succeed("curl -L http://localhost:8065/index.html | grep 'Mattermost'")
|
||||
|
||||
# Get the initial config
|
||||
mutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}")
|
||||
@@ -110,6 +122,8 @@ import ./make-test-python.nix (
|
||||
## Mostly mutable node tests ##
|
||||
mostlyMutable.wait_for_unit("mattermost.service")
|
||||
mostlyMutable.wait_for_open_port(8065)
|
||||
mostlyMutable.succeed("curl -L http://localhost:8065/index.html | grep '${siteName}'")
|
||||
mostlyMutable.succeed("curl -L http://localhost:8065/index.html | grep 'Mattermost'")
|
||||
|
||||
# Get the initial config
|
||||
mostlyMutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org"''}")
|
||||
@@ -126,6 +140,8 @@ import ./make-test-python.nix (
|
||||
## Immutable node tests ##
|
||||
immutable.wait_for_unit("mattermost.service")
|
||||
immutable.wait_for_open_port(8065)
|
||||
# Since we patched it, it doesn't replace the site name at runtime anymore
|
||||
immutable.succeed("curl -L http://localhost:8065/index.html | grep 'Patched Mattermost'")
|
||||
|
||||
# Get the initial config
|
||||
immutable.succeed("${expectConfig ''.AboutLink == "https://nixos.org" and .HelpLink == "https://search.nixos.org"''}")
|
||||
@@ -143,6 +159,8 @@ import ./make-test-python.nix (
|
||||
## Environment File node tests ##
|
||||
environmentFile.wait_for_unit("mattermost.service")
|
||||
environmentFile.wait_for_open_port(8065)
|
||||
environmentFile.succeed("curl -L http://localhost:8065/index.html | grep '${siteName}'")
|
||||
environmentFile.succeed("curl -L http://localhost:8065/index.html | grep 'Mattermost'")
|
||||
|
||||
# Settings in the environment file should override settings set otherwise
|
||||
environmentFile.succeed("${expectConfig ''.AboutLink == "https://nixos.org"''}")
|
||||
|
||||
@@ -31,6 +31,8 @@ import ./make-test-python.nix (
|
||||
enable = true;
|
||||
settings.server.HTTP_PORT = 3000;
|
||||
};
|
||||
# Uncomment the next line to lint service scripts (Note: breaks VM startup; see #373166)
|
||||
#systemd.enableStrictShellChecks = true;
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
{ lib, ... }:
|
||||
let
|
||||
# Forward SSH and WebUI ports to host machine
|
||||
#
|
||||
# Connect with: ssh root@localhost -p <hostPort>
|
||||
# Access WebUI from: http://localhost:<hostPort>
|
||||
#
|
||||
# NOTE: This is only accessible from an interactive test, for example:
|
||||
# $ eval $(nix-build -A nixosTests.taler.basic.driver)/bin/nixos-test-driver
|
||||
mkNode =
|
||||
{
|
||||
sshPort ? 0,
|
||||
webuiPort ? 0,
|
||||
nodeSettings ? { },
|
||||
}:
|
||||
lib.recursiveUpdate {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PermitRootLogin = "yes";
|
||||
PermitEmptyPasswords = "yes";
|
||||
};
|
||||
};
|
||||
security.pam.services.sshd.allowNullPassword = true;
|
||||
virtualisation.forwardPorts =
|
||||
(lib.optionals (sshPort != 0) [
|
||||
{
|
||||
from = "host";
|
||||
host.port = sshPort;
|
||||
guest.port = 22;
|
||||
}
|
||||
])
|
||||
++ (lib.optionals (webuiPort != 0) [
|
||||
{
|
||||
from = "host";
|
||||
host.port = webuiPort;
|
||||
guest.port = webuiPort;
|
||||
}
|
||||
]);
|
||||
} nodeSettings;
|
||||
in
|
||||
rec {
|
||||
CURRENCY = "KUDOS";
|
||||
FIAT_CURRENCY = "CHF";
|
||||
|
||||
nodes = {
|
||||
exchange =
|
||||
{ config, lib, ... }:
|
||||
mkNode {
|
||||
sshPort = 1111;
|
||||
webuiPort = 8081;
|
||||
|
||||
nodeSettings = {
|
||||
services.taler = {
|
||||
settings = {
|
||||
taler.CURRENCY = CURRENCY;
|
||||
};
|
||||
includes = [ ../conf/taler-accounts.conf ];
|
||||
exchange = {
|
||||
enable = true;
|
||||
debug = true;
|
||||
openFirewall = true;
|
||||
denominationConfig = lib.readFile ../conf/taler-denominations.conf;
|
||||
settings = {
|
||||
exchange = {
|
||||
MASTER_PUBLIC_KEY = "2TQSTPFZBC2MC4E52NHPA050YXYG02VC3AB50QESM6JX1QJEYVQ0";
|
||||
BASE_URL = "http://exchange:8081/";
|
||||
};
|
||||
exchange-offline = {
|
||||
MASTER_PRIV_FILE = "${../conf/private.key}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
bank =
|
||||
{ config, ... }:
|
||||
mkNode {
|
||||
sshPort = 2222;
|
||||
webuiPort = 8082;
|
||||
|
||||
nodeSettings = {
|
||||
services.libeufin.bank = {
|
||||
enable = true;
|
||||
debug = true;
|
||||
|
||||
openFirewall = true;
|
||||
createLocalDatabase = true;
|
||||
|
||||
initialAccounts = [
|
||||
{
|
||||
username = "exchange";
|
||||
password = "exchange";
|
||||
name = "Exchange";
|
||||
}
|
||||
];
|
||||
|
||||
settings = {
|
||||
libeufin-bank = {
|
||||
WIRE_TYPE = "x-taler-bank";
|
||||
# WIRE_TYPE = "iban";
|
||||
X_TALER_BANK_PAYTO_HOSTNAME = "bank:8082";
|
||||
# IBAN_PAYTO_BIC = "SANDBOXX";
|
||||
BASE_URL = "bank:8082";
|
||||
|
||||
# Allow creating new accounts
|
||||
ALLOW_REGISTRATION = "yes";
|
||||
|
||||
# A registration bonus makes withdrawals easier since the
|
||||
# bank account balance is not empty
|
||||
REGISTRATION_BONUS_ENABLED = "yes";
|
||||
REGISTRATION_BONUS = "${CURRENCY}:100";
|
||||
|
||||
DEFAULT_DEBT_LIMIT = "${CURRENCY}:500";
|
||||
|
||||
# NOTE: The exchange's bank account must be initialised before
|
||||
# the main bank service starts, else it doesn't work.
|
||||
# The `services.libeufin.bank.initialAccounts` option can be used to do this.
|
||||
ALLOW_CONVERSION = "yes";
|
||||
ALLOW_EDIT_CASHOUT_PAYTO_URI = "yes";
|
||||
|
||||
SUGGESTED_WITHDRAWAL_EXCHANGE = "http://exchange:8081/";
|
||||
|
||||
inherit CURRENCY FIAT_CURRENCY;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.libeufin.nexus = {
|
||||
enable = true;
|
||||
debug = true;
|
||||
|
||||
openFirewall = true;
|
||||
createLocalDatabase = true;
|
||||
|
||||
settings = {
|
||||
# https://docs.taler.net/libeufin/setup-ebics-at-postfinance.html
|
||||
nexus-ebics = {
|
||||
# == Mandatory ==
|
||||
CURRENCY = FIAT_CURRENCY;
|
||||
# Bank
|
||||
HOST_BASE_URL = "https://isotest.postfinance.ch/ebicsweb/ebicsweb";
|
||||
BANK_DIALECT = "postfinance";
|
||||
# EBICS IDs
|
||||
HOST_ID = "PFEBICS";
|
||||
USER_ID = "PFC00639";
|
||||
PARTNER_ID = "PFC00639";
|
||||
# Account information
|
||||
IBAN = "CH4740123RW4167362694";
|
||||
BIC = "BIC";
|
||||
NAME = "nixosTest nixosTest";
|
||||
|
||||
# == Optional ==
|
||||
CLIENT_PRIVATE_KEYS_FILE = "${../conf/client-ebics-keys.json}";
|
||||
BANK_PUBLIC_KEYS_FILE = "${../conf/bank-ebics-keys.json}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
merchant =
|
||||
{ config, ... }:
|
||||
mkNode {
|
||||
sshPort = 3333;
|
||||
webuiPort = 8083;
|
||||
|
||||
nodeSettings = {
|
||||
services.taler = {
|
||||
settings = {
|
||||
taler.CURRENCY = CURRENCY;
|
||||
};
|
||||
merchant = {
|
||||
enable = true;
|
||||
debug = true;
|
||||
openFirewall = true;
|
||||
settings.merchant-exchange-test = {
|
||||
EXCHANGE_BASE_URL = "http://exchange:8081/";
|
||||
MASTER_KEY = "2TQSTPFZBC2MC4E52NHPA050YXYG02VC3AB50QESM6JX1QJEYVQ0";
|
||||
inherit CURRENCY;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
client =
|
||||
{ pkgs, ... }:
|
||||
mkNode {
|
||||
sshPort = 4444;
|
||||
|
||||
nodeSettings = {
|
||||
environment.systemPackages = [ pkgs.taler-wallet-core ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
nodes,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfgNodes = pkgs.callPackage ./nodes.nix { inherit lib; };
|
||||
bankConfig = nodes.bank.config.environment.etc."libeufin/libeufin.conf".source;
|
||||
|
||||
inherit (cfgNodes) CURRENCY FIAT_CURRENCY;
|
||||
in
|
||||
{
|
||||
commonScripts =
|
||||
# python
|
||||
''
|
||||
def succeed(machine, commands):
|
||||
"""A more convenient `machine.succeed` that supports multi-line inputs"""
|
||||
flattened_commands = [c.replace("\n", "") for c in commands] # flatten multi-line
|
||||
return machine.succeed(" ".join(flattened_commands))
|
||||
|
||||
|
||||
def systemd_run(machine, cmd, user="nobody", group="nobody"):
|
||||
"""Execute command as a systemd DynamicUser"""
|
||||
machine.log(f"Executing command (via systemd-run): \"{cmd}\"")
|
||||
|
||||
(status, out) = machine.execute( " ".join([
|
||||
"systemd-run",
|
||||
"--service-type=exec",
|
||||
"--quiet",
|
||||
"--wait",
|
||||
"-E PATH=\"$PATH\"",
|
||||
"-p StandardOutput=journal",
|
||||
"-p StandardError=journal",
|
||||
"-p DynamicUser=yes",
|
||||
f"-p Group={group}" if group != "nobody" else "",
|
||||
f"-p User={user}" if user != "nobody" else "",
|
||||
f"$SHELL -c '{cmd}'"
|
||||
]) )
|
||||
|
||||
if status != 0:
|
||||
raise Exception(f"systemd_run failed (status {status})")
|
||||
|
||||
machine.log("systemd-run finished successfully")
|
||||
|
||||
|
||||
def register_bank_account(username, password, name, is_exchange=False):
|
||||
"""Register Libeufin bank account for the x-taler-bank wire method"""
|
||||
return systemd_run(bank, " ".join([
|
||||
'libeufin-bank',
|
||||
'create-account',
|
||||
'-c ${bankConfig}',
|
||||
f'--username {username}',
|
||||
f'--password {password}',
|
||||
f'--name {name}',
|
||||
f'--payto_uri="payto://x-taler-bank/bank:8082/{username}?receiver-name={name}"',
|
||||
'--exchange' if (is_exchange or username.lower()=="exchange") else ' '
|
||||
]),
|
||||
user="libeufin-bank")
|
||||
|
||||
|
||||
def wallet_cli(command):
|
||||
"""Wrapper for the Taler CLI wallet"""
|
||||
return client.succeed(
|
||||
"taler-wallet-cli "
|
||||
"--no-throttle " # don't do any request throttling
|
||||
+ command
|
||||
)
|
||||
|
||||
|
||||
def verify_balance(balanceWanted: str):
|
||||
"""Compare Taler CLI wallet balance with expected amount"""
|
||||
balance = wallet_cli("balance --json")
|
||||
try:
|
||||
balanceGot = json.loads(balance)["balances"][0]["available"]
|
||||
except:
|
||||
balanceGot = "${CURRENCY}:0"
|
||||
|
||||
# Compare balance with expected value
|
||||
if balanceGot != balanceWanted:
|
||||
client.fail(f'echo Wanted balance: "{balanceWanted}", got: "{balanceGot}"')
|
||||
else:
|
||||
client.succeed(f"echo Withdraw successfully made. New balance: {balanceWanted}")
|
||||
|
||||
|
||||
def verify_conversion(regionalWanted: str):
|
||||
"""Compare converted Libeufin Nexus funds with expected regional currency"""
|
||||
# Get transaction details
|
||||
response = json.loads(
|
||||
succeed(bank, [
|
||||
"curl -sSfL",
|
||||
# TODO: get exchange from config?
|
||||
"-u exchange:exchange",
|
||||
"http://bank:8082/accounts/exchange/transactions"
|
||||
])
|
||||
)
|
||||
amount = response["transactions"][0]["amount"].split(":") # CURRENCY:VALUE
|
||||
currencyGot, regionalGot = amount
|
||||
|
||||
# Check conversion (1:1 ratio)
|
||||
if (regionalGot != regionalWanted) or (currencyGot != "${CURRENCY}"):
|
||||
client.fail(f'echo Wanted "${CURRENCY}:{regionalWanted}", got: "{currencyGot}:{regionalGot}"')
|
||||
else:
|
||||
client.succeed(f'echo Conversion successfully made: "${FIAT_CURRENCY}:{regionalWanted}" -> "{currencyGot}:{regionalGot}"')
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"bank_encryption_public_key":"621028HG1M30JAM6923FE381040GA003G80GY01GG80GM0M2040G1EACATA11EF5SVKNBNBYF1S3WSKQ2A2R9VZ7RW2HRX00293JPZ7VQ780RFRVYTQKKDDNJAQGBH4659GT9QYBMJCG1RKZEH1WDJ0GAAY7B7NBMW6FWXCKFYRMZQME0WBGZ1AAMY2VBQ5XAFV8216EFNF2EPG6M5ZGHG9RG6EGED56TK9JESQ02Q7AAVBRAAARVBN9NHCN64KQ3SRRHYXB8RWRK4TSSC93XG8RWMQH4ZDJSBYDCEXFY6G3AWTZ0EZNCJJAYB98T4GNFWZMN81AVYCQHXT1APX81AXCAYNK7J9XETF5CN1J1WV0BVA2BYG4VAMAW123REPN67JF1TNWPTADBMHS17N2V1GFYT8JRWX4TGM2996NXTEPMA8C2CDDE0CRY2A6HT8C5H2D6C62YGRSCF820C0G008","bank_authentication_public_key":"621028HG1M30JAM6923FE381040GA003G80GY01GG80GM0M2040G1EACATA11EF5SVKNBNBYF1S3WSKQ2A2R9VZ7RW2HRX00293JPZ7VQ780RFRVYTQKKDDNJAQGBH4659GT9QYBMJCG1RKZEH1WDJ0GAAY7B7NBMW6FWXCKFYRMZQME0WBGZ1AAMY2VBQ5XAFV8216EFNF2EPG6M5ZGHG9RG6EGED56TK9JESQ02Q7AAVBRAAARVBN9NHCN64KQ3SRRHYXB8RWRK4TSSC93XG8RWMQH4ZDJSBYDCEXFY6G3AWTZ0EZNCJJAYB98T4GNFWZMN81AVYCQHXT1APX81AXCAYNK7J9XETF5CN1J1WV0BVA2BYG4VAMAW123REPN67JF1TNWPTADBMHS17N2V1GFYT8JRWX4TGM2996NXTEPMA8C2CDDE0CRY2A6HT8C5H2D6C62YGRSCF820C0G008","accepted":true}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
|
||||
[
|
||||
{
|
||||
"operation": "exchange-enable-wire-0",
|
||||
"arguments": {
|
||||
"payto_uri": "payto://x-taler-bank/bank:8082/exchange?receiver-name=Exchange",
|
||||
"debit_restrictions": [],
|
||||
"credit_restrictions": [],
|
||||
"priority": 0,
|
||||
"validity_start": {
|
||||
"t_s": 1725886541
|
||||
},
|
||||
"master_sig_add": "68WDT3JX1S5GQ9D3RZWXQVZK9AHFZ46YY5DA993720YA3SCBR4SW3X09NH5DECTXGWBKSN0MGKE1ANA9QZ95SKSNYPS9T9G46PCJC20",
|
||||
"master_sig_wire": "39CEN9007DEXXMSDFZX1R2YYNANZYAFHX4EZC4ZX3C8DQEYT83JNVCVYMWYDGWEX6S891ZPXD6QHJE9J41YV9EN703Q0NM0MVE4FP18"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
�Ř'IŐ‚–v&©�űľ˘¶ßH{VWýr�¶CjÜ>¦
|
||||
@@ -0,0 +1,10 @@
|
||||
[exchange-account-test]
|
||||
PAYTO_URI = payto://x-taler-bank/bank:8082/exchange?receiver-name=Exchange
|
||||
ENABLE_DEBIT = YES
|
||||
ENABLE_CREDIT = YES
|
||||
|
||||
[exchange-accountcredentials-test]
|
||||
WIRE_GATEWAY_URL = http://bank:8082/accounts/exchange/taler-wire-gateway/
|
||||
WIRE_GATEWAY_AUTH_METHOD = BASIC
|
||||
USERNAME = exchange
|
||||
PASSWORD = exchange
|
||||
@@ -0,0 +1,95 @@
|
||||
[COIN-KUDOS-n1-t1726827661]
|
||||
VALUE = KUDOS:0.1
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n2-t1726827661]
|
||||
VALUE = KUDOS:0.2
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n3-t1726827661]
|
||||
VALUE = KUDOS:0.4
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n4-t1726827661]
|
||||
VALUE = KUDOS:0.8
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n5-t1726827661]
|
||||
VALUE = KUDOS:1.6
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n6-t1726827661]
|
||||
VALUE = KUDOS:3.2
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n7-t1726827661]
|
||||
VALUE = KUDOS:6.4
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
|
||||
[COIN-KUDOS-n8-t1726827661]
|
||||
VALUE = KUDOS:12.8
|
||||
DURATION_WITHDRAW = 7 days
|
||||
DURATION_SPEND = 2 years
|
||||
DURATION_LEGAL = 6 years
|
||||
FEE_WITHDRAW = KUDOS:0
|
||||
FEE_DEPOSIT = KUDOS:0
|
||||
FEE_REFRESH = KUDOS:0
|
||||
FEE_REFUND = KUDOS:0
|
||||
RSA_KEYSIZE = 2048
|
||||
CIPHER = RSA
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
system ? builtins.currentSystem,
|
||||
pkgs ? import ../../.. { inherit system; },
|
||||
}:
|
||||
{
|
||||
basic = import ./tests/basic.nix { inherit system pkgs; };
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
import ../../make-test-python.nix (
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
cfgNodes = pkgs.callPackage ../common/nodes.nix { inherit lib; };
|
||||
in
|
||||
{
|
||||
# NOTE: The Nexus conversion subtest requires internet access, so to run it
|
||||
# you must run the test with:
|
||||
# - nix run .#nixosTests.taler.basic.driver
|
||||
# or interactively:
|
||||
# - nix run .#nixosTests.taler.basic.driverInteractive
|
||||
# - run_tests()
|
||||
|
||||
name = "GNU Taler Basic Test";
|
||||
meta = {
|
||||
maintainers = lib.teams.ngi.members;
|
||||
};
|
||||
|
||||
# Taler components virtual-machine nodes
|
||||
nodes = {
|
||||
inherit (cfgNodes.nodes)
|
||||
bank
|
||||
client
|
||||
exchange
|
||||
merchant
|
||||
;
|
||||
};
|
||||
|
||||
# TODO: make tests for each component?
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
let
|
||||
cfgScripts = pkgs.callPackage ../common/scripts.nix { inherit lib pkgs nodes; };
|
||||
|
||||
inherit (cfgNodes) CURRENCY FIAT_CURRENCY;
|
||||
inherit (cfgScripts) commonScripts;
|
||||
|
||||
bankConfig = nodes.bank.config.environment.etc."libeufin/libeufin.conf".source;
|
||||
bankSettings = nodes.bank.services.libeufin.settings.libeufin-bank;
|
||||
nexusSettings = nodes.bank.services.libeufin.nexus.settings;
|
||||
|
||||
# Bank admin account credentials
|
||||
AUSER = "admin";
|
||||
APASS = "admin";
|
||||
|
||||
TUSER = "testUser";
|
||||
TPASS = "testUser";
|
||||
|
||||
exchangeAccount = ../conf/exchange-account.json;
|
||||
in
|
||||
|
||||
# python
|
||||
''
|
||||
import json
|
||||
|
||||
# import common scripts
|
||||
${commonScripts}
|
||||
|
||||
|
||||
# NOTE: start components up individually so they don't conflict before their setup is done
|
||||
bank.start()
|
||||
client.start()
|
||||
bank.wait_for_open_port(8082)
|
||||
|
||||
with subtest("Set up Libeufin bank"):
|
||||
# Modify admin account password, increase debit threshold
|
||||
systemd_run(bank, 'libeufin-bank passwd -c "${bankConfig}" "${AUSER}" "${APASS}"', "libeufin-bank")
|
||||
systemd_run(bank, 'libeufin-bank edit-account -c ${bankConfig} --debit_threshold="${bankSettings.CURRENCY}:1000000" ${AUSER}', "libeufin-bank")
|
||||
|
||||
# NOTE: the exchange is enabled before the bank starts using the `initialAccounts` option
|
||||
# TODO: just use that option instead of this?
|
||||
with subtest("Register bank accounts"):
|
||||
# username, password, name
|
||||
register_bank_account("testUser", "testUser", "User")
|
||||
register_bank_account("merchant", "merchant", "Merchant")
|
||||
|
||||
|
||||
exchange.start()
|
||||
exchange.wait_for_open_port(8081)
|
||||
|
||||
|
||||
with subtest("Set up exchange"):
|
||||
exchange.wait_until_succeeds("taler-exchange-offline download sign upload")
|
||||
# Enable exchange wire account
|
||||
exchange.succeed('taler-exchange-offline upload < ${exchangeAccount}')
|
||||
|
||||
# NOTE: cannot deposit coins/pay merchant if wire fees are not set up
|
||||
exchange.succeed('taler-exchange-offline wire-fee now x-taler-bank "${CURRENCY}:0" "${CURRENCY}:0" upload')
|
||||
exchange.succeed('taler-exchange-offline global-fee now "${CURRENCY}:0" "${CURRENCY}:0" "${CURRENCY}:0" 1h 6a 0 upload')
|
||||
|
||||
|
||||
# Verify that exchange keys exist
|
||||
bank.succeed("curl -s http://exchange:8081/keys")
|
||||
|
||||
|
||||
merchant.start()
|
||||
merchant.wait_for_open_port(8083)
|
||||
|
||||
|
||||
with subtest("Set up merchant"):
|
||||
# Create default instance (similar to admin)
|
||||
succeed(merchant, [
|
||||
"curl -X POST",
|
||||
"-H 'Authorization: Bearer secret-token:super_secret'",
|
||||
"""
|
||||
--data '{
|
||||
"auth": { "method": "external" },
|
||||
"id": "default",
|
||||
"name": "default",
|
||||
"user_type": "business",
|
||||
"address": {},
|
||||
"jurisdiction": {},
|
||||
"use_stefan": true,
|
||||
"default_wire_transfer_delay": { "d_us": 3600000000 },
|
||||
"default_pay_delay": { "d_us": 3600000000 }
|
||||
}'
|
||||
""",
|
||||
"-sSfL 'http://merchant:8083/management/instances'"
|
||||
])
|
||||
# Register bank account address
|
||||
succeed(merchant, [
|
||||
"curl -X POST",
|
||||
"-H 'Content-Type: application/json'",
|
||||
"""
|
||||
--data '{
|
||||
"payto_uri": "payto://x-taler-bank/bank:8082/merchant?receiver-name=Merchant",
|
||||
"credit_facade_url": "http://bank:8082/accounts/merchant/taler-revenue/",
|
||||
"credit_facade_credentials":{"type":"basic","username":"merchant","password":"merchant"}
|
||||
}'
|
||||
""",
|
||||
"-sSfL 'http://merchant:8083/private/accounts'"
|
||||
])
|
||||
# Register a new product to be ordered
|
||||
succeed(merchant, [
|
||||
"curl -X POST",
|
||||
"-H 'Content-Type: application/json'",
|
||||
"""
|
||||
--data '{
|
||||
"product_id": "1",
|
||||
"description": "Product with id 1 and price 1",
|
||||
"price": "${CURRENCY}:1",
|
||||
"total_stock": 20,
|
||||
"unit": "packages",
|
||||
"next_restock": { "t_s": "never" }
|
||||
}'
|
||||
""",
|
||||
"-sSfL 'http://merchant:8083/private/products'"
|
||||
])
|
||||
|
||||
|
||||
client.succeed("curl -s http://exchange:8081/")
|
||||
|
||||
|
||||
# Make a withdrawal from the CLI wallet
|
||||
with subtest("Make a withdrawal from the CLI wallet"):
|
||||
balanceWanted = "${CURRENCY}:10"
|
||||
|
||||
# Register exchange
|
||||
with subtest("Register exchange"):
|
||||
wallet_cli("exchanges add http://exchange:8081/")
|
||||
wallet_cli("exchanges accept-tos http://exchange:8081/")
|
||||
|
||||
# Request withdrawal from the bank
|
||||
withdrawal = json.loads(
|
||||
succeed(client, [
|
||||
"curl -X POST",
|
||||
"-u ${TUSER}:${TPASS}",
|
||||
"-H 'Content-Type: application/json'",
|
||||
f"""--data '{{"amount": "{balanceWanted}"}}'""", # double brackets escapes them
|
||||
"-sSfL 'http://bank:8082/accounts/${TUSER}/withdrawals'"
|
||||
])
|
||||
)
|
||||
|
||||
# Accept & confirm withdrawal
|
||||
with subtest("Accept & confirm withdrawal"):
|
||||
wallet_cli(f"withdraw accept-uri {withdrawal["taler_withdraw_uri"]} --exchange http://exchange:8081/")
|
||||
succeed(client, [
|
||||
"curl -X POST",
|
||||
"-u ${TUSER}:${TPASS}",
|
||||
"-H 'Content-Type: application/json'",
|
||||
f"-sSfL 'http://bank:8082/accounts/${TUSER}/withdrawals/{withdrawal["withdrawal_id"]}/confirm'"
|
||||
])
|
||||
|
||||
# Process transactions
|
||||
wallet_cli("run-until-done")
|
||||
|
||||
verify_balance(balanceWanted)
|
||||
|
||||
|
||||
with subtest("Pay for an order"):
|
||||
balanceWanted = "${CURRENCY}:9" # after paying
|
||||
|
||||
# Create an order to be paid
|
||||
response = json.loads(
|
||||
succeed(merchant, [
|
||||
"curl -X POST",
|
||||
"-H 'Content-Type: application/json'",
|
||||
"""
|
||||
--data '{
|
||||
"order": { "amount": "${CURRENCY}:1", "summary": "Test Order" },
|
||||
"inventory_products": [{ "product_id": "1", "quantity": 1 }]
|
||||
}'
|
||||
""",
|
||||
"-sSfL 'http://merchant:8083/private/orders'"
|
||||
])
|
||||
)
|
||||
order_id = response["order_id"]
|
||||
token = response["token"]
|
||||
|
||||
# Get order pay URI
|
||||
response = json.loads(
|
||||
succeed(merchant, [
|
||||
"curl -sSfL",
|
||||
f"http://merchant:8083/private/orders/{order_id}"
|
||||
])
|
||||
)
|
||||
wallet_cli("run-until-done")
|
||||
|
||||
# Process transaction
|
||||
wallet_cli(f"""handle-uri -y '{response["taler_pay_uri"]}'""")
|
||||
wallet_cli("run-until-done")
|
||||
|
||||
verify_balance(balanceWanted)
|
||||
|
||||
# Only run Nexus conversion test if ebics server is available
|
||||
(status, out) = bank.execute('curl -sSfL "${nexusSettings.nexus-ebics.HOST_BASE_URL}"')
|
||||
|
||||
if status != 0:
|
||||
bank.log("Can't connect to ebics server. Skipping Nexus conversion subtest.")
|
||||
else:
|
||||
with subtest("Libeufin Nexus currency conversion"):
|
||||
regionalWanted = "20"
|
||||
|
||||
# Setup Nexus ebics keys
|
||||
systemd_run(bank, "libeufin-nexus ebics-setup -L debug -c /etc/libeufin/libeufin.conf", "libeufin-nexus")
|
||||
|
||||
# Set currency conversion rates (1:1)
|
||||
succeed(bank, [
|
||||
"curl -X POST",
|
||||
"-H 'Content-Type: application/json'",
|
||||
"-u ${AUSER}:${APASS}",
|
||||
"""
|
||||
--data '{
|
||||
"cashin_ratio": "1",
|
||||
"cashin_fee": "${CURRENCY}:0",
|
||||
"cashin_tiny_amount": "${CURRENCY}:0.01",
|
||||
"cashin_rounding_mode": "nearest",
|
||||
"cashin_min_amount": "${FIAT_CURRENCY}:1",
|
||||
"cashout_ratio": "1",
|
||||
"cashout_fee": "${FIAT_CURRENCY}:0",
|
||||
"cashout_tiny_amount": "${FIAT_CURRENCY}:0.01",
|
||||
"cashout_rounding_mode": "nearest",
|
||||
"cashout_min_amount": "${CURRENCY}:1"
|
||||
}'
|
||||
""",
|
||||
"-sSfL 'http://bank:8082/conversion-info/conversion-rate'"
|
||||
])
|
||||
|
||||
# Make fake transaction (we only need reservePub)
|
||||
response = wallet_cli("""api 'acceptManualWithdrawal' '{ "exchangeBaseUrl":"http://exchange:8081/", "amount":"${CURRENCY}:5" }'""")
|
||||
reservePub = json.loads(response)["result"]["reservePub"]
|
||||
|
||||
# Convert fiat currency to regional
|
||||
systemd_run(bank, f"""libeufin-nexus testing fake-incoming -c ${bankConfig} --amount="${FIAT_CURRENCY}:{regionalWanted}" --subject="{reservePub}" "payto://iban/CH4740123RW4167362694" """, "libeufin-nexus")
|
||||
wallet_cli("run-until-done")
|
||||
|
||||
verify_conversion(regionalWanted)
|
||||
'';
|
||||
}
|
||||
)
|
||||
@@ -69,9 +69,9 @@ in rec {
|
||||
|
||||
unstable = fetchurl rec {
|
||||
# NOTE: Don't forget to change the hash for staging as well.
|
||||
version = "10.0-rc4";
|
||||
version = "10.0-rc5";
|
||||
url = "https://dl.winehq.org/wine/source/10.0/wine-${version}.tar.xz";
|
||||
hash = "sha256-/oos3wn91MNBpew0ascvCyJN4L3Qp64J+RGwLpyvEAg=";
|
||||
hash = "sha256-7IlPe1wH0tTCHVNNf0OUZnuO8ngH4w4hKJhpp02XbtI=";
|
||||
inherit (stable) patches;
|
||||
|
||||
## see http://wiki.winehq.org/Gecko
|
||||
@@ -117,7 +117,7 @@ in rec {
|
||||
staging = fetchFromGitLab rec {
|
||||
# https://gitlab.winehq.org/wine/wine-staging
|
||||
inherit (unstable) version;
|
||||
hash = "sha256-Hfpsi/XJOa7KmW1tEz8wibkM5SnskKMldNqjigRmmMs=";
|
||||
hash = "sha256-no+yYF/xhy0kRfBqPer0UbpJNEh9LtKCmyVvhQB58K4=";
|
||||
domain = "gitlab.winehq.org";
|
||||
owner = "wine";
|
||||
repo = "wine-staging";
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "albert";
|
||||
version = "0.26.11";
|
||||
version = "0.26.13";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "albertlauncher";
|
||||
repo = "albert";
|
||||
rev = "v${finalAttrs.version}";
|
||||
hash = "sha256-rPQ6nxUT7qiuOgmmQKCrYHl4kKJODe+nw4VNGjF+n/g=";
|
||||
hash = "sha256-p/8kCj9dN9x7gEvXnHGABL9Ab5zUJP5jI2L6AvCT8Qs=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,13 +49,23 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
"man"
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
cmake
|
||||
gtest
|
||||
(lib.getBin libxslt)
|
||||
pkg-config
|
||||
triehash
|
||||
];
|
||||
nativeBuildInputs =
|
||||
[
|
||||
cmake
|
||||
dpkg # dpkg-architecture
|
||||
gettext # msgfmt
|
||||
gtest
|
||||
(lib.getBin libxslt)
|
||||
pkg-config
|
||||
triehash
|
||||
perlPackages.perl
|
||||
]
|
||||
++ lib.optionals withDocs [
|
||||
docbook_xml_dtd_45
|
||||
doxygen
|
||||
perlPackages.Po4a
|
||||
w3m
|
||||
];
|
||||
|
||||
buildInputs =
|
||||
[
|
||||
@@ -64,30 +74,25 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
db
|
||||
dpkg
|
||||
gnutls
|
||||
gtest
|
||||
libgcrypt
|
||||
libgpg-error
|
||||
libseccomp
|
||||
libtasn1
|
||||
lz4
|
||||
p11-kit
|
||||
perlPackages.perl
|
||||
udev
|
||||
xxHash
|
||||
xz
|
||||
zstd
|
||||
]
|
||||
++ lib.optionals withDocs [
|
||||
docbook_xml_dtd_45
|
||||
doxygen
|
||||
perlPackages.Po4a
|
||||
w3m
|
||||
]
|
||||
++ lib.optionals withNLS [
|
||||
gettext
|
||||
];
|
||||
|
||||
cmakeFlags = [
|
||||
(lib.cmakeOptionType "filepath" "BERKELEY_INCLUDE_DIRS" "${lib.getDev db}/include")
|
||||
(lib.cmakeOptionType "filepath" "DPKG_DATADIR" "${dpkg}/share/dpkg")
|
||||
(lib.cmakeOptionType "filepath" "DOCBOOK_XSL" "${docbook_xsl}/share/xml/docbook-xsl")
|
||||
(lib.cmakeOptionType "filepath" "GNUTLS_INCLUDE_DIR" "${lib.getDev gnutls}/include")
|
||||
(lib.cmakeFeature "DROOT_GROUP" "root")
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
{
|
||||
mkDerivation,
|
||||
aeson,
|
||||
aeson-pretty,
|
||||
ansi-terminal,
|
||||
attoparsec,
|
||||
base,
|
||||
bytestring,
|
||||
clock,
|
||||
containers,
|
||||
criterion-measurement,
|
||||
deepseq,
|
||||
dlist,
|
||||
filepath,
|
||||
formatting,
|
||||
hashable,
|
||||
haxl,
|
||||
hspec,
|
||||
hspec-core,
|
||||
hspec-expectations,
|
||||
lib,
|
||||
mtl,
|
||||
network-uri,
|
||||
optparse-applicative,
|
||||
postgresql-libpq,
|
||||
postgresql-simple,
|
||||
QuickCheck,
|
||||
random,
|
||||
resourcet,
|
||||
statistics,
|
||||
streaming,
|
||||
text,
|
||||
time,
|
||||
transformers,
|
||||
typed-process,
|
||||
unliftio,
|
||||
unliftio-core,
|
||||
unordered-containers,
|
||||
uuid,
|
||||
vector,
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "codd";
|
||||
version = "0.1.6";
|
||||
src = ./.;
|
||||
isLibrary = true;
|
||||
isExecutable = true;
|
||||
libraryHaskellDepends = [
|
||||
aeson
|
||||
aeson-pretty
|
||||
ansi-terminal
|
||||
attoparsec
|
||||
base
|
||||
bytestring
|
||||
clock
|
||||
containers
|
||||
deepseq
|
||||
dlist
|
||||
filepath
|
||||
formatting
|
||||
hashable
|
||||
haxl
|
||||
mtl
|
||||
network-uri
|
||||
postgresql-libpq
|
||||
postgresql-simple
|
||||
resourcet
|
||||
streaming
|
||||
text
|
||||
time
|
||||
transformers
|
||||
unliftio
|
||||
unliftio-core
|
||||
unordered-containers
|
||||
vector
|
||||
];
|
||||
executableHaskellDepends = [
|
||||
base
|
||||
optparse-applicative
|
||||
postgresql-simple
|
||||
text
|
||||
time
|
||||
];
|
||||
testHaskellDepends = [
|
||||
aeson
|
||||
attoparsec
|
||||
base
|
||||
containers
|
||||
filepath
|
||||
hashable
|
||||
hspec
|
||||
hspec-core
|
||||
mtl
|
||||
network-uri
|
||||
postgresql-simple
|
||||
QuickCheck
|
||||
random
|
||||
resourcet
|
||||
streaming
|
||||
text
|
||||
time
|
||||
typed-process
|
||||
unliftio
|
||||
uuid
|
||||
];
|
||||
benchmarkHaskellDepends = [
|
||||
aeson
|
||||
base
|
||||
criterion-measurement
|
||||
deepseq
|
||||
hspec
|
||||
hspec-core
|
||||
hspec-expectations
|
||||
statistics
|
||||
streaming
|
||||
text
|
||||
vector
|
||||
];
|
||||
homepage = "https://github.com/mzabani/codd#readme";
|
||||
license = lib.licenses.bsd3;
|
||||
mainProgram = "codd";
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
{
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
haskell,
|
||||
haskellPackages,
|
||||
}:
|
||||
|
||||
##############
|
||||
# To upgrade codd you typically only need to change the version, revision and SHA hash
|
||||
# in this very file.
|
||||
# If codd's dependencies change, however, clone codd at https://github.com/mzabani/codd,
|
||||
# checkout the desired tag and run `cabal2nix .` to produce and replace the generated.nix
|
||||
# file. Finally, do change the version in this file.
|
||||
##############
|
||||
|
||||
let
|
||||
# Haxl has relatively tight version requirements and is thus often marked as broken.
|
||||
haxlJailbroken = haskell.lib.markUnbroken (haskell.lib.doJailbreak haskellPackages.haxl);
|
||||
|
||||
generated = haskellPackages.callPackage ./generated.nix { haxl = haxlJailbroken; };
|
||||
|
||||
derivationWithVersion = haskell.lib.compose.overrideCabal (rec {
|
||||
version = "0.1.6";
|
||||
src = fetchFromGitHub {
|
||||
owner = "mzabani";
|
||||
repo = "codd";
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-KdZCL09TERy/PolQyYYykEbPtG5yhxrLZSSo9n6p2WE=";
|
||||
};
|
||||
|
||||
# We only run codd's tests that don't require postgresql nor strace. We need to support unix sockets in codd's test suite
|
||||
# before enabling postgresql's tests, and SystemResourcesSpecs might fail on macOS because of the need for strace and parsing
|
||||
# libc calls. Not that we really gain much from running SystemResourcesSpecs here anyway.
|
||||
testFlags = [
|
||||
"--skip"
|
||||
"/DbDependentSpecs/"
|
||||
"--skip"
|
||||
"/SystemResourcesSpecs/"
|
||||
];
|
||||
|
||||
isLibrary = false;
|
||||
testToolDepends = [ haskellPackages.hspec-discover ];
|
||||
|
||||
description = "CLI tool that applies postgres SQL migrations atomically with schema equality checks";
|
||||
|
||||
homepage = "https://github.com/mzabani/codd";
|
||||
|
||||
changelog = "https://github.com/mzabani/codd/releases/tag/v${version}";
|
||||
|
||||
maintainers = with lib.maintainers; [ mzabani ];
|
||||
}) generated;
|
||||
in
|
||||
haskell.lib.compose.justStaticExecutables derivationWithVersion
|
||||
@@ -49,10 +49,14 @@ stdenv.mkDerivation rec {
|
||||
for i in $(find . -name Makefile.in); do
|
||||
substituteInPlace $i --replace "install-data-local:" "disabled:" ;
|
||||
done
|
||||
|
||||
# Skip check broken when cross-compiling.
|
||||
substituteInPlace configure \
|
||||
--replace-fail 'as_fn_error $? "cannot find a GNU tar program"' "#"
|
||||
'';
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs .
|
||||
patchShebangs --host .
|
||||
|
||||
# Dpkg commands sometimes calls out to shell commands
|
||||
substituteInPlace lib/dpkg/dpkg.h \
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
buildGoModule,
|
||||
fetchFromGitHub,
|
||||
makeWrapper,
|
||||
nixosTests,
|
||||
}:
|
||||
|
||||
buildGoModule {
|
||||
pname = "echoip";
|
||||
version = "unstable-2021-08-03";
|
||||
version = "unstable-2023-05-21";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mpolden";
|
||||
repo = "echoip";
|
||||
rev = "ffa6674637a5bf906d78ae6675f9a4680a78ab7b";
|
||||
sha256 = "sha256-yN7PIwoIi2SPwwFWnHDoXnwvKohkPPf4kVsNxHLpqCE=";
|
||||
rev = "d84665c26cf7df612061e9c35abe325ba9d86b8d";
|
||||
hash = "sha256-7qc1NZu0hC1np/EKf5fU5Cnd7ikC1+tIrYOXhxK/++Y=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-lXYpkeGpBK+WGHqyLxJz7kS3t7a55q55QQLTqtxzroc=";
|
||||
@@ -26,15 +27,18 @@ buildGoModule {
|
||||
--add-flags "-t $out/share/echoip/html"
|
||||
'';
|
||||
|
||||
doCheck = false;
|
||||
passthru = {
|
||||
tests = { inherit (nixosTests) echoip; };
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
meta = {
|
||||
description = "IP address lookup service";
|
||||
homepage = "https://github.com/mpolden/echoip";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [
|
||||
license = lib.licenses.bsd3;
|
||||
maintainers = with lib.maintainers; [
|
||||
rvolosatovs
|
||||
SuperSandro2000
|
||||
defelo
|
||||
];
|
||||
mainProgram = "echoip";
|
||||
};
|
||||
|
||||
@@ -29,7 +29,13 @@ stdenv.mkDerivation rec {
|
||||
done
|
||||
'';
|
||||
|
||||
env.CFLAGS = lib.optionalString stdenv.cc.isClang "-Wno-return-type -Wno-error=implicit-function-declaration -Wno-error=implicit-int";
|
||||
# lib.escapeShellArgs does not work
|
||||
env.CFLAGS = lib.concatStringsSep " " [
|
||||
"-Wno-error=implicit-function-declaration"
|
||||
"-Wno-error=implicit-int"
|
||||
"-Wno-error=return-mismatch"
|
||||
"-Wno-error=incompatible-pointer-types"
|
||||
];
|
||||
|
||||
doCheck = true;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
fetchFromGitLab,
|
||||
makeWrapper,
|
||||
ocamlPackages,
|
||||
fetchpatch,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
@@ -18,6 +19,13 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
hash = "sha256-b4O48MQT3Neh8a1Z5wRgS701w6XrwpsbSMprlqTT+CE=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
url = "https://gitlab.inria.fr/synchrone/heptagon/-/commit/f10405e385ca25dc737727e0c210a44986929bf0.patch";
|
||||
hash = "sha256-Sn55jEoRDYnEUg4SjuBDCNN4TNl2Dwn1fTjb9O8O1bo=";
|
||||
})
|
||||
];
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
nativeBuildInputs = with ocamlPackages; [
|
||||
+17
-32
@@ -1,60 +1,45 @@
|
||||
{
|
||||
mkDerivation,
|
||||
fetchpatch,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
lib,
|
||||
extra-cmake-modules,
|
||||
kdoctools,
|
||||
wrapGAppsHook3,
|
||||
exiv2,
|
||||
ffmpeg,
|
||||
libkdcraw,
|
||||
phonon,
|
||||
libvlc,
|
||||
kconfig,
|
||||
kiconthemes,
|
||||
kio,
|
||||
kinit,
|
||||
kpurpose,
|
||||
kdePackages,
|
||||
}:
|
||||
|
||||
mkDerivation rec {
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "kphotoalbum";
|
||||
version = "5.11.0";
|
||||
version = "6.0.1";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://kde/stable/${pname}/${version}/${pname}-${version}.tar.xz";
|
||||
hash = "sha256-NWtOIHJXtc8PlltYbbp2YwDf/3QI3MdHNDX7WVQMig4=";
|
||||
url = "mirror://kde/stable/kphotoalbum/${finalAttrs.version}/kphotoalbum-${finalAttrs.version}.tar.xz";
|
||||
hash = "sha256-LLsQ66wKDg77nZUIxjcfzvC3AwLOtojuuDgkJm2dsww=";
|
||||
};
|
||||
|
||||
# Fix build against exiv2 0.28.1
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
url = "https://invent.kde.org/graphics/kphotoalbum/-/commit/1ceb1ae37f3f95aa290b0846969af4b26f616760.patch";
|
||||
hash = "sha256-SfBJHyJZcysvemc/F09GPczBjcofxGomgjJ814PSU+c=";
|
||||
})
|
||||
];
|
||||
env.LANG = "C.UTF-8";
|
||||
|
||||
# not sure if we really need phonon when we have vlc, but on KDE it's bound to
|
||||
# be on the system anyway, so there is no real harm including it
|
||||
buildInputs = [
|
||||
kdePackages.qtbase
|
||||
exiv2
|
||||
phonon
|
||||
libvlc
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
extra-cmake-modules
|
||||
kdoctools
|
||||
wrapGAppsHook3
|
||||
kdePackages.wrapQtAppsHook
|
||||
];
|
||||
|
||||
propagatedBuildInputs = [
|
||||
# not sure if we really need phonon when we have vlc, but on KDE it's bound to
|
||||
# be on the system anyway, so there is no real harm including it
|
||||
propagatedBuildInputs = with kdePackages; [
|
||||
kconfig
|
||||
kiconthemes
|
||||
kio
|
||||
kinit
|
||||
kpurpose
|
||||
kxmlgui
|
||||
phonon
|
||||
purpose
|
||||
libkdcraw
|
||||
];
|
||||
|
||||
@@ -67,6 +52,6 @@ mkDerivation rec {
|
||||
homepage = "https://www.kphotoalbum.org/";
|
||||
license = licenses.gpl2Plus;
|
||||
maintainers = with maintainers; [ peterhoeg ];
|
||||
inherit (kconfig.meta) platforms;
|
||||
inherit (kdePackages.kconfig.meta) platforms;
|
||||
};
|
||||
}
|
||||
})
|
||||
@@ -1,57 +1,72 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
fetchFromGitHub,
|
||||
buildNpmPackage,
|
||||
electron,
|
||||
makeWrapper,
|
||||
testers,
|
||||
mattermost-desktop,
|
||||
nix-update-script,
|
||||
}:
|
||||
|
||||
let
|
||||
|
||||
buildNpmPackage rec {
|
||||
pname = "mattermost-desktop";
|
||||
version = "5.9.0";
|
||||
version = "5.10.2";
|
||||
|
||||
srcs = {
|
||||
"x86_64-linux" = {
|
||||
url = "https://releases.mattermost.com/desktop/${version}/${pname}-${version}-linux-x64.tar.gz";
|
||||
hash = "sha256-zLKdfu5p7TyJOw8vJX7i/uu4j0PrUf2/BDmb1kdqqMc=";
|
||||
};
|
||||
|
||||
"aarch64-linux" = {
|
||||
url = "https://releases.mattermost.com/desktop/${version}/${pname}-${version}-linux-arm64.tar.gz";
|
||||
hash = "sha256-JljK7d4KLAn1+NwF+VcedL/7hEsp/9LzLdzROa1fgJA=";
|
||||
};
|
||||
src = fetchFromGitHub {
|
||||
owner = "mattermost";
|
||||
repo = "desktop";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-LHjVmrsOdk8vfsqvNEWkzpusm6jbz3SOb3bEaIb7rb4=";
|
||||
};
|
||||
|
||||
inherit (stdenv.hostPlatform) system;
|
||||
|
||||
in
|
||||
|
||||
stdenv.mkDerivation {
|
||||
inherit pname version;
|
||||
|
||||
src = fetchurl (srcs."${system}" or (throw "Unsupported system ${system}"));
|
||||
npmDepsHash = "sha256-LAbqsMdMmmHGgvg2ilz6neQxMOK3jtCKt8K0M8BWifs=";
|
||||
npmBuildScript = "build-prod";
|
||||
makeCacheWritable = true;
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1";
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace webpack.config.base.js \
|
||||
--replace-fail \
|
||||
"const VERSION = childProcess.execSync('git rev-parse --short HEAD', {cwd: __dirname}).toString();" \
|
||||
"const VERSION = process.env.version;"
|
||||
'';
|
||||
|
||||
postBuild = ''
|
||||
# electronDist needs to be writable
|
||||
cp -r ${electron.dist} electron-dist
|
||||
chmod -R u+w electron-dist
|
||||
|
||||
npm exec electron-builder -- \
|
||||
--config electron-builder.json \
|
||||
--dir \
|
||||
-c.electronDist=electron-dist \
|
||||
-c.electronVersion=${electron.version}
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
# Mattermost tarball comes with executable bit set for everything.
|
||||
# We’ll apply it only to files that need it.
|
||||
find . -type f -print0 | xargs -0 chmod -x
|
||||
find . -type f \( -name '*.so.*' -o -name '*.s[oh]' \) -print0 | xargs -0 chmod +x
|
||||
chmod +x mattermost-desktop chrome-sandbox
|
||||
mkdir --parents \
|
||||
$out/bin \
|
||||
$out/share/applications \
|
||||
$out/share/icons/hicolor/512x512/apps
|
||||
|
||||
mkdir -p $out/bin $out/share/applications $out/share/${pname}/
|
||||
cp -r app_icon.png create_desktop_file.sh locales/ resources/* $out/share/${pname}/
|
||||
readonly dist=release/linux-unpacked
|
||||
|
||||
patchShebangs $out/share/${pname}/create_desktop_file.sh
|
||||
$out/share/${pname}/create_desktop_file.sh
|
||||
rm $out/share/${pname}/create_desktop_file.sh
|
||||
mv Mattermost.desktop $out/share/applications/Mattermost.desktop
|
||||
cp -a $dist/resources $out/share/${pname}
|
||||
|
||||
patchShebangs $dist/create_desktop_file.sh
|
||||
$dist/create_desktop_file.sh
|
||||
mv Mattermost.desktop $out/share/applications/
|
||||
substituteInPlace $out/share/applications/Mattermost.desktop \
|
||||
--replace /share/mattermost-desktop/mattermost-desktop /bin/mattermost-desktop
|
||||
--replace-fail /build/source/$dist/app_icon.png ${pname} \
|
||||
--replace-fail /build/source/$dist/ $out/bin/
|
||||
|
||||
cp src/assets/linux/app_icon.png $out/share/icons/hicolor/512x512/apps/${pname}.png
|
||||
|
||||
makeWrapper '${lib.getExe electron}' $out/bin/${pname} \
|
||||
--set-default ELECTRON_IS_DEV 0 \
|
||||
@@ -61,16 +76,25 @@ stdenv.mkDerivation {
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
passthru = {
|
||||
tests.version = testers.testVersion {
|
||||
package = mattermost-desktop;
|
||||
# Invoking with `--version` insists on being able to write to a log file.
|
||||
command = "env HOME=/tmp ${meta.mainProgram} --version";
|
||||
};
|
||||
updateScript = nix-update-script { };
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "Mattermost Desktop client";
|
||||
mainProgram = "mattermost-desktop";
|
||||
homepage = "https://about.mattermost.com/";
|
||||
sourceProvenance = with sourceTypes; [ binaryNativeCode ];
|
||||
license = licenses.asl20;
|
||||
platforms = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
changelog = "https://github.com/mattermost/desktop/releases/tag/${src.tag}";
|
||||
license = lib.licenses.asl20;
|
||||
platforms = electron.meta.platforms;
|
||||
maintainers = with lib.maintainers; [
|
||||
joko
|
||||
liff
|
||||
];
|
||||
maintainers = [ maintainers.joko ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
nix-update-script,
|
||||
npm-lockfile-fix,
|
||||
fetchNpmDeps,
|
||||
diffutils,
|
||||
jq,
|
||||
nixosTests,
|
||||
}:
|
||||
@@ -94,7 +93,7 @@ buildGoModule rec {
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out
|
||||
cp -r channels/dist/* $out
|
||||
cp -a channels/dist/* $out
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
@@ -123,11 +122,20 @@ buildGoModule rec {
|
||||
];
|
||||
|
||||
postInstall = ''
|
||||
mkdir -p $out/{client,i18n,fonts,templates,config}
|
||||
cp -r ${webapp}/* $out/client/
|
||||
cp -r ${src}/server/i18n/* $out/i18n/
|
||||
cp -r ${src}/server/fonts/* $out/fonts/
|
||||
cp -r ${src}/server/templates/* $out/templates/
|
||||
shopt -s extglob
|
||||
mkdir -p $out/{i18n,fonts,templates,config}
|
||||
|
||||
# Link in the client and copy the language packs.
|
||||
ln -sf $webapp $out/client
|
||||
cp -a $src/server/i18n/* $out/i18n/
|
||||
|
||||
# Fonts have the execute bit set, remove it.
|
||||
cp --no-preserve=mode $src/server/fonts/* $out/fonts/
|
||||
|
||||
# Don't copy the Makefile.
|
||||
cp -a $src/server/templates/!(Makefile) $out/templates/
|
||||
|
||||
# Generate the config.
|
||||
OUTPUT_CONFIG=$out/config/config.json \
|
||||
go run -tags production ./scripts/config_generator
|
||||
'';
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "mieru";
|
||||
version = "3.10.0";
|
||||
version = "3.11.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "enfein";
|
||||
repo = "mieru";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-4uJi8+kpVBjigTkLmV9fL0igmcOt5Gb40qkQHYR8kCU=";
|
||||
hash = "sha256-xwi9T7M4FEl79kyGj+F1HX8000PFLrBfTmnEaLwnEFg=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-hSTKhn39xKZx1N9x66EH/ql4oP4qn0eysGTbUk9mRAk=";
|
||||
vendorHash = "sha256-AOtq6bGijQqpNMNZA3XeMjzKAo7tWTpdrKB6KxQsdMM=";
|
||||
proxyVendor = true;
|
||||
|
||||
ldflags = [
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "nvitop";
|
||||
version = "1.4.0";
|
||||
version = "1.4.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "XuehaiPan";
|
||||
repo = "nvitop";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-Z0JGW7vcZFxguQqhqhpPpOvcOct7B9z8RoEFu5NsOl0=";
|
||||
hash = "sha256-H5WfSGQpShmJGffGMIejs0A9ksht43I1d3BvXbvP6vI=";
|
||||
};
|
||||
|
||||
pythonRelaxDeps = [ "nvidia-ml-py" ];
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
stdenv,
|
||||
rustPlatform,
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
pkg-config,
|
||||
installShellFiles,
|
||||
libgit2,
|
||||
openssl,
|
||||
installShellFiles,
|
||||
buildPackages,
|
||||
versionCheckHook,
|
||||
nix-update-script,
|
||||
@@ -15,26 +14,17 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "pixi";
|
||||
version = "0.39.5";
|
||||
version = "0.40.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "prefix-dev";
|
||||
repo = "pixi";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-Y4d8eMfsag2cNTaK8qnOGfi35kwwPrUy2y51EwVFrss=";
|
||||
hash = "sha256-LuRnPG8vag8SNSChZlWBBavxAlLRk1P73N+VpO0SeTA=";
|
||||
};
|
||||
|
||||
# TODO: Remove this patch when the next version is released.
|
||||
cargoPatches = [
|
||||
(fetchpatch {
|
||||
# chore: make sure we only build one version of version-ranges
|
||||
# https://github.com/prefix-dev/pixi/commit/82fc219be3f5d1499922e89a5c458b7c154a7b8e
|
||||
url = "https://github.com/prefix-dev/pixi/commit/82fc219be3f5d1499922e89a5c458b7c154a7b8e.patch";
|
||||
hash = "sha256-fKDqUJtjxIQsCez95RObnJHQvdlxhmjJ+G7fJitE6v0=";
|
||||
})
|
||||
];
|
||||
useFetchCargoVendor = true;
|
||||
cargoHash = "sha256-oGlPxFwJVpBajJQ5XED98SUP8qw312nUSRND6ycEOjk=";
|
||||
cargoHash = "sha256-I3TnZ9ZHU4TUOUkBIeeRjP+sc/k2qVNtltzkyN87aZo=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
@@ -77,6 +67,7 @@ rustPlatform.buildRustPackage rec {
|
||||
meta = {
|
||||
description = "Package management made easy";
|
||||
homepage = "https://pixi.sh/";
|
||||
changelog = "https://pixi.sh/latest/CHANGELOG";
|
||||
license = lib.licenses.bsd3;
|
||||
maintainers = with lib.maintainers; [
|
||||
aaronjheng
|
||||
|
||||
@@ -34,13 +34,13 @@ assert lib.assertMsg (
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "prismlauncher-unwrapped";
|
||||
version = "9.1";
|
||||
version = "9.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "PrismLauncher";
|
||||
repo = "PrismLauncher";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-LVrWFBsI4+BOY5hlevfzqfRXQM6AFd5bMnXbBqTrxzA=";
|
||||
hash = "sha256-0KDhX8mfh11pyYQS/lB6qlUvRSOcYEbQKgsdQVA+Q3U=";
|
||||
};
|
||||
|
||||
postUnpack = ''
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
libX11,
|
||||
libdrm,
|
||||
libgbm,
|
||||
vaapiSupport ? true,
|
||||
vaapiSupport ? !stdenv.hostPlatform.isDarwin,
|
||||
libva,
|
||||
gitUpdater,
|
||||
}:
|
||||
@@ -27,13 +27,17 @@ stdenv.mkDerivation rec {
|
||||
|
||||
separateDebugInfo = true;
|
||||
|
||||
buildInputs = [
|
||||
libGLU
|
||||
libepoxy
|
||||
libX11
|
||||
libdrm
|
||||
libgbm
|
||||
] ++ lib.optionals vaapiSupport [ libva ];
|
||||
buildInputs =
|
||||
[
|
||||
libepoxy
|
||||
]
|
||||
++ lib.optionals vaapiSupport [ libva ]
|
||||
++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||
libGLU
|
||||
libX11
|
||||
libdrm
|
||||
libgbm
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
@@ -58,7 +62,7 @@ stdenv.mkDerivation rec {
|
||||
mainProgram = "virgl_test_server";
|
||||
homepage = "https://virgil3d.github.io/";
|
||||
license = licenses.mit;
|
||||
platforms = platforms.linux;
|
||||
platforms = platforms.unix;
|
||||
maintainers = [ maintainers.xeji ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ stdenv.mkDerivation rec {
|
||||
./0001-Fix-build-for-glibc-2.32.patch
|
||||
];
|
||||
|
||||
NIX_CFLAGS_COMPILE = "-Wno-error=implicit-function-declaration";
|
||||
|
||||
buildInputs = [
|
||||
ncurses
|
||||
libjpeg
|
||||
|
||||
@@ -17,13 +17,13 @@ python3Packages.buildPythonApplication rec {
|
||||
# The websites yt-dlp deals with are a very moving target. That means that
|
||||
# downloads break constantly. Because of that, updates should always be backported
|
||||
# to the latest stable release.
|
||||
version = "2024.12.23";
|
||||
version = "2025.1.12";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
inherit version;
|
||||
pname = "yt_dlp";
|
||||
hash = "sha256-rA5ytakBe6EEtCWFRiAafO3DjovSByfgxjt3yCm0Jek=";
|
||||
hash = "sha256-jn4kbipaLP8KnBPbRoRKN6VHaAcCASBYyU7Bj84Molo=";
|
||||
};
|
||||
|
||||
build-system = with python3Packages; [
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchFromGitHub,
|
||||
|
||||
glib,
|
||||
wrapGAppsHook3,
|
||||
gobject-introspection,
|
||||
meson,
|
||||
pkg-config,
|
||||
ninja,
|
||||
vala,
|
||||
wayland,
|
||||
wayland-scanner,
|
||||
python3,
|
||||
}:
|
||||
let
|
||||
cleanArgs = lib.flip builtins.removeAttrs [
|
||||
"name"
|
||||
"sourceRoot"
|
||||
"nativeBuildInputs"
|
||||
"buildInputs"
|
||||
"website-path"
|
||||
"meta"
|
||||
];
|
||||
|
||||
buildAstalModule =
|
||||
{
|
||||
name,
|
||||
sourceRoot ? "lib/${name}",
|
||||
nativeBuildInputs ? [ ],
|
||||
buildInputs ? [ ],
|
||||
website-path ? name,
|
||||
meta ? { },
|
||||
...
|
||||
}@args:
|
||||
stdenv.mkDerivation (
|
||||
finalAttrs:
|
||||
cleanArgs args
|
||||
// {
|
||||
pname = "astal-${name}";
|
||||
version = "0-unstable-2025-01-12";
|
||||
|
||||
__structuredAttrs = true;
|
||||
strictDeps = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Aylur";
|
||||
repo = "astal";
|
||||
rev = "6fd7ae514af36ff9baf1209a2eeebd3a26cf94ce";
|
||||
hash = "sha256-IjLW96gjrCAjx/QZOvYyNpoeb53bkOJ6dDQt8ubaMMY=";
|
||||
};
|
||||
|
||||
sourceRoot = "${finalAttrs.src.name}/${sourceRoot}";
|
||||
|
||||
nativeBuildInputs = nativeBuildInputs ++ [
|
||||
wrapGAppsHook3
|
||||
gobject-introspection
|
||||
meson
|
||||
pkg-config
|
||||
ninja
|
||||
vala
|
||||
wayland
|
||||
wayland-scanner
|
||||
python3
|
||||
];
|
||||
|
||||
buildInputs = [ glib ] ++ buildInputs;
|
||||
|
||||
meta = {
|
||||
homepage = "https://aylur.github.io/astal/guide/libraries/${website-path}";
|
||||
license = lib.licenses.lgpl21;
|
||||
maintainers = with lib.maintainers; [ perchun ];
|
||||
platforms = [
|
||||
"aarch64-linux"
|
||||
"x86_64-linux"
|
||||
];
|
||||
} // meta;
|
||||
}
|
||||
);
|
||||
in
|
||||
|
||||
args:
|
||||
# to support (finalAttrs: {...})
|
||||
if builtins.typeOf args == "function" then
|
||||
buildAstalModule (lib.fix args)
|
||||
else
|
||||
buildAstalModule args
|
||||
@@ -0,0 +1,23 @@
|
||||
{ wireplumber }:
|
||||
self: {
|
||||
buildAstalModule = self.callPackage ./buildAstalModule.nix { };
|
||||
|
||||
apps = self.callPackage ./modules/apps.nix { };
|
||||
astal3 = self.callPackage ./modules/astal3.nix { };
|
||||
astal4 = self.callPackage ./modules/astal4.nix { };
|
||||
auth = self.callPackage ./modules/auth.nix { };
|
||||
battery = self.callPackage ./modules/battery.nix { };
|
||||
bluetooth = self.callPackage ./modules/bluetooth.nix { };
|
||||
cava = self.callPackage ./modules/cava.nix { };
|
||||
gjs = self.callPackage ./modules/gjs.nix { };
|
||||
greet = self.callPackage ./modules/greet.nix { };
|
||||
hyprland = self.callPackage ./modules/hyprland.nix { };
|
||||
io = self.callPackage ./modules/io.nix { };
|
||||
mpris = self.callPackage ./modules/mpris.nix { };
|
||||
network = self.callPackage ./modules/network.nix { };
|
||||
notifd = self.callPackage ./modules/notifd.nix { };
|
||||
powerprofiles = self.callPackage ./modules/powerprofiles.nix { };
|
||||
river = self.callPackage ./modules/river.nix { };
|
||||
tray = self.callPackage ./modules/tray.nix { };
|
||||
wireplumber = self.callPackage ./modules/wireplumber.nix { inherit wireplumber; };
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
json-glib,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "apps";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for application query";
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
gtk3,
|
||||
gtk-layer-shell,
|
||||
io,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "astal3";
|
||||
sourceRoot = "lib/astal/gtk3";
|
||||
buildInputs = [ io ];
|
||||
propagatedBuildInputs = [
|
||||
gtk3
|
||||
gtk-layer-shell
|
||||
];
|
||||
meta.description = "Astal module for GTK3 widgets";
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
gtk4,
|
||||
gtk4-layer-shell,
|
||||
io,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "astal4";
|
||||
sourceRoot = "lib/astal/gtk4";
|
||||
buildInputs = [
|
||||
io
|
||||
gtk4
|
||||
gtk4-layer-shell
|
||||
];
|
||||
meta.description = "Astal module for GTK4 widgets";
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
pam,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "auth";
|
||||
buildInputs = [ pam ];
|
||||
meta.description = "Astal module for authentication using pam";
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
json-glib,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "battery";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for upowerd devices (DBus proxy)";
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{ buildAstalModule }:
|
||||
buildAstalModule {
|
||||
name = "bluetooth";
|
||||
meta.description = "Astal module for bluez using DBus";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ buildAstalModule }:
|
||||
buildAstalModule {
|
||||
name = "cava";
|
||||
meta.description = "Astal module for audio visualization using cava";
|
||||
meta.broken = true; # https://github.com/NixOS/nixpkgs/pull/368312
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
astal3,
|
||||
io,
|
||||
|
||||
meson,
|
||||
ninja,
|
||||
pkg-config,
|
||||
}:
|
||||
(buildAstalModule {
|
||||
name = "gjs";
|
||||
sourceRoot = "lang/gjs";
|
||||
meta.description = "Astal module for GJS";
|
||||
}).overrideAttrs
|
||||
{
|
||||
# Remove all unused here inputs
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
];
|
||||
buildInputs = [
|
||||
astal3
|
||||
io
|
||||
];
|
||||
propagatedBuildInputs = [ ];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ buildAstalModule, json-glib }:
|
||||
buildAstalModule {
|
||||
name = "greet";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for greetd using IPC";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ buildAstalModule, json-glib }:
|
||||
buildAstalModule {
|
||||
name = "hyprland";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for Hyprland using IPC";
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{ buildAstalModule, nix-update-script }:
|
||||
(buildAstalModule {
|
||||
name = "io";
|
||||
sourceRoot = "lib/astal/io";
|
||||
meta.description = "Astal core library";
|
||||
}).overrideAttrs
|
||||
{
|
||||
# add an update script only in one place,
|
||||
# so r-ryantm won't run it multiple times
|
||||
passthru.updateScript = nix-update-script { extraArgs = [ "--version=branch" ]; };
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
gvfs,
|
||||
json-glib,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "mpris";
|
||||
buildInputs = [
|
||||
gvfs
|
||||
json-glib
|
||||
];
|
||||
meta.description = "Astal module for mpris players";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ buildAstalModule, networkmanager }:
|
||||
buildAstalModule {
|
||||
name = "network";
|
||||
buildInputs = [ networkmanager ];
|
||||
meta.description = "Astal module for NetworkManager";
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
json-glib,
|
||||
gdk-pixbuf,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "notifd";
|
||||
buildInputs = [
|
||||
json-glib
|
||||
gdk-pixbuf
|
||||
];
|
||||
meta.description = "Astal module for notification daemon";
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ buildAstalModule, json-glib }:
|
||||
buildAstalModule {
|
||||
name = "powerprofiles";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for upowerd profiles using DBus";
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{ buildAstalModule, json-glib }:
|
||||
buildAstalModule {
|
||||
name = "river";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for River using IPC";
|
||||
|
||||
postUnpack = ''
|
||||
rm -rf $sourceRoot/subprojects
|
||||
mkdir -p $sourceRoot/subprojects
|
||||
cp -r --remove-destination $src/lib/wayland-glib $sourceRoot/subprojects/wayland-glib
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
buildAstalModule,
|
||||
json-glib,
|
||||
}:
|
||||
buildAstalModule {
|
||||
name = "tray";
|
||||
buildInputs = [ json-glib ];
|
||||
meta.description = "Astal module for StatusNotifierItem";
|
||||
meta.broken = true; # https://github.com/NixOS/nixpkgs/issues/337630
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ buildAstalModule, wireplumber }:
|
||||
buildAstalModule {
|
||||
name = "wireplumber";
|
||||
buildInputs = [ wireplumber ];
|
||||
meta.description = "Astal module for wireplumber";
|
||||
}
|
||||
@@ -4,40 +4,34 @@
|
||||
fetchFromGitHub,
|
||||
qmake,
|
||||
qtbase,
|
||||
protobuf,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "qtpbfimageplugin";
|
||||
version = "3.2";
|
||||
version = "4.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "tumic0";
|
||||
repo = "QtPBFImagePlugin";
|
||||
rev = version;
|
||||
sha256 = "sha256-RbGVjwVIwO6Rj/hbNEowtZLqJdtkTfnq5YdnEYnbkTM=";
|
||||
tag = version;
|
||||
hash = "sha256-17mQ7aTpZhmsoAHhnueHSRTvCIHRcpWwZHZM+YUdeps=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ qmake ];
|
||||
nativeBuildInputs = [
|
||||
qmake
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
qtbase
|
||||
protobuf
|
||||
];
|
||||
|
||||
dontWrapQtApps = true;
|
||||
|
||||
postPatch =
|
||||
''
|
||||
# Fix plugin dir
|
||||
substituteInPlace pbfplugin.pro \
|
||||
--replace "\$\$[QT_INSTALL_PLUGINS]" "$out/$qtPluginPrefix"
|
||||
''
|
||||
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||
# Fix darwin build
|
||||
substituteInPlace pbfplugin.pro \
|
||||
--replace '$$PROTOBUF/include' '${protobuf}/include' \
|
||||
--replace '$$PROTOBUF/lib/libprotobuf-lite.a' '${protobuf}/lib/libprotobuf-lite.dylib'
|
||||
'';
|
||||
postPatch = ''
|
||||
# Fix plugin dir
|
||||
substituteInPlace pbfplugin.pro \
|
||||
--replace "\$\$[QT_INSTALL_PLUGINS]" "$out/$qtPluginPrefix"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "Qt image plugin for displaying Mapbox vector tiles";
|
||||
|
||||
@@ -7,30 +7,34 @@
|
||||
camlp4,
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ocaml-config-file";
|
||||
version = "1.2";
|
||||
lib.throwIf (lib.versionAtLeast ocaml.version "5.0")
|
||||
"config-file is not available for OCaml ${ocaml.version}"
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://forge.ocamlcore.org/frs/download.php/1387/config-file-${version}.tar.gz";
|
||||
sha256 = "1b02yxcnsjhr05ssh2br2ka4hxsjpdw34ldl3nk33wfnkwk7g67q";
|
||||
};
|
||||
stdenv.mkDerivation
|
||||
rec {
|
||||
pname = "ocaml-config-file";
|
||||
version = "1.2";
|
||||
|
||||
nativeBuildInputs = [
|
||||
ocaml
|
||||
findlib
|
||||
camlp4
|
||||
];
|
||||
src = fetchurl {
|
||||
url = "https://forge.ocamlcore.org/frs/download.php/1387/config-file-${version}.tar.gz";
|
||||
sha256 = "1b02yxcnsjhr05ssh2br2ka4hxsjpdw34ldl3nk33wfnkwk7g67q";
|
||||
};
|
||||
|
||||
strictDeps = true;
|
||||
nativeBuildInputs = [
|
||||
ocaml
|
||||
findlib
|
||||
camlp4
|
||||
];
|
||||
|
||||
createFindlibDestdir = true;
|
||||
strictDeps = true;
|
||||
|
||||
meta = {
|
||||
homepage = "http://config-file.forge.ocamlcore.org/";
|
||||
platforms = ocaml.meta.platforms or [ ];
|
||||
description = "OCaml library used to manage the configuration file(s) of an application";
|
||||
license = lib.licenses.lgpl2Plus;
|
||||
maintainers = with lib.maintainers; [ vbgl ];
|
||||
};
|
||||
}
|
||||
createFindlibDestdir = true;
|
||||
|
||||
meta = {
|
||||
homepage = "http://config-file.forge.ocamlcore.org/";
|
||||
platforms = ocaml.meta.platforms or [ ];
|
||||
description = "OCaml library used to manage the configuration file(s) of an application";
|
||||
license = lib.licenses.lgpl2Plus;
|
||||
maintainers = with lib.maintainers; [ vbgl ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,39 +23,43 @@ let
|
||||
};
|
||||
in
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
name = "ocaml${ocaml.version}-${pname}-${version}";
|
||||
inherit (param) version;
|
||||
lib.throwIf (lib.versionAtLeast ocaml.version "5.0")
|
||||
"ulex is not available for OCaml ${ocaml.version}"
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "whitequark";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
inherit (param) sha256;
|
||||
};
|
||||
stdenv.mkDerivation
|
||||
rec {
|
||||
name = "ocaml${ocaml.version}-${pname}-${version}";
|
||||
inherit (param) version;
|
||||
|
||||
createFindlibDestdir = true;
|
||||
src = fetchFromGitHub {
|
||||
owner = "whitequark";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
inherit (param) sha256;
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
ocaml
|
||||
findlib
|
||||
ocamlbuild
|
||||
camlp4
|
||||
];
|
||||
propagatedBuildInputs = [ camlp4 ];
|
||||
createFindlibDestdir = true;
|
||||
|
||||
strictDeps = true;
|
||||
nativeBuildInputs = [
|
||||
ocaml
|
||||
findlib
|
||||
ocamlbuild
|
||||
camlp4
|
||||
];
|
||||
propagatedBuildInputs = [ camlp4 ];
|
||||
|
||||
buildFlags = [
|
||||
"all"
|
||||
"all.opt"
|
||||
];
|
||||
strictDeps = true;
|
||||
|
||||
meta = {
|
||||
inherit (src.meta) homepage;
|
||||
description = "Lexer generator for Unicode and OCaml";
|
||||
license = lib.licenses.mit;
|
||||
inherit (ocaml.meta) platforms;
|
||||
maintainers = [ lib.maintainers.roconnor ];
|
||||
};
|
||||
}
|
||||
buildFlags = [
|
||||
"all"
|
||||
"all.opt"
|
||||
];
|
||||
|
||||
meta = {
|
||||
inherit (src.meta) homepage;
|
||||
description = "Lexer generator for Unicode and OCaml";
|
||||
license = lib.licenses.mit;
|
||||
inherit (ocaml.meta) platforms;
|
||||
maintainers = [ lib.maintainers.roconnor ];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
pythonOlder,
|
||||
fetchFromGitHub,
|
||||
setuptools,
|
||||
aesara,
|
||||
numpy,
|
||||
scipy,
|
||||
numdifftools,
|
||||
pytestCheckHook,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aeppl";
|
||||
version = "0.1.5";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "aesara-devs";
|
||||
repo = "aeppl";
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-mqBbXwWJwQA2wSHuEdBeXQMfTIcgwYEjpq8AVmOjmHM=";
|
||||
};
|
||||
|
||||
build-system = [ setuptools ];
|
||||
|
||||
dependencies = [
|
||||
aesara
|
||||
numpy
|
||||
scipy
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
numdifftools
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
preCheck = ''
|
||||
export HOME=$(mktemp -d);
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "aeppl" ];
|
||||
|
||||
disabledTests = [
|
||||
# Compute issue
|
||||
"test_initial_values"
|
||||
];
|
||||
|
||||
pytestFlagsArray = [
|
||||
# `numpy.distutils` is deprecated since NumPy 1.23.0, as a result of the deprecation of `distutils` itself.
|
||||
# It will be removed for Python >= 3.12. For older Python versions it will remain present.
|
||||
"-Wignore::DeprecationWarning"
|
||||
# Blas cannot be found, allow fallback to the numpy slower implementation
|
||||
"-Wignore::UserWarning"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Library for an Aesara-based PPL";
|
||||
homepage = "https://github.com/aesara-devs/aeppl";
|
||||
changelog = "https://github.com/aesara-devs/aeppl/releases/tag/v${version}";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ fab ];
|
||||
};
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
stdenv,
|
||||
buildPythonPackage,
|
||||
cons,
|
||||
cython,
|
||||
etuples,
|
||||
fetchFromGitHub,
|
||||
filelock,
|
||||
hatch-vcs,
|
||||
hatchling,
|
||||
jax,
|
||||
jaxlib,
|
||||
logical-unification,
|
||||
minikanren,
|
||||
numba,
|
||||
numba-scipy,
|
||||
numpy,
|
||||
pytestCheckHook,
|
||||
pythonAtLeast,
|
||||
pythonOlder,
|
||||
scipy,
|
||||
typing-extensions,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aesara";
|
||||
version = "2.9.4";
|
||||
pyproject = true;
|
||||
|
||||
# Python 3.12 is not supported: https://github.com/aesara-devs/aesara/issues/1520
|
||||
disabled = pythonOlder "3.8" || pythonAtLeast "3.12";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "aesara-devs";
|
||||
repo = "aesara";
|
||||
rev = "refs/tags/rel-${version}";
|
||||
hash = "sha256-V34uP50TfH6cLU7nWOx+8oXY1QawtaoIaKQpbLnz7eo=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
cython
|
||||
hatch-vcs
|
||||
hatchling
|
||||
];
|
||||
|
||||
dependencies = [
|
||||
cons
|
||||
etuples
|
||||
filelock
|
||||
logical-unification
|
||||
minikanren
|
||||
numpy
|
||||
scipy
|
||||
typing-extensions
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
jax
|
||||
jaxlib
|
||||
numba
|
||||
numba-scipy
|
||||
pytestCheckHook
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace-fail "--durations=50" "" \
|
||||
--replace-fail "hatch-vcs >=0.3.0,<0.4.0" "hatch-vcs"
|
||||
'';
|
||||
|
||||
preBuild = ''
|
||||
export HOME=$(mktemp -d)
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "aesara" ];
|
||||
|
||||
disabledTestPaths = [
|
||||
# Don't run the most compute-intense tests
|
||||
"tests/scan/"
|
||||
"tests/tensor/"
|
||||
"tests/sandbox/"
|
||||
"tests/sparse/sandbox/"
|
||||
# JAX is not available on all platform and often broken
|
||||
"tests/link/jax/"
|
||||
|
||||
# 2024-04-27: The current nixpkgs numba version is too recent and incompatible with aesara 2.9.3
|
||||
"tests/link/numba/"
|
||||
];
|
||||
|
||||
disabledTests = [
|
||||
# Disable all benchmark tests
|
||||
"test_scan_multiple_output"
|
||||
"test_logsumexp_benchmark"
|
||||
|
||||
# TypeError: exceptions must be derived from Warning, not <class 'NoneType'>
|
||||
"test_api_deprecation_warning"
|
||||
# AssertionError: assert ['Elemwise{Co..._i{0} 0', ...] == ['Elemwise{Co..._i{0} 0', ...]
|
||||
# At index 3 diff: '| |Gemv{inplace} d={0: [0]} 2' != '| |CGemv{inplace} d={0: [0]} 2'
|
||||
"test_debugprint"
|
||||
# ValueError: too many values to unpack (expected 3)
|
||||
"test_ExternalCOp_c_code_cache_version"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "Python library to define, optimize, and efficiently evaluate mathematical expressions involving multi-dimensional arrays";
|
||||
homepage = "https://github.com/aesara-devs/aesara";
|
||||
changelog = "https://github.com/aesara-devs/aesara/releases/tag/rel-${version}";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ Etjean ];
|
||||
broken = (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64);
|
||||
};
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
freezegun,
|
||||
pytest-mock,
|
||||
pytestCheckHook,
|
||||
tornado_4,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
@@ -38,7 +37,7 @@ buildPythonPackage rec {
|
||||
freezegun
|
||||
pytest-mock
|
||||
pytestCheckHook
|
||||
] ++ lib.optionals (pythonOlder "3.10") [ tornado_4 ];
|
||||
];
|
||||
|
||||
disabledTests =
|
||||
[
|
||||
@@ -51,7 +50,7 @@ buildPythonPackage rec {
|
||||
"test_that_on_ping_responds_with_pong"
|
||||
];
|
||||
|
||||
disabledTestPaths = lib.optionals (pythonAtLeast "3.10") [
|
||||
disabledTestPaths = [
|
||||
# requires tornado_4, which is not compatible with python3.10
|
||||
"tests/test_integration.py"
|
||||
];
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
unittestCheckHook,
|
||||
buildPythonPackage,
|
||||
fetchPypi,
|
||||
fetchpatch,
|
||||
isPy27,
|
||||
pythonAtLeast,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "tornado";
|
||||
version = "4.5.3";
|
||||
disabled = isPy27 || pythonAtLeast "3.10";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "02jzd23l4r6fswmwxaica9ldlyc2p6q8dk6dyff7j58fmdzf853d";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
name = "CVE-2023-28370.patch";
|
||||
url = "https://github.com/tornadoweb/tornado/commit/32ad07c54e607839273b4e1819c347f5c8976b2f.patch";
|
||||
hash = "sha256-2dpPHkNThOaZD8T2g1vb/I5WYZ/vy/t690539uprJyc=";
|
||||
})
|
||||
];
|
||||
|
||||
nativeCheckInputs = [ unittestCheckHook ];
|
||||
|
||||
# We specify the name of the test files to prevent
|
||||
# https://github.com/NixOS/nixpkgs/issues/14634
|
||||
unittestFlagsArray = [ "*_test.py" ];
|
||||
|
||||
__darwinAllowLocalNetworking = true;
|
||||
|
||||
meta = {
|
||||
description = "Web framework and asynchronous networking library";
|
||||
homepage = "https://www.tornadoweb.org/";
|
||||
license = lib.licenses.asl20;
|
||||
};
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
unittestCheckHook,
|
||||
buildPythonPackage,
|
||||
fetchPypi,
|
||||
fetchpatch,
|
||||
isPy27,
|
||||
pythonAtLeast,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "tornado";
|
||||
version = "5.1.1";
|
||||
disabled = isPy27 || pythonAtLeast "3.10";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "4e5158d97583502a7e2739951553cbd88a72076f152b4b11b64b9a10c4c49409";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
name = "CVE-2023-28370.patch";
|
||||
url = "https://github.com/tornadoweb/tornado/commit/32ad07c54e607839273b4e1819c347f5c8976b2f.patch";
|
||||
hash = "sha256-2dpPHkNThOaZD8T2g1vb/I5WYZ/vy/t690539uprJyc=";
|
||||
})
|
||||
];
|
||||
|
||||
nativeCheckInputs = [ unittestCheckHook ];
|
||||
|
||||
# We specify the name of the test files to prevent
|
||||
# https://github.com/NixOS/nixpkgs/issues/14634
|
||||
unittestFlagsArray = [ "*_test.py" ];
|
||||
|
||||
__darwinAllowLocalNetworking = true;
|
||||
|
||||
meta = {
|
||||
description = "Web framework and asynchronous networking library";
|
||||
homepage = "https://www.tornadoweb.org/";
|
||||
license = lib.licenses.asl20;
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{ lib, fetchzip }:
|
||||
let
|
||||
version = "2.8.2";
|
||||
srcHash = "sha256-1TfD5CXOQKHyO7ARo7oqc2LdiHOyOU/OYNY8j+9QpQ8=";
|
||||
version = "2.8.3";
|
||||
srcHash = "sha256-/Ozzibz2BhVSxQeH9tg3cC5uVl0gEA/Hw2AMOELW/I8=";
|
||||
# The tarball contains vendored dependencies
|
||||
vendorHash = null;
|
||||
in
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
fetchzip,
|
||||
which,
|
||||
ocaml,
|
||||
camlp-streams,
|
||||
ocamlbuild,
|
||||
findlib,
|
||||
}:
|
||||
|
||||
if lib.versionAtLeast ocaml.version "4.15" then
|
||||
if lib.versionAtLeast ocaml.version "5.4" then
|
||||
throw "camlp4 is not available for OCaml ${ocaml.version}"
|
||||
else
|
||||
|
||||
@@ -66,6 +68,22 @@ else
|
||||
version = "4.14+1";
|
||||
sha256 = "sha256-cPN3GioZT/Zt6uzbjGUPEGVJcPQdsAnCkU/AQoPfvuo=";
|
||||
};
|
||||
"5.0" = {
|
||||
version = "5.0";
|
||||
sha256 = "sha256-oZptFNPUEAq5YlcqAoDWfLghGMF9AN7E7hUN55SAX+4=";
|
||||
};
|
||||
"5.1" = {
|
||||
version = "5.1";
|
||||
sha256 = "sha256-Ubedjg3BeHA0bJbEalQN9eEk5+LRAI/er+8mWfVYchg=";
|
||||
};
|
||||
"5.2" = {
|
||||
version = "5.2";
|
||||
sha256 = "sha256-lzbc9xsgeYlbVf71O+PWYS14QivAH1aPdnvWhe0HHME=";
|
||||
};
|
||||
"5.3" = {
|
||||
version = "5.3";
|
||||
sha256 = "sha256-V/kKhTP9U4jWDFuQKuB7BS3XICg1lq/2Avj7UJR55+k=";
|
||||
};
|
||||
}
|
||||
.${ocaml.meta.branch};
|
||||
in
|
||||
@@ -81,9 +99,18 @@ else
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
nativeBuildInputs = [
|
||||
which
|
||||
ocaml
|
||||
nativeBuildInputs =
|
||||
[
|
||||
which
|
||||
ocaml
|
||||
ocamlbuild
|
||||
]
|
||||
++ lib.optionals (lib.versionAtLeast ocaml.version "5.0") [
|
||||
findlib
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals (lib.versionAtLeast ocaml.version "5.0") [
|
||||
camlp-streams
|
||||
ocamlbuild
|
||||
];
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{ lib, stdenv, runtimeShell, pkg-config, gettext, ncurses, CoreFoundation
|
||||
, tiles, SDL2, SDL2_image, SDL2_mixer, SDL2_ttf, freetype, Cocoa
|
||||
{ lib, stdenv, runtimeShell, pkg-config, gettext, ncurses
|
||||
, tiles, SDL2, SDL2_image, SDL2_mixer, SDL2_ttf, freetype, zlib
|
||||
, debug
|
||||
, useXdgDir
|
||||
}:
|
||||
@@ -7,15 +7,26 @@
|
||||
let
|
||||
inherit (lib) optionals optionalString;
|
||||
|
||||
cursesDeps = [ gettext ncurses ]
|
||||
++ optionals stdenv.hostPlatform.isDarwin [ CoreFoundation ];
|
||||
commonDeps = [
|
||||
gettext
|
||||
zlib
|
||||
];
|
||||
|
||||
tilesDeps = [ SDL2 SDL2_image SDL2_mixer SDL2_ttf freetype ]
|
||||
++ optionals stdenv.hostPlatform.isDarwin [ Cocoa ];
|
||||
cursesDeps = commonDeps ++ [ ncurses ];
|
||||
|
||||
tilesDeps =
|
||||
commonDeps
|
||||
++ [
|
||||
SDL2
|
||||
SDL2_image
|
||||
SDL2_mixer
|
||||
SDL2_ttf
|
||||
freetype
|
||||
];
|
||||
|
||||
patchDesktopFile = ''
|
||||
substituteInPlace $out/share/applications/org.cataclysmdda.CataclysmDDA.desktop \
|
||||
--replace "Exec=cataclysm-tiles" "Exec=$out/bin/cataclysm-tiles"
|
||||
--replace-fail "Exec=cataclysm-tiles" "Exec=$out/bin/cataclysm-tiles"
|
||||
'';
|
||||
|
||||
installMacOSAppLauncher = ''
|
||||
@@ -37,7 +48,7 @@ stdenv.mkDerivation {
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
buildInputs = cursesDeps ++ optionals tiles tilesDeps;
|
||||
buildInputs = if tiles then tilesDeps else cursesDeps;
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs lang/compile_mo.sh
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
{ newScope, darwin }:
|
||||
{ newScope }:
|
||||
|
||||
let
|
||||
callPackage = newScope self;
|
||||
|
||||
stable = rec {
|
||||
tiles = callPackage ./stable.nix {
|
||||
inherit (darwin.apple_sdk.frameworks) CoreFoundation Cocoa;
|
||||
};
|
||||
tiles = callPackage ./stable.nix { };
|
||||
|
||||
curses = tiles.override { tiles = false; };
|
||||
};
|
||||
|
||||
git = rec {
|
||||
tiles = callPackage ./git.nix {
|
||||
inherit (darwin.apple_sdk.frameworks) CoreFoundation Cocoa;
|
||||
};
|
||||
tiles = callPackage ./git.nix { };
|
||||
|
||||
curses = tiles.override { tiles = false; };
|
||||
};
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{ lib, callPackage, CoreFoundation, fetchFromGitHub, fetchpatch, pkgs, wrapCDDA, attachPkgs
|
||||
, tiles ? true, Cocoa
|
||||
{ lib, callPackage, fetchFromGitHub, fetchpatch, pkgs, wrapCDDA, attachPkgs
|
||||
, tiles ? true
|
||||
, debug ? false
|
||||
, useXdgDir ? false
|
||||
, version ? "2024-07-28"
|
||||
, rev ? "bfeb1fffc4179fed242a042f24b1c97f6cfaff3d"
|
||||
, sha256 ? "sha256-IodXEA+pWfDdR9huRXieP3+J3WZJO19C8PUPT18dFBw="
|
||||
, version ? "2024-12-11"
|
||||
, rev ? "b871679a2d54dbc6bf3e6566033fadd2dc651592"
|
||||
, sha256 ? "sha256-t9R0QPky7zvjgGMq4kV8DdQFToJ/qngbJCw+8FlQztM="
|
||||
}:
|
||||
|
||||
let
|
||||
common = callPackage ./common.nix {
|
||||
inherit CoreFoundation tiles Cocoa debug useXdgDir;
|
||||
inherit tiles debug useXdgDir;
|
||||
};
|
||||
|
||||
self = common.overrideAttrs (common: rec {
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
diff --git a/src/debug.cpp b/src/debug.cpp
|
||||
index fa63a3b..1e8f554 100644
|
||||
--- a/src/debug.cpp
|
||||
+++ b/src/debug.cpp
|
||||
@@ -1494,6 +1494,14 @@ std::string game_info::operating_system()
|
||||
}
|
||||
|
||||
#if !defined(__CYGWIN__) && !defined (__ANDROID__) && ( defined (__linux__) || defined(unix) || defined(__unix__) || defined(__unix) || ( defined(__APPLE__) && defined(__MACH__) ) || defined(BSD) ) // linux; unix; MacOs; BSD
|
||||
+ //
|
||||
+class FILEDeleter
|
||||
+{
|
||||
+ public:
|
||||
+ void operator()( FILE *f ) const noexcept {
|
||||
+ pclose( f );
|
||||
+ }
|
||||
+};
|
||||
/** Execute a command with the shell by using `popen()`.
|
||||
* @param command The full command to execute.
|
||||
* @note The output buffer is limited to 512 characters.
|
||||
@@ -1504,7 +1512,7 @@ static std::string shell_exec( const std::string &command )
|
||||
std::vector<char> buffer( 512 );
|
||||
std::string output;
|
||||
try {
|
||||
- std::unique_ptr<FILE, decltype( &pclose )> pipe( popen( command.c_str(), "r" ), pclose );
|
||||
+ std::unique_ptr<FILE, FILEDeleter> pipe( popen( command.c_str(), "r" ) );
|
||||
if( pipe ) {
|
||||
while( fgets( buffer.data(), buffer.size(), pipe.get() ) != nullptr ) {
|
||||
output += buffer.data();
|
||||
@@ -4,10 +4,10 @@ diff --git a/src/translations.cpp b/src/translations.cpp
|
||||
@@ -52,13 +52,11 @@ std::string locale_dir()
|
||||
#define CATA_IS_ON_BSD
|
||||
#endif
|
||||
|
||||
|
||||
-#if !defined(__ANDROID__) && ((defined(__linux__) || defined(CATA_IS_ON_BSD) || (defined(MACOSX) && !defined(TILES))))
|
||||
if( !PATH_INFO::base_path().empty() ) {
|
||||
loc_dir = PATH_INFO::base_path() + "share/locale";
|
||||
if( !PATH_INFO::base_path().get_logical_root_path().empty() ) {
|
||||
loc_dir = ( PATH_INFO::base_path() / "share" / "locale" ).generic_u8string();
|
||||
} else {
|
||||
loc_dir = PATH_INFO::langdir();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
diff --git a/src/translations.cpp b/src/translations.cpp
|
||||
index 76bdfd0..6dd6109 100644
|
||||
--- a/src/translations.cpp
|
||||
+++ b/src/translations.cpp
|
||||
@@ -61,13 +61,11 @@ std::string locale_dir()
|
||||
#define BSD
|
||||
@@ -52,13 +52,11 @@ std::string locale_dir()
|
||||
#define CATA_IS_ON_BSD
|
||||
#endif
|
||||
|
||||
-#if !defined(__ANDROID__) && ((defined(__linux__) || defined(BSD) || (defined(MACOSX) && !defined(TILES))))
|
||||
|
||||
-#if !defined(__ANDROID__) && ((defined(__linux__) || defined(CATA_IS_ON_BSD) || (defined(MACOSX) && !defined(TILES))))
|
||||
if( !PATH_INFO::base_path().empty() ) {
|
||||
loc_dir = PATH_INFO::base_path() + "share/locale";
|
||||
} else {
|
||||
|
||||
@@ -1,66 +1,42 @@
|
||||
{ lib
|
||||
, callPackage
|
||||
, CoreFoundation
|
||||
, fetchFromGitHub
|
||||
, fetchpatch
|
||||
, pkgs
|
||||
, wrapCDDA
|
||||
, attachPkgs
|
||||
, tiles ? true
|
||||
, Cocoa
|
||||
, debug ? false
|
||||
, useXdgDir ? false
|
||||
}:
|
||||
|
||||
let
|
||||
common = callPackage ./common.nix {
|
||||
inherit CoreFoundation tiles Cocoa debug useXdgDir;
|
||||
inherit tiles debug useXdgDir;
|
||||
};
|
||||
|
||||
self = common.overrideAttrs (common: rec {
|
||||
version = "0.G";
|
||||
version = "0.H";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "CleverRaven";
|
||||
repo = "Cataclysm-DDA";
|
||||
rev = version;
|
||||
sha256 = "sha256-Hda0dVVHNeZ8MV5CaCbSpdOCG2iqQEEmXdh16vwIBXk=";
|
||||
tag = "${version}-RELEASE";
|
||||
sha256 = "sha256-ZCD5qgqYSX7sS+Tc1oNYq9soYwNUUuWamY2uXfLjGoY=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
# fix compilation of the vendored flatbuffers under gcc14
|
||||
(fetchpatch {
|
||||
name = "fix-flatbuffers-with-gcc14";
|
||||
url = "https://github.com/CleverRaven/Cataclysm-DDA/commit/1400b1018ff37196bd24ba4365bd50beb571ac14.patch";
|
||||
hash = "sha256-H0jct6lSQxu48eOZ4f8HICxo89qX49Ksw+Xwwtp7iFM=";
|
||||
})
|
||||
# Unconditionally look for translation files in $out/share/locale
|
||||
./locale-path.patch
|
||||
# Fixes for failing build with GCC 13, remove on updating next release after 0.G
|
||||
(fetchpatch {
|
||||
url = "https://sources.debian.org/data/main/c/cataclysm-dda/0.G-4/debian/patches/gcc13-dangling-reference-warning.patch";
|
||||
hash = "sha256-9nPbyz49IYBOVHqr7jzCIyS8z/SQgpK4EjEz1fruIPE=";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://sources.debian.org/data/main/c/cataclysm-dda/0.G-4/debian/patches/gcc13-cstdint.patch";
|
||||
hash = "sha256-8IBW2OzAHVgEJZoViQ490n37sl31hA55ePuqDL/lil0=";
|
||||
})
|
||||
(fetchpatch {
|
||||
url = "https://sources.debian.org/data/main/c/cataclysm-dda/0.G-4/debian/patches/gcc13-keyword-requires.patch";
|
||||
hash = "sha256-8yvHh0YKC7AC/qzia7AZAfMewMC0RiSepMXpOkMXRd8=";
|
||||
})
|
||||
# Fix build w/ glibc-2.39
|
||||
# From https://github.com/BrettDong/Cataclysm-DDA/commit/9b206e2dc969ad79345596e03c3980bd155d2f48
|
||||
./glibc-2.39.diff
|
||||
];
|
||||
|
||||
makeFlags = common.makeFlags ++ [
|
||||
# Makefile declares version as 0.F, with no minor release number
|
||||
"VERSION=${version}"
|
||||
];
|
||||
|
||||
env.NIX_CFLAGS_COMPILE = toString [
|
||||
# Needed with GCC 12
|
||||
"-Wno-error=array-bounds"
|
||||
];
|
||||
|
||||
meta = common.meta // {
|
||||
maintainers = with lib.maintainers;
|
||||
common.meta.maintainers;
|
||||
changelog = "https://github.com/CleverRaven/Cataclysm-DDA/blob/${version}/data/changelog.txt";
|
||||
};
|
||||
});
|
||||
|
||||
@@ -3873,8 +3873,6 @@ with pkgs;
|
||||
|
||||
kio-fuse = libsForQt5.callPackage ../tools/filesystems/kio-fuse { };
|
||||
|
||||
kphotoalbum = libsForQt5.callPackage ../applications/graphics/kphotoalbum { };
|
||||
|
||||
krename = libsForQt5.callPackage ../applications/misc/krename { };
|
||||
|
||||
krunner-pass = libsForQt5.callPackage ../tools/security/krunner-pass { };
|
||||
@@ -6318,10 +6316,6 @@ with pkgs;
|
||||
inherit (emacs.pkgs.melpaStablePackages) irony;
|
||||
};
|
||||
|
||||
heptagon = callPackage ../development/compilers/heptagon {
|
||||
ocamlPackages = ocaml-ng.ocamlPackages_4_14;
|
||||
};
|
||||
|
||||
openjfx17 = openjfx;
|
||||
openjfx21 = callPackage ../by-name/op/openjfx/package.nix { featureVersion = "21"; };
|
||||
openjfx23 = callPackage ../by-name/op/openjfx/package.nix { featureVersion = "23"; };
|
||||
@@ -8552,6 +8546,8 @@ with pkgs;
|
||||
aspell = aspell.override { searchNixProfiles = false; };
|
||||
};
|
||||
|
||||
astal = recurseIntoAttrs (lib.makeScope newScope (callPackage ../development/libraries/astal { }));
|
||||
|
||||
attr = callPackage ../development/libraries/attr { };
|
||||
|
||||
# Not moved to aliases while we decide if we should split the package again.
|
||||
|
||||
@@ -38,6 +38,8 @@ mapAliases ({
|
||||
acebinf = throw "acebinf has been removed because it is abandoned and broken."; # Added 2023-05-19
|
||||
acoustics = throw "acoustics has been removed because the upstream repository was archived in 2024"; # Added 2024-10-04
|
||||
adafruit-nrfutil = throw "adafruit-nrfutil has been promoted to a top-level attribute name: `pkgs.adafruit-nrfutil`."; # Added 2023-11-19
|
||||
aeppl = throw "aeppl was removed as it depends on aesara, which is unmaintained"; # added 2025-01-12
|
||||
aesara = throw "aesara was removed as the upstream repository is unmaintained"; # added 2025-01-12
|
||||
aioaladdinconnect = throw "aioaladdinconnect has been removed, as the API is supported was obsoleted on 2024-01-24."; # Added 2024-06-07
|
||||
aiohttp-isal = throw "aiohttp-isal has been removed, as it has been archived and replace by aiohttp-fast-zlib"; # Added 2024-08-11
|
||||
aiohttp-zlib-ng = throw "aiohttp-zlib-ng has been removed, as it has been archived and replaced by aiohttp-fast-zlib"; # Added 2024-11-14
|
||||
@@ -689,6 +691,8 @@ mapAliases ({
|
||||
thumborPexif = throw "thumborPexif has been removed, because it was unused."; # added 2024-01-07
|
||||
tissue = throw "tissue has been removed, because it is archived since October 2022"; # added 2024-07-27
|
||||
torchgpipe = throw "torchgpipe has been removed, because it appears unmaintained and Pytorch now includes pipeline parallelism support"; # added 2024-05-18
|
||||
tornado_4 = throw "tornado_4 has been removed, use tornado instead"; # added 2025-01-13
|
||||
tornado_5 = throw "tornado_5 has been removed, use tornado instead"; # added 2025-01-13
|
||||
torrent_parser = torrent-parser; # added 2023-11-04
|
||||
transip = throw "transip has been removed because it is no longer maintained. TransIP SOAP V5 API was marked as deprecated"; # added 2023-02-27
|
||||
py-tree-sitter = throw "Was merged with tree-sitter."; # added 2024-03-20
|
||||
|
||||
@@ -99,12 +99,8 @@ self: super: with self; {
|
||||
|
||||
aenum = callPackage ../development/python-modules/aenum { };
|
||||
|
||||
aeppl = callPackage ../development/python-modules/aeppl { };
|
||||
|
||||
aerosandbox = callPackage ../development/python-modules/aerosandbox { };
|
||||
|
||||
aesara = callPackage ../development/python-modules/aesara { };
|
||||
|
||||
aesedb = callPackage ../development/python-modules/aesedb { };
|
||||
|
||||
aetcd = callPackage ../development/python-modules/aetcd { };
|
||||
@@ -16327,12 +16323,6 @@ self: super: with self; {
|
||||
|
||||
tornado = callPackage ../development/python-modules/tornado { };
|
||||
|
||||
# Used by circus and grab-site, 2020-08-29
|
||||
tornado_4 = callPackage ../development/python-modules/tornado/4.nix { };
|
||||
|
||||
# Used by streamlit, 2021-01-29
|
||||
tornado_5 = callPackage ../development/python-modules/tornado/5.nix { };
|
||||
|
||||
torchprofile = callPackage ../development/python-modules/torchprofile { };
|
||||
|
||||
torpy = callPackage ../development/python-modules/torpy { };
|
||||
|
||||
Reference in New Issue
Block a user