Skip to content

Commit 0161e34

Browse files
committed
make-disk-image: allow pre/post format files in vm
1 parent d32d150 commit 0161e34

File tree

2 files changed

+90
-20
lines changed

2 files changed

+90
-20
lines changed

lib/make-disk-image.nix

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,26 @@ let
4141
util-linux
4242
findutils
4343
] ++ cfg.extraDependencies;
44+
45+
prepareFile = name: content: ''
46+
out="$(echo "${name}" | base64)"
47+
${if lib.isStorePath content
48+
then ''cp --reflink=auto -r "${content}" "$out"''
49+
else content
50+
}
51+
'';
52+
53+
prepareFiles = ''
54+
(
55+
cd $TMPDIR/xchg
56+
mkdir -p pre_format_files post_format_files
57+
cd pre_format_files
58+
${lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs prepareFile cfg.preFormatFiles))}
59+
cd ../post_format_files
60+
${lib.concatStringsSep "\n" (lib.attrValues (lib.mapAttrs prepareFile cfg.postFormatFiles))}
61+
)
62+
'';
63+
4464
preVM = ''
4565
${lib.concatMapStringsSep "\n" (disk: "${pkgs.qemu}/bin/qemu-img create -f ${imageFormat} ${disk.name}.${imageFormat} ${disk.imageSize}") (lib.attrValues diskoCfg.devices.disk)}
4666
# This makes disko work, when canTouchEfiVariables is set to true.
@@ -58,8 +78,19 @@ let
5878
closureInfo = pkgs.closureInfo {
5979
rootPaths = [ systemToInstall.config.system.build.toplevel ];
6080
};
81+
6182
partitioner = ''
62-
set -efux
83+
set -eux
84+
85+
set +f
86+
for src in /tmp/xchg/pre_format_files/*; do
87+
[ -e "$src" ] || continue
88+
dst=$(basename "$src" | base64 -d)
89+
mkdir -p "$(dirname "$dst")"
90+
cp -r "$src" "$dst"
91+
done
92+
set -f
93+
6394
# running udev, stolen from stage-1.sh
6495
echo "running udev..."
6596
ln -sfn /proc/self/fd /dev/fd
@@ -79,6 +110,15 @@ let
79110
export IN_DISKO_TEST=1
80111
''}
81112
${systemToInstall.config.system.build.diskoScript}
113+
114+
set +f
115+
for src in /tmp/xchg/post_format_files/*; do
116+
[ -e "$src" ] || continue
117+
dst=/mnt/$(basename "$src" | base64 -d)
118+
mkdir -p "$(dirname "$dst")"
119+
cp -r "$src" "$dst"
120+
done
121+
set -f
82122
'';
83123

84124
installer = lib.optionalString cfg.copyNixStore ''
@@ -107,8 +147,9 @@ in
107147
system.build.diskoImages = vmTools.runInLinuxVM (pkgs.runCommand cfg.name
108148
{
109149
buildInputs = dependencies;
110-
inherit preVM postVM QEMU_OPTS;
150+
inherit postVM QEMU_OPTS;
111151
inherit (diskoCfg) memSize;
152+
preVM = preVM + prepareFiles;
112153
}
113154
(partitioner + installer));
114155

@@ -139,20 +180,20 @@ in
139180
trap 'rm -rf "$TMPDIR"' EXIT
140181
cd "$TMPDIR"
141182
142-
mkdir copy_before_disko copy_after_disko
183+
mkdir pre_format_files post_format_files
143184
144185
while [[ $# -gt 0 ]]; do
145186
case "$1" in
146187
--pre-format-files)
147188
src=$2
148189
dst=$3
149-
cp --reflink=auto -r "$src" copy_before_disko/"$(echo "$dst" | base64)"
190+
cp --reflink=auto -r "$src" pre_format_files/"$(echo "$dst" | base64)"
150191
shift 2
151192
;;
152193
--post-format-files)
153194
src=$2
154195
dst=$3
155-
cp --reflink=auto -r "$src" copy_after_disko/"$(echo "$dst" | base64)"
196+
cp --reflink=auto -r "$src" post_format_files/"$(echo "$dst" | base64)"
156197
shift 2
157198
;;
158199
--build-memory)
@@ -174,25 +215,11 @@ in
174215
175216
export preVM=${diskoLib.writeCheckedBash { inherit pkgs checked; } "preVM.sh" ''
176217
set -efu
177-
mv copy_before_disko copy_after_disko xchg/
218+
mv pre_format_files post_format_files xchg/
178219
origBuilder=${pkgs.writeScript "disko-builder" ''
179220
set -eu
180221
export PATH=${lib.makeBinPath dependencies}
181-
for src in /tmp/xchg/copy_before_disko/*; do
182-
[ -e "$src" ] || continue
183-
dst=$(basename "$src" | base64 -d)
184-
mkdir -p "$(dirname "$dst")"
185-
cp -r "$src" "$dst"
186-
done
187-
set -f
188222
${partitioner}
189-
set +f
190-
for src in /tmp/xchg/copy_after_disko/*; do
191-
[ -e "$src" ] || continue
192-
dst=/mnt/$(basename "$src" | base64 -d)
193-
mkdir -p "$(dirname "$dst")"
194-
cp -r "$src" "$dst"
195-
done
196223
${installer}
197224
''}
198225
echo "export origBuilder=$origBuilder" > xchg/saved-env

module.nix

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,49 @@ in
9696
default = { };
9797
};
9898

99+
preFormatFiles = lib.mkOption {
100+
type = lib.types.attrsOf (lib.types.either lib.types.str lib.types.path);
101+
description = ''
102+
Files to copy into the image builder VM before disko is run.
103+
This is useful to provide secrets like LUKS keys, or other files you need for formatting.
104+
105+
Names are interpreted as destination paths. If the value is a store path,
106+
that path will be copied as-is. If it's not a store path, the value will be interpreted
107+
as shell code is expected to write files into $out.
108+
'';
109+
default = {
110+
example = lib.literalExpression ''
111+
{
112+
"/tmp/pre/file" = pkgs.writeText "foo" "bar";
113+
"/tmp/pre/script" = "mkdir -p $out/foo; echo bar > $out/foo";
114+
}
115+
'';
116+
};
117+
};
118+
119+
postFormatFiles = lib.mkOption {
120+
type = lib.types.attrsOf (lib.types.either lib.types.str lib.types.path);
121+
description = ''
122+
Files to copy into the final image, after disko has run.
123+
These end up in the images later and is useful if you want to add some extra stateful files
124+
They will have the same permissions but will be owned by root:root.
125+
126+
Names are interpreted as destination paths. If the value is a store path,
127+
that path will be copied as-is. If it's not a store path, the value will be interpreted
128+
as shell code is expected to write files into $out.
129+
'';
130+
default = {
131+
example = lib.literalExpression ''
132+
{
133+
"/tmp/pre/file" = pkgs.writeText "foo" "bar";
134+
"/tmp/pre/script" = "mkdir -p $out/foo; echo bar > $out/foo";
135+
}
136+
'';
137+
};
138+
};
139+
140+
141+
99142
imageFormat = lib.mkOption {
100143
type = lib.types.enum [ "raw" "qcow2" ];
101144
description = "QEMU image format to use for the disk images";

0 commit comments

Comments
 (0)