difftreelog
fix primop registration
in: trunk
5 files changed
crates/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");
crates/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]| {
crates/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())?;
crates/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)?
}}
}
modules/nixos/secrets.nixdiffbeforeafterboth1{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}