summaryrefslogtreecommitdiff
path: root/scripts/build/binary_onie
blob: da11c5e5d0a3f0d4d70c98dece8d1e8d3a060297 (plain)
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
#!/bin/sh

## live-build(7) - System Build Scripts
## Copyright (C) 2017 Erik Ziegenbalg <eziegenb@brocade.com>
## Copyright (C) 2018 Luca Boccassi <bluca@debian.org>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.


set -e

# Including common functions
[ -e "${LIVE_BUILD}/scripts/build.sh" ] && . "${LIVE_BUILD}/scripts/build.sh" || . /usr/lib/live/build.sh

# Setting static variables
DESCRIPTION="Build ONIE binary image"
USAGE="${PROGRAM} [--force]"

# Processing arguments and configuration files
Init_config_data "${@}"

if [ "${LB_ONIE}" != "true" ]
then
	exit 0
fi

case "${LIVE_IMAGE_TYPE}" in
	iso)
		IMAGE="${LIVE_IMAGE_NAME}-${LB_ARCHITECTURES}.iso"
		;;
	iso-hybrid)
		IMAGE="${LIVE_IMAGE_NAME}-${LB_ARCHITECTURES}.hybrid.iso"
		;;
	*)
		exit 0
		;;
esac

Echo_message "Begin building onie binary..."

# Requiring stage file
Require_stagefile .build/config .build/binary_iso

# Checking stage file
Check_stagefile .build/binary_onie

# Checking lock file
Check_lockfile .lock

# Creating lock file
Create_lockfile .lock

Check_package host /bin/cpio cpio
Check_package host /usr/bin/file file
Check_package host /usr/bin/sha1sum coreutils
Check_package host /bin/zcat gzip
Check_package host /bin/gzip gzip
Check_package host /usr/bin/xzcat xz-utils
Check_package host /usr/bin/xz xz-utils
Check_package host /bin/bzcat bzip2
Check_package host /bin/bzip2 bzip2

### Adds needed helper script
## Based on https://github.com/opencomputeproject/onie/blob/master/contrib/debian-iso/sharch_body.sh
cat > sharch_body.sh << EOF
#!/bin/sh

#
#  Copyright (C) 2015 Curt Brune <curt@cumulusnetworks.com>
#
#  SPDX-License-Identifier:     GPL-2.0
#

#
#  Shell archive template
#
#  Strings of the form %%VAR%% are replaced during construction.
#

echo -n "Verifying image checksum ..."
sha1=\$(sed -e '1,/^exit_marker$/d' "\$0" | sha1sum | awk '{ print \$1 }')

payload_sha1=%%IMAGE_SHA1%%

if [ "\$sha1" != "\$payload_sha1" ] ; then
	echo
	echo "ERROR: Unable to verify archive checksum"
	echo "Expected: \$payload_sha1"
	echo "Found   : \$sha1"
	exit 1
fi

echo " OK."

tmp_dir=
clean_up() {
	if [ "\$(id -u)" = "0" ] ; then
		umount \$tmp_dir > /dev/null 2>&1
	fi
	rm -rf \$tmp_dir
	exit \$1
}

# Untar and launch install script in a tmpfs
cur_wd=\$(pwd)
archive_path=\$(realpath "\$0")
tmp_dir=\$(mktemp -d)
if [ "\$(id -u)" = "0" ] ; then
	mount -t tmpfs tmpfs-installer \$tmp_dir || clean_up 1
fi
cd \$tmp_dir
echo -n "Preparing image archive ..."
sed -e '1,/^exit_marker\$/d' \$archive_path | tar xf - || clean_up 1
echo " OK."
cd \$cur_wd

extract=no
args=":x"
while getopts "\$args" a ; do
	case \$a in
		x)
			extract=yes
			;;
		*)
			;;
	esac
done

if [ "\$extract" = "yes" ] ; then
	# stop here
	echo "Image extracted to: \$tmp_dir"
	if [ "\$(id -u)" = "0" ] ; then
		echo "To un-mount the tmpfs when finished type:  umount \$tmp_dir"
	fi
	exit 0
fi

\$tmp_dir/installer/install.sh "\$@"
rc="\$?"

clean_up \$rc

exit_marker
EOF


### Based on onie cookbits script...
### https://github.com/opencomputeproject/onie/blob/master/contrib/debian-iso/cook-bits.sh

CURDIR=`pwd`
OUT=${CURDIR}/output
rm -rf $OUT
mkdir -p $OUT

WORKDIR=${CURDIR}/work
EXTRACTDIR="$WORKDIR/extract"
INSTALLDIR="$WORKDIR/installer"

IN_IMAGE="${IMAGE}"

output_file="${OUT}/${IN_IMAGE}-ONIE.bin"

Echo_message "Creating $output_file:"

# prepare workspace
[ -d $EXTRACTDIR ] && chmod +w -R $EXTRACTDIR
rm -rf $WORKDIR
mkdir -p $EXTRACTDIR
mkdir -p $INSTALLDIR

# Link the iso binary root to the onie extract dir
ln -s ${CURDIR}/binary/* ${EXTRACTDIR}
echo -n "."

## pack ISO into initrd
# create initrd working dir
INITDIR=${WORKDIR}/initrd-extract
rm -rf ${INITDIR}
mkdir -p ${INITDIR}
cd ${INITDIR}
# extract current initrd
case $(file --brief --mime --dereference $EXTRACTDIR/live/initrd.img | \
		sed "s/application\/\(.*\);.*/\1/") in
	gzip)
		UNCOMPRESS="zcat"
		COMPRESS="gzip"
		;;
	x-xz)
		UNCOMPRESS="xzcat"
		COMPRESS="xz --check=crc32"
		;;
	x-bzip2)
		UNCOMPRESS="bzcat"
		COMPRESS="bzip2"
		;;
	x-lzma)
		UNCOMPRESS="lzcat --suffix \"\""
		COMPRESS="lzma"
		;;
	octet-stream)
		UNCOMPRESS="cat"
		COMPRESS="cat"
		;;
	*)
		echo "" #force newline
		Echo_error "Unable to detect initrd compression format."
		exit 1
		;;
esac

$UNCOMPRESS $EXTRACTDIR/live/initrd.img | cpio -d -i -m
echo -n "."
# copy inputed iso into initrd
cp "${CURDIR}/${IN_IMAGE}" ./conf/live.iso
echo -n "."
# repack
find . | cpio -o -H newc | $COMPRESS > ${WORKDIR}/initrd.img
# cd back into root dir
cd ${CURDIR}
echo -n "."

KERNEL='vmlinuz'
IN_KERNEL=$EXTRACTDIR/live/$KERNEL
[ -r $IN_KERNEL ] || {
	echo "" #force newline
	Echo_error "Unable to find kernel in ISO: $IN_KERNEL"
	exit 1
}
INITRD='initrd.img'
IN_INITRD=$WORKDIR/$INITRD
[ -r $IN_INITRD ] || {
	echo "" #force newline
	Echo_error "Unable to find initrd in ISO: $IN_INITRD"
	exit 1
}

# Note: specify kernel args you want the Debian installer to
# automatically append by putting them after the special marker "---".
# Here we want the Deb installer to auto include the serial console
# parameters.
# The minimal required parameters are included by default, and users
# can add more depending on what they need, eg: systemd parameters.
KERNEL_ARGS="--- boot=live nopersistent noeject dhcp fromiso=/conf/live.iso"
KERNEL_ARGS="${KERNEL_ARGS} ${LB_ONIE_KERNEL_CMDLINE}"

# To debug DI preseed file add these args
# DI_DEBUG_ARGS="DEBCONF_DEBUG=5 dbg/flags=all-x"

# Debian installer args
DI_ARGS="auto=true priority=critical $DI_DEBUG_ARGS"

cp -r $IN_KERNEL $IN_INITRD $INSTALLDIR

# Create custom install.sh script
touch $INSTALLDIR/install.sh
chmod +x $INSTALLDIR/install.sh

(cat <<EOF
#!/bin/sh

cd \$(dirname \$0)

# remove old partitions
for p in \$(seq 3 9) ; do
	sgdisk -d \$p /dev/vda > /dev/null 2&>1
done

# bonk out on errors
set -e

echo "auto-detecting console..."
tty=\$(cat /sys/class/tty/console/active 2>/dev/null | awk 'END {print \$NF}')
speed=\$(stty -F /dev/\$tty speed 2>/dev/null)
bits=\$(stty -F /dev/\$tty -a 2>/dev/null | grep -o cs[5-8])
bits=\$(echo \$bits | grep -o [5-8])

con=''
if [ -n "\$speed" ]; then
	con="console=\$tty,\${speed}n\${bits}"
else
	con="console=\$tty"
fi

echo "using \$con"

kcmd_console=\$(cat /proc/cmdline | grep -o 'console=.* ')
kcmd_console=\$(echo \$kcmd_console | cut -d' ' -f2) # remove tty0

if [ \${kcmd_console}x != \${con}x ]; then
	echo "WARNING: Detected console does not match boot console: \$kcmd_console != \$con"
fi

echo "Loading new kernel ..."
echo "kexec --load --initrd=$INITRD --append=\"$DI_ARGS $KERNEL_ARGS \$con\" $KERNEL"
kexec --load --initrd=$INITRD --append="$DI_ARGS $KERNEL_ARGS \$con" $KERNEL
kexec --exec

EOF
) >> $INSTALLDIR/install.sh
echo -n "."

# Repackage $INSTALLDIR into a self-extracting installer image
sharch="$WORKDIR/sharch.tar"
tar -C $WORKDIR -cf $sharch installer || {
	echo "" #force newline
	Echo_error "Problems creating $sharch archive"
	exit 1
}

[ -f "$sharch" ] || {
	echo "" #force newline
	Echo_error "$sharch not found"
	exit 1
}
echo -n "."

sha1=$(cat $sharch | sha1sum | awk '{print $1}')
echo -n "."

cp sharch_body.sh $output_file || {
	echo "" #force newline
	Echo_error "Problems copying sharch_body.sh"
	exit 1
}

# Replace variables in the sharch template
sed -i -e "s/%%IMAGE_SHA1%%/$sha1/" $output_file
echo -n "."
cat $sharch >> $output_file
mv $output_file ${CURDIR}
rm -rf $tmp_dir
rm -rf $OUT $WORKDIR
echo " Done."
ls -la $(basename $output_file)
Echo_message "onie-installer created..."

# Creating stage file
Create_stagefile .build/binary_onie