mirror of
https://github.com/NixOS/mobile-nixos.git
synced 2024-12-17 13:10:29 +03:00
153 lines
3.8 KiB
Nix
153 lines
3.8 KiB
Nix
{ stdenvNoCC, lib, writeText }:
|
|
|
|
/* */ let scope = { "fileSystem.makeFilesystem" =
|
|
|
|
let
|
|
inherit (lib) optionals optionalString assertMsg;
|
|
in
|
|
|
|
{
|
|
name
|
|
# Size (in bytes) the filesystem image will be given.
|
|
# When size is not given, it is assumed that `populateCommands` will populate
|
|
# the filesystem, and the size will be derived (see computeMinimalSize).
|
|
, size ? null
|
|
|
|
# The populate commands are executed in a subshell. The CWD at the star is the
|
|
# public API to know where to add files that will be added to the image.
|
|
, populateCommands ? null
|
|
|
|
# Used with the assumption that files are rounded up to blockSize increments.
|
|
, blockSize
|
|
|
|
# Additional commands to compute a required increase in size to fit files.
|
|
, computeMinimalSize ? null
|
|
|
|
# When automatic sizing is used, additional amount of bytes to pad the image by.
|
|
, extraPadding ? 0
|
|
, ...
|
|
} @ args:
|
|
|
|
assert lib.asserts.assertMsg
|
|
(size !=null || populateCommands != null)
|
|
"Either a size or populateCommands needs to be given to build a filesystem.";
|
|
|
|
let
|
|
partName = name;
|
|
in
|
|
stdenvNoCC.mkDerivation (args // rec {
|
|
# Do not inherit `size`; we don't want to accidentally use it. The `size` can
|
|
# be dynamic depending on the contents.
|
|
inherit partName blockSize;
|
|
|
|
name = "partition-${partName}";
|
|
filename = "${partName}.img";
|
|
img = "${placeholder "out"}/${filename}";
|
|
|
|
nativeBuildInputs = [
|
|
] ++ optionals (args ? nativeBuildInputs) args.nativeBuildInputs;
|
|
|
|
buildCommand = ''
|
|
adjust-minimal-size() {
|
|
size="$1"
|
|
|
|
echo "$size"
|
|
}
|
|
|
|
compute-minimal-size() {
|
|
local size=0
|
|
(
|
|
cd files
|
|
# Size rounded in blocks. This assumes all files are to be rounded to a
|
|
# multiple of blockSize.
|
|
# Use of `--apparent-size` is to ensure we don't get the block size of the underlying FS.
|
|
# Use of `--block-size` is to get *our* block size.
|
|
size=$(find . ! -type d -exec 'du' '--apparent-size' '--block-size' "$blockSize" '{}' ';' | cut -f1 | sum-lines)
|
|
echo "Reserving $size sectors for files..." 1>&2
|
|
|
|
# Adds one blockSize per directory, they do take some place, in the end.
|
|
# FIXME: write test to confirm this assumption
|
|
local directories=$(find . -type d | wc -l)
|
|
echo "Reserving $directories sectors for directories..." 1>&2
|
|
|
|
size=$(( directories + size ))
|
|
|
|
size=$((size * blockSize))
|
|
|
|
${if computeMinimalSize == null then "" else computeMinimalSize}
|
|
|
|
size=$(( size + ${toString extraPadding} ))
|
|
|
|
echo "$size"
|
|
)
|
|
}
|
|
|
|
sum-lines() {
|
|
local acc=0
|
|
while read -r number; do
|
|
acc=$((acc+number))
|
|
done
|
|
|
|
echo "$acc"
|
|
}
|
|
|
|
|
|
# The default stdenv/generic clashes with `runHook`.
|
|
# It doesn't override as expected.
|
|
unset -f checkPhase
|
|
|
|
mkdir -p $out
|
|
mkdir -p files
|
|
|
|
${optionalString (populateCommands != null) ''
|
|
echo
|
|
echo "Populating disk image"
|
|
echo
|
|
(
|
|
cd files
|
|
${populateCommands}
|
|
)
|
|
''}
|
|
${optionalString (size == null) ''
|
|
size=$(compute-minimal-size)
|
|
''}
|
|
|
|
if (( size < minimumSize )); then
|
|
size=$minimumSize
|
|
echo "WARNING: the '$partName' partition was too small, size increased to $minimumSize bytes."
|
|
fi
|
|
|
|
echo
|
|
echo "Building partition ${partName}"
|
|
echo "With ${if size == null
|
|
then "automatic size ($size bytes)"
|
|
else "$size bytes"
|
|
}"
|
|
echo
|
|
|
|
echo " -> Allocating space"
|
|
truncate -s $size "$img"
|
|
|
|
echo " -> Making filesystem"
|
|
runHook filesystemPhase
|
|
|
|
echo " -> Copying files"
|
|
(
|
|
cd files
|
|
runHook copyPhase
|
|
)
|
|
|
|
echo " -> Checking filesystem"
|
|
echo "$checkPhase"
|
|
runHook checkPhase
|
|
|
|
'';
|
|
|
|
})
|
|
# mkdir -p $out/nix-support
|
|
# cat ${writeText "${name}-metadata" (builtins.toJSON {
|
|
# inherit size;
|
|
# })} > $out/nix-support/partition-metadata.json
|
|
|
|
/* */ ;}; in scope."fileSystem.makeFilesystem"
|