fix(tvix/cli): handle SRI hashes in outputHash
Instead of being called with `md5`, `sha1`, `sha256` or `sha512`, `fetchurl.nix` (from corepkgs / `<nix`) can also be called with a `hash` attribute, being an SRI hash. In that case, `builtin.derivation` is called with `outputHashAlgo` being an empty string, and `outputHash` being an SRI hash string. In other cases, an SRI hash is passed as outputHash, but outputHashAlgo is set too. Nix does modify these values in (single, fixed) output specification it serializes to ATerm, but keeps it unharmed in `env`. Move this into a construct_output_hash helper function, that can be tested better in isolation. Change-Id: Id9d716a119664c44ea7747540399966752e20187 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7933 Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
This commit is contained in:
parent
bda5fc58d0
commit
a94a1434cc
5 changed files with 573 additions and 38 deletions
129
tvix/Cargo.lock
generated
129
tvix/Cargo.lock
generated
|
@ -171,6 +171,15 @@ dependencies = [
|
|||
"nix 0.23.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
|
@ -215,17 +224,38 @@ dependencies = [
|
|||
"cc",
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
"digest",
|
||||
"digest 0.10.6",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.14.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -234,6 +264,12 @@ version = "3.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
|
@ -495,7 +531,7 @@ version = "0.1.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"generic-array 0.14.6",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
|
@ -521,13 +557,22 @@ version = "0.1.13"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"block-buffer 0.10.3",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
@ -616,6 +661,12 @@ dependencies = [
|
|||
"str-buf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fastcdc"
|
||||
version = "2.0.0"
|
||||
|
@ -768,6 +819,15 @@ dependencies = [
|
|||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
|
@ -856,6 +916,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.8"
|
||||
|
@ -1294,6 +1360,12 @@ version = "11.1.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
|
@ -1911,6 +1983,30 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3",
|
||||
"digest 0.8.1",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3",
|
||||
"digest 0.8.1",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.6"
|
||||
|
@ -1919,7 +2015,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
"digest 0.10.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1982,6 +2078,21 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ssri"
|
||||
version = "7.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9cec0d388f39fbe79d7aa600e8d38053bf97b1bc8d350da7c0ba800d0f423f2"
|
||||
dependencies = [
|
||||
"base64 0.10.1",
|
||||
"digest 0.8.1",
|
||||
"hex",
|
||||
"serde",
|
||||
"sha-1",
|
||||
"sha2 0.8.2",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
@ -2302,7 +2413,7 @@ dependencies = [
|
|||
"async-stream",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"base64",
|
||||
"base64 0.13.1",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
|
@ -2498,11 +2609,15 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"aho-corasick",
|
||||
"clap 4.0.32",
|
||||
"data-encoding",
|
||||
"dirs",
|
||||
"rustyline",
|
||||
"smol_str",
|
||||
"ssri",
|
||||
"test-case",
|
||||
"tvix-derivation",
|
||||
"tvix-eval",
|
||||
"tvix-store-bin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2514,7 +2629,7 @@ dependencies = [
|
|||
"glob",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sha2 0.10.6",
|
||||
"test-case",
|
||||
"test-generator",
|
||||
"thiserror",
|
||||
|
|
318
tvix/Cargo.nix
318
tvix/Cargo.nix
|
@ -635,7 +635,24 @@ rec {
|
|||
];
|
||||
|
||||
};
|
||||
"base64" = rec {
|
||||
"base64 0.10.1" = rec {
|
||||
crateName = "base64";
|
||||
version = "0.10.1";
|
||||
edition = "2015";
|
||||
sha256 = "13k6bvd3n6dm7jqn9x918w65dd9xhx454bqphbnv0bkd6n9dj98b";
|
||||
authors = [
|
||||
"Alice Maz <alice@alicemaz.com>"
|
||||
"Marshall Pierce <marshall@mpierce.org>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "byteorder";
|
||||
packageId = "byteorder";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"base64 0.13.1" = rec {
|
||||
crateName = "base64";
|
||||
version = "0.13.1";
|
||||
edition = "2018";
|
||||
|
@ -743,7 +760,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest";
|
||||
packageId = "digest 0.10.6";
|
||||
optional = true;
|
||||
features = [ "mac" ];
|
||||
}
|
||||
|
@ -768,7 +785,7 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "default" "digest" "rayon" "std" ];
|
||||
};
|
||||
"block-buffer" = rec {
|
||||
"block-buffer 0.10.3" = rec {
|
||||
crateName = "block-buffer";
|
||||
version = "0.10.3";
|
||||
edition = "2018";
|
||||
|
@ -779,7 +796,52 @@ rec {
|
|||
dependencies = [
|
||||
{
|
||||
name = "generic-array";
|
||||
packageId = "generic-array";
|
||||
packageId = "generic-array 0.14.6";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"block-buffer 0.7.3" = rec {
|
||||
crateName = "block-buffer";
|
||||
version = "0.7.3";
|
||||
edition = "2015";
|
||||
sha256 = "12v8wizynqin0hqf140kmp9s38q223mp1b0hkqk8j5pk8720v560";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "block-padding";
|
||||
packageId = "block-padding";
|
||||
}
|
||||
{
|
||||
name = "byte-tools";
|
||||
packageId = "byte-tools";
|
||||
}
|
||||
{
|
||||
name = "byteorder";
|
||||
packageId = "byteorder";
|
||||
usesDefaultFeatures = false;
|
||||
}
|
||||
{
|
||||
name = "generic-array";
|
||||
packageId = "generic-array 0.12.4";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"block-padding" = rec {
|
||||
crateName = "block-padding";
|
||||
version = "0.1.5";
|
||||
edition = "2015";
|
||||
sha256 = "1xbkmysiz23vimd17rnsjpw9bgjxipwfslwyygqlkx4in3dxwygs";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "byte-tools";
|
||||
packageId = "byte-tools";
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -795,6 +857,16 @@ rec {
|
|||
features = { };
|
||||
resolvedDefaultFeatures = [ "default" ];
|
||||
};
|
||||
"byte-tools" = rec {
|
||||
crateName = "byte-tools";
|
||||
version = "0.3.1";
|
||||
edition = "2015";
|
||||
sha256 = "1mqi29wsm8njpl51pfwr31wmpzs5ahlcb40wsjyd92l90ixcmdg3";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
|
||||
};
|
||||
"byteorder" = rec {
|
||||
crateName = "byteorder";
|
||||
version = "1.4.3";
|
||||
|
@ -1503,7 +1575,7 @@ rec {
|
|||
dependencies = [
|
||||
{
|
||||
name = "generic-array";
|
||||
packageId = "generic-array";
|
||||
packageId = "generic-array 0.14.6";
|
||||
features = [ "more_lengths" ];
|
||||
}
|
||||
{
|
||||
|
@ -1564,7 +1636,7 @@ rec {
|
|||
];
|
||||
|
||||
};
|
||||
"digest" = rec {
|
||||
"digest 0.10.6" = rec {
|
||||
crateName = "digest";
|
||||
version = "0.10.6";
|
||||
edition = "2018";
|
||||
|
@ -1575,7 +1647,7 @@ rec {
|
|||
dependencies = [
|
||||
{
|
||||
name = "block-buffer";
|
||||
packageId = "block-buffer";
|
||||
packageId = "block-buffer 0.10.3";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
|
@ -1604,6 +1676,26 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "alloc" "block-buffer" "core-api" "default" "mac" "std" "subtle" ];
|
||||
};
|
||||
"digest 0.8.1" = rec {
|
||||
crateName = "digest";
|
||||
version = "0.8.1";
|
||||
edition = "2015";
|
||||
sha256 = "1madjl27f3kj5ql7kwgvb9c8b7yb7bv7yfgx7rqzj4i3fp4cil7k";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "generic-array";
|
||||
packageId = "generic-array 0.12.4";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"blobby" = [ "dep:blobby" ];
|
||||
"dev" = [ "blobby" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "std" ];
|
||||
};
|
||||
"dirs" = rec {
|
||||
crateName = "dirs";
|
||||
version = "4.0.0";
|
||||
|
@ -1806,6 +1898,16 @@ rec {
|
|||
];
|
||||
features = { };
|
||||
};
|
||||
"fake-simd" = rec {
|
||||
crateName = "fake-simd";
|
||||
version = "0.1.2";
|
||||
edition = "2015";
|
||||
sha256 = "1vfylvk4va2ivqx85603lyqqp0zk52cgbs4n5nfbbbqx577qm2p8";
|
||||
authors = [
|
||||
"The Rust-Crypto Project Developers"
|
||||
];
|
||||
|
||||
};
|
||||
"fastcdc" = rec {
|
||||
crateName = "fastcdc";
|
||||
version = "2.0.0";
|
||||
|
@ -2214,7 +2316,27 @@ rec {
|
|||
];
|
||||
|
||||
};
|
||||
"generic-array" = rec {
|
||||
"generic-array 0.12.4" = rec {
|
||||
crateName = "generic-array";
|
||||
version = "0.12.4";
|
||||
edition = "2015";
|
||||
sha256 = "1gfpay78vijl9vrwl1k9v7fbvbhkhcmnrk4kfg9l6x24y4s9zpzz";
|
||||
libName = "generic_array";
|
||||
authors = [
|
||||
"Bartłomiej Kamiński <fizyk20@gmail.com>"
|
||||
"Aaron Trent <novacrazy@gmail.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "typenum";
|
||||
packageId = "typenum";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"serde" = [ "dep:serde" ];
|
||||
};
|
||||
};
|
||||
"generic-array 0.14.6" = rec {
|
||||
crateName = "generic-array";
|
||||
version = "0.14.6";
|
||||
edition = "2015";
|
||||
|
@ -2478,6 +2600,16 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "default" ];
|
||||
};
|
||||
"hex" = rec {
|
||||
crateName = "hex";
|
||||
version = "0.3.2";
|
||||
edition = "2015";
|
||||
sha256 = "0xsdcjiik5j750j67zk42qdnmm4ahirk3gmkmcqgq7qls2jjcl40";
|
||||
authors = [
|
||||
"KokaKiwi <kokakiwi@kokakiwi.net>"
|
||||
];
|
||||
features = { };
|
||||
};
|
||||
"http" = rec {
|
||||
crateName = "http";
|
||||
version = "0.2.8";
|
||||
|
@ -3748,6 +3880,16 @@ rec {
|
|||
"Simon Heath <icefox@dreamquest.io>"
|
||||
];
|
||||
|
||||
};
|
||||
"opaque-debug" = rec {
|
||||
crateName = "opaque-debug";
|
||||
version = "0.2.3";
|
||||
edition = "2015";
|
||||
sha256 = "172j6bs8ndclqxa2m64qc0y1772rr73g4l9fg2svscgicnbfff98";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
|
||||
};
|
||||
"os_str_bytes" = rec {
|
||||
crateName = "os_str_bytes";
|
||||
|
@ -5514,7 +5656,51 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "serde" ];
|
||||
};
|
||||
"sha2" = rec {
|
||||
"sha-1" = rec {
|
||||
crateName = "sha-1";
|
||||
version = "0.8.2";
|
||||
edition = "2015";
|
||||
sha256 = "1pv387q0r7llk2cqzyq0nivzvkgqgzsiygqzlv7b68z9xl5lvngp";
|
||||
libName = "sha1";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "block-buffer";
|
||||
packageId = "block-buffer 0.7.3";
|
||||
}
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest 0.8.1";
|
||||
}
|
||||
{
|
||||
name = "fake-simd";
|
||||
packageId = "fake-simd";
|
||||
}
|
||||
{
|
||||
name = "opaque-debug";
|
||||
packageId = "opaque-debug";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest 0.8.1";
|
||||
features = [ "dev" ];
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"asm" = [ "sha1-asm" ];
|
||||
"asm-aarch64" = [ "asm" "libc" ];
|
||||
"default" = [ "std" ];
|
||||
"libc" = [ "dep:libc" ];
|
||||
"sha1-asm" = [ "dep:sha1-asm" ];
|
||||
"std" = [ "digest/std" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "default" "std" ];
|
||||
};
|
||||
"sha2 0.10.6" = rec {
|
||||
crateName = "sha2";
|
||||
version = "0.10.6";
|
||||
edition = "2018";
|
||||
|
@ -5534,13 +5720,13 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest";
|
||||
packageId = "digest 0.10.6";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest";
|
||||
packageId = "digest 0.10.6";
|
||||
features = [ "dev" ];
|
||||
}
|
||||
];
|
||||
|
@ -5554,6 +5740,49 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "default" "std" ];
|
||||
};
|
||||
"sha2 0.8.2" = rec {
|
||||
crateName = "sha2";
|
||||
version = "0.8.2";
|
||||
edition = "2015";
|
||||
sha256 = "0s9yddvyg6anaikdl86wmwfim25c0d4m0xq0y2ghs34alxpg8mm2";
|
||||
authors = [
|
||||
"RustCrypto Developers"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "block-buffer";
|
||||
packageId = "block-buffer 0.7.3";
|
||||
}
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest 0.8.1";
|
||||
}
|
||||
{
|
||||
name = "fake-simd";
|
||||
packageId = "fake-simd";
|
||||
}
|
||||
{
|
||||
name = "opaque-debug";
|
||||
packageId = "opaque-debug";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest 0.8.1";
|
||||
features = [ "dev" ];
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"asm" = [ "sha2-asm" ];
|
||||
"asm-aarch64" = [ "asm" "libc" ];
|
||||
"default" = [ "std" ];
|
||||
"libc" = [ "dep:libc" ];
|
||||
"sha2-asm" = [ "dep:sha2-asm" ];
|
||||
"std" = [ "digest/std" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "default" "std" ];
|
||||
};
|
||||
"sharded-slab" = rec {
|
||||
crateName = "sharded-slab";
|
||||
version = "0.1.4";
|
||||
|
@ -5730,6 +5959,51 @@ rec {
|
|||
features = { };
|
||||
resolvedDefaultFeatures = [ "all" ];
|
||||
};
|
||||
"ssri" = rec {
|
||||
crateName = "ssri";
|
||||
version = "7.0.0";
|
||||
edition = "2018";
|
||||
sha256 = "1wi3yk801a0bgkd51ly83dxzjfq5726hwq5asxwvx7zki39w1km9";
|
||||
authors = [
|
||||
"Kat Marchán <kzm@zkat.tech>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "base64";
|
||||
packageId = "base64 0.10.1";
|
||||
}
|
||||
{
|
||||
name = "digest";
|
||||
packageId = "digest 0.8.1";
|
||||
}
|
||||
{
|
||||
name = "hex";
|
||||
packageId = "hex";
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "sha-1";
|
||||
packageId = "sha-1";
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2 0.8.2";
|
||||
}
|
||||
{
|
||||
name = "thiserror";
|
||||
packageId = "thiserror";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"default" = [ "serde" ];
|
||||
"serde" = [ "dep:serde" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "default" "serde" ];
|
||||
};
|
||||
"static_assertions" = rec {
|
||||
crateName = "static_assertions";
|
||||
version = "1.1.0";
|
||||
|
@ -6635,7 +6909,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "base64";
|
||||
packageId = "base64";
|
||||
packageId = "base64 0.13.1";
|
||||
}
|
||||
{
|
||||
name = "bytes";
|
||||
|
@ -7439,6 +7713,10 @@ rec {
|
|||
packageId = "clap 4.0.32";
|
||||
features = [ "derive" "env" ];
|
||||
}
|
||||
{
|
||||
name = "data-encoding";
|
||||
packageId = "data-encoding";
|
||||
}
|
||||
{
|
||||
name = "dirs";
|
||||
packageId = "dirs";
|
||||
|
@ -7451,6 +7729,10 @@ rec {
|
|||
name = "smol_str";
|
||||
packageId = "smol_str";
|
||||
}
|
||||
{
|
||||
name = "ssri";
|
||||
packageId = "ssri";
|
||||
}
|
||||
{
|
||||
name = "tvix-derivation";
|
||||
packageId = "tvix-derivation";
|
||||
|
@ -7459,6 +7741,16 @@ rec {
|
|||
name = "tvix-eval";
|
||||
packageId = "tvix-eval";
|
||||
}
|
||||
{
|
||||
name = "tvix-store-bin";
|
||||
packageId = "tvix-store-bin";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "test-case";
|
||||
packageId = "test-case";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
|
@ -7492,7 +7784,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2";
|
||||
packageId = "sha2 0.10.6";
|
||||
}
|
||||
{
|
||||
name = "thiserror";
|
||||
|
|
|
@ -12,6 +12,12 @@ tvix-eval = { path = "../eval" }
|
|||
tvix-derivation = { path = "../derivation" }
|
||||
rustyline = "10.0.0"
|
||||
clap = { version = "4.0", features = ["derive", "env"] }
|
||||
tvix-store-bin = { path = "../store" }
|
||||
dirs = "4.0.0"
|
||||
smol_str = "0.1"
|
||||
aho-corasick = "0.7"
|
||||
ssri = "7.0.0"
|
||||
data-encoding = "2.3.3"
|
||||
|
||||
[dev-dependencies]
|
||||
test-case = "2.2.2"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Implements `builtins.derivation`, the core of what makes Nix build packages.
|
||||
|
||||
use data_encoding::BASE64;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{btree_map, BTreeSet};
|
||||
use std::rc::Rc;
|
||||
|
@ -79,6 +80,82 @@ fn populate_inputs<I: IntoIterator<Item = String>>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Due to the support for SRI hashes, and how these are passed along to
|
||||
/// builtins.derivation, outputHash and outputHashAlgo can have values which
|
||||
/// need to be further modified before constructing the Derivation struct.
|
||||
///
|
||||
/// If outputHashAlgo is an SRI hash, outputHashAlgo must either be an empty
|
||||
/// string, or the hash algorithm as specified in the (single) SRI (entry).
|
||||
/// SRI strings with multiple hash algorithms are not supported.
|
||||
///
|
||||
/// In case an SRI string was used, the (single) fixed output is populated
|
||||
/// with the hash algo name, and the hash digest is populated with the
|
||||
/// (lowercase) hex encoding of the digest.
|
||||
///
|
||||
/// These values are only rewritten for the outputs, not what's passed to env.
|
||||
fn construct_output_hash(digest: &str, algo: &str, hash_mode: Option<&str>) -> Result<Hash, Error> {
|
||||
let sri_parsed = digest.parse::<ssri::Integrity>();
|
||||
// SRI strings can embed multiple hashes with different algos, but that's probably not supported
|
||||
|
||||
let (digest, algo): (String, String) = match sri_parsed {
|
||||
Err(e) => {
|
||||
// unable to parse as SRI, but algo not set
|
||||
if algo.is_empty() {
|
||||
// InvalidSRIString doesn't implement PartialEq, but our error does
|
||||
return Err(Error::InvalidSRIString(e.to_string()));
|
||||
}
|
||||
|
||||
// algo is set. Assume the digest is set to some nixbase32.
|
||||
// TODO: more validation here
|
||||
|
||||
(digest.to_string(), algo.to_string())
|
||||
}
|
||||
Ok(sri_parsed) => {
|
||||
// We don't support more than one SRI hash
|
||||
if sri_parsed.hashes.len() != 1 {
|
||||
return Err(Error::UnsupportedSRIMultiple(sri_parsed.hashes.len()).into());
|
||||
}
|
||||
|
||||
// grab the first (and only hash)
|
||||
let sri_parsed_hash = &sri_parsed.hashes[0];
|
||||
|
||||
// ensure the algorithm in the SRI is supported
|
||||
if !(sri_parsed_hash.algorithm == ssri::Algorithm::Sha1
|
||||
|| sri_parsed_hash.algorithm == ssri::Algorithm::Sha256
|
||||
|| sri_parsed_hash.algorithm == ssri::Algorithm::Sha512)
|
||||
{
|
||||
Error::UnsupportedSRIAlgo(sri_parsed_hash.algorithm.to_string());
|
||||
}
|
||||
|
||||
// if algo is set, it needs to match what the SRI says
|
||||
if !algo.is_empty() && algo != sri_parsed_hash.algorithm.to_string() {
|
||||
return Err(Error::ConflictingSRIHashAlgo(
|
||||
algo.to_string(),
|
||||
sri_parsed_hash.algorithm.to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
// the digest comes base64-encoded. We need to decode, and re-encode as hexlower.
|
||||
match BASE64.decode(sri_parsed_hash.digest.as_bytes()) {
|
||||
Err(e) => return Err(Error::InvalidSRIDigest(e).into()),
|
||||
Ok(sri_digest) => (
|
||||
data_encoding::HEXLOWER.encode(&sri_digest),
|
||||
sri_parsed_hash.algorithm.to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// mutate the algo string a bit more, depending on hashMode
|
||||
let algo = match hash_mode {
|
||||
None | Some("flat") => algo,
|
||||
Some("recursive") => format!("r:{}", algo),
|
||||
Some(other) => return Err(Error::InvalidOutputHashMode(other.to_string()).into()),
|
||||
};
|
||||
|
||||
Ok(Hash { algo, digest })
|
||||
}
|
||||
|
||||
/// Populate the output configuration of a derivation based on the
|
||||
/// parameters passed to the call, flipping the required
|
||||
/// parameters for a fixed-output derivation if necessary.
|
||||
|
@ -102,6 +179,12 @@ fn populate_output_configuration(
|
|||
.as_str()
|
||||
.to_string();
|
||||
|
||||
let digest_str = hash
|
||||
.force(vm)?
|
||||
.coerce_to_string(CoercionKind::Strong, vm)?
|
||||
.as_str()
|
||||
.to_string();
|
||||
|
||||
let hash_mode = match hash_mode {
|
||||
None => None,
|
||||
Some(mode) => Some(
|
||||
|
@ -112,23 +195,12 @@ fn populate_output_configuration(
|
|||
),
|
||||
};
|
||||
|
||||
let algo = match hash_mode.as_deref() {
|
||||
None | Some("flat") => algo,
|
||||
Some("recursive") => format!("r:{}", algo),
|
||||
Some(other) => {
|
||||
return Err(Error::InvalidOutputHashMode(other.to_string()).into())
|
||||
}
|
||||
};
|
||||
|
||||
out.hash = Some(Hash {
|
||||
algo,
|
||||
|
||||
digest: hash
|
||||
.force(vm)?
|
||||
.coerce_to_string(CoercionKind::Strong, vm)?
|
||||
.as_str()
|
||||
.to_string(),
|
||||
});
|
||||
// construct out.hash
|
||||
out.hash = Some(construct_output_hash(
|
||||
&digest_str,
|
||||
&algo,
|
||||
hash_mode.as_deref(),
|
||||
)?);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -371,6 +443,7 @@ pub use derivation_builtins::builtins as derivation_builtins;
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use test_case::test_case;
|
||||
use tvix_eval::observer::NoOpObserver;
|
||||
|
||||
static mut OBSERVER: NoOpObserver = NoOpObserver {};
|
||||
|
@ -576,4 +649,23 @@ mod tests {
|
|||
vec!["--foo".to_string(), "42".to_string(), "--bar".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
"sha256-swapHA/ZO8QoDPwumMt6s5gf91oYe+oyk4EfRSyJqMg=", "sha256", Some("flat"),
|
||||
Ok(Hash { algo: "sha256".to_string(), digest: "b306a91c0fd93bc4280cfc2e98cb7ab3981ff75a187bea3293811f452c89a8c8".to_string() });
|
||||
"sha256 and SRI"
|
||||
)]
|
||||
#[test_case(
|
||||
"sha256-s6JN6XqP28g1uYMxaVAQMLiXcDG8tUs7OsE3QPhGqzA=", "", Some("flat"),
|
||||
Ok(Hash { algo: "sha256".to_string(), digest: "b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30".to_string() });
|
||||
"SRI only"
|
||||
)]
|
||||
fn test_construct_output_hash(
|
||||
digest: &str,
|
||||
algo: &str,
|
||||
hash_mode: Option<&str>,
|
||||
result: Result<Hash, Error>,
|
||||
) {
|
||||
assert_eq!(construct_output_hash(digest, algo, hash_mode), result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{error, fmt::Display, rc::Rc};
|
||||
use tvix_derivation::DerivationError;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Error {
|
||||
// Errors related to derivation construction
|
||||
DuplicateOutput(String),
|
||||
|
@ -10,6 +10,11 @@ pub enum Error {
|
|||
ShadowedOutput(String),
|
||||
InvalidDerivation(DerivationError),
|
||||
InvalidOutputHashMode(String),
|
||||
UnsupportedSRIAlgo(String),
|
||||
UnsupportedSRIMultiple(usize),
|
||||
InvalidSRIDigest(data_encoding::DecodeError),
|
||||
InvalidSRIString(String),
|
||||
ConflictingSRIHashAlgo(String, String),
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
|
@ -38,6 +43,31 @@ impl Display for Error {
|
|||
f,
|
||||
"invalid output hash mode: '{mode}', only 'recursive' and 'flat` are supported"
|
||||
),
|
||||
Error::UnsupportedSRIAlgo(algo) => {
|
||||
write!(
|
||||
f,
|
||||
"unsupported sri algorithm: {algo}, only sha1, sha256 or sha512 is supported"
|
||||
)
|
||||
}
|
||||
Error::UnsupportedSRIMultiple(n) => {
|
||||
write!(
|
||||
f,
|
||||
"invalid number of sri hashes in string ({n}), only one hash is supported"
|
||||
)
|
||||
}
|
||||
Error::InvalidSRIDigest(err) => {
|
||||
write!(f, "invalid sri digest: {}", err)
|
||||
}
|
||||
Error::InvalidSRIString(err) => {
|
||||
write!(f, "failed to parse SRI string: {}", err)
|
||||
}
|
||||
Error::ConflictingSRIHashAlgo(algo, sri_algo) => {
|
||||
write!(
|
||||
f,
|
||||
"outputHashAlgo is set to {}, but outputHash contains SRI with algo {}",
|
||||
algo, sri_algo
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue