diff --git a/Cargo.lock b/Cargo.lock index 3d19a8c7..fb0bc18f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -705,6 +705,7 @@ dependencies = [ "mime", "openssl", "percent-encoding", + "pkg-config", "serde", "serde_json", "tempfile", diff --git a/harmonia/Cargo.toml b/harmonia/Cargo.toml index e3b8df41..4cbaa96d 100644 --- a/harmonia/Cargo.toml +++ b/harmonia/Cargo.toml @@ -34,3 +34,6 @@ url = "2.4.1" libnixstore = { path = "../libnixstore" } + +[build-dependencies] +pkg-config = "0.3" diff --git a/harmonia/build.rs b/harmonia/build.rs new file mode 100644 index 00000000..17cd1c15 --- /dev/null +++ b/harmonia/build.rs @@ -0,0 +1,3 @@ +fn main() { + pkg_config::probe_library("libsodium").unwrap(); +} diff --git a/harmonia/src/narlist.rs b/harmonia/src/narlist.rs index 0a6b38c5..c75bd399 100644 --- a/harmonia/src/narlist.rs +++ b/harmonia/src/narlist.rs @@ -14,6 +14,10 @@ use std::collections::HashMap; use std::path::PathBuf; use tokio::fs::symlink_metadata; +fn is_false(b: &bool) -> bool { + !b +} + #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)] #[serde(tag = "type")] enum NarEntry { @@ -24,7 +28,8 @@ enum NarEntry { #[serde(rename = "narOffset")] nar_offset: Option, size: u64, - #[serde(default)] + + #[serde(default, skip_serializing_if = "is_false")] executable: bool, }, #[serde(rename = "symlink")] @@ -236,7 +241,6 @@ mod test { .unwrap(); let parsed_json: serde_json::Value = serde_json::from_slice(&res2.stdout).unwrap(); let pretty_string = serde_json::to_string_pretty(&parsed_json).unwrap(); - println!("{}", pretty_string); assert!(res2.status.success()); let mut reference_json: NarEntry = serde_json::from_str(&pretty_string).unwrap(); @@ -244,9 +248,9 @@ mod test { unset_nar_offset(&mut reference_json); println!("get_nar_list:"); - println!("{:?}", json.root); + println!("{}", serde_json::to_string_pretty(&json.root).unwrap()); println!("nix nar ls --json --recursive:"); - println!("{:?}", reference_json); + println!("{}", pretty_string); assert_eq!(json.root, reference_json); Ok(()) diff --git a/harmonia/src/signing.rs b/harmonia/src/signing.rs index 91c6c6e5..7bb42d0f 100644 --- a/harmonia/src/signing.rs +++ b/harmonia/src/signing.rs @@ -10,6 +10,17 @@ use crate::config::SigningKey; // omitted: E O U T const BASE32_CHARS: &[u8] = b"0123456789abcdfghijklmnpqrsvwxyz"; +#[link(name = "sodium")] +extern "C" { + fn crypto_sign_detached( + sig: *mut u8, + sig_len: *mut usize, + msg: *const u8, + msg_len: usize, + sk: *const u8, + ) -> i32; +} + /// Converts the given byte slice to a nix-compatible base32 encoded String. fn to_nix_base32(bytes: &[u8]) -> String { let len = (bytes.len() * 8 - 1) / 5 + 1; @@ -127,8 +138,19 @@ pub(crate) fn fingerprint_path( } pub(crate) fn sign_string(sign_key: &SigningKey, msg: &str) -> String { - let signature = libnixstore::sign_detached(&sign_key.key, msg); - let base64 = general_purpose::STANDARD.encode(signature); + let mut signature = vec![0u8; 64]; // crypto_sign_BYTES -> 64 + let mut signature_len: usize = 0; + let msg = msg.as_bytes(); + unsafe { + crypto_sign_detached( + signature.as_mut_ptr(), + &mut signature_len, + msg.as_ptr(), + msg.len(), + sign_key.key.as_ptr(), + ) + }; + let base64 = general_purpose::STANDARD.encode(&signature[..signature_len]); format!("{}:{}", sign_key.name, base64) } diff --git a/libnixstore/README.md b/libnixstore/README.md index e7519268..86e9e042 100644 --- a/libnixstore/README.md +++ b/libnixstore/README.md @@ -1,16 +1,12 @@ # libnixstore -Is a library that provides simple access to your local nix store, based on c++ -bindings. It mimics the already available perl bindings but also adds bindings -on top, that might be useful. +These are libnix bindings required by harmonia to communicate with the local nix daemon. +Over time we will replace the dependencies on libnix with rust-native code. Note: This project provides bindings, this makes the project automatically unsafe. Supported nix version: -- nix 2.8 -- nix 2.9 -- nix 2.10 -- nix 2.11 +- nix 2.24 ## Requirements @@ -26,7 +22,6 @@ stdenv.mkDerivation { # required nix nlohmann_json - libsodium boost # additional packages you might need diff --git a/libnixstore/build.rs b/libnixstore/build.rs index d3bf01d8..668cc5b9 100644 --- a/libnixstore/build.rs +++ b/libnixstore/build.rs @@ -5,7 +5,6 @@ fn main() { pkg_config::probe_library("nix-store").unwrap(); pkg_config::probe_library("nix-main").unwrap(); - pkg_config::probe_library("libsodium").unwrap(); let includedir = pkg_config::get_variable("nix-store", "includedir").expect("Failed to get includedir"); diff --git a/libnixstore/include/nix.h b/libnixstore/include/nix.h index 518eeae0..814fc25f 100644 --- a/libnixstore/include/nix.h +++ b/libnixstore/include/nix.h @@ -10,8 +10,6 @@ rust::String query_path_hash(rust::Str path); InternalPathInfo query_path_info(rust::Str path, bool base32); rust::String query_path_from_hash_part(rust::Str hash_part); rust::String sign_string(rust::Str secret_key, rust::Str msg); -rust::Vec -sign_detached(rust::Slice secret_key, rust::Str msg); rust::String get_store_dir(); rust::String get_real_store_dir(); rust::String get_build_log(rust::Str derivation_path); diff --git a/libnixstore/src/lib.rs b/libnixstore/src/lib.rs index 742753c1..479499fc 100644 --- a/libnixstore/src/lib.rs +++ b/libnixstore/src/lib.rs @@ -29,7 +29,6 @@ mod ffi { fn query_path_hash(path: &str) -> Result; fn query_path_info(path: &str, base32: bool) -> Result; fn query_path_from_hash_part(hash_part: &str) -> Result; - fn sign_detached(secret_key: &[u8], msg: &str) -> Vec; fn get_store_dir() -> String; fn get_real_store_dir() -> String; fn get_build_log(derivation_path: &str) -> Result; @@ -129,12 +128,6 @@ pub fn query_path_from_hash_part(hash_part: &str) -> Option { } } -#[inline] -/// Return a detached signature of the given string. -pub fn sign_detached(secret_key: &[u8], msg: &str) -> Vec { - ffi::sign_detached(secret_key, msg) -} - #[inline] #[must_use] /// Returns the path to the directory where nix store sources and derived files. diff --git a/libnixstore/src/nix.cpp b/libnixstore/src/nix.cpp index 9c2134e3..818e56df 100644 --- a/libnixstore/src/nix.cpp +++ b/libnixstore/src/nix.cpp @@ -14,7 +14,6 @@ #include #include -#include #include @@ -127,22 +126,6 @@ rust::String query_path_from_hash_part(rust::Str hash_part) { get_store()->queryPathFromHashPart(STRING_VIEW(hash_part))); } -rust::Vec -sign_detached(rust::Slice secret_key, rust::Str msg) { - rust::Vec sig; - sig.reserve(crypto_sign_BYTES); - unsigned long long sigLen; - for (size_t i = 0; i < crypto_sign_BYTES; i++) { - sig.push_back(0); - } - - crypto_sign_detached(sig.data(), &sigLen, (unsigned char *)msg.data(), - msg.size(), (unsigned char *)secret_key.data()); - sig.truncate(sigLen); - - return sig; -} - rust::String get_store_dir() { return nix::settings.nixStore; } diff --git a/tests/lib.nix b/tests/lib.nix index d079b5b6..5af62976 100644 --- a/tests/lib.nix +++ b/tests/lib.nix @@ -3,14 +3,11 @@ test: pkgs ? import { }, ... }@args: -let - inherit (pkgs) lib; - nixos-lib = import (pkgs.path + "/nixos/lib") { }; -in -(nixos-lib.runTest { - hostPkgs = pkgs; +(pkgs.testers.runNixOSTest { # speed-up evaluation - defaults.documentation.enable = lib.mkDefault false; + defaults.documentation.enable = pkgs.lib.mkDefault false; + # Faster dhcp + defaults.networking.useNetworkd = pkgs.lib.mkDefault true; # to accept external dependencies such as disko node.specialArgs.inputs = args; imports = [ test ]; diff --git a/tests/t00-simple.nix b/tests/t00-simple.nix index 7644b911..3cc9feaa 100644 --- a/tests/t00-simple.nix +++ b/tests/t00-simple.nix @@ -45,7 +45,7 @@ import json start_all() - client01.wait_until_succeeds("curl -f http://harmonia:5000/version") + client01.wait_until_succeeds("timeout 1 curl -f http://harmonia:5000") client01.succeed("curl -f http://harmonia:5000/nix-cache-info") client01.wait_until_succeeds("nix copy --from http://harmonia:5000/ ${pkgs.hello}") diff --git a/tests/t02-varnish.nix b/tests/t02-varnish.nix index d68afe17..9fc40e15 100644 --- a/tests/t02-varnish.nix +++ b/tests/t02-varnish.nix @@ -44,7 +44,7 @@ testScript = '' start_all() - client01.wait_until_succeeds("curl -f http://harmonia/version") + client01.wait_until_succeeds("timeout 1 curl -f http://harmonia/version") client01.succeed("curl -f http://harmonia/nix-cache-info") client01.wait_until_succeeds("nix copy --from http://harmonia/ ${pkgs.hello}") diff --git a/tests/t03-chroot.nix b/tests/t03-chroot.nix index d7ac87e5..83360276 100644 --- a/tests/t03-chroot.nix +++ b/tests/t03-chroot.nix @@ -42,7 +42,7 @@ harmonia.systemctl("start harmonia-dev.service") harmonia.wait_for_unit("harmonia-dev.service") - client01.wait_until_succeeds("curl -f http://harmonia:5000/version") + client01.wait_until_succeeds("timeout 1 curl -f http://harmonia:5000/version") client01.succeed("curl -f http://harmonia:5000/nix-cache-info") client01.wait_until_succeeds(f"nix copy --from http://harmonia:5000/ {f}")