Preload cache into Nix store

This commit is contained in:
Stéphan Kochen
2020-08-25 22:37:26 +02:00
parent 5d3ed3c119
commit fcba68fd6f
3 changed files with 145 additions and 15 deletions
+62
View File
@@ -0,0 +1,62 @@
import { createHash } from "crypto";
import { Filename, PortablePath, ppath } from "@yarnpkg/fslib";
const charset = "0123456789abcdfghijklmnpqrsvwxyz";
/**
* Short-hand for simple hash computation.
*/
export const computeHash = (algorithm: string, data: string | Buffer) =>
createHash(algorithm).update(data).digest();
/**
* Nix-compatible hash compression.
*/
export const compressHash = (hash: Buffer, size: number) => {
const result = Buffer.alloc(size);
for (let idx = 0; idx < hash.length; idx++) {
result[idx % size] ^= hash[idx];
}
return result;
};
/**
* Nix-compatible base32 encoding.
*
* This is probably a super inefficient implementation, but we only process
* small inputs. (20 bytes)
*/
export const encodeBase32 = (buf: Buffer) => {
let result = ``;
let bits = [...buf]
.reverse()
.map((n) => n.toString(2).padStart(8, `0`))
.join(``);
while (bits) {
result += charset[parseInt(bits.slice(0, 5), 2)];
bits = bits.slice(5);
}
return result;
};
/**
* Compute the Nix store path for a fixed-output derivation.
*/
export const computeFixedOutputStorePath = (
name: string,
hashAlgorithm: string,
hash: Buffer,
storePath = `/nix/store` as PortablePath
) => {
const hashHex = hash.toString("hex");
const innerStr = `fixed:out:${hashAlgorithm}:${hashHex}:`;
const innerHash = computeHash(`sha256`, innerStr);
const innerHashHex = innerHash.toString("hex");
const outerStr = `output:out:sha256:${innerHashHex}:${storePath}:${name}`;
const outerHash = computeHash(`sha256`, outerStr);
const outerHash32 = encodeBase32(compressHash(outerHash, 20));
return ppath.join(storePath, `${outerHash32}-${name}` as Filename);
};