mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-12-27 08:04:14 +00:00
5b4a8db4d9
Allow customisation of the algorithm used to convert nix references graph (created from docker image contents) to docker layers. A collection of building blocks (python functions) is provided, which use can assembled into a processing pipeline by specifying a list of operations (and their initial arguments) via a nix list. Nix references graph if first converted into a python igraph.Graph object (with each vertex representing a nix path), which is then fed into the user defined pipeline. Each stage in the pipeline represents a function call, with initial arguments specified by the user in nix, and the last argument being the result of the previous stage in the pipeline (or the initial Graph object). Each step of the pipeline is expected to produce a data structure consisting of arbitrarily nested lists/dicts with Graph objects (representing docker layers) at it's leafs. The result of the last stage in the pipeline is recursively flattened (with each dict converted into list of values), until a flat list of Graphs remains. This is then output as a json array of arrays (each Graph converted into an array of paths). This functionality is made available via new `layeringPipeline` argument to the `streamLayeredImage`/`buildLayeredImage` functions. The default value of the argument has been chosen to to preserve current layering behaviour. Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
35 lines
1.1 KiB
Nix
35 lines
1.1 KiB
Nix
{
|
|
lib,
|
|
runCommand,
|
|
jq,
|
|
}:
|
|
{
|
|
maxLayers,
|
|
fromImage ? null,
|
|
}:
|
|
runCommand "popularity-contest-layering-pipeline.json" { inherit maxLayers; } ''
|
|
# Compute the number of layers that are already used by a potential
|
|
# 'fromImage' as well as the customization layer. Ensure that there is
|
|
# still at least one layer available to store the image contents.
|
|
# one layer will be taken up by the customisation layer
|
|
usedLayers=1
|
|
|
|
${lib.optionalString (fromImage != null) ''
|
|
# subtract number of base image layers
|
|
baseImageLayersCount=$(tar -xOf "${fromImage}" manifest.json | ${lib.getExe jq} '.[0].Layers | length')
|
|
|
|
(( usedLayers += baseImageLayersCount ))
|
|
''}
|
|
|
|
if ! (( $usedLayers < $maxLayers )); then
|
|
echo >&2 "Error: usedLayers $usedLayers layers to store 'fromImage' and" \
|
|
"'extraCommands', but only maxLayers=$maxLayers were" \
|
|
"allowed. At least 1 layer is required to store contents."
|
|
exit 1
|
|
fi
|
|
availableLayers=$(( maxLayers - usedLayers ))
|
|
|
|
# Produce pipeline which uses popularity_contest algo.
|
|
echo '[["popularity_contest"],["limit_layers",'$availableLayers']]' > $out
|
|
''
|