Skip to content

Commit 344ec71

Browse files
jleboncgwalters
authored andcommittedSep 12, 2019
cmd-build: Split out qemu building into separate command
For FCOS signing, we need a way to build just the OSTree, then have it signed, and then build the image artifacts with the signatures embedded. To do this, we need to decouple qemu image building from `cosa build`. This patch does this by making `cmd-buildextend-qemu` a symlink to `cmd-buildextend-metal` and enhancing the latter to handle both cases. A big advantage of this is that base image building is now located in a single location. We then extend `cosa build` to just take any arbitrary `TARGET` arguments which become semantically equivalent to calling `cosa buildextend-$TARGET`, where `TARGET` is one of `ostree`, `qemu`, `metal`. (And of course, we default to building the qemu image to not break compatibility).
1 parent 0242ba6 commit 344ec71

File tree

5 files changed

+100
-103
lines changed

5 files changed

+100
-103
lines changed
 

‎Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ mantle:
5050
install:
5151
install -d $(DESTDIR)$(PREFIX)/lib/coreos-assembler
5252
install -D -t $(DESTDIR)$(PREFIX)/lib/coreos-assembler $$(find src/ -maxdepth 1 -type f)
53+
cp -df -t $(DESTDIR)$(PREFIX)/lib/coreos-assembler $$(find src/ -maxdepth 1 -type l)
5354
install -d $(DESTDIR)$(PREFIX)/lib/coreos-assembler/cosalib
5455
install -D -t $(DESTDIR)$(PREFIX)/lib/coreos-assembler/cosalib $$(find src/cosalib/ -maxdepth 1 -type f)
5556
install -d $(DESTDIR)$(PREFIX)/bin

‎src/cmd-build

+34-77
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,17 @@ dn=$(dirname "$0")
88
print_help() {
99
cat 1>&2 <<'EOF'
1010
Usage: coreos-assembler build --help
11-
coreos-assembler build [--force] [--skip-prune] [--version VERSION] [TARGETS]
11+
coreos-assembler build [--force] [--skip-prune] [--version VERSION] [TARGET...]
1212
13-
Build OSTree and image artifacts from previously fetched packages.
14-
The TARGETS argument is a list of artifact types to build; if unspecified it
15-
defaults to "qemu".
13+
Build OSTree and image base artifacts from previously fetched packages.
14+
Accepted TARGET arguments:
1615
17-
Valid targets:
16+
- ostree
17+
- qemu
18+
- metal
1819
19-
- ostree
20-
- qemu
21-
22-
Note that all image targets also require the "ostree" target.
20+
The "qemu" and "metal" targets imply "ostree". If unspecified, defaults to
21+
"qemu". They are equivalent to manually running buildextend-[TARGET] after.
2322
EOF
2423
}
2524

@@ -74,16 +73,24 @@ if [ $# -eq 0 ]; then
7473
set -- qemu
7574
fi
7675

77-
build_qemu=
76+
# sanity check the targets and aggregate into a set
77+
declare -A targets=( )
7878
for target in "$@"; do
79-
case $target in
80-
ostree) ;;
81-
qemu) build_qemu=1;;
82-
*) fatal "Unrecognized target: $target";;
83-
esac
79+
if [[ $target != ostree ]]; then
80+
case "$target" in
81+
metal|qemu) ;;
82+
*) fatal "Unrecognized target: $target" ;;
83+
esac
84+
targets[$target]=1
85+
fi
8486
done
8587

86-
export LIBGUESTFS_BACKEND=direct
88+
build_followup_targets() {
89+
cd "${workdir}"
90+
for target in "${!targets[@]}"; do
91+
"/usr/lib/coreos-assembler/cmd-buildextend-${target}"
92+
done
93+
}
8794

8895
prepare_build
8996

@@ -93,8 +100,8 @@ rpm-ostree --version
93100
previous_build=$(get_latest_build)
94101
if [ -n "${previous_build}" ]; then
95102
previous_builddir=$(get_build_dir "${previous_build}")
96-
echo "Previous build: ${previous_build}"
97103
fi
104+
echo "Previous build: ${previous_build:-none}"
98105

99106
previous_commit=
100107
if [ -n "${previous_build}" ]; then
@@ -218,6 +225,11 @@ else
218225
# first build.
219226
if [ -n "${previous_build}" ] && [ "${image_input_checksum}" = "${previous_image_input_checksum}" ]; then
220227
echo "No changes in image inputs."
228+
# But still run through the follow-up targets. This allows us to have
229+
# e.g. `cosa build metal` be idempotent even if the initial build failed
230+
# for whatever reason. `buildextend-[metal|qemu]` should already be
231+
# idempotent.
232+
build_followup_targets
221233
exit 0
222234
fi
223235

@@ -264,50 +276,6 @@ else
264276
fi
265277
echo "New build ID: ${buildid}"
266278

267-
imageprefix="${name}"-"${buildid}"
268-
# Make these two verbose
269-
set -x
270-
271-
build_image() {
272-
local size kargs ostree_remote
273-
size="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin)["size"])' < "$configdir/image.yaml")G"
274-
kargs="$(python3 -c 'import sys, yaml; args = yaml.safe_load(sys.stdin).get("extra-kargs", []); print(" ".join(args))' < "$configdir/image.yaml")"
275-
# use NONE here instead of empty string because this has to survive through various string processing
276-
ostree_remote="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("ostree-remote", "NONE"))' < "$configdir/image.yaml")"
277-
save_var_subdirs="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("save-var-subdirs-for-selabel-workaround", "NONE"))' < "$configdir/image.yaml")"
278-
tty="console=tty0 console=${VM_TERMINAL},115200n8"
279-
# tty0 does not exist on s390x
280-
[ "$arch" = "s390x" ] && tty="console=${VM_TERMINAL}"
281-
kargs="$kargs $tty ignition.platform.id=qemu"
282-
283-
qemu-img create -f qcow2 "$1" "$size"
284-
runvm_with_disk "$1" qcow2 /usr/lib/coreos-assembler/create_disk.sh /dev/vda "$tmprepo" "${ref-:${commit}}" "${ostree_remote}" /usr/lib/coreos-assembler/grub.cfg "$name" "${save_var_subdirs}" "\"$kargs\""
285-
}
286-
287-
echo '{}' > tmp/vm-iso-checksum.json
288-
if [ -n "${build_qemu}" ]; then
289-
img_qemu=${imageprefix}-qemu.qcow2
290-
case "$arch" in
291-
"x86_64"|"aarch64"|"s390x")
292-
build_image "$img_qemu"
293-
;;
294-
*)
295-
mkdir -p tmp/anaconda
296-
# forgive me for this sin
297-
checksum_location=$(find /usr/lib/coreos-assembler-anaconda/ -name '*CHECKSUM' | head -1)
298-
img_base=tmp/${imageprefix}-base.qcow2
299-
run_virtinstall "${tmprepo}" "${ref}" "${PWD}"/"${img_base}" --variant=cloud
300-
/usr/lib/coreos-assembler/gf-platformid "$(pwd)"/"${img_base}" "$(pwd)"/"${img_qemu}" qemu
301-
vm_iso_checksum=$(awk '/SHA256.*iso/{print$NF}' "${checksum_location}")
302-
cat > tmp/vm-iso-checksum.json <<EOF
303-
{
304-
"coreos-assembler.vm-iso-checksum": "${vm_iso_checksum}"
305-
}
306-
EOF
307-
;;
308-
esac
309-
fi
310-
311279
"${dn}"/write-commit-object "${tmprepo}" "${commit}" "$(pwd)"
312280

313281
build_timestamp=$(date -u +$RFC3339)
@@ -340,21 +308,7 @@ cat > tmp/meta.json <<EOF
340308
}
341309
EOF
342310

343-
if [ -n "${build_qemu}" ]; then
344-
cat > tmp/images.json <<EOF
345-
{
346-
"images": {
347-
"qemu": {
348-
"path": "${img_qemu}",
349-
"sha256": "$(sha256sum_str < "${img_qemu}")",
350-
"size": $(stat -c '%s' "${img_qemu}")
351-
}
352-
}
353-
}
354-
EOF
355-
else
356-
echo '{ "images": {} }' > tmp/images.json
357-
fi
311+
echo '{ "images": {} }' > tmp/images.json
358312

359313
# And the build information about our container, if we are executing
360314
# from a container.
@@ -368,7 +322,7 @@ fi
368322

369323
# Merge all the JSON; note that we want ${composejson} first
370324
# since we may be overriding data from a previous build.
371-
cat "${composejson}" tmp/meta.json tmp/diff.json tmp/images.json tmp/vm-iso-checksum.json tmp/cosa-image.json "${commitmeta_input_json}" | jq -s add > meta.json
325+
cat "${composejson}" tmp/meta.json tmp/diff.json tmp/images.json tmp/cosa-image.json "${commitmeta_input_json}" | jq -s add > meta.json
372326

373327
# Filter out `ref` if it's temporary
374328
if [ -n "${ref_is_temp}" ]; then
@@ -429,3 +383,6 @@ else
429383
"${dn}"/prune_builds --workdir "${workdir}"
430384
fi
431385
rm builds/.build-commit
386+
387+
# and finally, build the specified targets
388+
build_followup_targets

‎src/cmd-buildextend-metal

+63-25
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,18 @@ dn=$(dirname "$0")
55
# shellcheck source=src/cmdlib.sh
66
. "${dn}"/cmdlib.sh
77

8+
# This script is used for creating both the bare metal and the canonical VM
9+
# image (qemu). `buildextend-qemu` is a symlink to `buildextend-metal`.
10+
case "$(basename "$0")" in
11+
"cmd-buildextend-metal") image_type=metal;;
12+
"cmd-buildextend-qemu") image_type=qemu;;
13+
*) fatal "called as unexpected name $0";;
14+
esac
15+
816
print_help() {
9-
cat 1>&2 <<'EOF'
10-
Usage: coreos-assembler buildextend-metal --help
11-
coreos-assembler buildextend-metal [--build ID]
17+
cat 1>&2 <<EOF
18+
Usage: coreos-assembler buildextend-${image_type} --help
19+
coreos-assembler buildextend-${image_type} [--build ID]
1220
1321
Build a bare metal image.
1422
EOF
@@ -54,12 +62,16 @@ if [ $# -ne 0 ]; then
5462
fi
5563

5664
case "$arch" in
57-
"x86_64"|"aarch64"|"s390x")
58-
## fall through to the rest of the file
59-
;;
65+
"x86_64"|"aarch64"|"s390x") use_anaconda=;;
6066
*)
61-
echo "$arch is not supported for this command"
62-
exit 1
67+
# for qemu, we can fallback to Anaconda
68+
if [[ ${image_type} == qemu ]]; then
69+
use_anaconda=1
70+
else
71+
# otherwise, we don't know how to create bare metal images for this
72+
# architecture
73+
fatal "$arch is not supported for this command"
74+
fi
6375
;;
6476
esac
6577

@@ -112,49 +124,75 @@ if [ "${rev_parsed}" != "${commit}" ]; then
112124
fi # otherwise, the repo already has a ref, so no need to create
113125
fi
114126

127+
image_format=raw
128+
if [[ $image_type == qemu ]]; then
129+
image_format=qcow2
130+
fi
115131

116-
img=${name}-${build}-metal.raw
132+
img=${name}-${build}-${image_type}.${image_format}
117133
if [ -f "${builddir}/${img}" ]; then
118-
echo "Bare metal image already exists"
134+
echo "${image_type} image already exists"
119135
exit
120136
fi
121137

122138
path=${PWD}/${img}
123139

124-
echo "Estimating disk size..."
125-
/usr/lib/coreos-assembler/estimate-commit-disk-size --repo "$ostree_repo" "$ref" --add-percent 20 > "$PWD/tmp/ostree-size.json"
126-
size="$(jq '."estimate-mb".final' "$PWD/tmp/ostree-size.json")"
127-
# extra size is the non-ostree partitions, see create_disk.sh
128-
size="$(( size + 513 ))M"
129-
echo "Disk size estimated to $size"
140+
# For bare metal images, we estimate the disk size. For qemu, we get it from
141+
# image.yaml.
142+
if [[ $image_type == metal ]]; then
143+
echo "Estimating disk size..."
144+
/usr/lib/coreos-assembler/estimate-commit-disk-size --repo "$ostree_repo" "$ref" --add-percent 20 > "$PWD/tmp/ostree-size.json"
145+
size="$(jq '."estimate-mb".final' "$PWD/tmp/ostree-size.json")"
146+
# extra size is the non-ostree partitions, see create_disk.sh
147+
size="$(( size + 513 ))M"
148+
echo "Disk size estimated to $size"
149+
else
150+
size="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin)["size"])' < "$configdir/image.yaml")G"
151+
fi
152+
130153
kargs="$(python3 -c 'import sys, yaml; args = yaml.safe_load(sys.stdin).get("extra-kargs", []); print(" ".join(args))' < "$configdir/image.yaml")"
131154
tty="console=tty0 console=${VM_TERMINAL},115200n8"
132155
# tty0 does not exist on s390x
133156
if [ "$arch" == "s390x" ]; then
134157
tty="console=${VM_TERMINAL}"
135158
fi
136-
kargs="$kargs $tty ignition.platform.id=metal"
159+
kargs="$kargs $tty ignition.platform.id=$image_type"
160+
137161
ostree_remote="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("ostree-remote", "NONE"))' < "$configdir/image.yaml")"
138162
save_var_subdirs="$(python3 -c 'import sys, yaml; print(yaml.safe_load(sys.stdin).get("save-var-subdirs-for-selabel-workaround", "NONE"))' < "$configdir/image.yaml")"
139163

140-
qemu-img create -f raw "${path}.tmp" "$size"
141-
runvm_with_disk "${path}.tmp" raw /usr/lib/coreos-assembler/create_disk.sh /dev/vda "$ostree_repo" "${ref-:${commit}}" "${ostree_remote}" /usr/lib/coreos-assembler/grub.cfg "$name" "${save_var_subdirs}" "\"$kargs\""
142-
mv "${path}.tmp" "$path"
143-
144-
# flush it out before going to the next one so we don't have to redo both if
145-
# the next one fails
164+
if [ -z "${use_anaconda}" ]; then
165+
qemu-img create -f ${image_format} "${path}.tmp" "$size"
166+
runvm_with_disk "${path}.tmp" ${image_format} /usr/lib/coreos-assembler/create_disk.sh /dev/vda "$ostree_repo" "${ref-:${commit}}" "${ostree_remote}" /usr/lib/coreos-assembler/grub.cfg "$name" "${save_var_subdirs}" "\"$kargs\""
167+
mv "${path}.tmp" "$path"
168+
echo "{}" > tmp/vm-iso-checksum.json
169+
else
170+
[ "${image_type}" == qemu ]
171+
mkdir -p tmp/anaconda
172+
# forgive me for this sin
173+
checksum_location=$(find /usr/lib/coreos-assembler-anaconda/ -name '*CHECKSUM' | head -1)
174+
img_base=tmp/${name}-${build}-base.qcow2
175+
run_virtinstall "${ostree_repo}" "${ref}" "${PWD}"/"${img_base}" --variant=cloud
176+
/usr/lib/coreos-assembler/gf-platformid "$(pwd)"/"${img_base}" "${path}" qemu
177+
vm_iso_checksum=$(awk '/SHA256.*iso/{print$NF}' "${checksum_location}")
178+
cat > tmp/vm-iso-checksum.json <<EOF
179+
{
180+
"coreos-assembler.vm-iso-checksum": "${vm_iso_checksum}"
181+
}
182+
EOF
183+
fi
146184

147185
# there's probably a jq one-liner for this...
148186
python3 -c "
149187
import sys, json
150188
j = json.load(sys.stdin)
151-
j['images']['metal'] = {
189+
j['images']['${image_type}'] = {
152190
'path': '${img}',
153191
'sha256': '$(sha256sum_str < "${img}")',
154192
'size': $(stat -c '%s' "${img}")
155193
}
156194
json.dump(j, sys.stdout, indent=4)
157-
" < "${builddir}/meta.json" > meta.json.new
195+
" < "${builddir}/meta.json" | cat - tmp/vm-iso-checksum.json | jq -s add > meta.json.new
158196

159197
# and now the crucial bit
160198
mv -T meta.json.new "${builddir}/meta.json"

‎src/cmd-buildextend-qemu

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cmd-buildextend-metal

‎src/coreos-assembler

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ cmd=${1:-}
3838
build_commands="init fetch build run prune clean"
3939
# commands more likely to be used in a prod pipeline only
4040
advanced_build_commands="buildprep buildupload oscontainer"
41-
buildextend_commands="aws azure gcp openstack installer vmware metal"
41+
buildextend_commands="qemu aws azure gcp openstack installer vmware metal"
4242
utility_commands="tag compress bump-timestamp koji-upload kola aws-replicate"
4343
other_commands="shell"
4444
if [ -z "${cmd}" ]; then

0 commit comments

Comments
 (0)
Please sign in to comment.