diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 91d37a1fafc58..71be98d7796db 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -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"; diff --git a/nixos/doc/manual/release-notes/rl-2505.section.md b/nixos/doc/manual/release-notes/rl-2505.section.md index 97aa4643cd3da..5899bf33058f2 100644 --- a/nixos/doc/manual/release-notes/rl-2505.section.md +++ b/nixos/doc/manual/release-notes/rl-2505.section.md @@ -97,6 +97,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). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 8fa4b6e9d1107..00b2f556c3d9e 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -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 diff --git a/nixos/modules/services/finance/libeufin/bank.nix b/nixos/modules/services/finance/libeufin/bank.nix new file mode 100644 index 0000000000000..77397d25fd528 --- /dev/null +++ b/nixos/modules/services/finance/libeufin/bank.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"; + }; +} diff --git a/nixos/modules/services/finance/libeufin/common.nix b/nixos/modules/services/finance/libeufin/common.nix new file mode 100644 index 0000000000000..d5e72b8ad0c5b --- /dev/null +++ b/nixos/modules/services/finance/libeufin/common.nix @@ -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."; + } + ]; + + }; +} diff --git a/nixos/modules/services/finance/libeufin/module.nix b/nixos/modules/services/finance/libeufin/module.nix new file mode 100644 index 0000000000000..1e78e93df3d3c --- /dev/null +++ b/nixos/modules/services/finance/libeufin/module.nix @@ -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; + }; +} diff --git a/nixos/modules/services/finance/libeufin/nexus.nix b/nixos/modules/services/finance/libeufin/nexus.nix new file mode 100644 index 0000000000000..19f877ba6b1b3 --- /dev/null +++ b/nixos/modules/services/finance/libeufin/nexus.nix @@ -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"; + }; +} diff --git a/nixos/modules/services/finance/taler/common.nix b/nixos/modules/services/finance/taler/common.nix new file mode 100644 index 0000000000000..426647f8f4764 --- /dev/null +++ b/nixos/modules/services/finance/taler/common.nix @@ -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; + } + ]; + }; + }; +} diff --git a/nixos/modules/services/finance/taler/exchange.nix b/nixos/modules/services/finance/taler/exchange.nix new file mode 100644 index 0000000000000..16428a43d78dc --- /dev/null +++ b/nixos/modules/services/finance/taler/exchange.nix @@ -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} + ''; + }; +} diff --git a/nixos/modules/services/finance/taler/merchant.nix b/nixos/modules/services/finance/taler/merchant.nix new file mode 100644 index 0000000000000..e5a2f2ce5d106 --- /dev/null +++ b/nixos/modules/services/finance/taler/merchant.nix @@ -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} + ''; + }; +} diff --git a/nixos/modules/services/finance/taler/module.nix b/nixos/modules/services/finance/taler/module.nix new file mode 100644 index 0000000000000..844601b19a386 --- /dev/null +++ b/nixos/modules/services/finance/taler/module.nix @@ -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 + ''; + + }; +} diff --git a/nixos/modules/services/misc/renovate.nix b/nixos/modules/services/misc/renovate.nix index cc1185fb0580d..5d968dc41a680 100644 --- a/nixos/modules/services/misc/renovate.nix +++ b/nixos/modules/services/misc/renovate.nix @@ -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)} ''; diff --git a/nixos/modules/services/web-apps/echoip.nix b/nixos/modules/services/web-apps/echoip.nix new file mode 100644 index 0000000000000..4bfba2ae138a5 --- /dev/null +++ b/nixos/modules/services/web-apps/echoip.nix @@ -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 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"; + }; + }; +} diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 5043fc0ca6700..be9af22e58b38 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -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 '' diff --git a/nixos/modules/testing/test-instrumentation.nix b/nixos/modules/testing/test-instrumentation.nix index 050c817e8718a..208bf4f854882 100644 --- a/nixos/modules/testing/test-instrumentation.nix +++ b/nixos/modules/testing/test-instrumentation.nix @@ -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"; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index be546f2acc3aa..aeb59348fd932 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -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 {}; diff --git a/nixos/tests/echoip.nix b/nixos/tests/echoip.nix new file mode 100644 index 0000000000000..036018b264386 --- /dev/null +++ b/nixos/tests/echoip.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" + ''; + } +) diff --git a/nixos/tests/mattermost.nix b/nixos/tests/mattermost.nix index 04df954eef1a6..a39033ced31d6 100644 --- a/nixos/tests/mattermost.nix +++ b/nixos/tests/mattermost.nix @@ -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"''}") diff --git a/nixos/tests/renovate.nix b/nixos/tests/renovate.nix index 4bfdab4edec3d..52bcc867173cd 100644 --- a/nixos/tests/renovate.nix +++ b/nixos/tests/renovate.nix @@ -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 = '' diff --git a/nixos/tests/taler/common/nodes.nix b/nixos/tests/taler/common/nodes.nix new file mode 100644 index 0000000000000..3e8b81ed5179d --- /dev/null +++ b/nixos/tests/taler/common/nodes.nix @@ -0,0 +1,200 @@ +{ lib, ... }: +let + # Forward SSH and WebUI ports to host machine + # + # Connect with: ssh root@localhost -p + # Access WebUI from: http://localhost: + # + # 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 ]; + }; + }; + }; + +} diff --git a/nixos/tests/taler/common/scripts.nix b/nixos/tests/taler/common/scripts.nix new file mode 100644 index 0000000000000..3860ae229070a --- /dev/null +++ b/nixos/tests/taler/common/scripts.nix @@ -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}"') + ''; +} diff --git a/nixos/tests/taler/conf/bank-ebics-keys.json b/nixos/tests/taler/conf/bank-ebics-keys.json new file mode 100644 index 0000000000000..e3ebadb6ba5b8 --- /dev/null +++ b/nixos/tests/taler/conf/bank-ebics-keys.json @@ -0,0 +1 @@ +{"bank_encryption_public_key":"621028HG1M30JAM6923FE381040GA003G80GY01GG80GM0M2040G1EACATA11EF5SVKNBNBYF1S3WSKQ2A2R9VZ7RW2HRX00293JPZ7VQ780RFRVYTQKKDDNJAQGBH4659GT9QYBMJCG1RKZEH1WDJ0GAAY7B7NBMW6FWXCKFYRMZQME0WBGZ1AAMY2VBQ5XAFV8216EFNF2EPG6M5ZGHG9RG6EGED56TK9JESQ02Q7AAVBRAAARVBN9NHCN64KQ3SRRHYXB8RWRK4TSSC93XG8RWMQH4ZDJSBYDCEXFY6G3AWTZ0EZNCJJAYB98T4GNFWZMN81AVYCQHXT1APX81AXCAYNK7J9XETF5CN1J1WV0BVA2BYG4VAMAW123REPN67JF1TNWPTADBMHS17N2V1GFYT8JRWX4TGM2996NXTEPMA8C2CDDE0CRY2A6HT8C5H2D6C62YGRSCF820C0G008","bank_authentication_public_key":"621028HG1M30JAM6923FE381040GA003G80GY01GG80GM0M2040G1EACATA11EF5SVKNBNBYF1S3WSKQ2A2R9VZ7RW2HRX00293JPZ7VQ780RFRVYTQKKDDNJAQGBH4659GT9QYBMJCG1RKZEH1WDJ0GAAY7B7NBMW6FWXCKFYRMZQME0WBGZ1AAMY2VBQ5XAFV8216EFNF2EPG6M5ZGHG9RG6EGED56TK9JESQ02Q7AAVBRAAARVBN9NHCN64KQ3SRRHYXB8RWRK4TSSC93XG8RWMQH4ZDJSBYDCEXFY6G3AWTZ0EZNCJJAYB98T4GNFWZMN81AVYCQHXT1APX81AXCAYNK7J9XETF5CN1J1WV0BVA2BYG4VAMAW123REPN67JF1TNWPTADBMHS17N2V1GFYT8JRWX4TGM2996NXTEPMA8C2CDDE0CRY2A6HT8C5H2D6C62YGRSCF820C0G008","accepted":true} diff --git a/nixos/tests/taler/conf/client-ebics-keys.json b/nixos/tests/taler/conf/client-ebics-keys.json new file mode 100644 index 0000000000000..d599e86893de0 --- /dev/null +++ b/nixos/tests/taler/conf/client-ebics-keys.json @@ -0,0 +1 @@ +{"signature_private_key":"62109F020403038614N8CJ46YW6G20810M0090G4MRR84152080G00M2040G1G344ZCHJWVZJVC7X42WJ6H99ZM4MND4QA766HQXG24QCE3FMAZWVSDWJYRPNM0PVWB1AH39685XN11P7EEHDHW89W0XNDYB4EMYTMA771DVMQWV57NZA9C5QGAK2N7FGKE73020ENJF74N49DEQCXW78FQQNZSDPAC07Y0GNJCR53Q59Z97T14E29NRKFMFYF2CQK45TPAK8M80H8K275TG5FMW16YVTSK3YJBSJN0G7MT187QCNS6P25SJD9Q30K578H3YY30F6R852ZG904BW07PAZT29HTV5F3ZE5K86F4MAQ9H2H7C3AYG8P6SZEK60E0QWWX79M0SP2BAC0QT8310X0TDZ16298SBSD5SDFGQT6FG44BEQNES1KVW1JZYD8GSB6TQQZ3VDFE7N9SBNST820C0G0082G7ZNG0X14DZMZZNP1NY2FQCKTRWN6JJVJR8F6AF76PWSAJ2A6R4P8MAMAJATDC0HKKQ6M9JDTFXRX9J8TFPZSEWD2N3CYZP39PGJG26GE8F6EN5P367K2JX45W1GC0FJF2Q1Z131QMKMYQNKT87C8Q5WXXKZ010H6N6YD47PFHBM3KPTEJJ0MSVH9RTCCABKA5MJ7N262BPRVYD6Y4G0Q3TDNYKX62MRXB4GAGS1CEEEGMYZ6TSC2WMWTVJYJCG4ZSDM2D9GEJ5KTH2RTWSJCYHN6E807VQM3GMMZCFCQP4309H592WQE93R2Y93VWD6PDQRJEXSZJDM4F7XHB9BNGAP4S1T67971K1AJQ2PSJXC99KFF8D1JN7GH40E8ZC3W599Y0WHKSD69Q1SB0WCEQEGZ90G50C103FCEV1ZD5CXVQ4T2Q438DGWKVE1K2JVR4EAKYT9AQ7F7EQZ35J04ACC2XVXZ8DN2ZDRY70WDK36GDRGFKZ2SFPACAQ7QAYXJW4PT3VGXAXP78HD8X9T608FY92SJWEE235AAYR26FEYX9VKQ6RH7XJE9Z5QYHZDJBSNY3VJES8GW8FR0WXVVDH5NFYRNPC5H8TESBFYDQXWQW82G60G1Q8MNSTSWRPWZ9GDZ7P73RQFBKXVNFKVY5T2VH3JEW68PGR1P4MV75ZM4SHN7RTGB0BZQEMRRC9SNDTJ2NF9YCZG8DHES8AYHZKWXQN5GSJBE0MTP316PW23W2RVNJCVCS6TC28J6GGJ660JEET1T1G2YJ0R846NQRK575WT24DR2Q2PK1Q837VE2EN05KQMCD8C4SCDTTVRF4183080NT78B8YY25XM9EHV5M3B82WJY8ADA4VNX7BCNFDRHP9EWHXA0SRTEJJCNMRVW30YD1XYDRZ2VD3SEDE55A3VDTQFHPAZQ8C227RV2WN1H8WD8FSM5WTQXH4PX6R09ERRXWFY15B67JA1W0RGA77BJS5X4D7N9XDJZ8EDE1NHXHNETX71FR7FA979E6ESAE8CGK8SNDYC8Z5920M1G0JESJAYPYZREV826MBMVSMANNFTXNNXEGXJRQD27K12F8W0SNJC8B2C8W4CY9XYNXBBQG6T8TH0M8EB0HR5E36VKYB7A9H7JTPBNB7T24EV9HYX1Q38ZJ6DKABKRQGDMSDHVSHQ2Y77EZVH6KF3XNEGVBACVJ1ZPKSH2E8J963AW6K4S22N3JPMCCTYJZPQT001GCB7E91ZNW82G60G1F5TBF02RRWS5FENV7SVW0P2WXKM4KGZNP0H3T0SP1S8H2P9R5ARQYT1XB44D4C6N9DGXW0ZY9RTPDN7FV2ZZ809EKEVD0PFJNNE7QENVE3AJ9YB4CEQ30APTVY6DJBSE90MXVJ1DT7PG7P404J6A6VCCJVSSCH330X97D8E8GCJV8T3A5TMANN5CAC8M5RR22PJAMP3ZC9XVC","encryption_private_key":"62109F020403038614N8CJ46YW6G20810M0090G4MRR84152080G00M2040G1M43X9T1PGMHQDXM3307ZR8A6E00XHF5FZEAMSTS7RZ3JZVAP50C0FKX592V5AM55E38Q6HXJA8K8SVRYCTDV6CATPTRGPW5NQ3T38CJ77KW0V8H20FBJSB69N51TMKG6MW7GJ1VBR5WY0JJ1VM5Z061SHT0G61S0WNMDZDSEYJP8QC0WW63CDV1HFHYV63TCDQB16PV1SZ53AHB3P2H2CKWQVN8P00RBGS9A6TEA1NZCR8RWXDTB1KBWJWWNW5EV94PCH6YJPVRA0DB12TAC2AR9FP4BDJTZS322Z1ZRDCXMBZXPMRHFVECEPAJGER1DBXM1HWE8NBC7D1MR3RSV9PSRPTXT07WVKH1YRDQ8S1CPCRACXZ953YT2PGESGD2FFQ9JDDR8Q0HJAHTDC8S83K0ZRR20C0G0082G80G0166J2QHM55V7EYGBWJC3288XZ3GC3WR8C36VK5J567WJHTPSMX7PV5JYWPY6YNEAGGXZFN7KHEC20W1NJM50KQWYG51ANKB91GA67GD7184Q0QKZ8BRM3BXFDAV0E1W4ENYGVAQ2TZN8ZBC3PTMNGNB5PG9DCPZADZVAFW8D3N1QMTWD5Q4JAWSHDBTR43AYMQ0NMVH4BSDFCAHKEHVCDPZTNPZ79BS52XPC36B95YDRSWFJ4ZS0VFS4KNQTJBHFXVS017N892FMBX3600TMPPB6QX0XTB03Q2CS755CXERJ75ZGE3G6C01EQZ7W1VKEFKBKF83RZG6TTKTY4PHV7N8CF7NTXA5WF4WDQR60TZG6GG7NQ2S4XF9S8MD3NPKZ80WE7QZGZH5Y59VWVPWG3GJZG82G60G1VWXEXJQZHXZFSQGFA3JWWEB8TFRMGJ9HMRF9GQFX0XB5QQVVTFWK563SG6SR0GZFGXRZY6AS31VM3SN2SFMQS51GWHF9QS8Z40G29CG96NDW5XTTTQEHF8SADQVXYSKEC8WPES3278B1X0NDQSY8B9NJ083X1V1FSVBCKZB62B9M6HCCR3YFFJJVTCBP9DCJ75RXJZF8YYNC4183080VV30KFVNSRC3NTKW174J3MC415EK8MKGNN1J62X235SM49KYBG3MMENBV03FGMWH55QE35PTVKQG48M6VAJHGNNYTGXGT0X7C9YECGC700414Z74D42W08Q53TWC9AGFR035D93CBKYXPQ5RY3CGWPA3RGZTDGDEE4J6PVHCZX6RBYRYQG53XFE7E4VKRM5Q54N62WAY13KW60M1G0XGR76Y416G5ZCF6BEYKRPP183RPH1QV24KMQENQVB8F6KWAZD8YTPZGJGJK1YNAW7HWJDB9BH0QNXFVS0KFF54V6YNKDQ5NN3HT3P8DM00J5B5QBM7SZ3BKD7VYTF498BRMC9639047XVGDJ6ZNWYGSN01HK3J7PAW7ETHM2GH6B67RR3GAS2PMYKW7JS1W0MQKM5DGQJZCG82G602QH54XPJEQ57Z3S5BGWBQVXZ1V26YBB2211KC810DSNSM9FSWZ27F427XN9D3XHKKSJ5R66VNCT7EYSRT0JW7F2HRTXQWKEBJPNKPPTRHPS3TKNKH5TSTA2GCPS39VWQV1ZMDSX42P38550V7VEV7G953MA3Q9VF4613GRVWBGG1PXTDSYFHM1NYKVN98B21P7SRVPQV4ZCCS0A0R0WGQ4AEKG8JFSYPMC03TA8M2J5PN51PVZP6WZ1R167B92AQGM3YTKAK1QECQK1S4T2HV04Y2YJDCYK5AYVJQYXFYQPFP1CYSE3Q458BBN8RXW5QMJEPCTGK2N3H7K5T2ZJMWNJY27J53B08703K93X0JSM643V7Z95CBJNKVZR4QXRKHFPG5W79AKZ3WP9CXY43XXSHG0KN424","authentication_private_key":"62109F820403038614N8CJ46YW6G20810M0090G4MWR84153080G00M2040G1CZR41XW4ANY74SDV2B2ZEFWPR0E9RXRWFAVAXJHZBMSYXHE5F32X4PKDTVBNHVNYAQYXDXMFV9WCYZA16PKDCEWZ87FKKDH8EJP7NQZB5GK83HJ6KX3P04BD878D99QZ44EE6SYK3YJZMBEP9H1755FKR25RBH5VEYRZ9X2T2DTBV34SREH7F7A81KCC4ZWBRWP1EH179T4RH17R278A9834G2FNPAKST9HK7P878W85DW9XG9BJQ40YCDTP6DGACTKZBJ992M6BDJN69HQZ9GDHF73M2CV7C96YYH8YKMD3V3YXNR17PP0BMKAB30T7KGTDMM92XH6Z0CKA6VQSRFFA59H77GESQYT05SY4N2AGRM9468G1XYJ7M2PM3EXZAYM1GJ934PRGG965Z8KRVZEFF820C0G0082G80G05FQQ0106J3KPWETPQ35EPRCTP0K8VTBJTDZ7P6PG6CXM968G5AP2GN6640WVE6D5AB2J4RYSNTVF4X6JJWWSYDCB7JTDFK1W27T7ZMEQB2MA2K57J0S5QPN4PQAF4C19J962JV51YSFNECVDT328F8H05MJF05H76N61QX5VQ2REQ879M02B7QRQ9NH284XCWWTA5T8HSJ6BG70SCF7S0YJX8F3DQDB763X3D4RY8Y7HVPVBCR9JKJC521R2BHR12WYZ329KN38MVJ69NHJMH2BFT76TRQXY8N6ECEGVC9GWC1KCVSGKQE4XSP6ZYFFVFBNTEVR3653PMF9S9XYSJYBPKQBTF2Q4SY2D56B0Z5MN0A0R7YY1PGZN69A9RPT8H18QVQPJR1YTM1BBNTQHS6KC382G60G1R1Q8A547XJHMF7Z9BR8PC9YPKAMCRKMFNFD71MS5P8CY3TC81MYWRBVNBC7DJA7DCFXHTW3BMC0RCZ39SYY2PS29FQJQR7ZDT8H260P4X8Q8D5JYYAJFDBSY82BQY4K71V5PGYH6PS0Q79CRWWQJQ68JHESE2C829CMNXDWTCW21G9SZC6JJ32P6HSGQ1T5K8VD9B6GFPZ6XC183080SNXJNZ2MFM6GRPHEN3SHTNE9M63KWHG4EQBEPYYG7E5DH5Q4NYP19ZGJ192XV7GJFRSH14XB3DXR4GEZACKMMEMSFTFJ16NQXMYYXTRF4KY9NPYPSD3E65RMF9CDGWAGMT46RTWZE2PRSSRFS15Z0CQ0HCN5K9EG16GGE77E27DNN43XFD2G3YKYXAMDPF7CGT3K8V3T328ZE0M1G1SM8XBMTY9SWK7MXZWVR8SM5SBWDXZDC72DSYWFDBNJ5Y0D3NMVKVPRDGJ23SQM7H0JSXAY8SPBM8D5NNAKD6SRRRHN8VYSHMX2S21FB0594DRA8G8VY4D1XRR90G4VNHF06BSHWVPRCPC1R68ZPW0BGBBE3ZHWN344AD0HM7GCA3N8B0276YZHQRJ2YAZ4RKG7Q8V4VJ8Q9682G60G1F9CJZV9E4J9W42PBKY5GD66FHBYDPKAH54MQ5BX7VFXES4ZAR46BM6MRBM90FQQ7DRVXGVGER6NWJK2195XJXMKQHW7B36HGT12HK1QQFF1J7RB6QWJEEFXR2M7M4YK3CS00RRMYA5XKVNNPV2VZNBXKGJ5SCHGSN6GKDNXE0HSM2VMBKS794DGB7D4PYSEYKSB9BM57G1B4418303W3D38F61CC4RC8DNDZNH9S7N0E4AM97QVRPMY7FERHN0JM4VHD5ET49RYJVW9Y9GBREB801N4A70Z9EGCBM2WJZYSF9KXX8EVDFX37KDJ2G4MTJNR628QV206M1QJ4P4EKS04D9GB8TTQNHJCXJ1PX9PJ44WYGAPKQQP5ENN1VCJAHVXTD5BXHJZYASWZ8QZJY7V760W36ER0","submitted_ini":true,"submitted_hia":true} diff --git a/nixos/tests/taler/conf/exchange-account.json b/nixos/tests/taler/conf/exchange-account.json new file mode 100644 index 0000000000000..4bc476ff894f9 --- /dev/null +++ b/nixos/tests/taler/conf/exchange-account.json @@ -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" + } + } +] diff --git a/nixos/tests/taler/conf/private.key b/nixos/tests/taler/conf/private.key new file mode 100644 index 0000000000000..3025c97740ad7 --- /dev/null +++ b/nixos/tests/taler/conf/private.key @@ -0,0 +1 @@ +ƒØ'IÕ‚–v&©ˆû¾¢¶ßH{VWýrƒ¶CjÜ>¦ \ No newline at end of file diff --git a/nixos/tests/taler/conf/taler-accounts.conf b/nixos/tests/taler/conf/taler-accounts.conf new file mode 100644 index 0000000000000..9246c25a83ad2 --- /dev/null +++ b/nixos/tests/taler/conf/taler-accounts.conf @@ -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 diff --git a/nixos/tests/taler/conf/taler-denominations.conf b/nixos/tests/taler/conf/taler-denominations.conf new file mode 100644 index 0000000000000..e0c46ba9d6f6f --- /dev/null +++ b/nixos/tests/taler/conf/taler-denominations.conf @@ -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 diff --git a/nixos/tests/taler/default.nix b/nixos/tests/taler/default.nix new file mode 100644 index 0000000000000..00ce30ded6b6d --- /dev/null +++ b/nixos/tests/taler/default.nix @@ -0,0 +1,7 @@ +{ + system ? builtins.currentSystem, + pkgs ? import ../../.. { inherit system; }, +}: +{ + basic = import ./tests/basic.nix { inherit system pkgs; }; +} diff --git a/nixos/tests/taler/tests/basic.nix b/nixos/tests/taler/tests/basic.nix new file mode 100644 index 0000000000000..3eeb50b04fa98 --- /dev/null +++ b/nixos/tests/taler/tests/basic.nix @@ -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) + ''; + } +) diff --git a/pkgs/applications/emulators/wine/sources.nix b/pkgs/applications/emulators/wine/sources.nix index 7485ff402d823..959fdf6e5c4cb 100644 --- a/pkgs/applications/emulators/wine/sources.nix +++ b/pkgs/applications/emulators/wine/sources.nix @@ -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"; diff --git a/pkgs/by-name/al/albert/package.nix b/pkgs/by-name/al/albert/package.nix index c1fe2144e67d1..ea79bdd0c6ba0 100644 --- a/pkgs/by-name/al/albert/package.nix +++ b/pkgs/by-name/al/albert/package.nix @@ -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; }; diff --git a/pkgs/by-name/ap/apt/package.nix b/pkgs/by-name/ap/apt/package.nix index 2e0e68c13ea75..e28dde96197e4 100644 --- a/pkgs/by-name/ap/apt/package.nix +++ b/pkgs/by-name/ap/apt/package.nix @@ -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") diff --git a/pkgs/by-name/co/codd/generated.nix b/pkgs/by-name/co/codd/generated.nix new file mode 100644 index 0000000000000..142bb4f2baf02 --- /dev/null +++ b/pkgs/by-name/co/codd/generated.nix @@ -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"; +} diff --git a/pkgs/by-name/co/codd/package.nix b/pkgs/by-name/co/codd/package.nix new file mode 100644 index 0000000000000..cf042055a3894 --- /dev/null +++ b/pkgs/by-name/co/codd/package.nix @@ -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 diff --git a/pkgs/by-name/dp/dpkg/package.nix b/pkgs/by-name/dp/dpkg/package.nix index dc12b465987b0..0516effef9557 100644 --- a/pkgs/by-name/dp/dpkg/package.nix +++ b/pkgs/by-name/dp/dpkg/package.nix @@ -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 \ diff --git a/pkgs/by-name/ec/echoip/package.nix b/pkgs/by-name/ec/echoip/package.nix index 7c8d1f13114bb..0b533cc7b3b20 100644 --- a/pkgs/by-name/ec/echoip/package.nix +++ b/pkgs/by-name/ec/echoip/package.nix @@ -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"; }; diff --git a/pkgs/by-name/gn/gnu-cim/package.nix b/pkgs/by-name/gn/gnu-cim/package.nix index bf2835959ff11..b2c339d45a393 100644 --- a/pkgs/by-name/gn/gnu-cim/package.nix +++ b/pkgs/by-name/gn/gnu-cim/package.nix @@ -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; diff --git a/pkgs/development/compilers/heptagon/default.nix b/pkgs/by-name/he/heptagon/package.nix similarity index 83% rename from pkgs/development/compilers/heptagon/default.nix rename to pkgs/by-name/he/heptagon/package.nix index 0bfdb702aaafb..be1b69a3a263b 100644 --- a/pkgs/development/compilers/heptagon/default.nix +++ b/pkgs/by-name/he/heptagon/package.nix @@ -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; [ diff --git a/pkgs/applications/graphics/kphotoalbum/default.nix b/pkgs/by-name/kp/kphotoalbum/package.nix similarity index 51% rename from pkgs/applications/graphics/kphotoalbum/default.nix rename to pkgs/by-name/kp/kphotoalbum/package.nix index 6af9d69f5574e..41792f04b4755 100644 --- a/pkgs/applications/graphics/kphotoalbum/default.nix +++ b/pkgs/by-name/kp/kphotoalbum/package.nix @@ -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; }; -} +}) diff --git a/pkgs/by-name/ma/mattermost-desktop/package.nix b/pkgs/by-name/ma/mattermost-desktop/package.nix index b6f4085a688fb..d907d627dda2f 100644 --- a/pkgs/by-name/ma/mattermost-desktop/package.nix +++ b/pkgs/by-name/ma/mattermost-desktop/package.nix @@ -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"; - - srcs = { - "x86_64-linux" = { - url = "https://releases.mattermost.com/desktop/${version}/${pname}-${version}-linux-x64.tar.gz"; - hash = "sha256-zLKdfu5p7TyJOw8vJX7i/uu4j0PrUf2/BDmb1kdqqMc="; - }; + version = "5.10.2"; - "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; + npmDepsHash = "sha256-LAbqsMdMmmHGgvg2ilz6neQxMOK3jtCKt8K0M8BWifs="; + npmBuildScript = "build-prod"; + makeCacheWritable = true; -in + nativeBuildInputs = [ makeWrapper ]; -stdenv.mkDerivation { - inherit pname version; + env.ELECTRON_SKIP_BINARY_DOWNLOAD = "1"; - src = fetchurl (srcs."${system}" or (throw "Unsupported system ${system}")); + 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;" + ''; - nativeBuildInputs = [ makeWrapper ]; + 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 ]; }; } diff --git a/pkgs/by-name/ma/mattermost/package.nix b/pkgs/by-name/ma/mattermost/package.nix index 87bbe84027130..61036a0fdb9ef 100644 --- a/pkgs/by-name/ma/mattermost/package.nix +++ b/pkgs/by-name/ma/mattermost/package.nix @@ -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 ''; diff --git a/pkgs/by-name/mi/mieru/package.nix b/pkgs/by-name/mi/mieru/package.nix index a8babccde6d69..794d7e727c188 100644 --- a/pkgs/by-name/mi/mieru/package.nix +++ b/pkgs/by-name/mi/mieru/package.nix @@ -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 = [ diff --git a/pkgs/by-name/nv/nvitop/package.nix b/pkgs/by-name/nv/nvitop/package.nix index 6c7bb31081184..cce03aca75c74 100644 --- a/pkgs/by-name/nv/nvitop/package.nix +++ b/pkgs/by-name/nv/nvitop/package.nix @@ -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" ]; diff --git a/pkgs/by-name/pi/pixi/package.nix b/pkgs/by-name/pi/pixi/package.nix index ed6f8e51da12d..b22361ead18e3 100644 --- a/pkgs/by-name/pi/pixi/package.nix +++ b/pkgs/by-name/pi/pixi/package.nix @@ -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 diff --git a/pkgs/by-name/pr/prismlauncher-unwrapped/package.nix b/pkgs/by-name/pr/prismlauncher-unwrapped/package.nix index 3a88065bca9d1..39d05e56805c6 100644 --- a/pkgs/by-name/pr/prismlauncher-unwrapped/package.nix +++ b/pkgs/by-name/pr/prismlauncher-unwrapped/package.nix @@ -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 = '' diff --git a/pkgs/by-name/vi/virglrenderer/package.nix b/pkgs/by-name/vi/virglrenderer/package.nix index 79516f5ed487b..fc9f165f6369a 100644 --- a/pkgs/by-name/vi/virglrenderer/package.nix +++ b/pkgs/by-name/vi/virglrenderer/package.nix @@ -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 ]; }; } diff --git a/pkgs/by-name/xa/xawtv/package.nix b/pkgs/by-name/xa/xawtv/package.nix index 3a4da5eb0eaa2..5486b7b6e261e 100644 --- a/pkgs/by-name/xa/xawtv/package.nix +++ b/pkgs/by-name/xa/xawtv/package.nix @@ -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 diff --git a/pkgs/by-name/yt/yt-dlp/package.nix b/pkgs/by-name/yt/yt-dlp/package.nix index 971c68aa0c76c..c0613c53eefd5 100644 --- a/pkgs/by-name/yt/yt-dlp/package.nix +++ b/pkgs/by-name/yt/yt-dlp/package.nix @@ -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; [ diff --git a/pkgs/development/libraries/astal/buildAstalModule.nix b/pkgs/development/libraries/astal/buildAstalModule.nix new file mode 100644 index 0000000000000..a29c5905db3bd --- /dev/null +++ b/pkgs/development/libraries/astal/buildAstalModule.nix @@ -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 diff --git a/pkgs/development/libraries/astal/default.nix b/pkgs/development/libraries/astal/default.nix new file mode 100644 index 0000000000000..9edaebb2a92ed --- /dev/null +++ b/pkgs/development/libraries/astal/default.nix @@ -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; }; +} diff --git a/pkgs/development/libraries/astal/modules/apps.nix b/pkgs/development/libraries/astal/modules/apps.nix new file mode 100644 index 0000000000000..b6f45ff9a6557 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/apps.nix @@ -0,0 +1,9 @@ +{ + buildAstalModule, + json-glib, +}: +buildAstalModule { + name = "apps"; + buildInputs = [ json-glib ]; + meta.description = "Astal module for application query"; +} diff --git a/pkgs/development/libraries/astal/modules/astal3.nix b/pkgs/development/libraries/astal/modules/astal3.nix new file mode 100644 index 0000000000000..85c6168885d5c --- /dev/null +++ b/pkgs/development/libraries/astal/modules/astal3.nix @@ -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"; +} diff --git a/pkgs/development/libraries/astal/modules/astal4.nix b/pkgs/development/libraries/astal/modules/astal4.nix new file mode 100644 index 0000000000000..7bdb7c67e5f27 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/astal4.nix @@ -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"; +} diff --git a/pkgs/development/libraries/astal/modules/auth.nix b/pkgs/development/libraries/astal/modules/auth.nix new file mode 100644 index 0000000000000..027cd3a198a71 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/auth.nix @@ -0,0 +1,9 @@ +{ + buildAstalModule, + pam, +}: +buildAstalModule { + name = "auth"; + buildInputs = [ pam ]; + meta.description = "Astal module for authentication using pam"; +} diff --git a/pkgs/development/libraries/astal/modules/battery.nix b/pkgs/development/libraries/astal/modules/battery.nix new file mode 100644 index 0000000000000..e2fc3474a046c --- /dev/null +++ b/pkgs/development/libraries/astal/modules/battery.nix @@ -0,0 +1,9 @@ +{ + buildAstalModule, + json-glib, +}: +buildAstalModule { + name = "battery"; + buildInputs = [ json-glib ]; + meta.description = "Astal module for upowerd devices (DBus proxy)"; +} diff --git a/pkgs/development/libraries/astal/modules/bluetooth.nix b/pkgs/development/libraries/astal/modules/bluetooth.nix new file mode 100644 index 0000000000000..64467f4a120c1 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/bluetooth.nix @@ -0,0 +1,5 @@ +{ buildAstalModule }: +buildAstalModule { + name = "bluetooth"; + meta.description = "Astal module for bluez using DBus"; +} diff --git a/pkgs/development/libraries/astal/modules/cava.nix b/pkgs/development/libraries/astal/modules/cava.nix new file mode 100644 index 0000000000000..f22ec48d033b6 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/cava.nix @@ -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 +} diff --git a/pkgs/development/libraries/astal/modules/gjs.nix b/pkgs/development/libraries/astal/modules/gjs.nix new file mode 100644 index 0000000000000..00e57c54417c7 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/gjs.nix @@ -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 = [ ]; + } diff --git a/pkgs/development/libraries/astal/modules/greet.nix b/pkgs/development/libraries/astal/modules/greet.nix new file mode 100644 index 0000000000000..20be11464cba5 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/greet.nix @@ -0,0 +1,6 @@ +{ buildAstalModule, json-glib }: +buildAstalModule { + name = "greet"; + buildInputs = [ json-glib ]; + meta.description = "Astal module for greetd using IPC"; +} diff --git a/pkgs/development/libraries/astal/modules/hyprland.nix b/pkgs/development/libraries/astal/modules/hyprland.nix new file mode 100644 index 0000000000000..a5c5038342f74 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/hyprland.nix @@ -0,0 +1,6 @@ +{ buildAstalModule, json-glib }: +buildAstalModule { + name = "hyprland"; + buildInputs = [ json-glib ]; + meta.description = "Astal module for Hyprland using IPC"; +} diff --git a/pkgs/development/libraries/astal/modules/io.nix b/pkgs/development/libraries/astal/modules/io.nix new file mode 100644 index 0000000000000..716430bdf5a19 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/io.nix @@ -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" ]; }; + } diff --git a/pkgs/development/libraries/astal/modules/mpris.nix b/pkgs/development/libraries/astal/modules/mpris.nix new file mode 100644 index 0000000000000..02fa7c0722650 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/mpris.nix @@ -0,0 +1,13 @@ +{ + buildAstalModule, + gvfs, + json-glib, +}: +buildAstalModule { + name = "mpris"; + buildInputs = [ + gvfs + json-glib + ]; + meta.description = "Astal module for mpris players"; +} diff --git a/pkgs/development/libraries/astal/modules/network.nix b/pkgs/development/libraries/astal/modules/network.nix new file mode 100644 index 0000000000000..efd84459c9f86 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/network.nix @@ -0,0 +1,6 @@ +{ buildAstalModule, networkmanager }: +buildAstalModule { + name = "network"; + buildInputs = [ networkmanager ]; + meta.description = "Astal module for NetworkManager"; +} diff --git a/pkgs/development/libraries/astal/modules/notifd.nix b/pkgs/development/libraries/astal/modules/notifd.nix new file mode 100644 index 0000000000000..a40e5c54091dc --- /dev/null +++ b/pkgs/development/libraries/astal/modules/notifd.nix @@ -0,0 +1,13 @@ +{ + buildAstalModule, + json-glib, + gdk-pixbuf, +}: +buildAstalModule { + name = "notifd"; + buildInputs = [ + json-glib + gdk-pixbuf + ]; + meta.description = "Astal module for notification daemon"; +} diff --git a/pkgs/development/libraries/astal/modules/powerprofiles.nix b/pkgs/development/libraries/astal/modules/powerprofiles.nix new file mode 100644 index 0000000000000..6eee36c2b6cf8 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/powerprofiles.nix @@ -0,0 +1,6 @@ +{ buildAstalModule, json-glib }: +buildAstalModule { + name = "powerprofiles"; + buildInputs = [ json-glib ]; + meta.description = "Astal module for upowerd profiles using DBus"; +} diff --git a/pkgs/development/libraries/astal/modules/river.nix b/pkgs/development/libraries/astal/modules/river.nix new file mode 100644 index 0000000000000..bed2492189fe1 --- /dev/null +++ b/pkgs/development/libraries/astal/modules/river.nix @@ -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 + ''; +} diff --git a/pkgs/development/libraries/astal/modules/tray.nix b/pkgs/development/libraries/astal/modules/tray.nix new file mode 100644 index 0000000000000..6ccf216fc029d --- /dev/null +++ b/pkgs/development/libraries/astal/modules/tray.nix @@ -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 +} diff --git a/pkgs/development/libraries/astal/modules/wireplumber.nix b/pkgs/development/libraries/astal/modules/wireplumber.nix new file mode 100644 index 0000000000000..1180bad621edc --- /dev/null +++ b/pkgs/development/libraries/astal/modules/wireplumber.nix @@ -0,0 +1,6 @@ +{ buildAstalModule, wireplumber }: +buildAstalModule { + name = "wireplumber"; + buildInputs = [ wireplumber ]; + meta.description = "Astal module for wireplumber"; +} diff --git a/pkgs/development/libraries/qtpbfimageplugin/default.nix b/pkgs/development/libraries/qtpbfimageplugin/default.nix index 9caa9b5af4de8..38629fe04c335 100644 --- a/pkgs/development/libraries/qtpbfimageplugin/default.nix +++ b/pkgs/development/libraries/qtpbfimageplugin/default.nix @@ -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"; diff --git a/pkgs/development/ocaml-modules/config-file/default.nix b/pkgs/development/ocaml-modules/config-file/default.nix index f20a7d9b113f6..4bb913d544bf4 100644 --- a/pkgs/development/ocaml-modules/config-file/default.nix +++ b/pkgs/development/ocaml-modules/config-file/default.nix @@ -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 ]; + }; + } diff --git a/pkgs/development/ocaml-modules/ulex/default.nix b/pkgs/development/ocaml-modules/ulex/default.nix index bbc26d8650f8f..ac98285c101f3 100644 --- a/pkgs/development/ocaml-modules/ulex/default.nix +++ b/pkgs/development/ocaml-modules/ulex/default.nix @@ -23,39 +23,43 @@ let }; in -stdenv.mkDerivation rec { - name = "ocaml${ocaml.version}-${pname}-${version}"; - inherit (param) version; - - src = fetchFromGitHub { - owner = "whitequark"; - repo = pname; - rev = "v${version}"; - inherit (param) sha256; - }; - - createFindlibDestdir = true; - - nativeBuildInputs = [ - ocaml - findlib - ocamlbuild - camlp4 - ]; - propagatedBuildInputs = [ camlp4 ]; - - strictDeps = true; - - 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 ]; - }; -} +lib.throwIf (lib.versionAtLeast ocaml.version "5.0") + "ulex is not available for OCaml ${ocaml.version}" + + stdenv.mkDerivation + rec { + name = "ocaml${ocaml.version}-${pname}-${version}"; + inherit (param) version; + + src = fetchFromGitHub { + owner = "whitequark"; + repo = pname; + rev = "v${version}"; + inherit (param) sha256; + }; + + createFindlibDestdir = true; + + nativeBuildInputs = [ + ocaml + findlib + ocamlbuild + camlp4 + ]; + propagatedBuildInputs = [ camlp4 ]; + + strictDeps = true; + + 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 ]; + }; + } diff --git a/pkgs/development/python-modules/aeppl/default.nix b/pkgs/development/python-modules/aeppl/default.nix deleted file mode 100644 index 62067166d5df0..0000000000000 --- a/pkgs/development/python-modules/aeppl/default.nix +++ /dev/null @@ -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 ]; - }; -} diff --git a/pkgs/development/python-modules/aesara/default.nix b/pkgs/development/python-modules/aesara/default.nix deleted file mode 100644 index d74c962883350..0000000000000 --- a/pkgs/development/python-modules/aesara/default.nix +++ /dev/null @@ -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 - "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); - }; -} diff --git a/pkgs/development/python-modules/lomond/default.nix b/pkgs/development/python-modules/lomond/default.nix index 58e560c43e6dd..7df0b38d54fee 100644 --- a/pkgs/development/python-modules/lomond/default.nix +++ b/pkgs/development/python-modules/lomond/default.nix @@ -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" ]; diff --git a/pkgs/development/python-modules/tornado/4.nix b/pkgs/development/python-modules/tornado/4.nix deleted file mode 100644 index 0381e25d953e8..0000000000000 --- a/pkgs/development/python-modules/tornado/4.nix +++ /dev/null @@ -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; - }; -} diff --git a/pkgs/development/python-modules/tornado/5.nix b/pkgs/development/python-modules/tornado/5.nix deleted file mode 100644 index a1b0d8979e208..0000000000000 --- a/pkgs/development/python-modules/tornado/5.nix +++ /dev/null @@ -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; - }; -} diff --git a/pkgs/development/tools/continuous-integration/woodpecker/common.nix b/pkgs/development/tools/continuous-integration/woodpecker/common.nix index 67875a83fe413..22d8adaf24544 100644 --- a/pkgs/development/tools/continuous-integration/woodpecker/common.nix +++ b/pkgs/development/tools/continuous-integration/woodpecker/common.nix @@ -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 diff --git a/pkgs/development/tools/ocaml/camlp4/default.nix b/pkgs/development/tools/ocaml/camlp4/default.nix index ac76bfba3f329..89cdc1eb6ec33 100644 --- a/pkgs/development/tools/ocaml/camlp4/default.nix +++ b/pkgs/development/tools/ocaml/camlp4/default.nix @@ -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 ]; diff --git a/pkgs/games/cataclysm-dda/common.nix b/pkgs/games/cataclysm-dda/common.nix index 268f5d5256d28..3388db143852f 100644 --- a/pkgs/games/cataclysm-dda/common.nix +++ b/pkgs/games/cataclysm-dda/common.nix @@ -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 + ]; + + cursesDeps = commonDeps ++ [ ncurses ]; - tilesDeps = [ SDL2 SDL2_image SDL2_mixer SDL2_ttf freetype ] - ++ optionals stdenv.hostPlatform.isDarwin [ Cocoa ]; + 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 diff --git a/pkgs/games/cataclysm-dda/default.nix b/pkgs/games/cataclysm-dda/default.nix index a42d4bf87f4dd..3502d7c0fb54a 100644 --- a/pkgs/games/cataclysm-dda/default.nix +++ b/pkgs/games/cataclysm-dda/default.nix @@ -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; }; }; diff --git a/pkgs/games/cataclysm-dda/git.nix b/pkgs/games/cataclysm-dda/git.nix index 495d5f97fb099..cc79728f29614 100644 --- a/pkgs/games/cataclysm-dda/git.nix +++ b/pkgs/games/cataclysm-dda/git.nix @@ -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 { diff --git a/pkgs/games/cataclysm-dda/glibc-2.39.diff b/pkgs/games/cataclysm-dda/glibc-2.39.diff deleted file mode 100644 index edc79ce76d79c..0000000000000 --- a/pkgs/games/cataclysm-dda/glibc-2.39.diff +++ /dev/null @@ -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 buffer( 512 ); - std::string output; - try { -- std::unique_ptr pipe( popen( command.c_str(), "r" ), pclose ); -+ std::unique_ptr pipe( popen( command.c_str(), "r" ) ); - if( pipe ) { - while( fgets( buffer.data(), buffer.size(), pipe.get() ) != nullptr ) { - output += buffer.data(); diff --git a/pkgs/games/cataclysm-dda/locale-path-git.patch b/pkgs/games/cataclysm-dda/locale-path-git.patch index 8f18b0ffb71ed..480f7107946e0 100644 --- a/pkgs/games/cataclysm-dda/locale-path-git.patch +++ b/pkgs/games/cataclysm-dda/locale-path-git.patch @@ -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(); } diff --git a/pkgs/games/cataclysm-dda/locale-path.patch b/pkgs/games/cataclysm-dda/locale-path.patch index 03f103a548fdd..8f18b0ffb71ed 100644 --- a/pkgs/games/cataclysm-dda/locale-path.patch +++ b/pkgs/games/cataclysm-dda/locale-path.patch @@ -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 { diff --git a/pkgs/games/cataclysm-dda/stable.nix b/pkgs/games/cataclysm-dda/stable.nix index 5c3ccb4bf2876..105d30346dbdf 100644 --- a/pkgs/games/cataclysm-dda/stable.nix +++ b/pkgs/games/cataclysm-dda/stable.nix @@ -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 = [ - # 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="; - }) + # fix compilation of the vendored flatbuffers under gcc14 (fetchpatch { - url = "https://sources.debian.org/data/main/c/cataclysm-dda/0.G-4/debian/patches/gcc13-keyword-requires.patch"; - hash = "sha256-8yvHh0YKC7AC/qzia7AZAfMewMC0RiSepMXpOkMXRd8="; + name = "fix-flatbuffers-with-gcc14"; + url = "https://github.com/CleverRaven/Cataclysm-DDA/commit/1400b1018ff37196bd24ba4365bd50beb571ac14.patch"; + hash = "sha256-H0jct6lSQxu48eOZ4f8HICxo89qX49Ksw+Xwwtp7iFM="; }) - # 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" + # Unconditionally look for translation files in $out/share/locale + ./locale-path.patch ]; meta = common.meta // { - maintainers = with lib.maintainers; - common.meta.maintainers; changelog = "https://github.com/CleverRaven/Cataclysm-DDA/blob/${version}/data/changelog.txt"; }; }); diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index a53140462e0de..7059353f9d83d 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -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. diff --git a/pkgs/top-level/python-aliases.nix b/pkgs/top-level/python-aliases.nix index 8bd8f32db7a3b..d0615eaed2ca7 100644 --- a/pkgs/top-level/python-aliases.nix +++ b/pkgs/top-level/python-aliases.nix @@ -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 diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 7572954ba7622..a9080f17a4197 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -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 { };