-
Notifications
You must be signed in to change notification settings - Fork 2
/
pack-image.sh
executable file
·179 lines (150 loc) · 5.65 KB
/
pack-image.sh
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
#!/bin/sh
#
# Run this script after the packages are available in
# apks/target/packages.
set -xe
TEMPLATE=${TEMPLATE:-template.img.gz}
IMAGE=${IMAGE:-fruitos.img}
MOUNTPOINT=${MOUNTPOINT:-targetroot}
NATIVE_COMMANDS=${NATIVE_COMMANDS:-no}
DOCKER_ARCH=${DOCKER_ARCH:-armhf}
REPO_FILE=${REPO_FILE:-}
ALPINE_VERSION=${ALPINE_VERSION:-v3.8}
DEVICE=${DEVICE:-$(losetup --find)}
VERSION=${VERSION:-}
MACHINE=${MACHINE:-}
PACKAGES=${PACKAGES:-}
SERVICES=${SERVICES:-}
# For speedy (de)compression, install `pigz`.
GZIP=$(which pigz || which gzip)
die () {
echo "$1" >&2
exit 1
}
die_if_empty () {
[ ! -z "$2" ] || die "No $1 specified."
}
[ ! -z "$DEVICE" ] || die "Could not find free /dev/loop* device."
[ ! -e "$MOUNTPOINT" ] || die "Mount point ${MOUNTPOINT} already exists."
die_if_empty PACKAGES "$PACKAGES"
die_if_empty SERVICES "$SERVICES"
die_if_empty VERSION "$VERSION"
die_if_empty MACHINE "$MACHINE"
invoke_command () {
# Shell quoting is a nightmare. Beware spaces.
#
if [ "$NATIVE_COMMANDS" = "yes" ]
then
$@
else
tmpscript=$(mktemp tmpscript.XXXXXXXXXX)
echo "$@" > $tmpscript
docker run -it --rm -v `pwd`:`pwd` multiarch/alpine:${DOCKER_ARCH}-${ALPINE_VERSION} \
/bin/sh -c "cd `pwd`; sh $tmpscript"
rm -f $tmpscript
fi
}
###########################################################################
TMP_REPO_FILE=$(mktemp repositories.XXXXXXXXXX)
cleanup () {
sync
umount ${MOUNTPOINT}/dev || echo "warning: unmount of ${MOUNTPOINT}/dev failed" >&2
umount ${MOUNTPOINT}/sys || echo "warning: unmount of ${MOUNTPOINT}/sys failed" >&2
umount ${MOUNTPOINT}/proc || echo "warning: unmount of ${MOUNTPOINT}/proc failed" >&2
umount ${MOUNTPOINT}/media/mmcblk0p1 || echo "warning: unmount of ${MOUNTPOINT}/media/mmcblk0p1 failed" >&2
mount -o remount,ro ${MOUNTPOINT} || echo "warning: remount ro of ${MOUNTPOINT} failed" >&2
sync
blockdev --flushbufs ${DEVICE} || echo "warning: flush of buffers for ${DEVICE} failed" >&2
python -c 'import os; os.fsync(open("'${DEVICE}'", "r+b"))' \
|| echo "warning: fsync of ${DEVICE} failed" >&2
sleep 1
umount ${MOUNTPOINT} || echo "warning: unmount of ${MOUNTPOINT} failed" >&2
rmdir ${MOUNTPOINT} || true
sync
sleep 1
losetup -d ${DEVICE} || echo "warning: losetup removal of ${DEVICE} failed" >&2
sleep 1
rm -f ${TMP_REPO_FILE} || true
}
trap cleanup 0
if [ -z "$REPO_FILE" ]
then
cat < /dev/null > ${TMP_REPO_FILE}
echo "@fruit `pwd`/apks/target/packages" >> ${TMP_REPO_FILE}
echo "`pwd`/apks/target/packages" >> ${TMP_REPO_FILE}
echo "https://dl-4.alpinelinux.org/alpine/${ALPINE_VERSION}/main" >> ${TMP_REPO_FILE}
echo "https://dl-4.alpinelinux.org/alpine/${ALPINE_VERSION}/community" >> ${TMP_REPO_FILE}
else
cat < ${REPO_FILE} > ${TMP_REPO_FILE}
fi
# ${GZIP} -dc ${TEMPLATE} > ${IMAGE}
./build-template.sh ${IMAGE}
losetup -P ${DEVICE} ${IMAGE}
# Format partitions
mkfs.vfat -n FRUITOS ${DEVICE}p1
mkfs.ext4 ${DEVICE}p2
# (don't format p3 -- it will be cloned from p2 later)
# Mount root partition - assume that the first of the two root
# partitions is to be the initial active root partition.
#
mkdir -p ${MOUNTPOINT}
mount ${DEVICE}p2 ${MOUNTPOINT}
# Mount boot partition within root partition.
#
mkdir -p ${MOUNTPOINT}/media/mmcblk0p1
mount ${DEVICE}p1 ${MOUNTPOINT}/media/mmcblk0p1
# Mount necessary system directories.
#
mkdir -p ${MOUNTPOINT}/dev ${MOUNTPOINT}/sys ${MOUNTPOINT}/proc
mount -o bind /dev ${MOUNTPOINT}/dev
mount -o bind /sys ${MOUNTPOINT}/sys
mount -o bind /proc ${MOUNTPOINT}/proc
# Create root file system.
#
echo "Repositories:"
cat ${TMP_REPO_FILE}
apkcmd="apk --repositories-file `pwd`/${TMP_REPO_FILE} -U --allow-untrusted"
invoke_command ${apkcmd} --root ${MOUNTPOINT} --initdb add ${PACKAGES}
invoke_command ${apkcmd} --no-script --root ${MOUNTPOINT} add fruit-initramfs mkinitfs
# Enable system services and configure various aspects of the image.
#
tmpbatch=$(mktemp tmpbatch.XXXXXXXXXX)
for svc in ${SERVICES}
do
name=$(echo $svc | cut -d. -f1)
level=$(echo $svc | cut -d. -f2)
echo "chroot ${MOUNTPOINT} /sbin/rc-update add $name $level" >> $tmpbatch
done
invoke_command sh ./$tmpbatch
rm -f $tmpbatch
# Allow root logins on ttyS0 / ttyAMA0
#
tmpsecuretty=$(mktemp tmpsecuretty.XXXXXXXXXX)
cat ${MOUNTPOINT}/etc/securetty | egrep -v '(ttyS0|ttyAMA0)' > $tmpsecuretty
echo ttyS0 >> $tmpsecuretty
echo ttyAMA0 >> $tmpsecuretty
cat $tmpsecuretty > ${MOUNTPOINT}/etc/securetty
rm -f $tmpsecuretty
sed -i -e 's/^VERSION=.*/VERSION='"${VERSION}"'/g' ${MOUNTPOINT}/etc/os-release
sed -i -e 's/^PRETTY_NAME=.*/PRETTY_NAME="FruitOS v'"${VERSION}"'"/g' ${MOUNTPOINT}/etc/os-release
echo "BUILT_TIMESTAMP=$(date +%s)" >> ${MOUNTPOINT}/etc/os-release
echo "COMMIT=$(git rev-parse HEAD)" >> ${MOUNTPOINT}/etc/os-release
cp -f ${MOUNTPOINT}/usr/share/fruit/fruit.json ${MOUNTPOINT}/media/mmcblk0p1/fruit.json
# Create U-boot initramfs.
#
invoke_command chroot ${MOUNTPOINT} mkinitfs -o /boot/initramfs-${MACHINE} \
$(cat ${MOUNTPOINT}/usr/share/kernel/${MACHINE}/kernel.release)
invoke_command chroot ${MOUNTPOINT} mkimage -A arm -T ramdisk -C none -n initramfs \
-d /boot/initramfs-${MACHINE} /boot/initramfs
rm -f ${MOUNTPOINT}/boot/initramfs-${MACHINE}
# Clone the new image to the other root partition.
#
mount -o remount,ro ${DEVICE}p2
dd if=${DEVICE}p2 of=${DEVICE}p3
# We're done with the partitions on the image file.
#
trap - 0
cleanup
###########################################################################
${GZIP} -c < ${IMAGE} > ${IMAGE}.gz
(cd $(dirname ${IMAGE}); sha512sum $(basename ${IMAGE}).gz > $(basename ${IMAGE}).gz.sha512)