git.delta.rocks / jrsonnet / refs/commits / d70668683ed2

difftreelog

fix primop registration

ynqztwqxYaroslav Bolyukin2026-01-22parent: #98314cf.patch.diff
in: trunk

5 files changed

modifiedcrates/fleet-base/src/opts.rsdiffbeforeafterboth
--- a/crates/fleet-base/src/opts.rs
+++ b/crates/fleet-base/src/opts.rs
@@ -22,7 +22,7 @@
 
 use crate::{
 	fleetdata::FleetData,
-	host::{Config, ConfigHost, FleetConfigInternals},
+	host::{Config, ConfigHost, FleetConfigInternals}, primops::init_primops,
 };
 
 #[derive(Clone)]
@@ -213,6 +213,8 @@
 			std::fs::read_to_string(&fleet_data_path).context("reading fleet state (fleet.nix)")?;
 		let data = Arc::new(Mutex::new(FleetData::from_str(&bytes)?));
 
+		init_primops(data.clone());
+
 		let mut fetch_settings = FetchSettings::new();
 		fetch_settings.set(c"warn-dirty", c"false");
 
modifiedcrates/fleet-base/src/primops.rsdiffbeforeafterboth
--- a/crates/fleet-base/src/primops.rs
+++ b/crates/fleet-base/src/primops.rs
@@ -2,6 +2,7 @@
 use std::sync::{Arc, Mutex};
 
 use nix_eval::{NativeFn, Value};
+use tracing::info;
 
 use crate::fleetdata::{FleetData, FleetSecrets};
 
@@ -23,21 +24,9 @@
 struct FsSecretsBackend {}
 
 pub fn init_primops(secrets: Arc<Mutex<FleetData>>) {
-	NativeFn::new(
-		c"fleet_ensure_host_secret",
-		c"Ensure secret existence for a host, regenerating it in case of some mismatch",
-		[c"host", c"secret", c"generator"],
-		|[host, secret, generator]| {
-			todo!("ensure secret");
-			Ok(Value::new_attrs(HashMap::from_iter([(
-				"raw",
-				Value::new_str("rawData"),
-			)])))
-		},
-	)
-	.register();
+	info!("initializing primops");
 	NativeFn::new(
-		c"fleet_ensure_host_secret",
+		c"__fleetEnsureHostSecret",
 		c"Ensure secret existence for a host, regenerating it in case of some mismatch",
 		[c"host", c"secret", c"generator"],
 		|[host, secret, generator]| {
modifiedcrates/nix-eval/src/lib.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/lib.rs
+++ b/crates/nix-eval/src/lib.rs
@@ -966,9 +966,9 @@
 		let mut args = args.into_iter().map(|v| v.as_ptr()).collect_vec();
 		args.push(null());
 		let args = args.as_mut_ptr();
-		let primop = with_default_context(|c, _| unsafe {
+		let primop = unsafe {
 			alloc_primop(
-				c,
+				null_mut(),
 				f,
 				N as i32,
 				name.as_ptr(),
@@ -976,14 +976,14 @@
 				doc.as_ptr(),
 				Box::into_raw(closure).cast(),
 			)
-		})
-		.expect("primop allocation should not fail");
+		};
+
+		assert!(!primop.is_null(), "primop allocation should not fail");
 
 		Self(primop)
 	}
 	pub fn register(self) {
-		with_default_context(|c, _| unsafe { register_primop(c, self.0) })
-			.expect("primop registration should not fail");
+		unsafe { register_primop(null_mut(), self.0) };
 	}
 }
 
@@ -999,6 +999,17 @@
 #[test_log::test]
 fn test_native() -> Result<()> {
 	init_libraries();
+	NativeFn::new(
+		c"__uppercaseSuffix2",
+		c"make string uppercase and add suffix",
+		[c"str", c"suffix"],
+		|[str, suffix]: [&Value; 2]| {
+			let str = str.to_string()?;
+			let suffix = suffix.to_string()?;
+			Ok(Value::new_str(&format!("{}{suffix}", str.to_uppercase())))
+		},
+	)
+	.register();
 
 	let mut fetch_settings = FetchSettings::new();
 	fetch_settings.set(c"warn-dirty", c"false");
@@ -1036,6 +1047,8 @@
 
 	let test_result: String = nix_go_json!(test_data.testPrimop(uppercase_suffix));
 	assert_eq!(test_result, "PREFIX_BODY_SUFFIX");
+	let test_result: String = nix_go_json!(builtins.uppercaseSuffix2("test")("suffix"));
+	assert_eq!(test_result, "TESTsuffix");
 
 	let nix_ctx = NixContext::new();
 	let store = GLOBAL_STATE.store.parse_path(s.as_c_str())?;
modifiedcrates/nix-eval/src/macros.rsdiffbeforeafterboth
--- a/crates/nix-eval/src/macros.rs
+++ b/crates/nix-eval/src/macros.rs
@@ -47,11 +47,7 @@
 		nix_expr_inner!(@field(out) $($tt)*);
 		out
 	}};
-	($v:literal) => {{
-		use $crate::macros::NixExprBuilder;
-		NixExprBuilder::string($v)
-	}};
-	({$v:expr}) => {{
+	($v:expr) => {{
 		$crate::Value::serialized(&$v)?
 	}}
 }
modifiedmodules/nixos/secrets.nixdiffbeforeafterboth
before · modules/nixos/secrets.nix
1{2  lib,3  fleetLib,4  config,5  pkgs,6  ...7}:8let9  inherit (builtins)10    hashString11    toJSON12    ;13  inherit (lib.stringsWithDeps) stringAfter;14  inherit (lib.options) mkOption literalExpression;15  inherit (lib.lists) optional;16  inherit (lib.attrsets) mapAttrs;17  inherit (lib.modules) mkIf;18  inherit (lib.types)19    submodule20    str21    attrsOf22    nullOr23    unspecified24    uniq25    functionTo26    package27    ;28  inherit (fleetLib.strings) decodeRawSecret;2930  sysConfig = config;31  secretPartType =32    secretName:33    submodule (34      { config, ... }:35      let36        partName = config._module.args.name;37      in38      {39        options = {40          hash = mkOption {41            type = str;42            description = "Hash of secret in encoded format";43          };44          path = mkOption {45            type = str;46            description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";47          };48          stablePath = mkOption {49            type = str;50            description = "Path to secret part, stable path (users are expected to watch for file changes/re-read secret on demand)";51          };52          data = mkOption {53            type = str;54            description = "Secret public data (only available for plaintext)";55          };56          raw = mkOption {57            type = str;58            description = "Raw (encoded/encrypted secret part data)";59          };60        };61        config = {62          hash = hashString "sha1" config.raw;63          data = decodeRawSecret config.raw;64          path = "/run/secrets/${secretName}/${config.hash}-${partName}";65          stablePath = "/run/secrets/${secretName}/${partName}";66        };67      }68    );69  secretType = submodule (70    {71      config,72      ...73    }:74    let75      secretName = config._module.args.name;76    in77    {78      options = {79        parts = mkOption {80          type = attrsOf (secretPartType secretName);81          description = "Definition of secret parts";82        };83        generator = mkOption {84          type = uniq (nullOr (functionTo package));85          description = "Derivation to evaluate for secret generation";86          default = null;87        };88        mode = mkOption {89          type = str;90          description = "Secret mode";91          default = "0440";92        };93        owner = mkOption {94          type = str;95          description = "Owner of the secret";96          default = "root";97        };98        group = mkOption {99          type = str;100          description = "Group of the secret";101          default = sysConfig.users.users.${config.owner}.group;102          defaultText = literalExpression "config.users.users.$${owner}.group";103        };104      };105      config = {106        parts = builtins.fleet_ensure_host_secret sysConfig.networking.hostName secretName config.generator;107      };108    }109  );110  secretsData = (mapAttrs (_: s: s.definition) config.secrets);111  secretsFile = pkgs.writeTextFile {112    name = "secrets.json";113    text = toJSON secretsData;114  };115  useSysusers =116    (config.systemd ? sysusers && config.systemd.sysusers.enable)117    || (config ? userborn && config.userborn.enable);118in119{120  options = {121    secrets = mkOption {122      type = attrsOf secretType;123      default = { };124      apply = v: (mapAttrs (_: secret: secret.parts // { definition = secret; }) v);125      description = "Host-local secrets";126    };127    system.secretsData = mkOption {128      type = unspecified;129      default = { };130      description = "secrets.json contents";131    };132  };133  config = {134    system = { inherit secretsData; };135    environment.systemPackages = [ pkgs.fleet-install-secrets ];136137    systemd.services.fleet-install-secrets = mkIf useSysusers {138      wantedBy = [ "sysinit.target" ];139      after = [ "systemd-sysusers.service" ];140      restartTriggers = [141        secretsFile142      ];143      aliases = [144        "sops-install-secrets"145        "agenix-install-secrets"146      ];147148      unitConfig.DefaultDependencies = false;149150      serviceConfig = {151        Type = "oneshot";152        RemainAfterExit = true;153        ExecStart = "${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}";154      };155    };156    system.activationScripts.decryptSecrets = mkIf (!useSysusers) (157      stringAfter158        (159          [160            # secrets are owned by user/group, thus we need to refer to those161            "users"162            "groups"163            "specialfs"164          ]165          # nixos-impermanence compatibility: secrets are encrypted by host-key,166          # but with impermanence we expect that the host-key is installed by167          # persist-file activation script.168          ++ (optional (config.system.activationScripts ? "persist-files") "persist-files")169        )170        ''171          1>&2 echo "setting up secrets"172          ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}173        ''174    );175  };176}