forked from treehouses/builder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtreehouse-builder
executable file
Β·265 lines (221 loc) Β· 7.59 KB
/
treehouse-builder
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
#!/bin/bash
# Download Raspbian Image, remove first-boot stuff, add repos and install packages.
#
# Open interactive Shell in chroot or write result to SD Card
#
# License: GNU General Public License, see http://www.gnu.org/copyleft/gpl.html for full text
#
# The following variables and arrays customize the behavior. To change them simply create a configuration
# file `pirateship-image-creator.config` which overrides them.
#
# Add at least the following lines to override the internal configuration:
# INSTALL_PACKAGES=()
# ADD_REPOS=()
# ADD_REPO_KEYS=()
# Raspbian
# Jessie
#RASPBIAN_TORRENT_URL=http://downloads.raspberrypi.org/raspbian/images/raspbian-2017-07-05/2017-07-05-raspbian-jessie.zip.torrent
#RASPBIAN_SHA1=e1edd4d26090b3e67a66939fa77eeb656de8a2c5
# Stretch
RASPBIAN_TORRENT_URL=https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-12-01/2017-11-29-raspbian-stretch.zip.torrent
RASPBIAN_SHA1=963dc69346fe20e8f849c694878b5fe1a63e6050
RASPBIAN_IMAGE_FILE=$(basename $RASPBIAN_TORRENT_URL | sed -e "s/.zip.torrent/.img/g")
############ End of User Cusomization
source lib.sh
missing_deps=()
for prog in kpartx wget gpg parted qemu-arm-static aria2c jq curl; do
if ! type $prog &>/dev/null ; then
missing_deps+=( "$prog" )
fi
done
if (( ${#missing_deps[@]} > 0 )) ; then
die "Missing required programs: ${missing_deps[*]}
On Debian/Ubuntu try 'sudo apt install kpartx qemu-user-static parted wget curl jq aria2'"
fi
function _umount {
for dir in "$@" ; do
if grep -q "$dir" /proc/self/mounts ; then
if ! umount -f "$dir" ; then
# shellcheck disable=SC2046,SC2086
die "Could not umount $dir, check running procs:$NL$(lsof 2>/dev/null | grep $(readlink -f $dir))"
fi
fi
done
}
function _get_image {
echo "Fetching $RASPBIAN_TORRENT_URL"
mkdir -p images
if [ ! -f "$RASPBIAN_TORRENT" ]; then
wget "$RASPBIAN_TORRENT_URL" -O "$RASPBIAN_TORRENT" || die "Download of $RASPBIAN_TORRENT failed"
fi
aria2c --continue "$RASPBIAN_TORRENT" -d images --seed-time 0
echo -n "Checksum of "
sha1sum --strict --check - <<<"$RASPBIAN_SHA1 *$IMAGE_ZIP" || die "Download checksum validation failed, please check http://www.raspberrypi.org/downloads"
}
function _decompress_image {
unzip -o "$IMAGE_ZIP" -d images || die "Could not unzip $IMAGE_ZIP"
}
function _disable_daemons {
# Prevent services from being started inside the chroot.
POLICY_RC_D=mnt/img_root/usr/sbin/policy-rc.d
echo "#!/bin/sh" >> $POLICY_RC_D
echo "exit 101" >> $POLICY_RC_D
chmod +x $POLICY_RC_D
}
function _enable_daemons {
POLICY_RC_D=mnt/img_root/usr/sbin/policy-rc.d
rm -f $POLICY_RC_D
}
function _disable_ld_preload {
cfg=mnt/img_root/etc/ld.so.preload
if grep -q '^[^#]' $cfg; then
sed -i -e 's/^/#/' $cfg || die "Could not disable ld.so.preload"
fi
}
function _enable_ld_preload {
cfg=mnt/img_root/etc/ld.so.preload
if grep -q '^#' $cfg; then
sed -i -e 's/^#//' $cfg || die "Could not enable ld.so.preload"
fi
}
function _resize_image {
RESIZE_IMAGE_PATH=images/$RASPBIAN_IMAGE_FILE
if [[ -L "images" ]];
then
rsync -Pav "images/$RASPBIAN_IMAGE_FILE" .
RESIZE_IMAGE_PATH=$RASPBIAN_IMAGE_FILE
fi
start_sector=$(fdisk -l "$RESIZE_IMAGE_PATH" | awk -F" " '{ print $2 }' | sed '/^$/d' | sed -e '$!d')
truncate -s +700M "$RESIZE_IMAGE_PATH"
losetup /dev/loop1 "$RESIZE_IMAGE_PATH"
fdisk /dev/loop1 <<EOF
p
d
2
n
p
2
$start_sector
p
w
EOF
losetup -d /dev/loop1
losetup -o $((start_sector*512)) /dev/loop2 "$RESIZE_IMAGE_PATH"
e2fsck -f /dev/loop2
resize2fs -f /dev/loop2
losetup -d /dev/loop2
if [[ -L "images" ]];
then
rsync -Pav "$RASPBIAN_IMAGE_FILE" images/
rm "$RASPBIAN_IMAGE_FILE"
fi
}
function _open_image {
echo "Loop-back mounting" "images/$RASPBIAN_IMAGE_FILE"
# shellcheck disable=SC2086
kpartx="$(kpartx -sav images/$RASPBIAN_IMAGE_FILE)" || die "Could not setup loop-back access to $RASPBIAN_IMAGE_FILE:$NL$kpartx"
# shellcheck disable=SC2162
read -d '' img_boot_dev img_root_dev <<<"$(grep -o 'loop.p.' <<<"$kpartx")"
test "$img_boot_dev" -a "$img_root_dev" || die "Could not extract boot and root loop device from kpartx output:$NL$kpartx"
img_boot_dev=/dev/mapper/$img_boot_dev
img_root_dev=/dev/mapper/$img_root_dev
mkdir -p mnt/img_root
mount -t ext4 "$img_root_dev" mnt/img_root || die "Could not mount $img_root_dev mnt/img_root"
mkdir -p mnt/img_root/boot || die "Could not mkdir mnt/img_root/boot"
mount -t vfat "$img_boot_dev" mnt/img_root/boot || die "Could not mount $img_boot_dev mnt/img_root/boot"
echo "Raspbian Image Details:"
df -h mnt/img_root/boot mnt/img_root | sed -e "s#$(pwd)/##"
}
function _close_image {
_umount mnt/img_root/var/cache/apt/archives \
mnt/img_root/{proc,sys,run,dev/pts} \
mnt/sd_root/bo?t mnt/img_root/boot \
mnt/sd_ro?t mnt/img_root
kpartx -d "images/$RASPBIAN_IMAGE_FILE" >/dev/null
}
function _prepare_chroot {
_disable_ld_preload
cp -a "$(type -p qemu-arm-static)" mnt/img_root/usr/bin/ || die "Could not copy qemu-arm-static"
_chroot date &>/dev/null || die "Could not chroot date"
mount -t devpts devpts -o noexec,nosuid,gid=5,mode=620 mnt/img_root/dev/pts || die "Could not mount /dev/pts"
mount -t proc proc mnt/img_root/proc || die "Could not mount /proc"
mount -t tmpfs -o mode=1777 none mnt/img_root/run || "Could not mount /run"
mkdir -p apt_cache
mount --bind apt_cache mnt/img_root/var/cache/apt/archives
}
function _cleanup_chroot {
_umount mnt/img_root/var/cache/apt/archives \
mnt/img_root/{proc,sys,run,dev/pts}
_enable_daemons
_enable_ld_preload
}
function _modify_image {
echo "Modifying Image"
_prepare_chroot
_disable_daemons
run-parts --exit-on-error -v --regex '[a-zA-Z.-_]*' scripts.d ||\
die "Image modification scripts failed"
_enable_daemons
_cleanup_chroot
}
function _usage {
echo "
Usage: $0 <--chroot|--noninteractive>
Download Raspbian Image, remove first-boot stuff, add repos and install packages.
Open interactive Shell in chroot or write result to SD Card
License: GNU General Public License, see http://www.gnu.org/copyleft/gpl.html for full text
"
}
function _shell {
_prepare_chroot
chroot mnt/img_root bash -i
_cleanup_chroot
}
export LANG="C" LANGUAGE="C" LC_ALL="C.UTF-8"
shopt -s nullglob
if [[ $# -eq 0 || "$*" == *-h* ]] ; then
_usage
exit 1
fi
if [[ "$USER" != root && $(id -u) != "0" ]] ; then
# restart as root
echo "Switching over to run as root"
exec sudo "$(readlink -f "$0")" "$@"
echo "Need sudo permission to run as root!"
exit 1
fi
if grep -wq "$(readlink -f mnt)" /proc/self/mounts; then
die "mnt/ is already mounted!"
fi
rm -Rf --one-file-system mnt temp
function exittrap {
set +u +e
_close_image
echo "Script execution time: $SECONDS seconds"
}
trap exittrap 0
trap exittrap ERR
RASPBIAN_TORRENT=images/$(basename $RASPBIAN_TORRENT_URL)
echo "$RASPBIAN_TORRENT"
IMAGE_ZIP=${RASPBIAN_TORRENT%.torrent}
echo "$IMAGE_ZIP"
IMAGE=${IMAGE_ZIP%.zip}.img
echo "$IMAGE"
if [ ! -e "$IMAGE_ZIP" ]; then
_get_image
fi
_decompress_image
_resize_image
_open_image
if [[ "$1" == "--chroot" ]] ; then
_modify_image
echo "Starting interactive Shell in image chroot"
_shell
elif [[ "$1" == "--noninteractive" ]] ; then
_modify_image
elif [[ "$1" == "--shell" ]]; then
_shell
else
die "Usage error. Try $0 --help"
fi
# vim:autoindent:tabstop=2:shiftwidth=2:expandtab:softtabstop=2: