Merge staging-next into staging
This commit is contained in:
commit
367477b054
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -49,7 +49,7 @@ jobs:
|
||||
mergedSha: ${{ inputs.mergedSha }}
|
||||
merged-as-untrusted: true
|
||||
|
||||
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
|
4
.github/workflows/codeowners-v2.yml
vendored
4
.github/workflows/codeowners-v2.yml
vendored
@ -59,7 +59,7 @@ jobs:
|
||||
merged-as-untrusted: true
|
||||
target-as-trusted: true
|
||||
|
||||
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
@ -107,7 +107,7 @@ jobs:
|
||||
name: Request
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
|
||||
# Important: Because we use pull_request_target, this checks out the base branch of the PR, not the PR head.
|
||||
# This is intentional, because we need to request the review of owners as declared in the base branch.
|
||||
|
6
.github/workflows/eval.yml
vendored
6
.github/workflows/eval.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
path: untrusted
|
||||
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
@ -166,7 +166,7 @@ jobs:
|
||||
path: trusted
|
||||
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
@ -243,7 +243,7 @@ jobs:
|
||||
merged-as-untrusted: true
|
||||
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
|
6
.github/workflows/lint.yml
vendored
6
.github/workflows/lint.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
||||
mergedSha: ${{ inputs.mergedSha }}
|
||||
merged-as-untrusted: true
|
||||
|
||||
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
@ -61,7 +61,7 @@ jobs:
|
||||
mergedSha: ${{ inputs.mergedSha }}
|
||||
merged-as-untrusted: true
|
||||
|
||||
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
@ -86,7 +86,7 @@ jobs:
|
||||
targetSha: ${{ inputs.targetSha }}
|
||||
target-as-trusted: true
|
||||
|
||||
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
|
2
.github/workflows/reviewers.yml
vendored
2
.github/workflows/reviewers.yml
vendored
@ -35,7 +35,7 @@ jobs:
|
||||
sparse-checkout: ci
|
||||
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
|
||||
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
|
||||
with:
|
||||
extra_nix_config: sandbox = true
|
||||
|
||||
|
@ -27506,6 +27506,11 @@
|
||||
github = "yanganto";
|
||||
githubId = 10803111;
|
||||
};
|
||||
yannham = {
|
||||
github = "yannham";
|
||||
githubId = 6530104;
|
||||
name = "Yann Hamdaoui";
|
||||
};
|
||||
yannickulrich = {
|
||||
email = "yannick.ulrich@proton.me";
|
||||
github = "yannickulrich";
|
||||
|
@ -45,6 +45,7 @@ lpeg,,,,,,vyp
|
||||
lpeg_patterns,,,,,,
|
||||
lpeglabel,,,,1.6.0,,
|
||||
lrexlib-gnu,,,,,,
|
||||
lrexlib-oniguruma,,,,,,junestepp
|
||||
lrexlib-pcre,,,,,,vyp
|
||||
lrexlib-posix,,,,,,
|
||||
lsp-progress.nvim,,,,,,gepbird
|
||||
|
|
@ -630,6 +630,7 @@ with lib.maintainers;
|
||||
leona
|
||||
theCapypara
|
||||
thiagokokada
|
||||
jamesward
|
||||
];
|
||||
shortName = "Jetbrains";
|
||||
scope = "Maintainers of the Jetbrains IDEs in nixpkgs";
|
||||
|
@ -42,6 +42,8 @@
|
||||
|
||||
- [Szurubooru](https://github.com/rr-/szurubooru), an image board engine inspired by services such as Danbooru, dedicated for small and medium communities. Available as [services.szurubooru](#opt-services.szurubooru.enable).
|
||||
|
||||
- The [Neat IP Address Planner](https://spritelink.github.io/NIPAP/) (NIPAP) can now be enabled through [services.nipap.enable](#opt-services.nipap.enable).
|
||||
|
||||
- [nix-store-veritysetup](https://github.com/nikstur/nix-store-veritysetup-generator), a systemd generator to unlock the Nix Store as a dm-verity protected block device. Available as [boot.initrd.nix-store-veritysetup](options.html#opt-boot.initrd.nix-store-veritysetup.enable).
|
||||
|
||||
- [SuiteNumérique Docs](https://github.com/suitenumerique/docs), a collaborative note taking, wiki and documentation web platform and alternative to Notion or Outline. Available as [services.lasuite-docs](#opt-services.lasuite-docs.enable).
|
||||
|
@ -1618,6 +1618,7 @@
|
||||
./services/web-apps/nextjs-ollama-llm-ui.nix
|
||||
./services/web-apps/nexus.nix
|
||||
./services/web-apps/nifi.nix
|
||||
./services/web-apps/nipap.nix
|
||||
./services/web-apps/node-red.nix
|
||||
./services/web-apps/nostr-rs-relay.nix
|
||||
./services/web-apps/ocis.nix
|
||||
|
331
nixos/modules/services/web-apps/nipap.nix
Normal file
331
nixos/modules/services/web-apps/nipap.nix
Normal file
@ -0,0 +1,331 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.services.nipap;
|
||||
iniFmt = pkgs.formats.ini { };
|
||||
|
||||
configFile = iniFmt.generate "nipap.conf" cfg.settings;
|
||||
|
||||
defaultUser = "nipap";
|
||||
defaultAuthBackend = "local";
|
||||
dataDir = "/var/lib/nipap";
|
||||
|
||||
defaultServiceConfig = {
|
||||
WorkingDirectory = dataDir;
|
||||
User = cfg.user;
|
||||
Group = config.users.users."${cfg.user}".group;
|
||||
Restart = "on-failure";
|
||||
RestartSec = 30;
|
||||
};
|
||||
|
||||
escapedHost = host: if lib.hasInfix ":" host then "[${host}]" else host;
|
||||
in
|
||||
{
|
||||
options.services.nipap = {
|
||||
enable = lib.mkEnableOption "global Neat IP Address Planner (NIPAP) configuration";
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "User to use for running NIPAP services.";
|
||||
default = defaultUser;
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
description = ''
|
||||
Configuration options to set in /etc/nipap/nipap.conf.
|
||||
'';
|
||||
|
||||
default = { };
|
||||
|
||||
type = lib.types.submodule {
|
||||
freeformType = iniFmt.type;
|
||||
|
||||
options = {
|
||||
nipapd = {
|
||||
listen = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "::1";
|
||||
description = "IP address to bind nipapd to.";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 1337;
|
||||
description = "Port to bind nipapd to.";
|
||||
};
|
||||
|
||||
foreground = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Remain in foreground rather than forking to background.";
|
||||
};
|
||||
debug = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Enable debug logging.";
|
||||
};
|
||||
|
||||
db_host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "";
|
||||
description = "PostgreSQL host to connect to. Empty means use UNIX socket.";
|
||||
};
|
||||
db_name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = cfg.user;
|
||||
defaultText = defaultUser;
|
||||
description = "Name of database to use on PostgreSQL server.";
|
||||
};
|
||||
};
|
||||
|
||||
auth = {
|
||||
default_backend = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultAuthBackend;
|
||||
description = "Name of auth backend to use by default.";
|
||||
};
|
||||
auth_cache_timeout = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 3600;
|
||||
description = "Seconds to store cached auth entries for.";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
authBackendSettings = lib.mkOption {
|
||||
description = ''
|
||||
auth.backends options to set in /etc/nipap/nipap.conf.
|
||||
'';
|
||||
|
||||
default = {
|
||||
"${defaultAuthBackend}" = {
|
||||
type = "SqliteAuth";
|
||||
db_path = "${dataDir}/local_auth.db";
|
||||
};
|
||||
};
|
||||
|
||||
type = lib.types.submodule {
|
||||
freeformType = iniFmt.type;
|
||||
};
|
||||
};
|
||||
|
||||
nipapd = {
|
||||
enable = lib.mkEnableOption "nipapd server";
|
||||
package = lib.mkPackageOption pkgs "nipap" { };
|
||||
|
||||
database.createLocally = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Create a nipap database automatically.";
|
||||
};
|
||||
};
|
||||
|
||||
nipap-www = {
|
||||
enable = lib.mkEnableOption "nipap-www server";
|
||||
package = lib.mkPackageOption pkgs "nipap-www" { };
|
||||
|
||||
xmlrpcURIFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = "Path to file containing XMLRPC URI for use by web UI - this is a secret, since it contains auth credentials. If null, it will be initialized assuming that the auth database is local.";
|
||||
};
|
||||
|
||||
workers = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 4;
|
||||
description = "Number of worker processes for Gunicorn to fork.";
|
||||
};
|
||||
umask = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0";
|
||||
description = "umask for files written by Gunicorn, including UNIX socket.";
|
||||
};
|
||||
|
||||
unixSocket = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Path to UNIX socket to bind to.";
|
||||
example = "/run/nipap/nipap-www.sock";
|
||||
};
|
||||
host = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "::";
|
||||
description = "Host to bind to.";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.port;
|
||||
default = 21337;
|
||||
description = "Port to bind to.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable (
|
||||
lib.mkMerge [
|
||||
{
|
||||
systemd.tmpfiles.rules = [
|
||||
"d '${dataDir}' - ${cfg.user} ${config.users.users."${cfg.user}".group} - -"
|
||||
];
|
||||
|
||||
environment.etc."nipap/nipap.conf" = {
|
||||
source = configFile;
|
||||
};
|
||||
|
||||
services.nipap.settings = lib.attrsets.mapAttrs' (name: value: {
|
||||
name = "auth.backends.${name}";
|
||||
inherit value;
|
||||
}) cfg.authBackendSettings;
|
||||
|
||||
services.nipap.nipapd.enable = lib.mkDefault true;
|
||||
services.nipap.nipap-www.enable = lib.mkDefault true;
|
||||
|
||||
environment.systemPackages = [
|
||||
cfg.nipapd.package
|
||||
];
|
||||
}
|
||||
(lib.mkIf (cfg.user == defaultUser) {
|
||||
users.users."${defaultUser}" = {
|
||||
isSystemUser = true;
|
||||
group = defaultUser;
|
||||
home = dataDir;
|
||||
};
|
||||
users.groups."${defaultUser}" = { };
|
||||
})
|
||||
(lib.mkIf (cfg.nipapd.enable && cfg.nipapd.database.createLocally) {
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
extensions = ps: with ps; [ ip4r ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = cfg.user;
|
||||
}
|
||||
];
|
||||
ensureDatabases = [ cfg.settings.nipapd.db_name ];
|
||||
};
|
||||
|
||||
systemd.services.postgresql.serviceConfig.ExecStartPost =
|
||||
let
|
||||
sqlFile = pkgs.writeText "nipapd-setup.sql" ''
|
||||
CREATE EXTENSION IF NOT EXISTS ip4r;
|
||||
|
||||
ALTER SCHEMA public OWNER TO "${cfg.user}";
|
||||
ALTER DATABASE "${cfg.settings.nipapd.db_name}" OWNER TO "${cfg.user}";
|
||||
'';
|
||||
in
|
||||
[
|
||||
''
|
||||
${lib.getExe' config.services.postgresql.finalPackage "psql"} -d "${cfg.settings.nipapd.db_name}" -f "${sqlFile}"
|
||||
''
|
||||
];
|
||||
})
|
||||
(lib.mkIf cfg.nipapd.enable {
|
||||
systemd.services.nipapd =
|
||||
let
|
||||
pkg = cfg.nipapd.package;
|
||||
in
|
||||
{
|
||||
description = "Neat IP Address Planner";
|
||||
after = [
|
||||
"network.target"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
] ++ lib.optional (cfg.settings.nipapd.db_host == "") "postgresql.service";
|
||||
requires = lib.optional (cfg.settings.nipapd.db_host == "") "postgresql.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
preStart = lib.optionalString (cfg.settings.auth.default_backend == defaultAuthBackend) ''
|
||||
# Create/upgrade local auth database
|
||||
umask 077
|
||||
${pkg}/bin/nipap-passwd create-database >/dev/null 2>&1
|
||||
${pkg}/bin/nipap-passwd upgrade-database >/dev/null 2>&1
|
||||
'';
|
||||
serviceConfig = defaultServiceConfig // {
|
||||
KillSignal = "SIGINT";
|
||||
ExecStart = ''
|
||||
${pkg}/bin/nipapd \
|
||||
--auto-install-db \
|
||||
--auto-upgrade-db \
|
||||
--foreground \
|
||||
--no-pid-file
|
||||
'';
|
||||
};
|
||||
};
|
||||
})
|
||||
(lib.mkIf cfg.nipap-www.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
cfg.nipap-www.xmlrpcURIFile == null -> cfg.settings.auth.default_backend == defaultAuthBackend;
|
||||
message = "If no XMLRPC URI secret file is specified, then the default auth backend must be in use to automatically generate credentials.";
|
||||
}
|
||||
];
|
||||
|
||||
# Ensure that _something_ exists in the [www] group.
|
||||
services.nipap.settings.www = lib.mkDefault { };
|
||||
|
||||
systemd.services.nipap-www =
|
||||
let
|
||||
pkg = cfg.nipap-www.package;
|
||||
in
|
||||
{
|
||||
description = "Neat IP Address Planner web server";
|
||||
after = [
|
||||
"network.target"
|
||||
"systemd-tmpfiles-setup.service"
|
||||
] ++ lib.optional cfg.nipapd.enable "nipapd.service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = {
|
||||
PYTHONPATH = pkg.pythonPath;
|
||||
};
|
||||
serviceConfig = defaultServiceConfig;
|
||||
script =
|
||||
let
|
||||
bind =
|
||||
if cfg.nipap-www.unixSocket != null then
|
||||
"unix:${cfg.nipap-www.unixSocket}"
|
||||
else
|
||||
"${escapedHost cfg.nipap-www.host}:${toString cfg.nipap-www.port}";
|
||||
generateXMLRPC = cfg.nipap-www.xmlrpcURIFile == null;
|
||||
xmlrpcURIFile = if generateXMLRPC then "${dataDir}/www_xmlrpc_uri" else cfg.nipap-www.xmlrpcURIFile;
|
||||
in
|
||||
''
|
||||
test -f "${dataDir}/www_secret" || {
|
||||
umask 0077
|
||||
${pkg.python}/bin/python -c "import secrets; print(secrets.token_hex())" > "${dataDir}/www_secret"
|
||||
}
|
||||
export FLASK_SECRET_KEY="$(cat "${dataDir}/www_secret")"
|
||||
|
||||
# Ensure that we have an XMLRPC URI.
|
||||
${
|
||||
if generateXMLRPC then
|
||||
''
|
||||
test -f "${dataDir}/www_xmlrpc_uri" || {
|
||||
umask 0077
|
||||
www_password="$(${pkg.python}/bin/python -c "import secrets; print(secrets.token_hex())")"
|
||||
${cfg.nipapd.package}/bin/nipap-passwd add --username nipap-www --password "''${www_password}" --name "User account for the web UI" --trusted
|
||||
|
||||
echo "http://nipap-www@${defaultAuthBackend}:''${www_password}@${escapedHost cfg.settings.nipapd.listen}:${toString cfg.settings.nipapd.port}" > "${xmlrpcURIFile}"
|
||||
}
|
||||
''
|
||||
else
|
||||
""
|
||||
}
|
||||
export FLASK_XMLRPC_URI="$(cat "${xmlrpcURIFile}")"
|
||||
|
||||
exec "${pkg.gunicorn}/bin/gunicorn" \
|
||||
--preload --workers ${toString cfg.nipap-www.workers} \
|
||||
--pythonpath "${pkg}/${pkg.python.sitePackages}" \
|
||||
--bind ${bind} --umask ${cfg.nipap-www.umask} \
|
||||
"nipapwww:create_app()"
|
||||
'';
|
||||
};
|
||||
})
|
||||
]
|
||||
);
|
||||
|
||||
meta.maintainers = with lib.maintainers; [ lukegb ];
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
let
|
||||
cfg = config.virtualisation.waydroid;
|
||||
kCfg = config.lib.kernelConfig;
|
||||
kernelPackages = config.boot.kernelPackages;
|
||||
waydroidGbinderConf = pkgs.writeText "waydroid.conf" ''
|
||||
[Protocol]
|
||||
/dev/binder = aidl2
|
||||
@ -26,6 +25,7 @@ in
|
||||
|
||||
options.virtualisation.waydroid = {
|
||||
enable = lib.mkEnableOption "Waydroid";
|
||||
package = lib.mkPackageOption pkgs "waydroid" { };
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
@ -49,7 +49,7 @@ in
|
||||
|
||||
environment.etc."gbinder.d/waydroid.conf".source = waydroidGbinderConf;
|
||||
|
||||
environment.systemPackages = with pkgs; [ waydroid ];
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
networking.firewall.trustedInterfaces = [ "waydroid0" ];
|
||||
|
||||
@ -63,7 +63,7 @@ in
|
||||
serviceConfig = {
|
||||
Type = "dbus";
|
||||
UMask = "0022";
|
||||
ExecStart = "${pkgs.waydroid}/bin/waydroid -w container start";
|
||||
ExecStart = "${cfg.package}/bin/waydroid -w container start";
|
||||
BusName = "id.waydro.Container";
|
||||
};
|
||||
};
|
||||
@ -72,7 +72,7 @@ in
|
||||
"d /var/lib/misc 0755 root root -" # for dnsmasq.leases
|
||||
];
|
||||
|
||||
services.dbus.packages = with pkgs; [ waydroid ];
|
||||
services.dbus.packages = [ cfg.package ];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -946,6 +946,7 @@ in
|
||||
nginx-unix-socket = runTest ./nginx-unix-socket.nix;
|
||||
nginx-variants = import ./nginx-variants.nix { inherit pkgs runTest; };
|
||||
nifi = runTestOn [ "x86_64-linux" ] ./web-apps/nifi.nix;
|
||||
nipap = runTest ./web-apps/nipap.nix;
|
||||
nitter = runTest ./nitter.nix;
|
||||
nix-config = runTest ./nix-config.nix;
|
||||
nix-ld = runTest ./nix-ld.nix;
|
||||
|
69
nixos/tests/web-apps/nipap.nix
Normal file
69
nixos/tests/web-apps/nipap.nix
Normal file
@ -0,0 +1,69 @@
|
||||
{ pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
nipapRc = pkgs.writeText "nipaprc" ''
|
||||
[global]
|
||||
hostname = [::1]
|
||||
port = 1337
|
||||
username = nixostest
|
||||
password = nIx0st3st
|
||||
default_vrf_rt = -
|
||||
default_list_vrf_rt = all
|
||||
'';
|
||||
in
|
||||
{
|
||||
name = "lukegb";
|
||||
meta.maintainers = [ lib.maintainers.lukegb ];
|
||||
|
||||
nodes.main =
|
||||
{ ... }:
|
||||
{
|
||||
services.nipap = {
|
||||
enable = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.nipap-cli
|
||||
];
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
main.wait_for_unit("nipapd.service")
|
||||
main.wait_for_unit("nipap-www.service")
|
||||
|
||||
# Make sure the web UI is up.
|
||||
main.wait_for_open_port(21337)
|
||||
main.succeed("curl -fvvv -Ls http://localhost:21337/ | grep 'NIPAP'")
|
||||
|
||||
# Check that none of the files we created in /var/lib/nipap are readable.
|
||||
out = main.succeed("ls -l /var/lib/nipap")
|
||||
bad_perms = False
|
||||
for ln in out.split("\n"):
|
||||
ln = ln.strip()
|
||||
if not ln or ln.startswith('total '):
|
||||
continue
|
||||
if not ln.startswith('-rw------- '):
|
||||
print(f"Bad file permissions: {ln}")
|
||||
bad_perms = True
|
||||
if bad_perms:
|
||||
t.fail("One or more files were overly permissive.")
|
||||
|
||||
# Check we created a web-frontend user.
|
||||
main.succeed("nipap-passwd list | grep nipap-www")
|
||||
|
||||
# Create a test user
|
||||
main.succeed("nipap-passwd add -u nixostest -p nIx0st3st -n 'NixOS Test User'")
|
||||
|
||||
# Try to log in with it on the web frontend
|
||||
main.succeed("curl -fvvv -Ls -b \"\" -d username=nixostest -d password=nIx0st3st http://localhost:21337/auth/login | grep 'PrefixListController'")
|
||||
|
||||
# Try to log in with it using the CLI
|
||||
main.copy_from_host("${nipapRc}", "/root/.nipaprc")
|
||||
main.succeed("chmod u=rw,go= /root/.nipaprc")
|
||||
main.succeed("nipap address add prefix 192.0.2.0/24 type assignment description RFC1166")
|
||||
main.succeed("nipap address add prefix 192.0.2.1/32 type host description 'test host'")
|
||||
main.succeed("nipap address add prefix 2001:db8::/32 type reservation description RFC3849")
|
||||
main.succeed("nipap address add prefix 2001:db8:f00f::/48 type assignment description 'eye pee vee six'")
|
||||
main.succeed("nipap address add prefix 2001:db8:f00f:face:dead:beef:cafe:feed/128 type host description 'test host 2'")
|
||||
'';
|
||||
}
|
@ -1,15 +1,13 @@
|
||||
{
|
||||
lib,
|
||||
fetchFromGitLab,
|
||||
stdenv,
|
||||
glib,
|
||||
gtk3,
|
||||
gobject-introspection,
|
||||
meson,
|
||||
ninja,
|
||||
pkg-config,
|
||||
gobject-introspection,
|
||||
vala,
|
||||
stdenv,
|
||||
wrapGAppsHook3,
|
||||
}:
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "appmenu-glib-translator";
|
||||
@ -19,7 +17,6 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
owner = "vala-panel-project";
|
||||
repo = "vala-panel-appmenu";
|
||||
tag = finalAttrs.version;
|
||||
fetchSubmodules = true;
|
||||
hash = "sha256-v5J3nwViNiSKRPdJr+lhNUdKaPG82fShPDlnmix5tlY=";
|
||||
};
|
||||
|
||||
@ -30,19 +27,15 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
ninja
|
||||
|
||||
pkg-config
|
||||
wrapGAppsHook3
|
||||
gobject-introspection
|
||||
vala
|
||||
];
|
||||
|
||||
buildInputs = [
|
||||
glib
|
||||
gobject-introspection
|
||||
gtk3
|
||||
];
|
||||
propagatedBuildInputs = [ glib ];
|
||||
|
||||
meta = {
|
||||
description = "GTK module that strips menus from all GTK programs, converts to MenuModel and sends to AppMenu";
|
||||
homepage = "https://gitlab.com/vala-panel-project/vala-panel-appmenu/-/tree/${finalAttrs.version}/subprojects/appmenu-gtk-module";
|
||||
description = "Library for translating from DBusMenu to GMenuModel";
|
||||
homepage = "https://gitlab.com/vala-panel-project/vala-panel-appmenu/-/tree/${finalAttrs.version}/subprojects/appmenu-glib-translator";
|
||||
license = lib.licenses.lgpl3Plus;
|
||||
maintainers = with lib.maintainers; [ perchun ];
|
||||
platforms = lib.platforms.linux;
|
||||
|
75
pkgs/by-name/br/bruijn/generated.nix
Normal file
75
pkgs/by-name/br/bruijn/generated.nix
Normal file
@ -0,0 +1,75 @@
|
||||
{
|
||||
mkDerivation,
|
||||
array,
|
||||
base,
|
||||
binary,
|
||||
bitstring,
|
||||
bytestring,
|
||||
clock,
|
||||
containers,
|
||||
deepseq,
|
||||
directory,
|
||||
fetchzip,
|
||||
filepath,
|
||||
haskeline,
|
||||
lib,
|
||||
megaparsec,
|
||||
mtl,
|
||||
optparse-applicative,
|
||||
process,
|
||||
random,
|
||||
time,
|
||||
}:
|
||||
mkDerivation {
|
||||
pname = "bruijn";
|
||||
version = "0.1.0.0";
|
||||
src = fetchzip {
|
||||
url = "https://github.com/marvinborner/bruijn/archive/d60ad52f135370635db3a2db3363005670af14b8.tar.gz";
|
||||
sha256 = "182v56vc71467q8x7bp83ch6wp3kv5wgxrm53l2vvnvfqyqswpi2";
|
||||
};
|
||||
isLibrary = true;
|
||||
isExecutable = true;
|
||||
enableSeparateDataOutput = true;
|
||||
libraryHaskellDepends = [
|
||||
array
|
||||
base
|
||||
binary
|
||||
bitstring
|
||||
bytestring
|
||||
clock
|
||||
containers
|
||||
deepseq
|
||||
directory
|
||||
filepath
|
||||
haskeline
|
||||
megaparsec
|
||||
mtl
|
||||
optparse-applicative
|
||||
process
|
||||
random
|
||||
time
|
||||
];
|
||||
executableHaskellDepends = [
|
||||
array
|
||||
base
|
||||
binary
|
||||
bitstring
|
||||
bytestring
|
||||
clock
|
||||
containers
|
||||
deepseq
|
||||
directory
|
||||
filepath
|
||||
haskeline
|
||||
megaparsec
|
||||
mtl
|
||||
optparse-applicative
|
||||
process
|
||||
random
|
||||
time
|
||||
];
|
||||
homepage = "https://github.com/githubuser/bruijn#readme";
|
||||
license = lib.licenses.mit;
|
||||
mainProgram = "bruijn";
|
||||
maintainers = [ lib.maintainers.defelo ];
|
||||
}
|
25
pkgs/by-name/br/bruijn/package.nix
Normal file
25
pkgs/by-name/br/bruijn/package.nix
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
haskell,
|
||||
haskellPackages,
|
||||
lib,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (haskell.lib.compose) justStaticExecutables overrideCabal;
|
||||
|
||||
generated = haskellPackages.callPackage ./generated.nix { };
|
||||
|
||||
overrides = {
|
||||
version = lib.fileContents ./version.txt;
|
||||
|
||||
passthru.updateScript = ./update.sh;
|
||||
|
||||
description = "Purely functional programming language based on lambda calculus and de Bruijn indices";
|
||||
homepage = "https://bruijn.marvinborner.de/";
|
||||
};
|
||||
in
|
||||
|
||||
lib.pipe generated [
|
||||
(overrideCabal overrides)
|
||||
justStaticExecutables
|
||||
]
|
16
pkgs/by-name/br/bruijn/update.sh
Executable file
16
pkgs/by-name/br/bruijn/update.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i bash -p coreutils cabal2nix curl jq nixfmt-rfc-style
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||
|
||||
{ read -r rev; read -r committer_date; } \
|
||||
< <(curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} -sfL https://api.github.com/repos/marvinborner/bruijn/branches/main \
|
||||
| jq -r '.commit | .sha, .commit.committer.date')
|
||||
|
||||
cabal2nix --maintainer defelo "https://github.com/marvinborner/bruijn/archive/${rev}.tar.gz" \
|
||||
| nixfmt \
|
||||
> generated.nix
|
||||
|
||||
echo "0-unstable-$(date -I --date="$committer_date")" > version.txt
|
1
pkgs/by-name/br/bruijn/version.txt
Normal file
1
pkgs/by-name/br/bruijn/version.txt
Normal file
@ -0,0 +1 @@
|
||||
0-unstable-2025-06-23
|
@ -10,15 +10,15 @@
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "cargo-show-asm";
|
||||
version = "0.2.49";
|
||||
version = "0.2.50";
|
||||
|
||||
src = fetchCrate {
|
||||
inherit pname version;
|
||||
hash = "sha256-DH3jE7nGdwIQVHk80EsC4gYh5+wk6VMWS0d+jZYnX1I=";
|
||||
hash = "sha256-BmRcaZKAWwRJQyVsymudDg6l7O9pcE2s+Y9VgaJ/Q48=";
|
||||
};
|
||||
|
||||
useFetchCargoVendor = true;
|
||||
cargoHash = "sha256-R+I6EVzHvI1Et4nvxENc3IvfmSLr/g77x4wCMNb2R88=";
|
||||
cargoHash = "sha256-+NOk3lzBsgPs1AIUfwWP4sOKSV3XPZsPxl0QNPXPgZQ=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
installShellFiles
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
rustPlatform.buildRustPackage {
|
||||
pname = "crosvm";
|
||||
version = "0-unstable-2025-06-06";
|
||||
version = "0-unstable-2025-06-17";
|
||||
|
||||
src = fetchgit {
|
||||
url = "https://chromium.googlesource.com/chromiumos/platform/crosvm";
|
||||
rev = "7083e31d219cdcd57866c70144e1b39ddc008f0f";
|
||||
hash = "sha256-oZR4UcN8lDoqNoUFGLbIDDRO55noDX0xMWa8W0DbVl4=";
|
||||
rev = "49e226a57f905b00e44a996c93d9a2439dcb86f3";
|
||||
hash = "sha256-+HtF9nBv6unnrav5Z84xSOhK+RrlOFBHed6SiuHAcfs=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "expected-lite";
|
||||
version = "0.8.0";
|
||||
version = "0.9.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "martinmoene";
|
||||
repo = "expected-lite";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-8Lf+R7wC7f2YliXqhR6pwVVSLZ6qheu7YOV5jHc0Cjc=";
|
||||
hash = "sha256-LRXxUaDQT5q9dXK2uYFvCgEuGWEHKr95lfdGTGjke0g=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -13,13 +13,13 @@
|
||||
|
||||
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
pname = "firefly-iii";
|
||||
version = "6.2.17";
|
||||
version = "6.2.18";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "firefly-iii";
|
||||
repo = "firefly-iii";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-g/mGCc7JxfWrbrh14OXaKgn0rjf4RMNL2NI4GzrphaY=";
|
||||
hash = "sha256-QQlfUbDanyj3n0EOhPxfMqsrl9laQq2CQbwRY4/gH8k=";
|
||||
};
|
||||
|
||||
buildInputs = [ php84 ];
|
||||
@ -38,13 +38,13 @@ stdenvNoCC.mkDerivation (finalAttrs: {
|
||||
composerNoScripts = true;
|
||||
composerStrictValidation = true;
|
||||
strictDeps = true;
|
||||
vendorHash = "sha256-2GvBlKRTqehD7eVpEGd9zBoiom30DRMqatyHNF4eDiU=";
|
||||
vendorHash = "sha256-h/DWKOlffEBWZhdf5iQf4f33IK+1Ie289Oqjb7GHfVY=";
|
||||
};
|
||||
|
||||
npmDeps = fetchNpmDeps {
|
||||
inherit (finalAttrs) src;
|
||||
name = "${finalAttrs.pname}-npm-deps";
|
||||
hash = "sha256-uZluWsHpbD2lMG/yNoZxry5X+Hiv3z/H4KqV7pydu/A=";
|
||||
hash = "sha256-YbMUM+fXIuXVrv7QMlPklct3mDHI05PoOW+fgHf8c3I=";
|
||||
};
|
||||
|
||||
preInstall = ''
|
||||
|
@ -35,18 +35,18 @@ let
|
||||
in
|
||||
buildGoModule rec {
|
||||
pname = "gitea";
|
||||
version = "1.24.0";
|
||||
version = "1.24.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "go-gitea";
|
||||
repo = "gitea";
|
||||
tag = "v${gitea.version}";
|
||||
hash = "sha256-lKeqoNL6RMjhm9egk6upbovJaWwm3r2kxi0Z9bjNxtI=";
|
||||
hash = "sha256-NQSilSF/W69j1qEYYmlQfu2T0OefB+8yf9rCHAL8a6c=";
|
||||
};
|
||||
|
||||
proxyVendor = true;
|
||||
|
||||
vendorHash = "sha256-nC8y3skBhnOo7Ki9nc7Ni6UpheArB8bGK4AR/1Gdjr0=";
|
||||
vendorHash = "sha256-VmlF86Sv6R2NmCtWi4kZ4rfmFAjgMB1RU/1jmnPiIkw=";
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
|
@ -13,6 +13,11 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "libblake3";
|
||||
version = "1.8.2";
|
||||
|
||||
outputs = [
|
||||
"out"
|
||||
"dev"
|
||||
];
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "BLAKE3-team";
|
||||
repo = "BLAKE3";
|
||||
|
@ -8,8 +8,8 @@ This patch hinders libnvidia-container from using the loader cache, which doesn'
|
||||
src/ldcache.c | 46 +++++++++++++++++-----------------------------
|
||||
src/ldcache.h | 2 +-
|
||||
src/nvc_info.c | 8 ++------
|
||||
src/nvc_ldcache.c | 2 +-
|
||||
4 files changed, 21 insertions(+), 37 deletions(-)
|
||||
src/nvc_ldcache.c | 4 ++--
|
||||
4 files changed, 22 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/src/ldcache.c b/src/ldcache.c
|
||||
index 38bab0553208f66b2866ccea6cdb0faca4357f19..1c4acd52b622be4ca6accdc80da5a6fcf9ae67dd 100644
|
||||
@ -86,7 +86,7 @@ index 33d78dd7e21f65eb696535c115bbd2839a6c67ca..2b087dbca1a6a2946cd495e676a61e95
|
||||
|
||||
#endif /* HEADER_LDCACHE_H */
|
||||
diff --git a/src/nvc_info.c b/src/nvc_info.c
|
||||
index b7b8adfa7c79c326a1acb481a06a05d1463e810f..cf4b1905fd2127c28ee16649501be122d3be5261 100644
|
||||
index bcc887b2345bd42a098f9b85d9c66fae2775f736..5eaef61ada5e955ab11c6a4eb8429c50468e3370 100644
|
||||
--- a/src/nvc_info.c
|
||||
+++ b/src/nvc_info.c
|
||||
@@ -217,15 +217,13 @@ find_library_paths(struct error *err, struct dxcore_context *dxcore, struct nvc_
|
||||
@ -122,15 +122,17 @@ index b7b8adfa7c79c326a1acb481a06a05d1463e810f..cf4b1905fd2127c28ee16649501be122
|
||||
}
|
||||
|
||||
diff --git a/src/nvc_ldcache.c b/src/nvc_ldcache.c
|
||||
index db3b2f69692270e9058b2e26f18eb31677909d05..ae5def43b4cb3973af3aad55361265173ca938a7 100644
|
||||
index 0535090dafbae5a00acb707bbbb5a35dbcea4a7a..5de429f4c2ea62775403a5fc1ed0f23a6c88655c 100644
|
||||
--- a/src/nvc_ldcache.c
|
||||
+++ b/src/nvc_ldcache.c
|
||||
@@ -367,7 +367,7 @@ nvc_ldcache_update(struct nvc_context *ctx, const struct nvc_container *cnt)
|
||||
if (validate_args(ctx, cnt != NULL) < 0)
|
||||
return (-1);
|
||||
|
||||
- argv = (char * []){cnt->cfg.ldconfig, "-f", "/etc/ld.so.conf", "-C", "/etc/ld.so.cache", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
|
||||
+ argv = (char * []){cnt->cfg.ldconfig, "-f", "/tmp/ld.so.conf.nvidia-host", "-C", "/tmp/ld.so.cache.nvidia-host", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
|
||||
if (*argv[0] == '@') {
|
||||
@@ -482,8 +482,8 @@ nvc_ldcache_update(struct nvc_context *ctx, const struct nvc_container *cnt)
|
||||
* See https://github.com/NVIDIA/libnvidia-container/issues/316 for an
|
||||
* in-depth investigation.
|
||||
*/
|
||||
- char *argv_default[] = {cnt->cfg.ldconfig, "-f", "/etc/ld.so.conf", "-C", "/etc/ld.so.cache", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
|
||||
- char *argv_with_compat_dir[] = {cnt->cfg.ldconfig, "-f", "/etc/ld.so.conf", "-C", "/etc/ld.so.cache", cnt->cuda_compat_dir, cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
|
||||
+ char *argv_default[] = {cnt->cfg.ldconfig, "-f", "/tmp/ld.so.conf.nvidia-host", "-C", "/tmp/ld.so.cache.nvidia-host", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
|
||||
+ char *argv_with_compat_dir[] = {cnt->cfg.ldconfig, "-f", "/tmp/ld.so.conf.nvidia-host", "-C", "/tmp/ld.so.cache.nvidia-host", cnt->cuda_compat_dir, cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
|
||||
if ((cnt->flags & OPT_CUDA_COMPAT_MODE_LDCONFIG) && (cnt->cuda_compat_dir != NULL)) {
|
||||
/*
|
||||
* We treat this path specially to be relative to the host filesystem.
|
||||
* We include the cuda_compat_dir directory on the ldconfig
|
||||
|
@ -9,7 +9,7 @@ This patch maintains compatibility with NixOS' `virtualisation.docker.enableNvid
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/nvc_info.c b/src/nvc_info.c
|
||||
index cf4b1905fd2127c28ee16649501be122d3be5261..cdfa19721bc913d8e2adb96d106cd65ee6111623 100644
|
||||
index 5eaef61ada5e955ab11c6a4eb8429c50468e3370..cac87500213e961e603494ac842d02522fc46a5e 100644
|
||||
--- a/src/nvc_info.c
|
||||
+++ b/src/nvc_info.c
|
||||
@@ -249,10 +249,13 @@ find_binary_paths(struct error *err, struct dxcore_context* dxcore, struct nvc_d
|
||||
|
@ -32,13 +32,13 @@ let
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "libnvidia-container";
|
||||
version = "1.17.6";
|
||||
version = "1.17.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "NVIDIA";
|
||||
repo = "libnvidia-container";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-kveP0Px9Fds7pS39aW+cqg2jtiQCMN2zG4GTGRqRrc0=";
|
||||
hash = "sha256-OzjcYxnWjzgmrjERyPN3Ch3EQj4t1J5/TbATluoDESg=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
@ -175,6 +175,7 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
maintainers = with lib.maintainers; [
|
||||
cpcloud
|
||||
msanft
|
||||
katexochen
|
||||
];
|
||||
};
|
||||
})
|
||||
|
@ -11,16 +11,16 @@
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "lstr";
|
||||
version = "0.2.0";
|
||||
version = "0.2.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "bgreenwell";
|
||||
repo = "lstr";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-Bg2tJYnXpJQasmcRv+ZIZAVteKUCuTgFKVRHw1CCiAQ=";
|
||||
hash = "sha256-uaefVDSTphboWW1BP2HkcuMiW87FmnVYxCthlrAKF5Y=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-KlO/Uz9UPea4DFC6U4hvn4kOWSzUmYmckw+IUstcmeQ=";
|
||||
cargoHash = "sha256-UVaqkNV1cNpbCNphk6YMqOz077xY9dUBgCGt7SLIH0U=";
|
||||
|
||||
nativeBuildInputs = [ pkg-config ];
|
||||
|
||||
|
@ -9,13 +9,13 @@
|
||||
}:
|
||||
buildGoModule (finalAttrs: {
|
||||
pname = "nelm";
|
||||
version = "1.6.0";
|
||||
version = "1.7.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "werf";
|
||||
repo = "nelm";
|
||||
tag = "v${finalAttrs.version}";
|
||||
hash = "sha256-bqVas9zF/xtL5K/7cOF/4q4weZtEBhfB5ngdAq0ZfjI=";
|
||||
hash = "sha256-XAieAxfpNi2XpjG8lyatAqP13wicx3JFjckgSmiKqjA=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-bx8e5jV+ORnJg/35VwO7qodFjmSf7XbzTKZKp3b8hqc=";
|
||||
|
@ -9,22 +9,22 @@
|
||||
pkg-config,
|
||||
nixVersions,
|
||||
nix-update-script,
|
||||
enableNixImport ? true,
|
||||
enableNixImport ? false,
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage (finalAttrs: {
|
||||
pname = "nickel";
|
||||
version = "1.11.0";
|
||||
version = "1.12.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "tweag";
|
||||
repo = "nickel";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-I7cLVrkJhB3aJeE/A3tpFEUj0AkvcONSXD8NtnE5eQ0=";
|
||||
hash = "sha256-iKLjYE4uT+luIRXjEuO7KjgkO+/jFpLjhCI5tO7TVMM=";
|
||||
};
|
||||
|
||||
useFetchCargoVendor = true;
|
||||
cargoHash = "sha256-DzSfwBVeRT/GAXWyZKZjlDvj95bQzrkqIgZZ2EZw7eQ=";
|
||||
cargoHash = "sha256-O/iat0JOvA90LD+ngAByLYQyd1VBeoa8yj7/NdEYprE=";
|
||||
|
||||
cargoBuildFlags = [
|
||||
"-p nickel-lang-cli"
|
||||
@ -99,6 +99,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
|
||||
maintainers = with lib.maintainers; [
|
||||
felschr
|
||||
matthiasbeyer
|
||||
yannham
|
||||
];
|
||||
mainProgram = "nickel";
|
||||
};
|
||||
|
56
pkgs/by-name/ni/nipap-cli/package.nix
Normal file
56
pkgs/by-name/ni/nipap-cli/package.nix
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
lib,
|
||||
python312Packages,
|
||||
nixosTests,
|
||||
}:
|
||||
|
||||
let
|
||||
python3Packages = python312Packages;
|
||||
in
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "nipap-cli";
|
||||
inherit (python3Packages.nipap) version src;
|
||||
pyproject = true;
|
||||
|
||||
sourceRoot = "${src.name}/nipap-cli";
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace-fail 'docutils==0.20.1' 'docutils'
|
||||
'';
|
||||
|
||||
build-system = with python3Packages; [
|
||||
setuptools
|
||||
docutils
|
||||
];
|
||||
|
||||
dependencies = with python3Packages; [
|
||||
ipy
|
||||
pynipap
|
||||
];
|
||||
|
||||
checkInputs = with python3Packages; [
|
||||
pythonImportsCheckHook
|
||||
];
|
||||
pythonImportsCheck = [
|
||||
"nipap_cli.nipap_cli"
|
||||
];
|
||||
|
||||
passthru.tests.nixos = nixosTests.nipap;
|
||||
|
||||
meta = {
|
||||
description = "Neat IP Address Planner CLI";
|
||||
longDescription = ''
|
||||
NIPAP is the best open source IPAM in the known universe,
|
||||
challenging classical IP address management (IPAM) systems in many areas.
|
||||
'';
|
||||
homepage = "https://github.com/SpriteLink/NIPAP";
|
||||
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
lukegb
|
||||
];
|
||||
platforms = lib.platforms.all;
|
||||
mainProgram = "nipap";
|
||||
};
|
||||
}
|
53
pkgs/by-name/ni/nipap-www/package.nix
Normal file
53
pkgs/by-name/ni/nipap-www/package.nix
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
lib,
|
||||
python3Packages,
|
||||
nixosTests,
|
||||
}:
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "nipap-www";
|
||||
inherit (python3Packages.nipap) version src;
|
||||
pyproject = true;
|
||||
|
||||
sourceRoot = "${src.name}/nipap-www";
|
||||
|
||||
postPatch = ''
|
||||
# Load Flask config additionally from FLASK_ environment variables.
|
||||
# This makes providing secrets easier.
|
||||
sed -i nipapwww/__init__.py \
|
||||
-e '/^\s*app =/a\ app.config.from_prefixed_env()'
|
||||
'';
|
||||
|
||||
pythonRelaxDeps = true; # deps are tightly specified
|
||||
|
||||
build-system = with python3Packages; [
|
||||
setuptools
|
||||
];
|
||||
|
||||
dependencies = with python3Packages; [
|
||||
flask
|
||||
nipap
|
||||
pynipap
|
||||
];
|
||||
|
||||
passthru = {
|
||||
inherit (python3Packages) gunicorn python;
|
||||
pythonPath = python3Packages.makePythonPath dependencies;
|
||||
tests.nixos = nixosTests.nipap;
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "Neat IP Address Planner CLI, web UI";
|
||||
longDescription = ''
|
||||
NIPAP is the best open source IPAM in the known universe,
|
||||
challenging classical IP address management (IPAM) systems in many areas.
|
||||
'';
|
||||
homepage = "https://github.com/SpriteLink/NIPAP";
|
||||
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
lukegb
|
||||
];
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
}
|
5
pkgs/by-name/ni/nipap/package.nix
Normal file
5
pkgs/by-name/ni/nipap/package.nix
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
python3Packages,
|
||||
}:
|
||||
|
||||
python3Packages.toPythonApplication python3Packages.nipap
|
@ -49,7 +49,7 @@ buildGoModule (
|
||||
'';
|
||||
|
||||
outputHashMode = "recursive";
|
||||
outputHash = "sha256-KygZ7NqkfhczYy1YMR824Om4NTq06+KHa/jvmsCty3s=";
|
||||
outputHash = "sha256-3CtcjqjPmK//f15aTE4bUA+moaXNz+AeWiopqWf9qq8=";
|
||||
};
|
||||
|
||||
webui = buildNpmPackage {
|
||||
@ -81,13 +81,13 @@ buildGoModule (
|
||||
|
||||
{
|
||||
pname = "olivetin";
|
||||
version = "2025.6.6";
|
||||
version = "2025.6.22";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "OliveTin";
|
||||
repo = "OliveTin";
|
||||
tag = finalAttrs.version;
|
||||
hash = "sha256-yzAuhrkJEBErf9yYuRoq5B7PT0XA0w668AG5LNSSRFM=";
|
||||
hash = "sha256-fNE8x0d0lnKVxy4fk3h5QrcWnMKBcxhrxpDbZYTXimc=";
|
||||
};
|
||||
|
||||
modRoot = "service";
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
lib,
|
||||
fetchFromGitHub,
|
||||
fetchpatch,
|
||||
stdenv,
|
||||
makeWrapper,
|
||||
gitUpdater,
|
||||
@ -67,6 +68,14 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
hash = "sha256-sCoCcN6950pH33bRZsLoLc1oSs5Qfpj9Bbywn/uA6Bc=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
(fetchpatch {
|
||||
name = "correctly-handle-version-10.0.0-of-qemu.patch";
|
||||
url = "https://github.com/quickemu-project/quickemu/commit/f25205f4513c4fa72be6940081c62e613d1fddc6.patch";
|
||||
hash = "sha256-OAXGyhMVDwbUypEPj/eRnH0wZYaL9WLGjbyoobe20UY=";
|
||||
})
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
sed -i \
|
||||
-e '/OVMF_CODE_4M.secboot.fd/s|ovmfs=(|ovmfs=("${OVMFFull.firmware}","${OVMFFull.variables}" |' \
|
||||
|
@ -16,13 +16,13 @@
|
||||
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "supermariowar";
|
||||
version = "2024-unstable-2025-04-03";
|
||||
version = "2024-unstable-2025-06-18";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "mmatyas";
|
||||
repo = "supermariowar";
|
||||
rev = "c0ed774a2415ad45e72bd6086add2a5cbfc88898";
|
||||
hash = "sha256-vh8SSMxAOG8f9nyJmKUlA8yb+G61Bfc62dhB2eLdo20=";
|
||||
rev = "71383b07b99a52b57be79cf371ab718337365019";
|
||||
hash = "sha256-PjweE8cGAp8V4LY0/6QzLekQ80Q1qbwDiiSzDirA29s=";
|
||||
fetchSubmodules = true;
|
||||
};
|
||||
|
||||
|
@ -62,7 +62,7 @@ let
|
||||
stdenv.cc.cc
|
||||
stdenv.cc.libc
|
||||
];
|
||||
version = "1.0.32";
|
||||
version = "1.0.36";
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "tana";
|
||||
@ -70,7 +70,7 @@ stdenv.mkDerivation {
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/tanainc/tana-desktop-releases/releases/download/v${version}/tana_${version}_amd64.deb";
|
||||
hash = "sha256-oAW9Vx4z0TOweKA6bsmCm7DY72pFWBnPLG0dS05oCw8=";
|
||||
hash = "sha256-dDB2RcTk58IQGqNGepaIvxGhR0/soWWDbBXxnSEYkdw=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -45,13 +45,13 @@ lib.checkListOfEnum "${pname}: theme variants"
|
||||
stdenvNoCC.mkDerivation
|
||||
rec {
|
||||
inherit pname;
|
||||
version = "2024-04-20";
|
||||
version = "2025-06-20";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "vinceliuice";
|
||||
repo = "vimix-gtk-themes";
|
||||
rev = version;
|
||||
sha256 = "RbAdoix+UWKiLB+04YiPa0UwzO1fFLy56IG1MipmE+E=";
|
||||
sha256 = "uRm6v+Zag4FO7nFVcHhZjVhOfdOeYBZYQym0IBR8+HU=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -1,14 +1,14 @@
|
||||
{
|
||||
"darwin": {
|
||||
"hash": "sha256-wlFmfHBSwBh9UFq6by52fGYN2EftP793u3L57XSDDKQ=",
|
||||
"version": "0.2025.06.18.08.11.stable_03"
|
||||
"hash": "sha256-UJAirS6JFFLW0OsOYj8RNUfG85dRHnxXasNw2QHX1Xs=",
|
||||
"version": "0.2025.06.20.22.47.stable_05"
|
||||
},
|
||||
"linux_x86_64": {
|
||||
"hash": "sha256-7CfqTRUMkqLXmJg7RQK0liVEhucMOgMtsJl4/lrg4XI=",
|
||||
"version": "0.2025.06.18.08.11.stable_03"
|
||||
"hash": "sha256-h0ODaO3SJcZAxFRFBYYjWXQYsRAemGizn/YA7AF36pw=",
|
||||
"version": "0.2025.06.20.22.47.stable_05"
|
||||
},
|
||||
"linux_aarch64": {
|
||||
"hash": "sha256-iDXAchU/b2ApDsmV0dnkXI1o0VOaegYWz4DufHtPFJM=",
|
||||
"version": "0.2025.06.18.08.11.stable_03"
|
||||
"hash": "sha256-H4xldFBMpfu6UFGFA/IkA1zPFqhFN6abhfHTRdYNpGA=",
|
||||
"version": "0.2025.06.20.22.47.stable_05"
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,6 @@ python3Packages.buildPythonApplication rec {
|
||||
homepage = "https://github.com/waydroid/waydroid";
|
||||
license = lib.licenses.gpl3Only;
|
||||
platforms = lib.platforms.linux;
|
||||
maintainers = with lib.maintainers; [ ];
|
||||
maintainers = with lib.maintainers; [ bot-wxt1221 ];
|
||||
};
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ let
|
||||
in
|
||||
python.pkgs.buildPythonApplication rec {
|
||||
pname = "weblate";
|
||||
version = "5.12.1";
|
||||
version = "5.12.2";
|
||||
|
||||
pyproject = true;
|
||||
|
||||
@ -40,7 +40,7 @@ python.pkgs.buildPythonApplication rec {
|
||||
owner = "WeblateOrg";
|
||||
repo = "weblate";
|
||||
tag = "weblate-${version}";
|
||||
hash = "sha256-8tqPxvSvVG1j/TGMozihtBYsn7oly41lP4iK3BwTmVk=";
|
||||
hash = "sha256-YaP0lhL7E0pv3ZyfpQ47CjhrzjJPDwGpSTcgXDaMZdA=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
|
@ -119,7 +119,12 @@ rustPlatform.buildRustPackage rec {
|
||||
cp -r assets/macos/WezTerm.app "$OUT_APP"
|
||||
rm $OUT_APP/*.dylib
|
||||
cp -r assets/shell-integration/* "$OUT_APP"
|
||||
ln -s $out/bin/{wezterm,wezterm-mux-server,wezterm-gui,strip-ansi-escapes} "$OUT_APP"
|
||||
# https://github.com/wezterm/wezterm/pull/6886
|
||||
# macOS will only recognize our application bundle
|
||||
# if the binaries are inside of it. Move them there
|
||||
# and create symbolic links for them in bin/.
|
||||
mv $out/bin/{wezterm,wezterm-mux-server,wezterm-gui,strip-ansi-escapes} "$OUT_APP"
|
||||
ln -s "$OUT_APP"/{wezterm,wezterm-mux-server,wezterm-gui,strip-ansi-escapes} "$out/bin"
|
||||
'';
|
||||
|
||||
passthru = {
|
||||
|
@ -7,12 +7,12 @@
|
||||
}:
|
||||
|
||||
let
|
||||
version = "3.10";
|
||||
version = "3.16";
|
||||
srcAll = fetchFromGitHub {
|
||||
owner = "WiringPi";
|
||||
repo = "WiringPi";
|
||||
rev = version;
|
||||
sha256 = "sha256-OWR+yo+SnYaMd8J+ku9ettZi+rDHcHlGZCoucCiRkCI=";
|
||||
tag = version;
|
||||
hash = "sha256-NBHmRA+6Os6/IpW8behbgpVjtN8QF9gkffXU2ZVC8ts=";
|
||||
};
|
||||
mkSubProject =
|
||||
{
|
||||
@ -78,11 +78,14 @@ symlinkJoin {
|
||||
passthru.wiringPiD
|
||||
passthru.gpio
|
||||
];
|
||||
meta = with lib; {
|
||||
meta = {
|
||||
description = "Gordon's Arduino wiring-like WiringPi Library for the Raspberry Pi (Unofficial Mirror for WiringPi bindings)";
|
||||
homepage = "https://github.com/WiringPi/WiringPi";
|
||||
license = licenses.lgpl3Plus;
|
||||
maintainers = with maintainers; [ doronbehar ];
|
||||
platforms = platforms.linux;
|
||||
license = lib.licenses.lgpl3Plus;
|
||||
maintainers = with lib.maintainers; [
|
||||
doronbehar
|
||||
ryand56
|
||||
];
|
||||
platforms = lib.platforms.linux;
|
||||
};
|
||||
}
|
||||
|
@ -1511,6 +1511,39 @@ final: prev: {
|
||||
}
|
||||
) { };
|
||||
|
||||
lrexlib-oniguruma = callPackage (
|
||||
{
|
||||
buildLuarocksPackage,
|
||||
fetchFromGitHub,
|
||||
fetchurl,
|
||||
luaOlder,
|
||||
}:
|
||||
buildLuarocksPackage {
|
||||
pname = "lrexlib-oniguruma";
|
||||
version = "2.9.2-1";
|
||||
knownRockspec =
|
||||
(fetchurl {
|
||||
url = "mirror://luarocks/lrexlib-oniguruma-2.9.2-1.rockspec";
|
||||
sha256 = "13m2v6mmmlkf2bd1mnngg118s4ymrqs7n34la6hrb4m1x772adhd";
|
||||
}).outPath;
|
||||
src = fetchFromGitHub {
|
||||
owner = "rrthomas";
|
||||
repo = "lrexlib";
|
||||
rev = "rel-2-9-2";
|
||||
hash = "sha256-DzNDve+xeKb+kAcW+o7GK/RsoDhaDAVAWAhgjISCyZc=";
|
||||
};
|
||||
|
||||
disabled = luaOlder "5.1";
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/rrthomas/lrexlib";
|
||||
description = "Regular expression library binding (oniguruma flavour).";
|
||||
maintainers = with lib.maintainers; [ junestepp ];
|
||||
license.fullName = "MIT/X11";
|
||||
};
|
||||
}
|
||||
) { };
|
||||
|
||||
lrexlib-pcre = callPackage (
|
||||
{
|
||||
buildLuarocksPackage,
|
||||
|
@ -39,6 +39,7 @@
|
||||
mariadb,
|
||||
mpfr,
|
||||
neovim-unwrapped,
|
||||
oniguruma,
|
||||
openldap,
|
||||
openssl,
|
||||
pcre,
|
||||
@ -380,6 +381,15 @@ in
|
||||
];
|
||||
});
|
||||
|
||||
lrexlib-oniguruma = prev.lrexlib-oniguruma.overrideAttrs (oa: {
|
||||
externalDeps = [
|
||||
{
|
||||
name = "ONIG";
|
||||
dep = oniguruma;
|
||||
}
|
||||
];
|
||||
});
|
||||
|
||||
lrexlib-pcre = prev.lrexlib-pcre.overrideAttrs (oa: {
|
||||
externalDeps = [
|
||||
{
|
||||
|
@ -16,14 +16,14 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aioamazondevices";
|
||||
version = "3.1.12";
|
||||
version = "3.1.14";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "chemelli74";
|
||||
repo = "aioamazondevices";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-nilYImyK057/yO/pnnhM9S+vRcslLLKTsYIzGNFM2UQ=";
|
||||
hash = "sha256-xCXzNeUIw2UxBcOMgab1lpN9/0RGLZAwgtHkZhwqxxY=";
|
||||
};
|
||||
|
||||
build-system = [ poetry-core ];
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "aioesphomeapi";
|
||||
version = "32.2.1";
|
||||
version = "33.1.1";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.9";
|
||||
@ -35,7 +35,7 @@ buildPythonPackage rec {
|
||||
owner = "esphome";
|
||||
repo = "aioesphomeapi";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-1ZepZJdJosPPdFhx8PwArIaoz415GfA1vfc3JJ77LNo=";
|
||||
hash = "sha256-vXBTumh1oB1vTVlX4VJvIUTnkYLG9j/8cNuHFQ2PklY=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
|
@ -8,23 +8,20 @@
|
||||
poetry-core,
|
||||
pytest-cov-stub,
|
||||
pytestCheckHook,
|
||||
pythonOlder,
|
||||
pytz,
|
||||
sensor-state-data,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "bthome-ble";
|
||||
version = "3.13.0";
|
||||
version = "3.13.1";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.9";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Bluetooth-Devices";
|
||||
repo = "bthome-ble";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-e6R3Qjj82z0E+gIxqDVM08Op3KlK9ZG1iNmkqqIEjWY=";
|
||||
hash = "sha256-oGFjWe9e386EPAJGKL8Qk55iXoyW3rXuyG7ElyQYurg=";
|
||||
};
|
||||
|
||||
build-system = [ poetry-core ];
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "deebot-client";
|
||||
version = "13.3.0";
|
||||
version = "13.4.0";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.13";
|
||||
@ -29,12 +29,12 @@ buildPythonPackage rec {
|
||||
owner = "DeebotUniverse";
|
||||
repo = "client.py";
|
||||
tag = version;
|
||||
hash = "sha256-dnh+3/viaaxlx3H0ceDH1N72kC1HBC7Szz+Gb6ryUJM=";
|
||||
hash = "sha256-CEE6RDcYQLJ9a8QFYpCURYV8hvs0mLK8R+p68OfHKWQ=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoVendor {
|
||||
inherit pname version src;
|
||||
hash = "sha256-v8FtW1gPoPfOpcxUrM7g0LKR8k0VPR13hsHCPT8uLzs=";
|
||||
hash = "sha256-0WdRkF5UAaPQS3A9DiAe9BuqF0aAaU0c2C0BU3Ue4n0=";
|
||||
};
|
||||
|
||||
pythonRelaxDeps = [
|
||||
|
50
pkgs/development/python-modules/flask-xml-rpc-re/default.nix
Normal file
50
pkgs/development/python-modules/flask-xml-rpc-re/default.nix
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
setuptools,
|
||||
flask,
|
||||
nose2,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "flask-xml-rpc-re";
|
||||
version = "0.2.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Croydon";
|
||||
repo = "flask-xml-rpc-reloaded";
|
||||
tag = version;
|
||||
hash = "sha256-S+9Ur22ExgVjKMOKG19cBz2aCVdEyOoS7uoz17CDzd8=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
];
|
||||
|
||||
dependencies = [
|
||||
flask
|
||||
];
|
||||
|
||||
nativeCheckInputs = [
|
||||
nose2
|
||||
];
|
||||
|
||||
installCheckPhase = ''
|
||||
runHook preInstallCheck
|
||||
nose2 -v
|
||||
runHook postInstallCheck
|
||||
'';
|
||||
|
||||
pythonImportsCheck = [ "flask_xmlrpcre" ];
|
||||
|
||||
meta = {
|
||||
description = "Let your Flask apps provide XML-RPC APIs";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
lukegb
|
||||
];
|
||||
homepage = "https://github.com/Croydon/flask-xml-rpc-reloaded";
|
||||
changelog = "https://github.com/Croydon/flask-xml-rpc-reloaded/releases/tag/${version}";
|
||||
};
|
||||
}
|
@ -20,13 +20,13 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "guidance-stitch";
|
||||
version = "0.1.4";
|
||||
version = "0.1.5";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
pname = "guidance_stitch";
|
||||
inherit version;
|
||||
hash = "sha256-Wthz02C2AU6hzQ+TTGs+sI73ejwHQRCStZXZts0i1+w=";
|
||||
hash = "sha256-Kg0O3oZds4eFfUlKe8sakDYhwT9XGGnN4RCcLFVpzZU=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "homematicip";
|
||||
version = "2.0.5";
|
||||
version = "2.0.6";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.12";
|
||||
@ -25,7 +25,7 @@ buildPythonPackage rec {
|
||||
owner = "hahn-th";
|
||||
repo = "homematicip-rest-api";
|
||||
tag = version;
|
||||
hash = "sha256-WvE5JTpAjRGLP7haIwD5hKOvz3hM7paV2jyds/yCxg8=";
|
||||
hash = "sha256-HV+4ZmYr6LsSBbQnr4PUD2u0y6uWxuCMUgNh7gG9IH8=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
|
100
pkgs/development/python-modules/nipap/default.nix
Normal file
100
pkgs/development/python-modules/nipap/default.nix
Normal file
@ -0,0 +1,100 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchFromGitHub,
|
||||
|
||||
# build deps
|
||||
setuptools,
|
||||
docutils,
|
||||
|
||||
# dependencies
|
||||
zipp,
|
||||
importlib-metadata,
|
||||
flask,
|
||||
flask-compress,
|
||||
flask-xml-rpc-re,
|
||||
flask-restx,
|
||||
requests,
|
||||
ipy,
|
||||
# indirect deps omitted: jinja2/markupsafe/werkzeug,
|
||||
parsedatetime,
|
||||
psutil,
|
||||
psycopg2,
|
||||
pyparsing,
|
||||
python-dateutil,
|
||||
pytz,
|
||||
pyjwt,
|
||||
tornado,
|
||||
|
||||
# optional deps
|
||||
## ldap
|
||||
python-ldap,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "nipap";
|
||||
version = "0.32.7";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "SpriteLink";
|
||||
repo = "NIPAP";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-FnCHW/yEhWtx+2fU+G6vxz50lWC7WL3cYKYOQzmH8zs=";
|
||||
};
|
||||
|
||||
sourceRoot = "${src.name}/nipap";
|
||||
|
||||
pythonRelaxDeps = true; # deps are tightly specified by upstream
|
||||
|
||||
postPatch = ''
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace-fail 'docutils==0.20.1' 'docutils'
|
||||
'';
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
docutils
|
||||
];
|
||||
|
||||
dependencies = [
|
||||
zipp
|
||||
importlib-metadata
|
||||
flask
|
||||
flask-compress
|
||||
flask-xml-rpc-re
|
||||
flask-restx
|
||||
requests
|
||||
ipy
|
||||
# indirect deps omitted: jinja2/markupsafe/werkzeug
|
||||
parsedatetime
|
||||
psutil
|
||||
psycopg2
|
||||
pyparsing
|
||||
python-dateutil
|
||||
pytz
|
||||
pyjwt
|
||||
tornado
|
||||
];
|
||||
|
||||
optional-dependencies = {
|
||||
ldap = [ python-ldap ];
|
||||
};
|
||||
|
||||
doCheck = false; # tests require nose, /etc/nipap/nipap.conf and a running nipapd
|
||||
|
||||
meta = {
|
||||
description = "Neat IP Address Planner";
|
||||
longDescription = ''
|
||||
NIPAP is the best open source IPAM in the known universe,
|
||||
challenging classical IP address management (IPAM) systems in many areas.
|
||||
'';
|
||||
homepage = "https://github.com/SpriteLink/NIPAP";
|
||||
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
lukegb
|
||||
];
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
}
|
38
pkgs/development/python-modules/pynipap/default.nix
Normal file
38
pkgs/development/python-modules/pynipap/default.nix
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
nipap,
|
||||
|
||||
# build deps
|
||||
setuptools,
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "pynipap";
|
||||
pyproject = true;
|
||||
|
||||
inherit (nipap) version src;
|
||||
|
||||
sourceRoot = "${src.name}/pynipap";
|
||||
|
||||
build-system = [
|
||||
setuptools
|
||||
];
|
||||
|
||||
doCheck = false; # tests require nose, /etc/nipap/nipap.conf and a running nipapd
|
||||
|
||||
meta = {
|
||||
description = "Python client library for Neat IP Address Planner";
|
||||
longDescription = ''
|
||||
NIPAP is the best open source IPAM in the known universe,
|
||||
challenging classical IP address management (IPAM) systems in many areas.
|
||||
'';
|
||||
homepage = "https://github.com/SpriteLink/NIPAP";
|
||||
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
|
||||
license = lib.licenses.mit;
|
||||
maintainers = with lib.maintainers; [
|
||||
lukegb
|
||||
];
|
||||
platforms = lib.platforms.all;
|
||||
};
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "zha";
|
||||
version = "0.0.59";
|
||||
version = "0.0.60";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.12";
|
||||
@ -36,7 +36,7 @@ buildPythonPackage rec {
|
||||
owner = "zigpy";
|
||||
repo = "zha";
|
||||
tag = version;
|
||||
hash = "sha256-wddMeXFKk8HBz8Hle5kbRaOkZLOr98HoiHYYlBtuxSA=";
|
||||
hash = "sha256-Bx6JcVKosf6wXe+LRP9R4iFAva/rJ15JhYchCx2CbJk=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "zigpy-zigate";
|
||||
version = "0.13.2";
|
||||
version = "0.13.3";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.8";
|
||||
@ -25,7 +25,7 @@ buildPythonPackage rec {
|
||||
owner = "zigpy";
|
||||
repo = "zigpy-zigate";
|
||||
tag = version;
|
||||
hash = "sha256-MlAX7dcRZziMYCpG64OemZ8czwvDXpdoRaDVo1sUCno=";
|
||||
hash = "sha256-reOt0bPPkKDKeu8CESJtLDEmpkOmgopXk65BqBlBIhY=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "zigpy-znp";
|
||||
version = "0.14.0";
|
||||
version = "0.14.1";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
@ -28,7 +28,7 @@ buildPythonPackage rec {
|
||||
owner = "zigpy";
|
||||
repo = "zigpy-znp";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-vYB04vEFqpqrjJMS73mtYXakp7lEIJjB+tT0SF9hpWM=";
|
||||
hash = "sha256-V662zDUBMbr+cARxrwt8196Ml4zlGEAudR3BtvY96HM=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
@ -1,347 +1,347 @@
|
||||
{
|
||||
"aurorae": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/aurorae-6.4.0.tar.xz",
|
||||
"hash": "sha256-VjxChfQmhIJW6SyISgWKVy1Z31q5pMi5BzhSJuxKwLI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/aurorae-6.4.1.tar.xz",
|
||||
"hash": "sha256-4hZ73nLjVc0AZXOeqNLNnR3z9D6beAn8VwKzs1K7/WU="
|
||||
},
|
||||
"bluedevil": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/bluedevil-6.4.0.tar.xz",
|
||||
"hash": "sha256-8yb1EFCmDqwRNlKeFojg3ZAL1brP3cDn3ZQbLXV2rrk="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/bluedevil-6.4.1.tar.xz",
|
||||
"hash": "sha256-mtR03dabzoVJgNMEL96JBb2UBZ/aqoAEJcds12J+Bu8="
|
||||
},
|
||||
"breeze": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/breeze-6.4.0.tar.xz",
|
||||
"hash": "sha256-z9s48KTixCjpylpf0SQAtoBKvN1TWbY2+lMno1Eh6GY="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/breeze-6.4.1.tar.xz",
|
||||
"hash": "sha256-T+AIX/ohsuOu9J3E5chi8i7xM5WpaBOHqZAwh0PwHFU="
|
||||
},
|
||||
"breeze-grub": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/breeze-grub-6.4.0.tar.xz",
|
||||
"hash": "sha256-syzAxAqtGM7tbowlxlTc/ELUbd2Zm8oFBKCSlZhvYwI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/breeze-grub-6.4.1.tar.xz",
|
||||
"hash": "sha256-c6yyJ5vbMtXpeqeHha4P6vBuQnQTtNvR3LZbu9zacwM="
|
||||
},
|
||||
"breeze-gtk": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/breeze-gtk-6.4.0.tar.xz",
|
||||
"hash": "sha256-WFJjJxTE17d1SBUe9efe2t7TMfbpARGxbdcQ4Bu6j60="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/breeze-gtk-6.4.1.tar.xz",
|
||||
"hash": "sha256-4Qj+nLx2oPUf2N+cYw05l4o8H7bPrznZqy9VVJRie1g="
|
||||
},
|
||||
"breeze-plymouth": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/breeze-plymouth-6.4.0.tar.xz",
|
||||
"hash": "sha256-S1DBCbItJbH7YT/K5Qq+NbEAuQgyaudqPdgydMoPTPI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/breeze-plymouth-6.4.1.tar.xz",
|
||||
"hash": "sha256-JSE/12TBsME2nbqFASXjsC2ZkKuQwcZ0PKodCHy3BkU="
|
||||
},
|
||||
"discover": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/discover-6.4.0.tar.xz",
|
||||
"hash": "sha256-CfsdY6puw61W5gb0i24Q1Z7rN9m1J+VKIRtKedblIkI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/discover-6.4.1.tar.xz",
|
||||
"hash": "sha256-80zqQ4qKCuC7b9E+QWTUnHoqmFfiBDAMzCdvLV+JgjA="
|
||||
},
|
||||
"drkonqi": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/drkonqi-6.4.0.tar.xz",
|
||||
"hash": "sha256-BGqJ475WIGBu2tlF6/L1KHWlytZ0A8Ha86G/5ShoPqI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/drkonqi-6.4.1.tar.xz",
|
||||
"hash": "sha256-REnekqvM46h7RyeWQffxcmqo0C5vMVSPDzJ3ks6C/UM="
|
||||
},
|
||||
"flatpak-kcm": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/flatpak-kcm-6.4.0.tar.xz",
|
||||
"hash": "sha256-KCw6dSf4sdsTLaB992jXLFK7yj4n8iFvS6ahcx3QTeI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/flatpak-kcm-6.4.1.tar.xz",
|
||||
"hash": "sha256-27UINtKXUF5efF/LKeIrb/IbUtBE7gf4QriZlMXapd4="
|
||||
},
|
||||
"kactivitymanagerd": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kactivitymanagerd-6.4.0.tar.xz",
|
||||
"hash": "sha256-zVaf4lsNZwHDMOCPw+3lfVf/guluxtNH51dbsy+qurs="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kactivitymanagerd-6.4.1.tar.xz",
|
||||
"hash": "sha256-tt1cG4TT0ucNt58W7O/iOsr1PEX9XCursu6ZS0ZsrJk="
|
||||
},
|
||||
"kde-cli-tools": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kde-cli-tools-6.4.0.tar.xz",
|
||||
"hash": "sha256-T06+18F6JQecVO8DGSmsVdZ3es089ZXKY0P00KTwC6k="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kde-cli-tools-6.4.1.tar.xz",
|
||||
"hash": "sha256-LZCrDANPudKBZ1Dams45twi3EtP3NBZj67v+iNWwLKQ="
|
||||
},
|
||||
"kde-gtk-config": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kde-gtk-config-6.4.0.tar.xz",
|
||||
"hash": "sha256-ygZtqEJyKAw/1qGBlw2U854Re+yM7pHXGi4lLCFF788="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kde-gtk-config-6.4.1.tar.xz",
|
||||
"hash": "sha256-S79X5NeYqJnD8SM1BClZrvz11q81SwSJXk6N3ujIxD4="
|
||||
},
|
||||
"kdecoration": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kdecoration-6.4.0.tar.xz",
|
||||
"hash": "sha256-pMyMS8dB0KQj11DO1m4UG5uY/McUaKshDlTaOCFTtYA="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kdecoration-6.4.1.tar.xz",
|
||||
"hash": "sha256-obRAHtr3/iFjw+HKtUjZPDExlXuFNPISSe787uSW4SI="
|
||||
},
|
||||
"kdeplasma-addons": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kdeplasma-addons-6.4.0.tar.xz",
|
||||
"hash": "sha256-XwS3FmjLhADglL7Oa7bHRra7k2W8EWk4tm2Kq9hJNVo="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kdeplasma-addons-6.4.1.tar.xz",
|
||||
"hash": "sha256-iUv51ID9vwo+AFczkVNaQemlfO5yP7rQ+NosFtKZ0vY="
|
||||
},
|
||||
"kgamma": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kgamma-6.4.0.tar.xz",
|
||||
"hash": "sha256-IRQh+vjZAB3JNgkv0fTyEVNIWvQ08AcfVdIovRo5xUg="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kgamma-6.4.1.tar.xz",
|
||||
"hash": "sha256-zClBxUYyHA9ACHqB4sPY1E6jhFA0wWQXmmOEtU7w+5A="
|
||||
},
|
||||
"kglobalacceld": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kglobalacceld-6.4.0.tar.xz",
|
||||
"hash": "sha256-9+Z6c2e2C9RTBVjvkZgN+ha7UA1VFutonrUAQeELDzI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kglobalacceld-6.4.1.tar.xz",
|
||||
"hash": "sha256-PuOK9MlVHeZAoYZ9J4NS2BcUaSz3AAwg0Z3CYuBL9DM="
|
||||
},
|
||||
"kinfocenter": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kinfocenter-6.4.0.tar.xz",
|
||||
"hash": "sha256-TS3q9MH/dv8QDtawfXyxWLoRbEwiG3tfeyVEAoUFRJQ="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kinfocenter-6.4.1.tar.xz",
|
||||
"hash": "sha256-IOr7rnikN/dnuLbpSTh1sjADP5dgRUcy6BBIPIISeSc="
|
||||
},
|
||||
"kmenuedit": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kmenuedit-6.4.0.tar.xz",
|
||||
"hash": "sha256-SuSmetygfhDCR1uaGay9KD0YQKmWu8CE2bGyN8fm74g="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kmenuedit-6.4.1.tar.xz",
|
||||
"hash": "sha256-VdsXXw897aYVS/sMchrfGD9jwTS3eFjJ+74IWK6cd3M="
|
||||
},
|
||||
"kpipewire": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kpipewire-6.4.0.tar.xz",
|
||||
"hash": "sha256-1ZdmWk7lekmT2QjmIVEkKumlo6JedtC6AD85ymhp41o="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kpipewire-6.4.1.tar.xz",
|
||||
"hash": "sha256-Npbf0ZtT5e+h57xpDDggkZuLvcDXj5Z3nMOzGekDX+I="
|
||||
},
|
||||
"krdp": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/krdp-6.4.0.tar.xz",
|
||||
"hash": "sha256-78FnobeNIWoopi/TzJmBhQKGK6hB7/F1k+4VchzhRdU="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/krdp-6.4.1.tar.xz",
|
||||
"hash": "sha256-zoGR8xXF9HBGuZh/Uv/wqI/8P51AmJ7yQj8QuY4sWMI="
|
||||
},
|
||||
"kscreen": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kscreen-6.4.0.tar.xz",
|
||||
"hash": "sha256-5M7giQpTQFMVH6XoU3Ktgukmm5TNPcMytzfDbEcRcn8="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kscreen-6.4.1.tar.xz",
|
||||
"hash": "sha256-w6KFacTwkt74RWTpFi64p/poGo9GWKFNgkNuohdU3Fs="
|
||||
},
|
||||
"kscreenlocker": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kscreenlocker-6.4.0.tar.xz",
|
||||
"hash": "sha256-uEAgK6a1vXgyqyEWvu4sjjhvqbhE5tsOQlqEAGtmmPo="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kscreenlocker-6.4.1.tar.xz",
|
||||
"hash": "sha256-yEnck5oFCibycDk/i1nouG1nGYOnUuAUr3yJoclVuSU="
|
||||
},
|
||||
"ksshaskpass": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/ksshaskpass-6.4.0.tar.xz",
|
||||
"hash": "sha256-zjx7qfFmOOteA3iCFEioS5oGGSKL6BluVcOV/U10OAY="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/ksshaskpass-6.4.1.tar.xz",
|
||||
"hash": "sha256-VJXbLUX5sqxQqBOC9+OMmauD1+o0rc9ysFwmDZ2KNDM="
|
||||
},
|
||||
"ksystemstats": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/ksystemstats-6.4.0.tar.xz",
|
||||
"hash": "sha256-4PiFWk25FQgGa52lEI3bzki7rdpku5ZlOsL7MS/BRo4="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/ksystemstats-6.4.1.tar.xz",
|
||||
"hash": "sha256-pwp0070kEW9gAQhrlCzJ1p91FPP1t8KgOC1dwoHn8Ko="
|
||||
},
|
||||
"kwallet-pam": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kwallet-pam-6.4.0.tar.xz",
|
||||
"hash": "sha256-RQ5Na4BMWX61EVkADhk2iJJuTYIlrhmhYn4l0R/ri14="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kwallet-pam-6.4.1.tar.xz",
|
||||
"hash": "sha256-BNTXB1y5PKwQp+BQSDbZYcei7aTwiYe7UA+ScgApi3w="
|
||||
},
|
||||
"kwayland": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kwayland-6.4.0.tar.xz",
|
||||
"hash": "sha256-CmSafVAjcCLJsMDz798qe/vreU43zzdcohkOZLXR2x8="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kwayland-6.4.1.tar.xz",
|
||||
"hash": "sha256-f48oQSL/2kTF4dZEJ76QWcoj9an78JLiod5tQd5FhiU="
|
||||
},
|
||||
"kwayland-integration": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kwayland-integration-6.4.0.tar.xz",
|
||||
"hash": "sha256-olIYm9HKCRWbtweBb/nVUqWzAJMpyTCg6YN3KEvw8Rw="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kwayland-integration-6.4.1.tar.xz",
|
||||
"hash": "sha256-IQk2AksNGsr5zZOo94SjSBBhno6zVvaPAgVHU1QK5gs="
|
||||
},
|
||||
"kwin": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kwin-6.4.0.tar.xz",
|
||||
"hash": "sha256-DTSSMXpxmmRb8ok/ysIbspeWBrrzcDYQ5Va1961U3mo="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kwin-6.4.1.tar.xz",
|
||||
"hash": "sha256-1OQwbJbMLouoYw6sMjT7wIVoWwCrxeWvwsLBxsb8pNQ="
|
||||
},
|
||||
"kwin-x11": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kwin-x11-6.4.0.tar.xz",
|
||||
"hash": "sha256-dtfAGOtu5lcpLIkquc50CYKQ7uB8P9+p18UxSX2OW3c="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kwin-x11-6.4.1.tar.xz",
|
||||
"hash": "sha256-eYy9ba9fstfr20lOaxLzmp7A4CWicjNiEhOWYUEgfAs="
|
||||
},
|
||||
"kwrited": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/kwrited-6.4.0.tar.xz",
|
||||
"hash": "sha256-ZCxWdKsNlcoKQtbRstrKtf+/wGcZgZUo+iUVPGimRUo="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/kwrited-6.4.1.tar.xz",
|
||||
"hash": "sha256-qApe1F7WM/Fc86QrLZVmCNnmpaePJn3zOslqr8wg2NQ="
|
||||
},
|
||||
"layer-shell-qt": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/layer-shell-qt-6.4.0.tar.xz",
|
||||
"hash": "sha256-K55BM9Cb6Fji7mEHpWir0xoWC0ZlRatLZjEcaDlcd7A="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/layer-shell-qt-6.4.1.tar.xz",
|
||||
"hash": "sha256-54HK3sALTDibkUPLOkDfd4iqTU0hHIhH9rm2UXbm6c4="
|
||||
},
|
||||
"libkscreen": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/libkscreen-6.4.0.tar.xz",
|
||||
"hash": "sha256-4kBHbhXFfoWnkQf++9zLBwgoiaSUtXqlx8Tm8gjpEho="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/libkscreen-6.4.1.tar.xz",
|
||||
"hash": "sha256-dBU8GUDd7sCZuhIMenm7yzn/42NE581cQ2CHdq9bLRQ="
|
||||
},
|
||||
"libksysguard": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/libksysguard-6.4.0.tar.xz",
|
||||
"hash": "sha256-v9C695c0B0RAk+E6XOKzEM7lhuO7xdThB4W8Gg1FpmM="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/libksysguard-6.4.1.tar.xz",
|
||||
"hash": "sha256-fDOUnb3MzuzjX779JEpESbI7UHHgytCC+RruZPeygeE="
|
||||
},
|
||||
"libplasma": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/libplasma-6.4.0.tar.xz",
|
||||
"hash": "sha256-/4bw2QYlS7yfkQfzg7Gfu1un2yQ/q38tfSeP6DFGNUw="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/libplasma-6.4.1.tar.xz",
|
||||
"hash": "sha256-O6Tx+KmWix0zlWT5GzOBjoDmEt5+U0WREXJGlj0scXs="
|
||||
},
|
||||
"milou": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/milou-6.4.0.tar.xz",
|
||||
"hash": "sha256-7SWKx4tH2O7oFxOIq8EtxzuvP+gkK8EZpqMUMdfbPzA="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/milou-6.4.1.tar.xz",
|
||||
"hash": "sha256-IZQ2nUxFpTe3kyK/3T7MUlL7Vd/Y968hA8j3t9ouUIA="
|
||||
},
|
||||
"ocean-sound-theme": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/ocean-sound-theme-6.4.0.tar.xz",
|
||||
"hash": "sha256-r6ZyqRyuqaNPn+aZA7/02M+ZsWOT21LVRvq+K1uOp3M="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/ocean-sound-theme-6.4.1.tar.xz",
|
||||
"hash": "sha256-o/ddckD0SKRnOT6xTxQxrAsFNf5JKYyf+hdLAFAJl/M="
|
||||
},
|
||||
"oxygen": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/oxygen-6.4.0.tar.xz",
|
||||
"hash": "sha256-p29NbjoPnvZzq3W3sULfUTbYevHwlMz63Svm5s5sLCQ="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/oxygen-6.4.1.tar.xz",
|
||||
"hash": "sha256-b5siN5HxUR5v7sS2i6YDThJF4D6iHRMf4YxKhJdVRqU="
|
||||
},
|
||||
"oxygen-sounds": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/oxygen-sounds-6.4.0.tar.xz",
|
||||
"hash": "sha256-Wz1d8nOQ7ggmCWSypo1Zl/L1B9F1MRRg+6Gs6kFNyFI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/oxygen-sounds-6.4.1.tar.xz",
|
||||
"hash": "sha256-pv3YCBYyLq0GRdiJUQpUAh/UvYGEiBTfh1SM8m4HaD8="
|
||||
},
|
||||
"plasma-activities": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-activities-6.4.0.tar.xz",
|
||||
"hash": "sha256-Go8DS7iVx1d5jFvoeiDbVGlvRe7ePXG4uBXPZmz864w="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-activities-6.4.1.tar.xz",
|
||||
"hash": "sha256-DsBpK13LBfyC0ef3KFq4LaImndt9Axi49KYQONpE2WM="
|
||||
},
|
||||
"plasma-activities-stats": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-activities-stats-6.4.0.tar.xz",
|
||||
"hash": "sha256-kxNliQbYG/KW2emKwZeQuD6Ii6ifESPGKwpy+TjyjuY="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-activities-stats-6.4.1.tar.xz",
|
||||
"hash": "sha256-rfX0v6dY/0EwmXjvULv1/wpZbq+RNzhtS4cOe8wjMLc="
|
||||
},
|
||||
"plasma-browser-integration": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-browser-integration-6.4.0.tar.xz",
|
||||
"hash": "sha256-FH4LixBeR8o/xpTdLYbsvqp8PDFdi/PaDUtuNagp56Q="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-browser-integration-6.4.1.tar.xz",
|
||||
"hash": "sha256-eqDYwMci6fdjuu9cFTp/iC9JDbz5lWPQRye3WcXC1jQ="
|
||||
},
|
||||
"plasma-desktop": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-desktop-6.4.0.tar.xz",
|
||||
"hash": "sha256-GOEUAzwYLSY8k39bxBeTJSkx3NrCKwTUnTOgEJuyrrI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-desktop-6.4.1.tar.xz",
|
||||
"hash": "sha256-tc979WDIpK/1oSGc+kF6h2uYIHGju4AdKv9T2/GKBYQ="
|
||||
},
|
||||
"plasma-dialer": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-dialer-6.4.0.tar.xz",
|
||||
"hash": "sha256-pyPbCGLDWhw48Fn8zs8rUECrOiv/+gHPY7fh+yUh45A="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-dialer-6.4.1.tar.xz",
|
||||
"hash": "sha256-8bIXU1QRiWxHwQ4cc99Zsp9mQwU8cdfuHWXqLiUr0Q4="
|
||||
},
|
||||
"plasma-disks": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-disks-6.4.0.tar.xz",
|
||||
"hash": "sha256-lMle0b1JREjIHjU2Dci0muBazsExZR7IFxb0pSIY6pA="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-disks-6.4.1.tar.xz",
|
||||
"hash": "sha256-yY+aDVMimCqQhJfXzAKGeCVIYle44lRi0ZfzNgEcUxQ="
|
||||
},
|
||||
"plasma-firewall": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-firewall-6.4.0.tar.xz",
|
||||
"hash": "sha256-8MCE2Yxff3Kjc1X9vN/nwv8CBe0kAJAUQGqSRNZIRoU="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-firewall-6.4.1.tar.xz",
|
||||
"hash": "sha256-ctXVNJPuOQGEf+Y8+XamjX9gGwh40spnBOhkoFwPv5w="
|
||||
},
|
||||
"plasma-integration": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-integration-6.4.0.tar.xz",
|
||||
"hash": "sha256-pxhoIFKN72+Ie2Qu+nv7TE4UjRTmXvCreH/DWmLigdA="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-integration-6.4.1.tar.xz",
|
||||
"hash": "sha256-EoE9sNZoVVBXAammIi5qUTpVV4kDJfEMofy/eH2R7eM="
|
||||
},
|
||||
"plasma-mobile": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-mobile-6.4.0.tar.xz",
|
||||
"hash": "sha256-1m4fkOvV+ZPueDW3+K6suq0VtB5W3wqyq65Ve0Ck2Dg="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-mobile-6.4.1.tar.xz",
|
||||
"hash": "sha256-+1ivtVRjh7bYN7rGEyNXTgywKBvKob3gH0KKzsWZ8xY="
|
||||
},
|
||||
"plasma-nano": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-nano-6.4.0.tar.xz",
|
||||
"hash": "sha256-gF400TsjLpf5D3pU/DnLx5qU2ZZ83e3t4GAgKD4+n/E="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-nano-6.4.1.tar.xz",
|
||||
"hash": "sha256-dg9AAdpOMJqWH27gpbl+df+cyzLwQgcLNAz/cHhbMRM="
|
||||
},
|
||||
"plasma-nm": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-nm-6.4.0.tar.xz",
|
||||
"hash": "sha256-JZC7gTpX7UEdNwfrrUuo4tvE7V2DC/I1R/loYpcV1Tc="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-nm-6.4.1.tar.xz",
|
||||
"hash": "sha256-UdwzjlHWBuEx9OM9T7e7KOrYpJzWikYiUtySClkRHFA="
|
||||
},
|
||||
"plasma-pa": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-pa-6.4.0.tar.xz",
|
||||
"hash": "sha256-exm0FHhwiDWhWASU5VIYA7ybeUdLUO0ev5MYog4e0ag="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-pa-6.4.1.tar.xz",
|
||||
"hash": "sha256-C3lyY/Ug3n1zgbcFsW1e/Ul2ZMTzdhoty6k8axxKttE="
|
||||
},
|
||||
"plasma-sdk": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-sdk-6.4.0.tar.xz",
|
||||
"hash": "sha256-s/ExaxY7tearhpcDBuZjdgrpOBSkPtQ/Ky92ESisKIU="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-sdk-6.4.1.tar.xz",
|
||||
"hash": "sha256-c6hlAmveq0XI9ItQrGVvDmJrsEE+dkfAFtkGi8sPVEY="
|
||||
},
|
||||
"plasma-systemmonitor": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-systemmonitor-6.4.0.tar.xz",
|
||||
"hash": "sha256-lDac1svv9f+vNgXudmDqSqoD2VkoKw8g1lmpU64tl1o="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-systemmonitor-6.4.1.tar.xz",
|
||||
"hash": "sha256-sYENMpuBrDWvynX1/yiHtyTi/HsfnFEBmLh8KcuL3l8="
|
||||
},
|
||||
"plasma-thunderbolt": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-thunderbolt-6.4.0.tar.xz",
|
||||
"hash": "sha256-w92KudTZFGkp87OWftV/ZpXQpW+Q8oGWTRzwTa9uXI4="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-thunderbolt-6.4.1.tar.xz",
|
||||
"hash": "sha256-FSxKrKBrV5HBGyBdehA+gGHcX/qt/3T0/Q8Zhc/Jzj0="
|
||||
},
|
||||
"plasma-vault": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-vault-6.4.0.tar.xz",
|
||||
"hash": "sha256-zdDtq+GiFchWaMRzSfOsju2VpGG71WTWfsjfIXDq52w="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-vault-6.4.1.tar.xz",
|
||||
"hash": "sha256-ayOumkp28MaGltQ0awdjtD5STWBceFcNsy/RC4Znp2w="
|
||||
},
|
||||
"plasma-welcome": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-welcome-6.4.0.tar.xz",
|
||||
"hash": "sha256-Lw08NImQOoZYa4Otb7UrwVLhtFnkq+yC/wIrUbjStDY="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-welcome-6.4.1.tar.xz",
|
||||
"hash": "sha256-BpW/epqDX01kBq2bdjycyWwH14GVlMT1CIfrcnfnToA="
|
||||
},
|
||||
"plasma-workspace": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-workspace-6.4.0.tar.xz",
|
||||
"hash": "sha256-lh71T3/SHyEvjWMzAPG7BSBSSql5TkM64avhasBWCys="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-workspace-6.4.1.tar.xz",
|
||||
"hash": "sha256-IGe1OeV0Rbs1/DtYmk9feu4xVJkG4iDojYeQ168yruQ="
|
||||
},
|
||||
"plasma-workspace-wallpapers": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma-workspace-wallpapers-6.4.0.tar.xz",
|
||||
"hash": "sha256-zEs1PLI63zJos4sVxvb70lpjd0tJgkaPgORQ9gDTkwI="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma-workspace-wallpapers-6.4.1.tar.xz",
|
||||
"hash": "sha256-ckXn4lj1YoL+IUJZ+ughSV78ArO5GqnWo58r7Z9eYdc="
|
||||
},
|
||||
"plasma5support": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plasma5support-6.4.0.tar.xz",
|
||||
"hash": "sha256-OuNktBqGjQ/ZlHxTs9iHI5OLsIA/H4Yphfkztslz6EM="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plasma5support-6.4.1.tar.xz",
|
||||
"hash": "sha256-EXo7m806Y96DcZ2U85o0zM9kOnFDXISlxQWwRERrjas="
|
||||
},
|
||||
"plymouth-kcm": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/plymouth-kcm-6.4.0.tar.xz",
|
||||
"hash": "sha256-WW0OK4QQbLkS1Poo38mmLPppMAEPJ7aPw0ph2TQSWVM="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/plymouth-kcm-6.4.1.tar.xz",
|
||||
"hash": "sha256-KL2d+x5qiAoCsJ3ylJLBbF+7KAU6oqe3wTao4+cGxF0="
|
||||
},
|
||||
"polkit-kde-agent-1": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/polkit-kde-agent-1-6.4.0.tar.xz",
|
||||
"hash": "sha256-qKtd9qseoF5j7wjrvlNuE5PU9tbdSylzBWGfweh1FcU="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/polkit-kde-agent-1-6.4.1.tar.xz",
|
||||
"hash": "sha256-uxzAN3JTaDNEOdE9x94SxfUXs5g4XxyfUpVxpTkqkwI="
|
||||
},
|
||||
"powerdevil": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/powerdevil-6.4.0.tar.xz",
|
||||
"hash": "sha256-0K1Uy21MzznA1bfwx98vUbyZ/9P9bKdTjtP0HfxPZ34="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/powerdevil-6.4.1.tar.xz",
|
||||
"hash": "sha256-k+Q4HyU/npYHh/61/LhuoafA4peOOzAJrhkqhq5zRi8="
|
||||
},
|
||||
"print-manager": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/print-manager-6.4.0.tar.xz",
|
||||
"hash": "sha256-KrsouJRLPkxIQTyzG1TgeMn6jR/YwRWmFQcxA52Sy/0="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/print-manager-6.4.1.tar.xz",
|
||||
"hash": "sha256-kJbF8osp9hmb8Kzph2Nh8zZ7efII4FxKWTOdF9S8GfI="
|
||||
},
|
||||
"qqc2-breeze-style": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/qqc2-breeze-style-6.4.0.tar.xz",
|
||||
"hash": "sha256-S+kIS9VZdE2Awgs4k8K7tE3Bk/2TJPTbjSf2rQl++kw="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/qqc2-breeze-style-6.4.1.tar.xz",
|
||||
"hash": "sha256-YI/1NtUTVx861Kyv1JYOwLWiq/z/MZMhS6wnonR5a+c="
|
||||
},
|
||||
"sddm-kcm": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/sddm-kcm-6.4.0.tar.xz",
|
||||
"hash": "sha256-N4t+twvSPMm7ZUs2a4X7YVgkdqvECIYRU0vDyJGPa/I="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/sddm-kcm-6.4.1.tar.xz",
|
||||
"hash": "sha256-otENV7QyyCJ83OGTrbuVAAaaKrHY1kYsahgZknXLnsY="
|
||||
},
|
||||
"spacebar": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/spacebar-6.4.0.tar.xz",
|
||||
"hash": "sha256-LHSJ/AczyJjSTexA0fuOUHFAMcJkFPaCYma9PJnAFYA="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/spacebar-6.4.1.tar.xz",
|
||||
"hash": "sha256-X/eec6cvsOSdE+PTQwPTRcqzP6T/IkdQWErePFJE/4k="
|
||||
},
|
||||
"spectacle": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/spectacle-6.4.0.tar.xz",
|
||||
"hash": "sha256-cxdWeX6+/p9evbYymwz0zdX2wWmq8WpYwpQF/5emprA="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/spectacle-6.4.1.tar.xz",
|
||||
"hash": "sha256-VHuMxlFzCRYQSosTE1BIFOyn/mpavOJUwQs3/6GxPjQ="
|
||||
},
|
||||
"systemsettings": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/systemsettings-6.4.0.tar.xz",
|
||||
"hash": "sha256-TDhVGapA6Q3LCxoLBw0zE/2e1fszyWPqVFnOXTFpLz8="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/systemsettings-6.4.1.tar.xz",
|
||||
"hash": "sha256-on8xKikqxMXD76GvcecMqDTX7I6PN6cQz4WuLXu+/5U="
|
||||
},
|
||||
"wacomtablet": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/wacomtablet-6.4.0.tar.xz",
|
||||
"hash": "sha256-c3FmxmiOSOIdTaNp3C83yG/kjx6rv4ndjPJ4WeGiltk="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/wacomtablet-6.4.1.tar.xz",
|
||||
"hash": "sha256-9n38GT270K5Rxt8IWb6HpNXtae4oO64HzpG0JF++4NE="
|
||||
},
|
||||
"xdg-desktop-portal-kde": {
|
||||
"version": "6.4.0",
|
||||
"url": "mirror://kde/stable/plasma/6.4.0/xdg-desktop-portal-kde-6.4.0.tar.xz",
|
||||
"hash": "sha256-ANt7FVEUaw2pEHi/VAyir1bJ0g+fJUaeJYOdCUVams4="
|
||||
"version": "6.4.1",
|
||||
"url": "mirror://kde/stable/plasma/6.4.1/xdg-desktop-portal-kde-6.4.1.tar.xz",
|
||||
"hash": "sha256-HwHWKfaBjkiqas+D9YwH8N3z4b8qHstEgDr2XN4RlYM="
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
mkKdeDerivation,
|
||||
pkg-config,
|
||||
systemd,
|
||||
elfutils,
|
||||
gdb,
|
||||
python3,
|
||||
replaceVars,
|
||||
@ -20,8 +21,9 @@ mkKdeDerivation {
|
||||
pname = "drkonqi";
|
||||
|
||||
patches = [
|
||||
(replaceVars ./gdb-path.patch {
|
||||
(replaceVars ./hardcode-paths.patch {
|
||||
gdb = "${gdb'}/bin/gdb";
|
||||
eu-unstrip = "${elfutils}/bin/eu-unstrip";
|
||||
})
|
||||
];
|
||||
|
||||
|
@ -1,5 +1,18 @@
|
||||
diff --git a/src/data/gdb_preamble/preamble.py b/src/data/gdb_preamble/preamble.py
|
||||
index 4855231b5..a488025c1 100644
|
||||
--- a/src/data/gdb_preamble/preamble.py
|
||||
+++ b/src/data/gdb_preamble/preamble.py
|
||||
@@ -773,7 +773,7 @@ def resolve_modules():
|
||||
# core doesn't contain one. That makes the ids a bit unreliable but still better than nothing I suppose.
|
||||
# Ultimately we'll want to use gdb here.
|
||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=32844
|
||||
- output = get_stdout(['eu-unstrip', "--list-only", f"--core={corefile}"], env=env)
|
||||
+ output = get_stdout(['@eu-unstrip@', "--list-only", f"--core={corefile}"], env=env)
|
||||
for line in output.splitlines():
|
||||
image = CoreImage(line)
|
||||
if image.valid:
|
||||
diff --git a/src/debugger.cpp b/src/debugger.cpp
|
||||
index 946bdd12..5c24b371 100644
|
||||
index 946bdd12e..5c24b3713 100644
|
||||
--- a/src/debugger.cpp
|
||||
+++ b/src/debugger.cpp
|
||||
@@ -36,12 +36,12 @@ QList<Debugger> Debugger::availableInternalDebuggers(const QString &backend)
|
@ -2,7 +2,7 @@
|
||||
# Do not edit!
|
||||
|
||||
{
|
||||
version = "2025.6.1";
|
||||
version = "2025.6.2";
|
||||
components = {
|
||||
"3_day_blinds" =
|
||||
ps: with ps; [
|
||||
|
@ -386,7 +386,7 @@ let
|
||||
extraBuildInputs = extraPackages python.pkgs;
|
||||
|
||||
# Don't forget to run update-component-packages.py after updating
|
||||
hassVersion = "2025.6.1";
|
||||
hassVersion = "2025.6.2";
|
||||
|
||||
in
|
||||
python.pkgs.buildPythonApplication rec {
|
||||
@ -407,13 +407,13 @@ python.pkgs.buildPythonApplication rec {
|
||||
owner = "home-assistant";
|
||||
repo = "core";
|
||||
tag = version;
|
||||
hash = "sha256-Pp2IIpVfzYE4BBJEq4Ll2s0vgsqxAApE8TmVd1zAg38=";
|
||||
hash = "sha256-5+L687sUD+e8F9UYnFURSUMG2/USuOpNu5a9By0yZ/g=";
|
||||
};
|
||||
|
||||
# Secondary source is pypi sdist for translations
|
||||
sdist = fetchPypi {
|
||||
inherit pname version;
|
||||
hash = "sha256-yc4tEyR3xpo4x9daWEwXFJBhSH3xeOc2ckO+7LWVRlA=";
|
||||
hash = "sha256-DLqP9/b68ikGuxrvFiJCqguE2WgnKP0HtiU2X7tUbkE=";
|
||||
};
|
||||
|
||||
build-system = with python.pkgs; [
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "pytest-homeassistant-custom-component";
|
||||
version = "0.13.251";
|
||||
version = "0.13.253";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.13";
|
||||
@ -27,7 +27,7 @@ buildPythonPackage rec {
|
||||
owner = "MatthewFlamm";
|
||||
repo = "pytest-homeassistant-custom-component";
|
||||
rev = "refs/tags/${version}";
|
||||
hash = "sha256-S+BC3ohAsY11SdZZdlETskCAopKeohgb16vMpko01YY=";
|
||||
hash = "sha256-P2ZYOHUc8tTzwSSUGKdm+zQD4hgVpewkKSg3GRpF70M=";
|
||||
};
|
||||
|
||||
build-system = [ setuptools ];
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "homeassistant-stubs";
|
||||
version = "2025.6.1";
|
||||
version = "2025.6.2";
|
||||
pyproject = true;
|
||||
|
||||
disabled = python.version != home-assistant.python.version;
|
||||
@ -19,7 +19,7 @@ buildPythonPackage rec {
|
||||
owner = "KapJI";
|
||||
repo = "homeassistant-stubs";
|
||||
tag = version;
|
||||
hash = "sha256-JTSIVe25EXZ7Bslkcz8/wLFJDx3f78OGsfDodtHMZ/Y=";
|
||||
hash = "sha256-Hdk7Lf0J4wgx+xhrKtBgBtO+DzCqQ2sih5DaoYcsWww=";
|
||||
};
|
||||
|
||||
build-system = [
|
||||
|
34
pkgs/servers/sql/postgresql/ext/ip4r.nix
Normal file
34
pkgs/servers/sql/postgresql/ext/ip4r.nix
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
fetchFromGitHub,
|
||||
lib,
|
||||
postgresql,
|
||||
postgresqlBuildExtension,
|
||||
postgresqlTestExtension,
|
||||
}:
|
||||
|
||||
postgresqlBuildExtension (finalAttrs: {
|
||||
pname = "ip4r";
|
||||
version = "2.4.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "RhodiumToad";
|
||||
repo = "ip4r";
|
||||
tag = "${finalAttrs.version}";
|
||||
hash = "sha256-3chAD4f4A6VlXVSI0kfC/ANcnFy4vBp4FZpT6QRAueQ=";
|
||||
};
|
||||
|
||||
passthru.tests = {
|
||||
extension = postgresqlTestExtension {
|
||||
inherit (finalAttrs) finalPackage;
|
||||
sql = "CREATE EXTENSION ip4r;";
|
||||
};
|
||||
};
|
||||
|
||||
meta = {
|
||||
description = "IPv4/v6 and IPv4/v6 range index type for PostgreSQL";
|
||||
homepage = "https://github.com/RhodiumToad/ip4r";
|
||||
license = lib.licenses.postgresql;
|
||||
maintainers = with lib.maintainers; [ lukegb ];
|
||||
inherit (postgresql.meta) platforms;
|
||||
};
|
||||
})
|
@ -9,6 +9,7 @@
|
||||
# `lix-doc`.
|
||||
docCargoDeps ? null,
|
||||
patches ? [ ],
|
||||
knownVulnerabilities ? [ ],
|
||||
}@args:
|
||||
|
||||
assert lib.assertMsg (
|
||||
@ -390,5 +391,6 @@ stdenv.mkDerivation (finalAttrs: {
|
||||
platforms = lib.platforms.unix;
|
||||
outputsToInstall = [ "out" ] ++ lib.optional enableDocumentation "man";
|
||||
mainProgram = "nix";
|
||||
inherit knownVulnerabilities;
|
||||
};
|
||||
})
|
||||
|
@ -133,6 +133,10 @@ lib.makeExtensible (self: {
|
||||
sourceRoot = "${src.name or src}/lix-doc";
|
||||
hash = "sha256-VPcrf78gfLlkTRrcbLkPgLOk0o6lsOJBm6HYLvavpNU=";
|
||||
};
|
||||
|
||||
knownVulnerabilities = [
|
||||
"Lix 2.90 is vulnerable to CVE-2025-46415 and CVE-2025-46416 and will not receive updates."
|
||||
];
|
||||
};
|
||||
|
||||
nix-eval-jobs-args = {
|
||||
@ -150,13 +154,13 @@ lib.makeExtensible (self: {
|
||||
attrName = "lix_2_91";
|
||||
|
||||
lix-args = rec {
|
||||
version = "2.91.1";
|
||||
version = "2.91.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "lix-project";
|
||||
repo = "lix";
|
||||
rev = version;
|
||||
hash = "sha256-hiGtfzxFkDc9TSYsb96Whg0vnqBVV7CUxyscZNhed0U=";
|
||||
hash = "sha256-TkRjskDnxMPugdLQE/LqIh59RYQFJLYpIuL8YZva2lM=";
|
||||
};
|
||||
|
||||
docCargoDeps = rustPlatform.fetchCargoVendor {
|
||||
@ -182,13 +186,13 @@ lib.makeExtensible (self: {
|
||||
attrName = "lix_2_92";
|
||||
|
||||
lix-args = rec {
|
||||
version = "2.92.0";
|
||||
version = "2.92.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "lix-project";
|
||||
repo = "lix";
|
||||
rev = version;
|
||||
hash = "sha256-CCKIAE84dzkrnlxJCKFyffAxP3yfsOAbdvydUGqq24g=";
|
||||
hash = "sha256-D7YepvFkGE4K1rOkEYA1P6wGj/eFbQXb03nLdBRjjwA=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoVendor {
|
||||
@ -212,14 +216,14 @@ lib.makeExtensible (self: {
|
||||
attrName = "lix_2_93";
|
||||
|
||||
lix-args = rec {
|
||||
version = "2.93.0";
|
||||
version = "2.93.1";
|
||||
|
||||
src = fetchFromGitea {
|
||||
domain = "git.lix.systems";
|
||||
owner = "lix-project";
|
||||
repo = "lix";
|
||||
rev = version;
|
||||
hash = "sha256-hsFe4Tsqqg4l+FfQWphDtjC79WzNCZbEFhHI8j2KJzw=";
|
||||
hash = "sha256-LmQhjQ7c+AOkwhvR9GFgJOy8oHW35MoQRELtrwyVnPw=";
|
||||
};
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoVendor {
|
||||
@ -249,6 +253,10 @@ lib.makeExtensible (self: {
|
||||
inherit src;
|
||||
hash = "sha256-YMyNOXdlx0I30SkcmdW/6DU0BYc3ZOa2FMJSKMkr7I8=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
./patches/LIX_HEAD_CVE-2025-46415_46416.patch
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -111,7 +111,7 @@ let
|
||||
"shadowstack"
|
||||
] ++ lib.optional stdenv.hostPlatform.isMusl "fortify";
|
||||
|
||||
nativeInstallCheckInputs = lib.optional atLeast224 [
|
||||
nativeInstallCheckInputs = lib.optionals atLeast224 [
|
||||
git
|
||||
man
|
||||
];
|
||||
|
@ -171,34 +171,39 @@ lib.makeExtensible (
|
||||
nix_2_24 = commonAutoconf {
|
||||
version = "2.24.14";
|
||||
hash = "sha256-SthMCsj6POjawLnJq9+lj/UzObX9skaeN1UGmMZiwTY=";
|
||||
patches = [ ./patches/ghsa-g948-229j-48j3-2.24.patch ];
|
||||
self_attribute_name = "nix_2_24";
|
||||
};
|
||||
|
||||
nix_2_26 = commonMeson {
|
||||
version = "2.26.3";
|
||||
hash = "sha256-5ZV8YqU8mfFmoAMiUEuBqNwk0T3vUR//x1D12BiYCeY=";
|
||||
patches = [ ./patches/ghsa-g948-229j-48j3-2.26.patch ];
|
||||
self_attribute_name = "nix_2_26";
|
||||
};
|
||||
|
||||
nix_2_28 = commonMeson {
|
||||
version = "2.28.3";
|
||||
hash = "sha256-TjZp5ITSUvNRAzNznmkZRQxNRzMLiSAplz4bV2T8cbs=";
|
||||
patches = [ ./patches/ghsa-g948-229j-48j3-2.28.patch ];
|
||||
self_attribute_name = "nix_2_28";
|
||||
};
|
||||
|
||||
nixComponents_2_29 = nixDependencies.callPackage ./modular/packages.nix rec {
|
||||
version = "2.29.0";
|
||||
inherit (self.nix_2_24.meta) maintainers teams;
|
||||
otherSplices = generateSplicesForNixComponents "nixComponents_2_29";
|
||||
src = fetchFromGitHub {
|
||||
# FIXME: back to NixOS org once they fix it
|
||||
owner = "vcunat";
|
||||
repo = "nix";
|
||||
rev = "p/jq-1.8.0"; # just a tiny test-only patch atop 2.29.0
|
||||
# see https://github.com/NixOS/nix/pull/13371
|
||||
hash = "sha256-F2ZODsET4cBsgsyOi8Sg/quESU0DnrYri0hYniqu37k=";
|
||||
};
|
||||
};
|
||||
nixComponents_2_29 =
|
||||
(nixDependencies.callPackage ./modular/packages.nix rec {
|
||||
version = "2.29.0";
|
||||
inherit (self.nix_2_24.meta) maintainers teams;
|
||||
otherSplices = generateSplicesForNixComponents "nixComponents_2_29";
|
||||
src = fetchFromGitHub {
|
||||
# FIXME: back to NixOS org once they fix it
|
||||
owner = "vcunat";
|
||||
repo = "nix";
|
||||
rev = "p/jq-1.8.0"; # just a tiny test-only patch atop 2.29.0
|
||||
# see https://github.com/NixOS/nix/pull/13371
|
||||
hash = "sha256-F2ZODsET4cBsgsyOi8Sg/quESU0DnrYri0hYniqu37k=";
|
||||
};
|
||||
}).appendPatches
|
||||
[ ./patches/ghsa-g948-229j-48j3-2.29.patch ];
|
||||
|
||||
nix_2_29 = addTests "nix_2_29" self.nixComponents_2_29.nix-everything;
|
||||
|
||||
|
@ -27,9 +27,7 @@ mkMesonLibrary (finalAttrs: {
|
||||
[
|
||||
brotli
|
||||
]
|
||||
++ lib.optional (lib.versionAtLeast version "2.27") [
|
||||
libblake3
|
||||
]
|
||||
++ lib.optional (lib.versionAtLeast version "2.27") libblake3
|
||||
++ [
|
||||
libsodium
|
||||
openssl
|
||||
|
@ -0,0 +1,436 @@
|
||||
From b0fab9f90b397a2b02f41df5f467ae3cf8b91c3c Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu, 19 Jun 2025 16:20:34 +0200
|
||||
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Squashed commit of the following:
|
||||
|
||||
commit 04fff3a637d455cbb1d75937a235950e43008db9
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:30:32 2025 +0200
|
||||
|
||||
Chown structured attr files safely
|
||||
|
||||
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:14:04 2025 +0200
|
||||
|
||||
Replace 'bool sync' with an enum for clarity
|
||||
|
||||
And drop writeFileAndSync().
|
||||
|
||||
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:35:28 2025 +0200
|
||||
|
||||
Drop guessOrInventPathFromFD()
|
||||
|
||||
No need to do hacky stuff like that when we already know the original path.
|
||||
|
||||
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:15:58 2025 +0200
|
||||
|
||||
Tweak comment
|
||||
|
||||
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Thu Mar 27 12:22:26 2025 +0100
|
||||
|
||||
libstore: ensure that temporary directory is always 0o000 before deletion
|
||||
|
||||
In the case the deletion fails, we should ensure that the temporary
|
||||
directory cannot be used for nefarious purposes.
|
||||
|
||||
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 12:42:55 2025 +0100
|
||||
|
||||
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
|
||||
|
||||
When calling `_deletePath` with a parent file descriptor, `openat` is
|
||||
made effective by using relative paths to the directory file descriptor.
|
||||
|
||||
To avoid the problem, the signature is changed to resist misuse with an
|
||||
assert in the prologue of the function.
|
||||
|
||||
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:07:47 2025 +0100
|
||||
|
||||
libstore: ensure that `passAsFile` is created in the original temp dir
|
||||
|
||||
This ensures that `passAsFile` data is created inside the expected
|
||||
temporary build directory by `openat()` from the parent directory file
|
||||
descriptor.
|
||||
|
||||
This avoids a TOCTOU which is part of the attack chain of CVE-????.
|
||||
|
||||
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:06:03 2025 +0100
|
||||
|
||||
libutil: writeFile variant for file descriptors
|
||||
|
||||
`writeFile` lose its `sync` boolean flag to make things simpler.
|
||||
|
||||
A new `writeFileAndSync` function is created and all call sites are
|
||||
converted to it.
|
||||
|
||||
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:05:34 2025 +0100
|
||||
|
||||
libstore: chown to builder variant for file descriptors
|
||||
|
||||
We use it immediately for the build temporary directory.
|
||||
|
||||
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:59 2025 +0100
|
||||
|
||||
libstore: open build directory as a dirfd as well
|
||||
|
||||
We now keep around a proper AutoCloseFD around the temporary directory
|
||||
which we plan to use for openat operations and avoiding the build
|
||||
directory being swapped out while we are doing something else.
|
||||
|
||||
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:12 2025 +0100
|
||||
|
||||
libutil: guess or invent a path from file descriptors
|
||||
|
||||
This is useful for certain error recovery paths (no pun intended) that
|
||||
does not thread through the original path name.
|
||||
|
||||
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
|
||||
---
|
||||
src/libstore/local-store.cc | 6 +--
|
||||
.../unix/build/local-derivation-goal.cc | 46 ++++++++++++++----
|
||||
.../unix/build/local-derivation-goal.hh | 20 ++++++++
|
||||
src/libutil/file-system.cc | 47 +++++++++++--------
|
||||
src/libutil/file-system.hh | 8 +++-
|
||||
5 files changed, 94 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
|
||||
index c6e3af456..c5489444e 100644
|
||||
--- a/src/libstore/local-store.cc
|
||||
+++ b/src/libstore/local-store.cc
|
||||
@@ -187,7 +187,7 @@ void migrateCASchema(SQLite& db, Path schemaPath, AutoCloseFD& lockFd)
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
- writeFile(schemaPath, fmt("%d", nixCASchemaVersion), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%d", nixCASchemaVersion), 0666, FsSync::Yes);
|
||||
lockFile(lockFd.get(), ltRead, true);
|
||||
}
|
||||
}
|
||||
@@ -345,7 +345,7 @@ LocalStore::LocalStore(
|
||||
else if (curSchema == 0) { /* new store */
|
||||
curSchema = nixSchemaVersion;
|
||||
openDB(*state, true);
|
||||
- writeFile(schemaPath, fmt("%1%", curSchema), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
|
||||
}
|
||||
|
||||
else if (curSchema < nixSchemaVersion) {
|
||||
@@ -394,7 +394,7 @@ LocalStore::LocalStore(
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
|
||||
|
||||
lockFile(globalLock.get(), ltRead, true);
|
||||
}
|
||||
diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc
|
||||
index f8824e9ce..82c79f361 100644
|
||||
--- a/src/libstore/unix/build/local-derivation-goal.cc
|
||||
+++ b/src/libstore/unix/build/local-derivation-goal.cc
|
||||
@@ -526,7 +526,14 @@ void LocalDerivationGoal::startBuilder()
|
||||
} else {
|
||||
tmpDir = topTmpDir;
|
||||
}
|
||||
- chownToBuilder(tmpDir);
|
||||
+
|
||||
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
|
||||
+ POSIX semantics.*/
|
||||
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
|
||||
+ if (!tmpDirFd)
|
||||
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
|
||||
+
|
||||
+ chownToBuilder(tmpDirFd.get(), tmpDir);
|
||||
|
||||
for (auto & [outputName, status] : initialOutputs) {
|
||||
/* Set scratch path we'll actually use during the build.
|
||||
@@ -1110,9 +1117,7 @@ void LocalDerivationGoal::initTmpDir() {
|
||||
} else {
|
||||
auto hash = hashString(HashAlgorithm::SHA256, i.first);
|
||||
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
|
||||
- Path p = tmpDir + "/" + fn;
|
||||
- writeFile(p, rewriteStrings(i.second, inputRewrites));
|
||||
- chownToBuilder(p);
|
||||
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
|
||||
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
|
||||
}
|
||||
}
|
||||
@@ -1217,11 +1222,9 @@ void LocalDerivationGoal::writeStructuredAttrs()
|
||||
|
||||
auto jsonSh = writeStructuredAttrsShell(json);
|
||||
|
||||
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.sh");
|
||||
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
|
||||
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.json");
|
||||
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
|
||||
}
|
||||
}
|
||||
@@ -1730,6 +1733,24 @@ void setupSeccomp()
|
||||
#endif
|
||||
}
|
||||
|
||||
+void LocalDerivationGoal::chownToBuilder(int fd, const Path & path)
|
||||
+{
|
||||
+ if (!buildUser) return;
|
||||
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
|
||||
+ throw SysError("cannot change ownership of file '%1%'", path);
|
||||
+}
|
||||
+
|
||||
+void LocalDerivationGoal::writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents)
|
||||
+{
|
||||
+ auto path = std::filesystem::path(tmpDir) / name;
|
||||
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
|
||||
+ if (!fd)
|
||||
+ throw SysError("creating file %s", path);
|
||||
+ writeFile(fd, path, contents);
|
||||
+ chownToBuilder(fd.get(), path);
|
||||
+}
|
||||
|
||||
void LocalDerivationGoal::runChild()
|
||||
{
|
||||
@@ -3006,6 +3027,15 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||
void LocalDerivationGoal::deleteTmpDir(bool force)
|
||||
{
|
||||
if (topTmpDir != "") {
|
||||
+ /* As an extra precaution, even in the event of `deletePath` failing to
|
||||
+ * clean up, the `tmpDir` will be chowned as if we were to move
|
||||
+ * it inside the Nix store.
|
||||
+ *
|
||||
+ * This hardens against an attack which smuggles a file descriptor
|
||||
+ * to make use of the temporary directory.
|
||||
+ */
|
||||
+ chmod(topTmpDir.c_str(), 0000);
|
||||
+
|
||||
/* Don't keep temporary directories for builtins because they
|
||||
might have privileged stuff (like a copy of netrc). */
|
||||
if (settings.keepFailed && !force && !drv->isBuiltin()) {
|
||||
diff --git a/src/libstore/unix/build/local-derivation-goal.hh b/src/libstore/unix/build/local-derivation-goal.hh
|
||||
index bf25cf2a6..69c517c4a 100644
|
||||
--- a/src/libstore/unix/build/local-derivation-goal.hh
|
||||
+++ b/src/libstore/unix/build/local-derivation-goal.hh
|
||||
@@ -37,6 +37,11 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
*/
|
||||
Path topTmpDir;
|
||||
|
||||
+ /**
|
||||
+ * The file descriptor of the temporary directory.
|
||||
+ */
|
||||
+ AutoCloseFD tmpDirFd;
|
||||
+
|
||||
/**
|
||||
* The path of the temporary directory in the sandbox.
|
||||
*/
|
||||
@@ -232,9 +237,24 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
|
||||
/**
|
||||
* Make a file owned by the builder.
|
||||
+ *
|
||||
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
|
||||
+ * It's only safe to call in a child of a directory only visible to the owner.
|
||||
*/
|
||||
void chownToBuilder(const Path & path);
|
||||
|
||||
+ /**
|
||||
+ * Make a file owned by the builder addressed by its file descriptor.
|
||||
+ */
|
||||
+ void chownToBuilder(int fd, const Path & path);
|
||||
+
|
||||
+ /**
|
||||
+ * Create a file in `tmpDir` owned by the builder.
|
||||
+ */
|
||||
+ void writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents);
|
||||
+
|
||||
int getChildStatus() override;
|
||||
|
||||
/**
|
||||
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
|
||||
index 8ec38e73b..554214d66 100644
|
||||
--- a/src/libutil/file-system.cc
|
||||
+++ b/src/libutil/file-system.cc
|
||||
@@ -247,7 +247,7 @@ void readFile(const Path & path, Sink & sink)
|
||||
}
|
||||
|
||||
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -257,22 +257,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
, mode));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
+
|
||||
+ writeFile(fd, path, s, mode, sync);
|
||||
+
|
||||
+ /* Close explicitly to propagate the exceptions. */
|
||||
+ fd.close();
|
||||
+}
|
||||
+
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
|
||||
+{
|
||||
+ assert(fd);
|
||||
try {
|
||||
writeFull(fd.get(), s);
|
||||
+
|
||||
+ if (sync == FsSync::Yes)
|
||||
+ fd.fsync();
|
||||
+
|
||||
} catch (Error & e) {
|
||||
- e.addTrace({}, "writing file '%1%'", path);
|
||||
+ e.addTrace({}, "writing file '%1%'", origPath);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
- fd.fsync();
|
||||
- // Explicitly close to make sure exceptions are propagated.
|
||||
- fd.close();
|
||||
- if (sync)
|
||||
- syncParent(path);
|
||||
}
|
||||
|
||||
-
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -296,11 +303,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
e.addTrace({}, "writing file '%1%'", path);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
fd.fsync();
|
||||
// Explicitly close to make sure exceptions are propagated.
|
||||
fd.close();
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
syncParent(path);
|
||||
}
|
||||
|
||||
@@ -318,7 +325,8 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
#ifndef _WIN32
|
||||
checkInterrupt();
|
||||
|
||||
- std::string name(baseNameOf(path.native()));
|
||||
+ std::string name(path.filename());
|
||||
+ assert(name != "." && name != ".." && !name.empty());
|
||||
|
||||
struct stat st;
|
||||
if (fstatat(parentfd, name.c_str(), &st,
|
||||
@@ -359,7 +367,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
throw SysError("chmod '%1%'", path);
|
||||
}
|
||||
|
||||
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
|
||||
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||
if (fd == -1)
|
||||
throw SysError("opening directory '%1%'", path);
|
||||
AutoCloseDir dir(fdopendir(fd));
|
||||
@@ -371,7 +379,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
checkInterrupt();
|
||||
std::string childName = dirent->d_name;
|
||||
if (childName == "." || childName == "..") continue;
|
||||
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
|
||||
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
|
||||
}
|
||||
if (errno) throw SysError("reading directory '%1%'", path);
|
||||
}
|
||||
@@ -389,14 +397,13 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
|
||||
static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
|
||||
{
|
||||
- Path dir = dirOf(path.string());
|
||||
- if (dir == "")
|
||||
- dir = "/";
|
||||
+ assert(path.is_absolute());
|
||||
+ assert(path.parent_path() != path);
|
||||
|
||||
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
|
||||
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
|
||||
if (!dirfd) {
|
||||
if (errno == ENOENT) return;
|
||||
- throw SysError("opening directory '%1%'", path);
|
||||
+ throw SysError("opening directory %s", path.parent_path());
|
||||
}
|
||||
|
||||
_deletePath(dirfd.get(), path, bytesFreed);
|
||||
diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh
|
||||
index ed1112c7e..32b84456d 100644
|
||||
--- a/src/libutil/file-system.hh
|
||||
+++ b/src/libutil/file-system.hh
|
||||
@@ -148,12 +148,16 @@ Descriptor openDirectory(const std::filesystem::path & path);
|
||||
std::string readFile(const Path & path);
|
||||
void readFile(const Path & path, Sink & sink);
|
||||
|
||||
+enum struct FsSync { Yes, No };
|
||||
+
|
||||
/**
|
||||
* Write a string to a file.
|
||||
*/
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
|
||||
/**
|
||||
* Flush a file's parent directory to disk
|
||||
--
|
||||
2.44.1
|
||||
|
@ -0,0 +1,463 @@
|
||||
From 787e012f26761e1455e711ab4ceedaa2c740621c Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu, 19 Jun 2025 16:20:34 +0200
|
||||
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Squashed commit of the following:
|
||||
|
||||
commit 04fff3a637d455cbb1d75937a235950e43008db9
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:30:32 2025 +0200
|
||||
|
||||
Chown structured attr files safely
|
||||
|
||||
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:14:04 2025 +0200
|
||||
|
||||
Replace 'bool sync' with an enum for clarity
|
||||
|
||||
And drop writeFileAndSync().
|
||||
|
||||
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:35:28 2025 +0200
|
||||
|
||||
Drop guessOrInventPathFromFD()
|
||||
|
||||
No need to do hacky stuff like that when we already know the original path.
|
||||
|
||||
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:15:58 2025 +0200
|
||||
|
||||
Tweak comment
|
||||
|
||||
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Thu Mar 27 12:22:26 2025 +0100
|
||||
|
||||
libstore: ensure that temporary directory is always 0o000 before deletion
|
||||
|
||||
In the case the deletion fails, we should ensure that the temporary
|
||||
directory cannot be used for nefarious purposes.
|
||||
|
||||
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 12:42:55 2025 +0100
|
||||
|
||||
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
|
||||
|
||||
When calling `_deletePath` with a parent file descriptor, `openat` is
|
||||
made effective by using relative paths to the directory file descriptor.
|
||||
|
||||
To avoid the problem, the signature is changed to resist misuse with an
|
||||
assert in the prologue of the function.
|
||||
|
||||
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:07:47 2025 +0100
|
||||
|
||||
libstore: ensure that `passAsFile` is created in the original temp dir
|
||||
|
||||
This ensures that `passAsFile` data is created inside the expected
|
||||
temporary build directory by `openat()` from the parent directory file
|
||||
descriptor.
|
||||
|
||||
This avoids a TOCTOU which is part of the attack chain of CVE-????.
|
||||
|
||||
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:06:03 2025 +0100
|
||||
|
||||
libutil: writeFile variant for file descriptors
|
||||
|
||||
`writeFile` lose its `sync` boolean flag to make things simpler.
|
||||
|
||||
A new `writeFileAndSync` function is created and all call sites are
|
||||
converted to it.
|
||||
|
||||
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:05:34 2025 +0100
|
||||
|
||||
libstore: chown to builder variant for file descriptors
|
||||
|
||||
We use it immediately for the build temporary directory.
|
||||
|
||||
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:59 2025 +0100
|
||||
|
||||
libstore: open build directory as a dirfd as well
|
||||
|
||||
We now keep around a proper AutoCloseFD around the temporary directory
|
||||
which we plan to use for openat operations and avoiding the build
|
||||
directory being swapped out while we are doing something else.
|
||||
|
||||
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:12 2025 +0100
|
||||
|
||||
libutil: guess or invent a path from file descriptors
|
||||
|
||||
This is useful for certain error recovery paths (no pun intended) that
|
||||
does not thread through the original path name.
|
||||
|
||||
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
|
||||
---
|
||||
src/libstore/local-store.cc | 6 +--
|
||||
.../unix/build/local-derivation-goal.cc | 46 ++++++++++++++----
|
||||
.../unix/build/local-derivation-goal.hh | 20 ++++++++
|
||||
src/libutil/file-content-address.cc | 2 +-
|
||||
src/libutil/file-system.cc | 47 +++++++++++--------
|
||||
src/libutil/file-system.hh | 14 ++++--
|
||||
6 files changed, 99 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
|
||||
index 9a7a941b6..c0c808e0a 100644
|
||||
--- a/src/libstore/local-store.cc
|
||||
+++ b/src/libstore/local-store.cc
|
||||
@@ -116,7 +116,7 @@ LocalStore::LocalStore(
|
||||
state->stmts = std::make_unique<State::Stmts>();
|
||||
|
||||
/* Create missing state directories if they don't already exist. */
|
||||
- createDirs(realStoreDir);
|
||||
+ createDirs(realStoreDir.get());
|
||||
if (readOnly) {
|
||||
experimentalFeatureSettings.require(Xp::ReadOnlyLocalStore);
|
||||
} else {
|
||||
@@ -248,7 +248,7 @@ LocalStore::LocalStore(
|
||||
else if (curSchema == 0) { /* new store */
|
||||
curSchema = nixSchemaVersion;
|
||||
openDB(*state, true);
|
||||
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
|
||||
}
|
||||
|
||||
else if (curSchema < nixSchemaVersion) {
|
||||
@@ -299,7 +299,7 @@ LocalStore::LocalStore(
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
|
||||
|
||||
lockFile(globalLock.get(), ltRead, true);
|
||||
}
|
||||
diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc
|
||||
index 5b9bc0bb0..80309e332 100644
|
||||
--- a/src/libstore/unix/build/local-derivation-goal.cc
|
||||
+++ b/src/libstore/unix/build/local-derivation-goal.cc
|
||||
@@ -559,7 +559,14 @@ void LocalDerivationGoal::startBuilder()
|
||||
} else {
|
||||
tmpDir = topTmpDir;
|
||||
}
|
||||
- chownToBuilder(tmpDir);
|
||||
+
|
||||
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
|
||||
+ POSIX semantics.*/
|
||||
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
|
||||
+ if (!tmpDirFd)
|
||||
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
|
||||
+
|
||||
+ chownToBuilder(tmpDirFd.get(), tmpDir);
|
||||
|
||||
for (auto & [outputName, status] : initialOutputs) {
|
||||
/* Set scratch path we'll actually use during the build.
|
||||
@@ -1157,9 +1164,7 @@ void LocalDerivationGoal::initTmpDir()
|
||||
} else {
|
||||
auto hash = hashString(HashAlgorithm::SHA256, i.first);
|
||||
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
|
||||
- Path p = tmpDir + "/" + fn;
|
||||
- writeFile(p, rewriteStrings(i.second, inputRewrites));
|
||||
- chownToBuilder(p);
|
||||
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
|
||||
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
|
||||
}
|
||||
}
|
||||
@@ -1264,11 +1269,9 @@ void LocalDerivationGoal::writeStructuredAttrs()
|
||||
|
||||
auto jsonSh = writeStructuredAttrsShell(json);
|
||||
|
||||
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.sh");
|
||||
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
|
||||
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.json");
|
||||
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
|
||||
}
|
||||
}
|
||||
@@ -1779,6 +1782,24 @@ void setupSeccomp()
|
||||
#endif
|
||||
}
|
||||
|
||||
+void LocalDerivationGoal::chownToBuilder(int fd, const Path & path)
|
||||
+{
|
||||
+ if (!buildUser) return;
|
||||
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
|
||||
+ throw SysError("cannot change ownership of file '%1%'", path);
|
||||
+}
|
||||
+
|
||||
+void LocalDerivationGoal::writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents)
|
||||
+{
|
||||
+ auto path = std::filesystem::path(tmpDir) / name;
|
||||
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
|
||||
+ if (!fd)
|
||||
+ throw SysError("creating file %s", path);
|
||||
+ writeFile(fd, path, contents);
|
||||
+ chownToBuilder(fd.get(), path);
|
||||
+}
|
||||
|
||||
void LocalDerivationGoal::runChild()
|
||||
{
|
||||
@@ -3038,6 +3059,15 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||
void LocalDerivationGoal::deleteTmpDir(bool force)
|
||||
{
|
||||
if (topTmpDir != "") {
|
||||
+ /* As an extra precaution, even in the event of `deletePath` failing to
|
||||
+ * clean up, the `tmpDir` will be chowned as if we were to move
|
||||
+ * it inside the Nix store.
|
||||
+ *
|
||||
+ * This hardens against an attack which smuggles a file descriptor
|
||||
+ * to make use of the temporary directory.
|
||||
+ */
|
||||
+ chmod(topTmpDir.c_str(), 0000);
|
||||
+
|
||||
/* Don't keep temporary directories for builtins because they
|
||||
might have privileged stuff (like a copy of netrc). */
|
||||
if (settings.keepFailed && !force && !drv->isBuiltin()) {
|
||||
diff --git a/src/libstore/unix/build/local-derivation-goal.hh b/src/libstore/unix/build/local-derivation-goal.hh
|
||||
index 1ea247661..74a1e1c50 100644
|
||||
--- a/src/libstore/unix/build/local-derivation-goal.hh
|
||||
+++ b/src/libstore/unix/build/local-derivation-goal.hh
|
||||
@@ -37,6 +37,11 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
*/
|
||||
Path topTmpDir;
|
||||
|
||||
+ /**
|
||||
+ * The file descriptor of the temporary directory.
|
||||
+ */
|
||||
+ AutoCloseFD tmpDirFd;
|
||||
+
|
||||
/**
|
||||
* The path of the temporary directory in the sandbox.
|
||||
*/
|
||||
@@ -244,9 +249,24 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
|
||||
/**
|
||||
* Make a file owned by the builder.
|
||||
+ *
|
||||
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
|
||||
+ * It's only safe to call in a child of a directory only visible to the owner.
|
||||
*/
|
||||
void chownToBuilder(const Path & path);
|
||||
|
||||
+ /**
|
||||
+ * Make a file owned by the builder addressed by its file descriptor.
|
||||
+ */
|
||||
+ void chownToBuilder(int fd, const Path & path);
|
||||
+
|
||||
+ /**
|
||||
+ * Create a file in `tmpDir` owned by the builder.
|
||||
+ */
|
||||
+ void writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents);
|
||||
+
|
||||
int getChildStatus() override;
|
||||
|
||||
/**
|
||||
diff --git a/src/libutil/file-content-address.cc b/src/libutil/file-content-address.cc
|
||||
index 69301d9c8..2b6839346 100644
|
||||
--- a/src/libutil/file-content-address.cc
|
||||
+++ b/src/libutil/file-content-address.cc
|
||||
@@ -93,7 +93,7 @@ void restorePath(
|
||||
{
|
||||
switch (method) {
|
||||
case FileSerialisationMethod::Flat:
|
||||
- writeFile(path, source, 0666, startFsync);
|
||||
+ writeFile(path, source, 0666, startFsync ? FsSync::Yes : FsSync::No);
|
||||
break;
|
||||
case FileSerialisationMethod::NixArchive:
|
||||
restorePath(path, source, startFsync);
|
||||
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
|
||||
index 6fe93b63a..b3183f495 100644
|
||||
--- a/src/libutil/file-system.cc
|
||||
+++ b/src/libutil/file-system.cc
|
||||
@@ -258,7 +258,7 @@ void readFile(const Path & path, Sink & sink)
|
||||
}
|
||||
|
||||
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -268,22 +268,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
, mode));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
+
|
||||
+ writeFile(fd, path, s, mode, sync);
|
||||
+
|
||||
+ /* Close explicitly to propagate the exceptions. */
|
||||
+ fd.close();
|
||||
+}
|
||||
+
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
|
||||
+{
|
||||
+ assert(fd);
|
||||
try {
|
||||
writeFull(fd.get(), s);
|
||||
+
|
||||
+ if (sync == FsSync::Yes)
|
||||
+ fd.fsync();
|
||||
+
|
||||
} catch (Error & e) {
|
||||
- e.addTrace({}, "writing file '%1%'", path);
|
||||
+ e.addTrace({}, "writing file '%1%'", origPath);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
- fd.fsync();
|
||||
- // Explicitly close to make sure exceptions are propagated.
|
||||
- fd.close();
|
||||
- if (sync)
|
||||
- syncParent(path);
|
||||
}
|
||||
|
||||
-
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -307,11 +314,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
e.addTrace({}, "writing file '%1%'", path);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
fd.fsync();
|
||||
// Explicitly close to make sure exceptions are propagated.
|
||||
fd.close();
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
syncParent(path);
|
||||
}
|
||||
|
||||
@@ -374,7 +381,8 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
#ifndef _WIN32
|
||||
checkInterrupt();
|
||||
|
||||
- std::string name(baseNameOf(path.native()));
|
||||
+ std::string name(path.filename());
|
||||
+ assert(name != "." && name != ".." && !name.empty());
|
||||
|
||||
struct stat st;
|
||||
if (fstatat(parentfd, name.c_str(), &st,
|
||||
@@ -415,7 +423,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
throw SysError("chmod %1%", path);
|
||||
}
|
||||
|
||||
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
|
||||
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||
if (fd == -1)
|
||||
throw SysError("opening directory %1%", path);
|
||||
AutoCloseDir dir(fdopendir(fd));
|
||||
@@ -427,7 +435,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
checkInterrupt();
|
||||
std::string childName = dirent->d_name;
|
||||
if (childName == "." || childName == "..") continue;
|
||||
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
|
||||
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
|
||||
}
|
||||
if (errno) throw SysError("reading directory %1%", path);
|
||||
}
|
||||
@@ -445,14 +453,13 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
|
||||
static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
|
||||
{
|
||||
- Path dir = dirOf(path.string());
|
||||
- if (dir == "")
|
||||
- dir = "/";
|
||||
+ assert(path.is_absolute());
|
||||
+ assert(path.parent_path() != path);
|
||||
|
||||
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
|
||||
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
|
||||
if (!dirfd) {
|
||||
if (errno == ENOENT) return;
|
||||
- throw SysError("opening directory '%1%'", path);
|
||||
+ throw SysError("opening directory %s", path.parent_path());
|
||||
}
|
||||
|
||||
_deletePath(dirfd.get(), path, bytesFreed);
|
||||
diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh
|
||||
index 204907339..b2db8869e 100644
|
||||
--- a/src/libutil/file-system.hh
|
||||
+++ b/src/libutil/file-system.hh
|
||||
@@ -194,21 +194,27 @@ std::string readFile(const Path & path);
|
||||
std::string readFile(const std::filesystem::path & path);
|
||||
void readFile(const Path & path, Sink & sink);
|
||||
|
||||
+enum struct FsSync { Yes, No };
|
||||
+
|
||||
/**
|
||||
* Write a string to a file.
|
||||
*/
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
|
||||
-static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), s, mode, sync);
|
||||
}
|
||||
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
|
||||
-static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, bool sync = false)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), source, mode, sync);
|
||||
}
|
||||
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
/**
|
||||
* Flush a path's parent directory to disk.
|
||||
*/
|
||||
--
|
||||
2.49.0
|
||||
|
@ -0,0 +1,454 @@
|
||||
From 24c1aa735a40d3bf5361755fa10ac0e577a55eed Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu, 19 Jun 2025 16:20:34 +0200
|
||||
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Squashed commit of the following:
|
||||
|
||||
commit 04fff3a637d455cbb1d75937a235950e43008db9
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:30:32 2025 +0200
|
||||
|
||||
Chown structured attr files safely
|
||||
|
||||
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:14:04 2025 +0200
|
||||
|
||||
Replace 'bool sync' with an enum for clarity
|
||||
|
||||
And drop writeFileAndSync().
|
||||
|
||||
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:35:28 2025 +0200
|
||||
|
||||
Drop guessOrInventPathFromFD()
|
||||
|
||||
No need to do hacky stuff like that when we already know the original path.
|
||||
|
||||
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:15:58 2025 +0200
|
||||
|
||||
Tweak comment
|
||||
|
||||
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Thu Mar 27 12:22:26 2025 +0100
|
||||
|
||||
libstore: ensure that temporary directory is always 0o000 before deletion
|
||||
|
||||
In the case the deletion fails, we should ensure that the temporary
|
||||
directory cannot be used for nefarious purposes.
|
||||
|
||||
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 12:42:55 2025 +0100
|
||||
|
||||
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
|
||||
|
||||
When calling `_deletePath` with a parent file descriptor, `openat` is
|
||||
made effective by using relative paths to the directory file descriptor.
|
||||
|
||||
To avoid the problem, the signature is changed to resist misuse with an
|
||||
assert in the prologue of the function.
|
||||
|
||||
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:07:47 2025 +0100
|
||||
|
||||
libstore: ensure that `passAsFile` is created in the original temp dir
|
||||
|
||||
This ensures that `passAsFile` data is created inside the expected
|
||||
temporary build directory by `openat()` from the parent directory file
|
||||
descriptor.
|
||||
|
||||
This avoids a TOCTOU which is part of the attack chain of CVE-????.
|
||||
|
||||
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:06:03 2025 +0100
|
||||
|
||||
libutil: writeFile variant for file descriptors
|
||||
|
||||
`writeFile` lose its `sync` boolean flag to make things simpler.
|
||||
|
||||
A new `writeFileAndSync` function is created and all call sites are
|
||||
converted to it.
|
||||
|
||||
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:05:34 2025 +0100
|
||||
|
||||
libstore: chown to builder variant for file descriptors
|
||||
|
||||
We use it immediately for the build temporary directory.
|
||||
|
||||
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:59 2025 +0100
|
||||
|
||||
libstore: open build directory as a dirfd as well
|
||||
|
||||
We now keep around a proper AutoCloseFD around the temporary directory
|
||||
which we plan to use for openat operations and avoiding the build
|
||||
directory being swapped out while we are doing something else.
|
||||
|
||||
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:12 2025 +0100
|
||||
|
||||
libutil: guess or invent a path from file descriptors
|
||||
|
||||
This is useful for certain error recovery paths (no pun intended) that
|
||||
does not thread through the original path name.
|
||||
|
||||
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
|
||||
---
|
||||
src/libstore/local-store.cc | 4 +-
|
||||
.../unix/build/local-derivation-goal.cc | 46 ++++++++++++++----
|
||||
.../nix/store/build/local-derivation-goal.hh | 20 ++++++++
|
||||
src/libutil/file-content-address.cc | 2 +-
|
||||
src/libutil/file-system.cc | 47 +++++++++++--------
|
||||
src/libutil/include/nix/util/file-system.hh | 14 ++++--
|
||||
6 files changed, 98 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
|
||||
index f3bee6953..eddc87ef9 100644
|
||||
--- a/src/libstore/local-store.cc
|
||||
+++ b/src/libstore/local-store.cc
|
||||
@@ -249,7 +249,7 @@ LocalStore::LocalStore(
|
||||
else if (curSchema == 0) { /* new store */
|
||||
curSchema = nixSchemaVersion;
|
||||
openDB(*state, true);
|
||||
- writeFile(schemaPath, fmt("%1%", curSchema), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
|
||||
}
|
||||
|
||||
else if (curSchema < nixSchemaVersion) {
|
||||
@@ -300,7 +300,7 @@ LocalStore::LocalStore(
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
|
||||
|
||||
lockFile(globalLock.get(), ltRead, true);
|
||||
}
|
||||
diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc
|
||||
index 9edb6fb0f..a0442d0b8 100644
|
||||
--- a/src/libstore/unix/build/local-derivation-goal.cc
|
||||
+++ b/src/libstore/unix/build/local-derivation-goal.cc
|
||||
@@ -567,7 +567,14 @@ void LocalDerivationGoal::startBuilder()
|
||||
} else {
|
||||
tmpDir = topTmpDir;
|
||||
}
|
||||
- chownToBuilder(tmpDir);
|
||||
+
|
||||
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
|
||||
+ POSIX semantics.*/
|
||||
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
|
||||
+ if (!tmpDirFd)
|
||||
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
|
||||
+
|
||||
+ chownToBuilder(tmpDirFd.get(), tmpDir);
|
||||
|
||||
for (auto & [outputName, status] : initialOutputs) {
|
||||
/* Set scratch path we'll actually use during the build.
|
||||
@@ -1159,9 +1166,7 @@ void LocalDerivationGoal::initTmpDir()
|
||||
} else {
|
||||
auto hash = hashString(HashAlgorithm::SHA256, i.first);
|
||||
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
|
||||
- Path p = tmpDir + "/" + fn;
|
||||
- writeFile(p, rewriteStrings(i.second, inputRewrites));
|
||||
- chownToBuilder(p);
|
||||
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
|
||||
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
|
||||
}
|
||||
}
|
||||
@@ -1266,11 +1271,9 @@ void LocalDerivationGoal::writeStructuredAttrs()
|
||||
|
||||
auto jsonSh = writeStructuredAttrsShell(json);
|
||||
|
||||
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.sh");
|
||||
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
|
||||
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.json");
|
||||
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
|
||||
}
|
||||
}
|
||||
@@ -1781,6 +1784,24 @@ void setupSeccomp()
|
||||
#endif
|
||||
}
|
||||
|
||||
+void LocalDerivationGoal::chownToBuilder(int fd, const Path & path)
|
||||
+{
|
||||
+ if (!buildUser) return;
|
||||
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
|
||||
+ throw SysError("cannot change ownership of file '%1%'", path);
|
||||
+}
|
||||
+
|
||||
+void LocalDerivationGoal::writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents)
|
||||
+{
|
||||
+ auto path = std::filesystem::path(tmpDir) / name;
|
||||
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
|
||||
+ if (!fd)
|
||||
+ throw SysError("creating file %s", path);
|
||||
+ writeFile(fd, path, contents);
|
||||
+ chownToBuilder(fd.get(), path);
|
||||
+}
|
||||
|
||||
void LocalDerivationGoal::runChild()
|
||||
{
|
||||
@@ -3000,6 +3021,15 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
|
||||
void LocalDerivationGoal::deleteTmpDir(bool force)
|
||||
{
|
||||
if (topTmpDir != "") {
|
||||
+ /* As an extra precaution, even in the event of `deletePath` failing to
|
||||
+ * clean up, the `tmpDir` will be chowned as if we were to move
|
||||
+ * it inside the Nix store.
|
||||
+ *
|
||||
+ * This hardens against an attack which smuggles a file descriptor
|
||||
+ * to make use of the temporary directory.
|
||||
+ */
|
||||
+ chmod(topTmpDir.c_str(), 0000);
|
||||
+
|
||||
/* Don't keep temporary directories for builtins because they
|
||||
might have privileged stuff (like a copy of netrc). */
|
||||
if (settings.keepFailed && !force && !drv->isBuiltin()) {
|
||||
diff --git a/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh b/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh
|
||||
index 795286a01..fb62e3ca4 100644
|
||||
--- a/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh
|
||||
+++ b/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh
|
||||
@@ -37,6 +37,11 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
*/
|
||||
Path topTmpDir;
|
||||
|
||||
+ /**
|
||||
+ * The file descriptor of the temporary directory.
|
||||
+ */
|
||||
+ AutoCloseFD tmpDirFd;
|
||||
+
|
||||
/**
|
||||
* The path of the temporary directory in the sandbox.
|
||||
*/
|
||||
@@ -239,9 +244,24 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||
|
||||
/**
|
||||
* Make a file owned by the builder.
|
||||
+ *
|
||||
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
|
||||
+ * It's only safe to call in a child of a directory only visible to the owner.
|
||||
*/
|
||||
void chownToBuilder(const Path & path);
|
||||
|
||||
+ /**
|
||||
+ * Make a file owned by the builder addressed by its file descriptor.
|
||||
+ */
|
||||
+ void chownToBuilder(int fd, const Path & path);
|
||||
+
|
||||
+ /**
|
||||
+ * Create a file in `tmpDir` owned by the builder.
|
||||
+ */
|
||||
+ void writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents);
|
||||
+
|
||||
int getChildStatus() override;
|
||||
|
||||
/**
|
||||
diff --git a/src/libutil/file-content-address.cc b/src/libutil/file-content-address.cc
|
||||
index 142bc70d5..d95781691 100644
|
||||
--- a/src/libutil/file-content-address.cc
|
||||
+++ b/src/libutil/file-content-address.cc
|
||||
@@ -93,7 +93,7 @@ void restorePath(
|
||||
{
|
||||
switch (method) {
|
||||
case FileSerialisationMethod::Flat:
|
||||
- writeFile(path, source, 0666, startFsync);
|
||||
+ writeFile(path, source, 0666, startFsync ? FsSync::Yes : FsSync::No);
|
||||
break;
|
||||
case FileSerialisationMethod::NixArchive:
|
||||
restorePath(path, source, startFsync);
|
||||
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
|
||||
index 9ce3682f1..204a63c4e 100644
|
||||
--- a/src/libutil/file-system.cc
|
||||
+++ b/src/libutil/file-system.cc
|
||||
@@ -298,7 +298,7 @@ void readFile(const Path & path, Sink & sink)
|
||||
}
|
||||
|
||||
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -308,22 +308,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
, mode));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
+
|
||||
+ writeFile(fd, path, s, mode, sync);
|
||||
+
|
||||
+ /* Close explicitly to propagate the exceptions. */
|
||||
+ fd.close();
|
||||
+}
|
||||
+
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
|
||||
+{
|
||||
+ assert(fd);
|
||||
try {
|
||||
writeFull(fd.get(), s);
|
||||
+
|
||||
+ if (sync == FsSync::Yes)
|
||||
+ fd.fsync();
|
||||
+
|
||||
} catch (Error & e) {
|
||||
- e.addTrace({}, "writing file '%1%'", path);
|
||||
+ e.addTrace({}, "writing file '%1%'", origPath);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
- fd.fsync();
|
||||
- // Explicitly close to make sure exceptions are propagated.
|
||||
- fd.close();
|
||||
- if (sync)
|
||||
- syncParent(path);
|
||||
}
|
||||
|
||||
-
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -347,11 +354,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
e.addTrace({}, "writing file '%1%'", path);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
fd.fsync();
|
||||
// Explicitly close to make sure exceptions are propagated.
|
||||
fd.close();
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
syncParent(path);
|
||||
}
|
||||
|
||||
@@ -414,7 +421,8 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
#ifndef _WIN32
|
||||
checkInterrupt();
|
||||
|
||||
- std::string name(baseNameOf(path.native()));
|
||||
+ std::string name(path.filename());
|
||||
+ assert(name != "." && name != ".." && !name.empty());
|
||||
|
||||
struct stat st;
|
||||
if (fstatat(parentfd, name.c_str(), &st,
|
||||
@@ -455,7 +463,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
throw SysError("chmod %1%", path);
|
||||
}
|
||||
|
||||
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
|
||||
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||
if (fd == -1)
|
||||
throw SysError("opening directory %1%", path);
|
||||
AutoCloseDir dir(fdopendir(fd));
|
||||
@@ -467,7 +475,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
checkInterrupt();
|
||||
std::string childName = dirent->d_name;
|
||||
if (childName == "." || childName == "..") continue;
|
||||
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
|
||||
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
|
||||
}
|
||||
if (errno) throw SysError("reading directory %1%", path);
|
||||
}
|
||||
@@ -485,14 +493,13 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
|
||||
|
||||
static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
|
||||
{
|
||||
- Path dir = dirOf(path.string());
|
||||
- if (dir == "")
|
||||
- dir = "/";
|
||||
+ assert(path.is_absolute());
|
||||
+ assert(path.parent_path() != path);
|
||||
|
||||
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
|
||||
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
|
||||
if (!dirfd) {
|
||||
if (errno == ENOENT) return;
|
||||
- throw SysError("opening directory '%1%'", path);
|
||||
+ throw SysError("opening directory %s", path.parent_path());
|
||||
}
|
||||
|
||||
_deletePath(dirfd.get(), path, bytesFreed);
|
||||
diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh
|
||||
index e6b1cfef3..9a0057bbe 100644
|
||||
--- a/src/libutil/include/nix/util/file-system.hh
|
||||
+++ b/src/libutil/include/nix/util/file-system.hh
|
||||
@@ -193,21 +193,27 @@ std::string readFile(const Path & path);
|
||||
std::string readFile(const std::filesystem::path & path);
|
||||
void readFile(const Path & path, Sink & sink);
|
||||
|
||||
+enum struct FsSync { Yes, No };
|
||||
+
|
||||
/**
|
||||
* Write a string to a file.
|
||||
*/
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
|
||||
-static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), s, mode, sync);
|
||||
}
|
||||
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
|
||||
-static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, bool sync = false)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), source, mode, sync);
|
||||
}
|
||||
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
/**
|
||||
* Flush a path's parent directory to disk.
|
||||
*/
|
||||
--
|
||||
2.44.1
|
||||
|
@ -0,0 +1,449 @@
|
||||
From 01619fbe2dc06b79609b95b6f95ddbf4e871e762 Mon Sep 17 00:00:00 2001
|
||||
From: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu, 19 Jun 2025 16:20:34 +0200
|
||||
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Squashed commit of the following:
|
||||
|
||||
commit 04fff3a637d455cbb1d75937a235950e43008db9
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:30:32 2025 +0200
|
||||
|
||||
Chown structured attr files safely
|
||||
|
||||
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 12:14:04 2025 +0200
|
||||
|
||||
Replace 'bool sync' with an enum for clarity
|
||||
|
||||
And drop writeFileAndSync().
|
||||
|
||||
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:35:28 2025 +0200
|
||||
|
||||
Drop guessOrInventPathFromFD()
|
||||
|
||||
No need to do hacky stuff like that when we already know the original path.
|
||||
|
||||
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
|
||||
Author: Eelco Dolstra <edolstra@gmail.com>
|
||||
Date: Thu Jun 12 11:15:58 2025 +0200
|
||||
|
||||
Tweak comment
|
||||
|
||||
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Thu Mar 27 12:22:26 2025 +0100
|
||||
|
||||
libstore: ensure that temporary directory is always 0o000 before deletion
|
||||
|
||||
In the case the deletion fails, we should ensure that the temporary
|
||||
directory cannot be used for nefarious purposes.
|
||||
|
||||
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 12:42:55 2025 +0100
|
||||
|
||||
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
|
||||
|
||||
When calling `_deletePath` with a parent file descriptor, `openat` is
|
||||
made effective by using relative paths to the directory file descriptor.
|
||||
|
||||
To avoid the problem, the signature is changed to resist misuse with an
|
||||
assert in the prologue of the function.
|
||||
|
||||
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:07:47 2025 +0100
|
||||
|
||||
libstore: ensure that `passAsFile` is created in the original temp dir
|
||||
|
||||
This ensures that `passAsFile` data is created inside the expected
|
||||
temporary build directory by `openat()` from the parent directory file
|
||||
descriptor.
|
||||
|
||||
This avoids a TOCTOU which is part of the attack chain of CVE-????.
|
||||
|
||||
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:06:03 2025 +0100
|
||||
|
||||
libutil: writeFile variant for file descriptors
|
||||
|
||||
`writeFile` lose its `sync` boolean flag to make things simpler.
|
||||
|
||||
A new `writeFileAndSync` function is created and all call sites are
|
||||
converted to it.
|
||||
|
||||
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:05:34 2025 +0100
|
||||
|
||||
libstore: chown to builder variant for file descriptors
|
||||
|
||||
We use it immediately for the build temporary directory.
|
||||
|
||||
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:59 2025 +0100
|
||||
|
||||
libstore: open build directory as a dirfd as well
|
||||
|
||||
We now keep around a proper AutoCloseFD around the temporary directory
|
||||
which we plan to use for openat operations and avoiding the build
|
||||
directory being swapped out while we are doing something else.
|
||||
|
||||
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
|
||||
Author: Raito Bezarius <raito@lix.systems>
|
||||
Date: Wed Mar 26 01:04:12 2025 +0100
|
||||
|
||||
libutil: guess or invent a path from file descriptors
|
||||
|
||||
This is useful for certain error recovery paths (no pun intended) that
|
||||
does not thread through the original path name.
|
||||
|
||||
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
|
||||
Signed-off-by: Raito Bezarius <raito@lix.systems>
|
||||
|
||||
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
|
||||
---
|
||||
src/libstore/local-store.cc | 4 +-
|
||||
src/libstore/unix/build/derivation-builder.cc | 66 ++++++++++++++++---
|
||||
src/libutil/file-content-address.cc | 2 +-
|
||||
src/libutil/file-system.cc | 47 +++++++------
|
||||
src/libutil/include/nix/util/file-system.hh | 14 ++--
|
||||
5 files changed, 98 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
|
||||
index 76fadba86..1ab3ed13a 100644
|
||||
--- a/src/libstore/local-store.cc
|
||||
+++ b/src/libstore/local-store.cc
|
||||
@@ -247,7 +247,7 @@ LocalStore::LocalStore(ref<const Config> config)
|
||||
else if (curSchema == 0) { /* new store */
|
||||
curSchema = nixSchemaVersion;
|
||||
openDB(*state, true);
|
||||
- writeFile(schemaPath, fmt("%1%", curSchema), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
|
||||
}
|
||||
|
||||
else if (curSchema < nixSchemaVersion) {
|
||||
@@ -298,7 +298,7 @@ LocalStore::LocalStore(ref<const Config> config)
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
|
||||
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
|
||||
|
||||
lockFile(globalLock.get(), ltRead, true);
|
||||
}
|
||||
diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc
|
||||
index 58e8d8ba6..856bc81c3 100644
|
||||
--- a/src/libstore/unix/build/derivation-builder.cc
|
||||
+++ b/src/libstore/unix/build/derivation-builder.cc
|
||||
@@ -129,6 +129,11 @@ private:
|
||||
*/
|
||||
Path topTmpDir;
|
||||
|
||||
+ /**
|
||||
+ * The file descriptor of the temporary directory.
|
||||
+ */
|
||||
+ AutoCloseFD tmpDirFd;
|
||||
+
|
||||
/**
|
||||
* The path of the temporary directory in the sandbox.
|
||||
*/
|
||||
@@ -325,9 +330,24 @@ private:
|
||||
|
||||
/**
|
||||
* Make a file owned by the builder.
|
||||
+ *
|
||||
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
|
||||
+ * It's only safe to call in a child of a directory only visible to the owner.
|
||||
*/
|
||||
void chownToBuilder(const Path & path);
|
||||
|
||||
+ /**
|
||||
+ * Make a file owned by the builder addressed by its file descriptor.
|
||||
+ */
|
||||
+ void chownToBuilder(int fd, const Path & path);
|
||||
+
|
||||
+ /**
|
||||
+ * Create a file in `tmpDir` owned by the builder.
|
||||
+ */
|
||||
+ void writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents);
|
||||
+
|
||||
/**
|
||||
* Run the builder's process.
|
||||
*/
|
||||
@@ -895,7 +915,14 @@ void DerivationBuilderImpl::startBuilder()
|
||||
} else {
|
||||
tmpDir = topTmpDir;
|
||||
}
|
||||
- chownToBuilder(tmpDir);
|
||||
+
|
||||
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
|
||||
+ POSIX semantics.*/
|
||||
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
|
||||
+ if (!tmpDirFd)
|
||||
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
|
||||
+
|
||||
+ chownToBuilder(tmpDirFd.get(), tmpDir);
|
||||
|
||||
for (auto & [outputName, status] : initialOutputs) {
|
||||
/* Set scratch path we'll actually use during the build.
|
||||
@@ -1469,9 +1496,7 @@ void DerivationBuilderImpl::initTmpDir()
|
||||
} else {
|
||||
auto hash = hashString(HashAlgorithm::SHA256, i.first);
|
||||
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
|
||||
- Path p = tmpDir + "/" + fn;
|
||||
- writeFile(p, rewriteStrings(i.second, inputRewrites));
|
||||
- chownToBuilder(p);
|
||||
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
|
||||
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
|
||||
}
|
||||
}
|
||||
@@ -1580,11 +1605,9 @@ void DerivationBuilderImpl::writeStructuredAttrs()
|
||||
|
||||
auto jsonSh = StructuredAttrs::writeShell(json);
|
||||
|
||||
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.sh");
|
||||
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
|
||||
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
|
||||
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
- chownToBuilder(tmpDir + "/.attrs.json");
|
||||
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
|
||||
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
|
||||
}
|
||||
}
|
||||
@@ -1838,6 +1861,24 @@ void setupSeccomp()
|
||||
#endif
|
||||
}
|
||||
|
||||
+void DerivationBuilderImpl::chownToBuilder(int fd, const Path & path)
|
||||
+{
|
||||
+ if (!buildUser) return;
|
||||
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
|
||||
+ throw SysError("cannot change ownership of file '%1%'", path);
|
||||
+}
|
||||
+
|
||||
+void DerivationBuilderImpl::writeBuilderFile(
|
||||
+ const std::string & name,
|
||||
+ std::string_view contents)
|
||||
+{
|
||||
+ auto path = std::filesystem::path(tmpDir) / name;
|
||||
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
|
||||
+ if (!fd)
|
||||
+ throw SysError("creating file %s", path);
|
||||
+ writeFile(fd, path, contents);
|
||||
+ chownToBuilder(fd.get(), path);
|
||||
+}
|
||||
|
||||
void DerivationBuilderImpl::runChild()
|
||||
{
|
||||
@@ -3043,6 +3084,15 @@ void DerivationBuilderImpl::checkOutputs(const std::map<std::string, ValidPathIn
|
||||
void DerivationBuilderImpl::deleteTmpDir(bool force)
|
||||
{
|
||||
if (topTmpDir != "") {
|
||||
+ /* As an extra precaution, even in the event of `deletePath` failing to
|
||||
+ * clean up, the `tmpDir` will be chowned as if we were to move
|
||||
+ * it inside the Nix store.
|
||||
+ *
|
||||
+ * This hardens against an attack which smuggles a file descriptor
|
||||
+ * to make use of the temporary directory.
|
||||
+ */
|
||||
+ chmod(topTmpDir.c_str(), 0000);
|
||||
+
|
||||
/* Don't keep temporary directories for builtins because they
|
||||
might have privileged stuff (like a copy of netrc). */
|
||||
if (settings.keepFailed && !force && !drv.isBuiltin()) {
|
||||
diff --git a/src/libutil/file-content-address.cc b/src/libutil/file-content-address.cc
|
||||
index 142bc70d5..d95781691 100644
|
||||
--- a/src/libutil/file-content-address.cc
|
||||
+++ b/src/libutil/file-content-address.cc
|
||||
@@ -93,7 +93,7 @@ void restorePath(
|
||||
{
|
||||
switch (method) {
|
||||
case FileSerialisationMethod::Flat:
|
||||
- writeFile(path, source, 0666, startFsync);
|
||||
+ writeFile(path, source, 0666, startFsync ? FsSync::Yes : FsSync::No);
|
||||
break;
|
||||
case FileSerialisationMethod::NixArchive:
|
||||
restorePath(path, source, startFsync);
|
||||
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
|
||||
index 90ec5eda5..aeee49e9b 100644
|
||||
--- a/src/libutil/file-system.cc
|
||||
+++ b/src/libutil/file-system.cc
|
||||
@@ -303,7 +303,7 @@ void readFile(const Path & path, Sink & sink, bool memory_map)
|
||||
}
|
||||
|
||||
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -313,22 +313,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
|
||||
, mode));
|
||||
if (!fd)
|
||||
throw SysError("opening file '%1%'", path);
|
||||
+
|
||||
+ writeFile(fd, path, s, mode, sync);
|
||||
+
|
||||
+ /* Close explicitly to propagate the exceptions. */
|
||||
+ fd.close();
|
||||
+}
|
||||
+
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
|
||||
+{
|
||||
+ assert(fd);
|
||||
try {
|
||||
writeFull(fd.get(), s);
|
||||
+
|
||||
+ if (sync == FsSync::Yes)
|
||||
+ fd.fsync();
|
||||
+
|
||||
} catch (Error & e) {
|
||||
- e.addTrace({}, "writing file '%1%'", path);
|
||||
+ e.addTrace({}, "writing file '%1%'", origPath);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
- fd.fsync();
|
||||
- // Explicitly close to make sure exceptions are propagated.
|
||||
- fd.close();
|
||||
- if (sync)
|
||||
- syncParent(path);
|
||||
}
|
||||
|
||||
-
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
|
||||
{
|
||||
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
|
||||
// TODO
|
||||
@@ -352,11 +359,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
|
||||
e.addTrace({}, "writing file '%1%'", path);
|
||||
throw;
|
||||
}
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
fd.fsync();
|
||||
// Explicitly close to make sure exceptions are propagated.
|
||||
fd.close();
|
||||
- if (sync)
|
||||
+ if (sync == FsSync::Yes)
|
||||
syncParent(path);
|
||||
}
|
||||
|
||||
@@ -419,7 +426,8 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
|
||||
#ifndef _WIN32
|
||||
checkInterrupt();
|
||||
|
||||
- std::string name(baseNameOf(path.native()));
|
||||
+ std::string name(path.filename());
|
||||
+ assert(name != "." && name != ".." && !name.empty());
|
||||
|
||||
struct stat st;
|
||||
if (fstatat(parentfd, name.c_str(), &st,
|
||||
@@ -460,7 +468,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
|
||||
throw SysError("chmod %1%", path);
|
||||
}
|
||||
|
||||
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
|
||||
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
|
||||
if (fd == -1)
|
||||
throw SysError("opening directory %1%", path);
|
||||
AutoCloseDir dir(fdopendir(fd));
|
||||
@@ -472,7 +480,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
|
||||
checkInterrupt();
|
||||
std::string childName = dirent->d_name;
|
||||
if (childName == "." || childName == "..") continue;
|
||||
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
|
||||
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
|
||||
}
|
||||
if (errno) throw SysError("reading directory %1%", path);
|
||||
}
|
||||
@@ -490,14 +498,13 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
|
||||
|
||||
static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed)
|
||||
{
|
||||
- Path dir = dirOf(path.string());
|
||||
- if (dir == "")
|
||||
- dir = "/";
|
||||
+ assert(path.is_absolute());
|
||||
+ assert(path.parent_path() != path);
|
||||
|
||||
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
|
||||
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
|
||||
if (!dirfd) {
|
||||
if (errno == ENOENT) return;
|
||||
- throw SysError("opening directory '%1%'", path);
|
||||
+ throw SysError("opening directory %s", path.parent_path());
|
||||
}
|
||||
|
||||
_deletePath(dirfd.get(), path, bytesFreed);
|
||||
diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh
|
||||
index b8fa4cfa0..a9a6e43bf 100644
|
||||
--- a/src/libutil/include/nix/util/file-system.hh
|
||||
+++ b/src/libutil/include/nix/util/file-system.hh
|
||||
@@ -175,21 +175,27 @@ std::string readFile(const Path & path);
|
||||
std::string readFile(const std::filesystem::path & path);
|
||||
void readFile(const Path & path, Sink & sink, bool memory_map = true);
|
||||
|
||||
+enum struct FsSync { Yes, No };
|
||||
+
|
||||
/**
|
||||
* Write a string to a file.
|
||||
*/
|
||||
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
|
||||
-static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false)
|
||||
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), s, mode, sync);
|
||||
}
|
||||
|
||||
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
|
||||
-static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, bool sync = false)
|
||||
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
+static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
|
||||
{
|
||||
return writeFile(path.string(), source, mode, sync);
|
||||
}
|
||||
|
||||
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
|
||||
+
|
||||
/**
|
||||
* Flush a path's parent directory to disk.
|
||||
*/
|
||||
--
|
||||
2.44.1
|
||||
|
@ -5234,6 +5234,8 @@ self: super: with self; {
|
||||
|
||||
flask-wtf = callPackage ../development/python-modules/flask-wtf { };
|
||||
|
||||
flask-xml-rpc-re = callPackage ../development/python-modules/flask-xml-rpc-re { };
|
||||
|
||||
flatbencode = callPackage ../development/python-modules/flatbencode { };
|
||||
|
||||
flatbuffers = callPackage ../development/python-modules/flatbuffers { inherit (pkgs) flatbuffers; };
|
||||
@ -10208,6 +10210,8 @@ self: super: with self; {
|
||||
|
||||
ninja = callPackage ../development/python-modules/ninja { inherit (pkgs) ninja; };
|
||||
|
||||
nipap = callPackage ../development/python-modules/nipap { };
|
||||
|
||||
nipreps-versions = callPackage ../development/python-modules/nipreps-versions { };
|
||||
|
||||
nipy = callPackage ../development/python-modules/nipy { };
|
||||
@ -13145,6 +13149,8 @@ self: super: with self; {
|
||||
|
||||
pynina = callPackage ../development/python-modules/pynina { };
|
||||
|
||||
pynipap = callPackage ../development/python-modules/pynipap { };
|
||||
|
||||
pynisher = callPackage ../development/python-modules/pynisher { };
|
||||
|
||||
pynitrokey = callPackage ../development/python-modules/pynitrokey { };
|
||||
|
Loading…
x
Reference in New Issue
Block a user