-
Notifications
You must be signed in to change notification settings - Fork 169
/
cmd-build-fast
executable file
·160 lines (151 loc) · 5.11 KB
/
cmd-build-fast
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env bash
set -euo pipefail
# This command can be run in two different ways. If COSA_DIR is unset, it
# must be run from a coreos-assembler working directory. It will takes new
# files from overrides/rootfs and applies them
# on top of a previously built qemu image. It creates a new deployment.
# If COSA_DIR is set, it's assumed instead that you are developing on *one*
# project - it will take the output of `make && make install DESTDIR=` as
# an overlay on top of the build from COSA_DIR. Notably, the qcow2 image
# will end up in the project's working directory - so you can effectively
# have independent CoreOS builds for each project.
# This model is likely preferable if you are developing on an individual
# project - you should turn to the main `cosa build/cosa build-fast` when
# working on multiple projects.
dn=$(dirname "$0")
# shellcheck source=src/cmdlib.sh
. "${dn}"/cmdlib.sh
print_help() {
cat 1>&2 <<'EOF'
Usage: coreos-assembler build-fast [--undeploy]
EOF
}
# Parse options
NO_UNDEPLOY=0
rc=0
options=$(getopt --options h --longoptions help,no-undeploy -- "$@") || rc=$?
[ $rc -eq 0 ] || {
print_help
exit 1
}
eval set -- "$options"
while true; do
case "$1" in
-h | --help)
print_help
exit 0
;;
--no-undeploy)
NO_UNDEPLOY=1
;;
--)
shift
break
;;
-*)
fatal "$0: unrecognized option: $1"
;;
*)
break
;;
esac
shift
done
# Detect the case that we're in a git repo without COSA_DIR
# Note we use -e and not -d here so it also works in git worktrees.
if test -e .git; then
if test -z "${COSA_DIR}"; then
# shellcheck disable=SC2016
fatal 'This command requires inheriting from a previous full OS build.
Use e.g. `export COSA_DIR=/path/to/fcos` that has a previous
run of `cosa build`.'
fi
projectdir=$(pwd)
cd "${COSA_DIR}"
else
# If it's not a git repo, assume it's a cosa dir
unset COSA_DIR
projectdir=
fi
prepare_build
previous_build=$(get_latest_build)
previous_qemu=
if [ -z "${previous_build}" ]; then
fatal "previous build required for a fast build"
fi
previous_builddir=$(get_build_dir "${previous_build}")
previous_commit=$(jq -r '.["ostree-commit"]' < "${previous_builddir}/meta.json")
previous_qemu=$(jq -r '.["images"]["qemu"]["path"]' < "${previous_builddir}/meta.json")
if [ "${previous_qemu}" = "null" ]; then
fatal "--shortcut requires a previous build with qemu"
fi
echo "Basing on previous build: ${previous_build:-none}"
if [ -n "${projectdir}" ]; then
cd "${projectdir}"
instroot=_install
# Rust projects will already have a handy directory for build artifacts
if test -d target; then
instroot=target/cosa-build-fast
fi
instroot=$(pwd)/${instroot} # Must be absolute for `make`
rm "${instroot}" -rf
make
make install DESTDIR="${instroot}"
fastref=cosa/fastbuild/"$(basename "${projectdir}")"
version="$(git describe --tags --abbrev=10)"
if ! git diff --quiet; then
version="${version}+dirty"
fi
outdir=${projectdir}/.cosa
rootfsoverrides="${instroot}"
else
fastref=cosa/fastbuild/${name}
version="$(date +"%s")"
outdir="${workdir}/tmp"
rootfsoverrides="${workdir}/overrides/rootfs"
fi
if test "$(find "${rootfsoverrides}" -maxdepth 1 | wc -l)" == 0; then
fatal "No rootfs overrides found"
fi
mkdir -p "${outdir}"
etcdir="${rootfsoverrides}/etc"
usretcdir="${rootfsoverrides}/usr/etc"
etcmoved=0
# FIXME add `ostree commit --rename=etc,usr/etc`
if [ -d "${etcdir}" ]; then
mv -nT "${etcdir}" "${usretcdir}"
etcmoved=1
fi
restore_etc() {
if [ "${etcmoved}" = 1 ]; then
mv -nT "${usretcdir}" "${etcdir}"
fi
}
set -x
commit_args=()
if [ -n "${projectdir}" ]; then
commit_args+=('--consume') # nom nom nom
fi
# Depends https://github.com/ostreedev/ostree/pull/2041/commits/b3bbbd154225e81980546b2c0b5ed98714830696
if ! ostree --repo="${tmprepo}" commit -b "${fastref}" --base="${previous_commit}" --tree=dir="${rootfsoverrides}" \
--owner-uid 0 --owner-gid 0 --selinux-policy-from-base --link-checkout-speedup --no-bindings --no-xattrs \
--add-metadata-string=version="${version}" --parent="${previous_commit}" --keep-metadata='coreos-assembler.basearch' \
--keep-metadata='fedora-coreos.stream' --keep-metadata='ostree.bootable' --fsync=0 "${commit_args[@]}"; then
restore_etc
exit 1
fi
set +x
commit=$(ostree --repo="${tmprepo}" rev-parse "${fastref}")
if [ -z "${projectdir}" ]; then
restore_etc
fi
imgname="$(basename "${fastref}")-${version}-qemu.qcow2"
# Prune previous images
rm -vf "${outdir}"/*.qcow2
qemu-img create -f qcow2 -o backing_fmt=qcow2,backing_file="${previous_builddir}/${previous_qemu}" "${imgname}.tmp" 20G
RUNVM_NONET=1 runvm -drive if=virtio,id=target,format=qcow2,file="${imgname}.tmp",cache=unsafe -- \
/usr/lib/coreos-assembler/offline-update-impl "${workdir}/tmp/repo" "${commit}" "${NO_UNDEPLOY}"
mv "${imgname}.tmp" "${imgname}"
mv "${imgname}" "${outdir}/${imgname}"
rm "${tmp_builddir}" -rf
echo "Created: ${outdir}/${imgname}"