42
42
--owner Set the owner of the resulting files
43
43
--copy Copy the final image for debugig to location
44
44
--manifest Where to drop the manfiest file
45
--livepath Location of live-build scripts
46
--serial image serial number, defaults to YYYYMMDD
47
--hookscript Add a script to hooks script section
48
--ec2-version Destription of EC2 image
45
--livepath Location of live-build scripts
46
--serial image serial number, defaults to YYYYMMDD
47
--hookscript Add a script to hooks script section
48
--ec2-version Destription of EC2 image
49
--propsoed Build from propoposed
55
long_opts="arch:,dest:,part:,debug,owner:,copy:,manifest:,name:,suite:,version:,type:,rootlabel:,moniker:,image:,rootsize:,livepath:,serial:,hookscript:,ec2-version:,config:"
56
long_opts="arch:,dest:,part:,debug,owner:,copy:,manifest:,name:,suite:,version:,type:,rootlabel:,moniker:,image:,rootsize:,livepath:,serial:,hookscript:,ec2-version:,config:,proposed"
56
57
getopt_out=$(getopt --name "${0##*/}" \
57
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
58
eval set -- "${getopt_out}" ||
58
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
59
eval set -- "${getopt_out}" ||
61
62
arch_types="amd64 i386"
62
63
finaldir="/tmp/live-build-$(date +%Y%m%d)_$(uuidgen)" # This is usually overriden at runtime
80
82
serial=$(date +%Y%m%d)
81
83
live_path="${LIVE_BUILD_PATH}"
83
85
while [ $# -ne 0 ]; do
85
--config) config="$2"; shift;;
86
--arch) arch_types="$2"; shift;;
87
--dest) finaldir="$2"; shift;;
88
--part) partfile="$2"; shift;;
89
-d|--debug) debug=1; shift;;
90
--owner) owner="$2"; shift;;
91
--manifest) manifest="$2"; shift;;
92
--copy) copy_final="$2"; shift;;
93
--name|--suite) suite="$2"; shift;;
94
--version) version="$2"; shift;;
95
--type) build_type="$2"; shift;;
96
--rootlabel) root_label="$2"; shift;;
97
--moniker) moniker="$2"; shift;;
98
--image) imagename="$2"; shift;;
99
--rootsize) root_size="$2"; shift;;
100
--livepath) live_path="$2"; shift;;
101
--serial) serial="$2"; shift;;
102
--hookscript) hookscript="$2"; shift;;
103
--ec2-version) description="$2"; shift;;
87
--config) config="$2"; shift;;
88
--arch) arch_types="$2"; shift;;
89
--dest) finaldir="$2"; shift;;
90
--part) partfile="$2"; shift;;
91
-d|--debug) debug=1; shift;;
92
--owner) owner="$2"; shift;;
93
--manifest) manifest="$2"; shift;;
94
--copy) copy_final="$2"; shift;;
95
--name|--suite) suite="$2"; shift;;
96
--version) version="$2"; shift;;
97
--type) build_type="$2"; shift;;
98
--rootlabel) root_label="$2"; shift;;
99
--moniker) moniker="$2"; shift;;
100
--image) imagename="$2"; shift;;
101
--rootsize) root_size="$2"; shift;;
102
--livepath) live_path="$2"; shift;;
103
--serial) serial="$2"; shift;;
104
--hookscript) hookscript="$2"; shift;;
105
--ec2-version) description="$2"; shift;;
106
--proposed) proposed=1; shift;;
105
-h|--help) Usage; exit 0;;
108
-h|--help) Usage; exit 0;;
111
114
#Done setting options
161
164
force_unuse_d() {
162
local d="$1" i=0 tries=10 pids=""
163
while pids_using "$d" && pids=${_RET} && [ -n "${pids}" ] &&
164
[ $i -lt $tries ] && i=$(($i+1)); do
165
error "killing pids occupying ${d}:"
166
sudo ps -p ${pids} 1>&2
171
# if there are pids around, then we failed
165
local d="$1" i=0 tries=10 pids=""
166
while pids_using "$d" && pids=${_RET} && [ -n "${pids}" ] &&
167
[ $i -lt $tries ] && i=$(($i+1)); do
168
error "killing pids occupying ${d}:"
169
sudo ps -p ${pids} 1>&2
174
# if there are pids around, then we failed
175
178
get_owner_chown_opts() {
176
local owner="$1" opts="${owner}:"
178
if [ -z "${owner}" -a -n "${SUDO_UID}" ]; then
179
opts="${SUDO_UID}:${SUDO_GID}"
180
elif [ -z "${owner}" -a -n "${SUDO_USER}" ]; then
181
opts="${SUDO_USER}:$(id ${SUDO_USER} -g)"
182
elif [ -n "${owner}" ]; then
183
opts="$(id -u ${owner}):$(id -g ${owner})"
185
opts="$(id -u):$(id -g)"
179
local owner="$1" opts="${owner}:"
181
if [ -z "${owner}" -a -n "${SUDO_UID}" ]; then
182
opts="${SUDO_UID}:${SUDO_GID}"
183
elif [ -z "${owner}" -a -n "${SUDO_USER}" ]; then
184
opts="${SUDO_USER}:$(id ${SUDO_USER} -g)"
185
elif [ -n "${owner}" ]; then
186
opts="$(id -u ${owner}):$(id -g ${owner})"
188
opts="$(id -u):$(id -g)"
192
#Run live-build. Hopefully this works
193
local base_d=${1} arch="${2}" imagename="${3}" out_d="${4}"
194
local chown_opts=${5} copy_final=${6}
195
local ret=0 start_d="$PWD"
197
debug "Running builder"
198
debug " builder1) Image will be named ${imagename}"
199
debug " builder1) Building for ${arch}"
200
debug " builder1) build location is "${base_d}""
202
local lbb="${base_d}/live-build" lb_env="" lbcmd=""
203
lb_env=( "LB_BASE=${lbb}" "PATH=${lbb}/scripts/build:${PATH}"
204
"${lbb}/scripts/build/lb" build )
205
lb_cmd=( sudo "${lb_env[@]}" "${lbb}/scripts/build/lb" build )
207
debug " builder2) cmd: " "${lb_cmd[@]}"
208
debug " builder3) Starting build prcoess...this might take a while"
210
debug " _______ LIVE-BUILD OUTPUT _______"
212
"${lb_cmd[@]}"; ret=$?
214
debug " _______ END LIVE-BUILD OUTPUT _____"
216
if ! umount_r "${base_d}/chroot" "${base_d}/cloud"; then
217
error "failed to unmount directories under ${base_d}";
218
force_unuse_d "${base_d}/chroot" "${base_d}/cloud" &&
219
umount_r "${base_d}/chroot" "${base_d}/cloud" &&
220
error " recovered via force_unuse_d"
224
# if live-build failed, return failure
225
[ ${ret} -eq 0 ] || { error "live-build failed"; return $ret; }
227
# Move the image into place
228
[ -e "${base_d}/binary-raw.img" ] ||
229
{ error "binary-raw.img did not exist in output directory"; return 1; }
230
mv "${base_d}/binary-raw.img" "${out_d}/${imagename}"
232
if [ ! -z "${copy_final}" ]; then
233
cp "${base_d}/binary-raw.img" "${copy}"
234
debug " builder3) Copied final image to ${copy_final}"
237
debug " builder3) Binary cloud image can be found at ${out_d}/${imagename}"
239
# Pull out the binary.packages
240
if [ -e "${base_d}/binary.packages" ]; then
241
cp "${base_d}/binary.packages" "${manifest}" || fail "Unable to copy ${base_d}/binary.packages to ${manifest}"
242
sed -i "s|\t| |g" "${manifest}" || fail "Unable to normalize format of manifest file"
244
error " builder3) !! ERROR !! Unable to find manifest"
247
# Clean up after ourselves
248
if [ -n "${chown_opts}" ]; then
249
sudo chown -R "${chown_opts}" "${base_d}" "${out_d}" ||
250
{ error "failed to change ownership to ${owner}" ; return 1; }
195
#Run live-build. Hopefully this works
196
local base_d=${1} arch="${2}" imagename="${3}" out_d="${4}"
197
local chown_opts=${5} copy_final=${6}
198
local ret=0 start_d="$PWD"
200
debug "Running builder"
201
debug " builder1) Image will be named ${imagename}"
202
debug " builder1) Building for ${arch}"
203
debug " builder1) build location is "${base_d}""
205
local lbb="${base_d}/live-build" lb_env="" lbcmd=""
206
lb_env=( "LB_BASE=${lbb}" "PATH=${lbb}/scripts/build:${PATH}"
207
"${lbb}/scripts/build/lb" build )
208
lb_cmd=( sudo "${lb_env[@]}" "${lbb}/scripts/build/lb" build )
210
debug " builder2) cmd: " "${lb_cmd[@]}"
211
debug " builder3) Starting build prcoess...this might take a while"
213
debug " _______ LIVE-BUILD OUTPUT _______"
215
"${lb_cmd[@]}"; ret=$?
217
debug " _______ END LIVE-BUILD OUTPUT _____"
219
if ! umount_r "${base_d}/chroot" "${base_d}/cloud"; then
220
error "failed to unmount directories under ${base_d}";
221
force_unuse_d "${base_d}/chroot" "${base_d}/cloud" &&
222
umount_r "${base_d}/chroot" "${base_d}/cloud" &&
223
error " recovered via force_unuse_d"
227
# if live-build failed, return failure
228
[ ${ret} -eq 0 ] || { error "live-build failed"; return $ret; }
230
# Move the image into place
231
[ -e "${base_d}/binary-raw.img" ] ||
232
{ error "binary-raw.img did not exist in output directory"; return 1; }
233
mv "${base_d}/binary-raw.img" "${out_d}/${imagename}"
235
if [ ! -z "${copy_final}" ]; then
236
cp "${base_d}/binary-raw.img" "${copy}"
237
debug " builder3) Copied final image to ${copy_final}"
240
debug " builder3) Binary cloud image can be found at ${out_d}/${imagename}"
242
# Pull out the binary.packages
243
if [ -e "${base_d}/binary.packages" ]; then
244
cp "${base_d}/binary.packages" "${manifest}" || fail "Unable to copy ${base_d}/binary.packages to ${manifest}"
245
sed -i "s|\t| |g" "${manifest}" || fail "Unable to normalize format of manifest file"
247
error " builder3) !! ERROR !! Unable to find manifest"
250
# Clean up after ourselves
251
if [ -n "${chown_opts}" ]; then
252
sudo chown -R "${chown_opts}" "${base_d}" "${out_d}" ||
253
{ error "failed to change ownership to ${owner}" ; return 1; }
268
271
for arch in ${arch_types}
270
work_d="${TEMP_D}/$arch"
271
conf_d="${work_d}/config"
275
# Dynamically configure LB
277
debug "Dynamically configuring live-build"
280
lbb="${work_d}/live-build"
281
lbb_path="${lbb}/scripts/build"
282
mkdir -p "${lbb_path}"
284
rsync -a "${live_path}/" "${work_d}/live-build" ||
285
fail "failed to copy ${live_path}"
287
new_path="PATH=${live_path}/scripts/build:${PATH}"
289
# %d-> distro, %l-> hard disk label, %s-> size, %q-> qemu-static location
290
lbcmd=( "${lb_conf[@]}" )
291
lbcmd=( "${lbcmd[@]//%d/${suite}}")
292
lbcmd=( "${lbcmd[@]//%l/${root_fs_label}}")
293
lbcmd=( "${lbcmd[@]//%s/${root_fs_size}}")
294
lbcmd=( "${lbcmd[@]//%P/${lbb_path}}")
295
lbcmd=( "${lbcmd[@]//%L/${lbb}}")
296
lbcmd=( "${lbcmd[@]//%x/${new_path}}")
297
lbcmd=( "${lbcmd[@]//%A/${arch}}")
299
# Discover qemu location and set it for arm images
300
[[ "${arch}" =~ (arm|arm64) ]] && {
302
armel|armhf) q_arch="arm";;
303
arm64) q_arch="aarch64";;
306
debug "looking for qemu-${q_arch}-static"
308
[ -e "${HOME}/ec2-daily/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ] &&
309
qemu_exec="${HOME}/ec2-daily/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ||
310
[ -e "${lb_config_src_loc}/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ] &&
311
qemu_exec="${lb_config_src_loc}/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ||
312
qemu_exec="$(which qemu-${q_arch}-static)" ||
313
fail "Unable to locate qemu-${q_arch}-static"
315
lbcmd=( "${lbcmd[@]//%q/${qemu_exec}}" )
316
debug "found ${qemu_exec}"
317
debug "debootstrap will be foreign"
321
debug "lb_config commmand is: ${lbcmd[@]}"
322
sudo "${lbcmd[@]}" ||
323
fail "Failed to dynammicaly configure live-build"
327
# Update ubuntu-cloud definition for precise
328
[ "${suite}" \< "precise" ] || {
329
echo "update-notifier-common" >> "${work_d}/live-build/package-lists/ubuntu-cloud" ||
330
fail "Unable append update-notifier-common to package definition"
333
# make config tempdir
334
rsync -a "${lb_config_src_loc}/common/" "${conf_d}" ||
335
fail "failed to copy common hooks"
338
mkdir -p "${conf_d}/includes.chroot/etc/cloud"
341
echo "build_name: ${build_type}" >> "${conf_d}/includes.chroot/etc/cloud/build.info" &&
342
echo "serial: ${serial}" >> "${conf_d}/includes.chroot/etc/cloud/build.info" ||
343
fail "Unable to write etc/cloud/build.info"
346
echo "${description}" >> "${conf_d}/includes.chroot/etc/ec2_version" ||
273
work_d="${TEMP_D}/$arch"
274
conf_d="${work_d}/config"
278
# Dynamically configure LB
280
debug "Dynamically configuring live-build"
283
lbb="${work_d}/live-build"
284
lbb_path="${lbb}/scripts/build"
285
mkdir -p "${lbb_path}"
287
rsync -a "${live_path}/" "${work_d}/live-build" ||
288
fail "failed to copy ${live_path}"
290
new_path="PATH=${live_path}/scripts/build:${PATH}"
292
# %d-> distro, %l-> hard disk label, %s-> size, %q-> qemu-static location
293
lbcmd=( "${lb_conf[@]}" )
294
lbcmd=( "${lbcmd[@]//%d/${suite}}")
295
lbcmd=( "${lbcmd[@]//%l/${root_fs_label}}")
296
lbcmd=( "${lbcmd[@]//%s/${root_fs_size}}")
297
lbcmd=( "${lbcmd[@]//%P/${lbb_path}}")
298
lbcmd=( "${lbcmd[@]//%L/${lbb}}")
299
lbcmd=( "${lbcmd[@]//%x/${new_path}}")
300
lbcmd=( "${lbcmd[@]//%A/${arch}}")
302
# Build the chroot from -proposed
303
[ "${proposed}" -eq 1 ] && lbcmd+=("--proposed=true")
305
# Discover qemu location and set it for arm images
306
[[ "${arch}" =~ (arm|arm64) ]] && {
308
armel|armhf) q_arch="arm";;
309
arm64) q_arch="aarch64";;
312
debug "looking for qemu-${q_arch}-static"
314
[ -e "${HOME}/ec2-daily/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ] &&
315
qemu_exec="${HOME}/ec2-daily/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ||
316
[ -e "${lb_config_src_loc}/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ] &&
317
qemu_exec="${lb_config_src_loc}/qemu-static/${host_lsb_release}/qemu-${q_arch}-static" ||
318
qemu_exec="$(which qemu-${q_arch}-static)" ||
319
fail "Unable to locate qemu-${q_arch}-static"
321
lbcmd=( "${lbcmd[@]//%q/${qemu_exec}}" )
322
debug "found ${qemu_exec}"
323
debug "debootstrap will be foreign"
327
debug "lb_config commmand is: ${lbcmd[@]}"
328
sudo "${lbcmd[@]}" ||
329
fail "Failed to dynammicaly configure live-build"
333
# Update ubuntu-cloud definition for precise
334
[ "${suite}" \< "precise" ] || {
335
echo "update-notifier-common" >> "${work_d}/live-build/package-lists/ubuntu-cloud" ||
336
fail "Unable append update-notifier-common to package definition"
339
# make config tempdir
340
rsync -a "${lb_config_src_loc}/common/" "${conf_d}" ||
341
fail "failed to copy common hooks"
344
mkdir -p "${conf_d}/includes.chroot/etc/cloud"
347
echo "build_name: ${build_type}" >> "${conf_d}/includes.chroot/etc/cloud/build.info" &&
348
echo "serial: ${serial}" >> "${conf_d}/includes.chroot/etc/cloud/build.info" ||
349
fail "Unable to write etc/cloud/build.info"
352
echo "${description}" >> "${conf_d}/includes.chroot/etc/ec2_version" ||
347
353
fail "Unable to write ${conf_d}/includes.chroot/etc/ec2_version"
349
[ -z "${hookscript}" ] || {
350
local_hook="${conf_d}/hooks/999hookscript.chroot"
352
cp -a "${hookscript}" "${local_hook}" ||
353
fail "Unable to copy ${hookscript} to ${local_hook}"
355
debug "Populated hookscript to: ${conf_d}/hooks"
358
builder "${work_d}" "${arch}" "${imagename}" "${finaldir}" \
359
"${chown_opts}" "${copy_final}" ||
360
fail "failed to build for ${suite}"
362
rm -Rf "${work_d}" || fail "Unable to clean ${temp_d}"
355
[ -z "${hookscript}" ] || {
356
local_hook="${conf_d}/hooks/999hookscript.chroot"
358
cp -a "${hookscript}" "${local_hook}" ||
359
fail "Unable to copy ${hookscript} to ${local_hook}"
361
debug "Populated hookscript to: ${conf_d}/hooks"
364
builder "${work_d}" "${arch}" "${imagename}" "${finaldir}" \
365
"${chown_opts}" "${copy_final}" ||
366
fail "failed to build for ${suite}"
368
rm -Rf "${work_d}" || fail "Unable to clean ${temp_d}"
366
372
cleanup && TEMP_D="" && FINAL_DIR="" && CHOWN_OPTS="" ||
367
fail "failed to cleanup"
373
fail "failed to cleanup"
369
375
debug "Images and logs can be found at "${finaldir}""