-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpirateship-image-creator
executable file
·334 lines (293 loc) · 13.7 KB
/
pirateship-image-creator
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
#!/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 ImmobilienScout24 configuration:
# INSTALL_PACKAGES=()
# ADD_REPOS=()
# ADD_REPO_KEYS=()
# Raspbian
RASPBIAN_URL=http://director.downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2016-03-18/2016-03-18-raspbian-jessie-lite.zip
RASPBIAN_SHA1=b78bb50bdac5ec8c108f34104f788e214ac23635
# Setting some options to default
SETUP_SSHKEYS=false
SETUP_NOPASSWD=false
SETUP_HOSTNAME="raspberrypi"
SETUP_HOSTNAMEBYDHCP=false
# List of packages to install
INSTALL_PACKAGES=(
avahi-daemon vim lshw iotop screen #essentials
build-essential rlwrap python-dev python-rpi.gpio #install node http://nodered.org/docs/hardware/raspberrypi.html
resolvconf #for https://www.npmjs.com/package/pirate-sh
libdbus-1-dev libdbus-glib-1-dev libglib2.0-dev libical-dev libreadline-dev libudev-dev libusb-dev #install ble
make #http://www.elinux.org/RPi_Bluetooth_LE
)
# List of packages to remove
PURGE_PACKAGES=(
)
# List of extra APT repositories
ADD_REPOS=(
)
# List of extra GPG keys to import from the LOCAL SYSTEM!
ADD_REPO_KEYS=(
)
# Extra command to run upon completion. This is run within a chroot environment.
# Example: CUSTOM_COMMAND="curl http://some.domain/script.sh | bash -i ; rm -f /some/file"
CUSTOM_COMMAND="\
update-alternatives --set editor /usr/bin/vim.basic;
mkdir /root/checknode;
cd /root/checknode;
wget http://node-arm.herokuapp.com/node_latest_armhf.deb;
mv node_latest_armhf.deb node_0.12.6_armhf.deb;
wget https://deb.nodesource.com/node_0.12/pool/main/n/nodejs/nodejs_0.12.7-1nodesource1~wheezy1_armhf.deb;
ln -s node_0.12.6_armhf.deb node-rpi1.deb;
ln -s nodejs_0.12.7-1nodesource1~wheezy1_armhf.deb node-rpi2.deb;
dpkg -i node-rpi1.deb;
cat > toggle.sh << EOF
#!/bin/sh
rpi=\\\$(cat /proc/cpuinfo | grep Revision | sed 's/.* //g' | tr -d '\n';)
if [[ \\\$rpi == 'a11041' ]] || [[ \\\$rpi == 'a21041' ]]; then
if [[ \\\$(dpkg -l|grep node|awk '{print \\\$2}') == 'node' ]]; then
aptitude purge -y node
dpkg -i /root/checknode/node-rpi2.deb
fi
else
if [[ \\\$(dpkg -l|grep node|awk '{print \\\$2}') == 'nodej' ]]; then
aptitude purge -y nodejs
dpkg -i /root/checknode/node-rpi1.deb
fi
fi
EOF
chmod 755 toggle.sh;
cd /usr/lib/;
ln -s /usr/local/lib/node_modules;
npm config set unsafe-perm true;
npm install -g pirate-sh;
npm config set unsafe-perm false;
dphys-swapfile swapoff;
dphys-swapfile uninstall;
update-rc.d dphys-swapfile disable;
apt-get -qq purge dphys-swapfile;
mkdir -p /root/bluez;
cd /root/bluez;
wget https://www.kernel.org/pub/linux/bluetooth/bluez-5.33.tar.xz;
tar xvf bluez-5.33.tar.xz;
cd bluez-5.33;
./configure --disable-systemd;
make;
make install;
"
############ End of User Cusomization
if [[ -r ./pirateship-image-creator.config ]] ; then
source ./pirateship-image-creator.config
fi
function die {
echo 1>&2 ERROR: "$*"
exit 1
}
missing_deps=()
for prog in kpartx wget gpg parted qemu-arm-static ; 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-get install kpartx qemu-user-static parted'"
fi
# Constants
NL="$(echo)"
# taken from http://debian-handbook.info/browse/wheezy/sect.automatic-upgrades.html
MIRACLE_COMBINATION_AUTO_UPGRADE_SCRIPT="
#!/bin/bash -e
exec &>/var/log/miracle-combination-auto-upgrade.log
date
apt-get update
export DEBIAN_FRONTEND=noninteractive
yes '' | apt-get -y -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' dist-upgrade
"
function _op {
"$@" &> >(sed -e 's/^/| /')
}
function _umount {
for dir in "$@" ; do
if grep -q "$dir" /proc/self/mounts ; then
if ! sudo umount -f "$dir" ; then
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_URL "
mkdir -p download
RASPBIAN_ARCHIVE_FILE=download/${RASPBIAN_URL##*/}
wget --no-verbose --continue --directory-prefix download $RASPBIAN_URL || die "Download of $RASPBIAN_URL failed"
echo -n "Checksum of "
sha1sum --strict --check - <<<"$RASPBIAN_SHA1 *$RASPBIAN_ARCHIVE_FILE" || die "Download checksum validation failed, please check http://www.raspberrypi.org/downloads"
unzip -q $RASPBIAN_ARCHIVE_FILE -d temp/ || die "Could not unzip $RASPBIAN_ARCHIVE_FILE"
}
function _open_image {
echo "Loop-back mounting" temp/*.img
kpartx="$(sudo kpartx -sav temp/*.img)" || die "Could not setup loop-back access to $RASPBIAN_ARCHIVE_FILE:$NL$kpartx"
read 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
ls -al /dev/mapper
echo $img_boot_dev
echo $img_root_dev
sudo mkdir -p mnt/img_root
sudo mount -t ext4 $img_root_dev mnt/img_root || die "Could not mount $img_root_dev mnt/img_root"
sudo mkdir -p mnt/img_root/boot || die "Could not mkdir mnt/img_root/boot"
sudo mount -t vfat $img_boot_dev mnt/img_root/boot || die "Could not mount $img_boot_dev mnt/img_root/boot"
cp -a "$(type -p qemu-arm-static)" mnt/img_root/usr/bin/ || die "Could not copy qemu-arm-static"
echo "Raspbian Image Details:"
df -h mnt/img_root/boot mnt/img_root | sed -e "s#$(pwd)/##"
}
function _modify_image {
echo "Modifying Image"
chroot mnt/img_root 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"
sed -i -e 's/^/#/' mnt/img_root/etc/ld.so.preload || die "Could not disable ld.so.preload"
rm -f mnt/img_root/etc/init.d/apply_noobs_os_config mnt/img_root/etc/rc2.d/S01apply_noobs_os_config mnt/img_root/etc/profile.d/raspi-config.sh \
|| die "Could not remove noobs and raspi-config first-boot stuff"
#sed -i -e '/RPICFG_TO_DISABLE/d' -e '/RPICFG_TO_ENABLE/s/^#//' -e '/RPICFG_TO_ENABLE/s/ #.*$//' mnt/img_root/etc/inittab || die "Could not remove raspi-config autorun from inittab"
sed -i -e 's/^#\(FSCKFIX=\)no/\1yes/' mnt/img_root/etc/default/rcS || die "Could not enable automatic filesystem fix on boot"
for f in /etc/default/{keyboard,console-setup} /etc/{resolv.conf,localtime} ; do
if [[ -r $f ]] ; then
cp $f mnt/img_root/$f || die "Could not copy $f"
fi
done
if [[ "$SETUP_SSHKEYS" == "raspberrypi" ]] ; then
echo "$SETUP_SSHKEYS" > mnt/img_root/etc/hostname || die "Could not set hostname to $SETUP_SSHKEYS"
fi
if [[ "$SETUP_HOSTNAMEBYDHCP" == true ]] ; then
echo "unset old_host_name # this will make the system always set the hostname from DHCP" \
> mnt/img_root/etc/dhcp/dhclient-enter-hooks.d/unset_old_hostname || die "Could not apply fix http://blog.schlomo.schapiro.org/2013/11/setting-hostname-from-dhcp-in-debian.html"
fi
if [[ "${ADD_REPOS:-}" ]] ; then
for repo in "${ADD_REPOS[@]}" ; do
echo "$repo"
done > mnt/img_root/etc/apt/sources.list.d/pirateship-image-creator.list || die "Could not add repos ${ADD_REPOS[@]}"
fi
if [[ ${ADD_REPO_KEYS:-} ]] ; then
gpg --no-permission-warning --no-default-keyring --keyring /etc/apt/trusted.gpg --export ${ADD_REPO_KEYS[@]} | gpg --no-permission-warning --no-default-keyring --keyring mnt/img_root/etc/apt/trusted.gpg --trustdb-name mnt/img_root/etc/apt/trustdb.gpg --import - || die "Could not import GPG keys ${ADD_REPO_KEYS[@]} for apt"
fi
if [[ "$SETUP_SSHKEYS" == true ]] ; then
IFS=: read a b c d e user_home g < <(getent passwd ${SUDO_USER:-$USER})
mkdir -p mnt/img_root/root/.ssh || die "Could not mkdir mnt/img_root/root/.ssh"
cat $user_home/.ssh/*.pub <<<"" >mnt/img_root/root/.ssh/authorized_keys || :
chmod 0600 mnt/img_root/root/.ssh/authorized_keys || die "Could not chmod 0600 mnt/img_root/root/.ssh/authorized_keys"
if (( $(wc -l <mnt/img_root/root/.ssh/authorized_keys) > 0 )) ; then
echo "Installed SSH keys from $user_home, disabling password access"
sed -i -e 's/.*PasswordAuthentication.*/PasswordAuthentication no/i' mnt/img_root/etc/ssh/sshd_config || die "Could not disable password auth in mnt/img_root/etc/ssh/sshd_config"
fi
if [[ "$SETUP_NOPASSWD" == true ]] ; then
sed -i -e 's/.*disable_overscan=.*/disable_overscan=1/i' mnt/img_root/boot/config.txt || die "Could not disable overscan in mnt/img_root/boot/config.txt"
fi
fi
PURGE_PACKAGES=( $(
for package in "${PURGE_PACKAGES[@]}" ; do
if chroot mnt/img_root dpkg -s "$package" &>/dev/null ; then
echo "$package"
fi
done
) )
if [[ ${PURGE_PACKAGES:-} ]] ; then
echo "Removing unwanted packages ${PURGE_PACKAGES[@]}"
_op chroot mnt/img_root apt-get -qq purge "${PURGE_PACKAGES[@]}" || die "Could not remove ${PURGE_PACKAGES[@]}"
fi
echo "Installing Updates"
_op chroot mnt/img_root apt-get -qq update || die "Could not update package sources"
_op chroot mnt/img_root apt-get -qq dist-upgrade || die "Could not upgrade system"
if [[ ${INSTALL_PACKAGES:-} ]] ; then
echo "Installing ${INSTALL_PACKAGES[@]}"
_op chroot mnt/img_root apt-get -qq install ${INSTALL_PACKAGES[@]} || die "Could not install ${INSTALL_PACKAGES[@]}"
fi
if [[ "${CUSTOM_COMMAND:-}" ]] ; then
echo "Running Custom Command: $CUSTOM_COMMAND"
_op chroot mnt/img_root bash -x -c "$CUSTOM_COMMAND" || die "Custom command failed"
fi
chroot mnt/img_root service rsyslog stop &>/dev/null || : # some packages start syslog
}
function _create_sdcard {
# putting it all onto SD card
DEST_DEVICE="$1"
test -b "$DEST_DEVICE" || die "Must give block device with SD Card as first parameter"
_umount mnt/img_root/{proc,sys,run,dev/pts}
echo "Preparing SD card in $DEST_DEVICE"
umount -f ${DEST_DEVICE}* &>/dev/null || :
dd if=/dev/zero of=$DEST_DEVICE bs=1M count=100 status=none || die "Could not wipe SD card in $DEST_DEVICE"
parted -a minimal -s $DEST_DEVICE mklabel msdos mkpart primary fat32 0mb 64mb mkpart primary ext2 64mb 100% set 1 boot on || die "Could not parted $DEST_DEVICE"
if [ -e ${DEST_DEVICE}p1 ] ; then sd_boot_dev=${DEST_DEVICE}p1 ; elif [ -e ${DEST_DEVICE}1 ] ; then sd_boot_dev=${DEST_DEVICE}1 ; else die "Could not find sd-card partition 1" ; fi
if [ -e ${DEST_DEVICE}p2 ] ; then sd_root_dev=${DEST_DEVICE}p2 ; elif [ -e ${DEST_DEVICE}2 ] ; then sd_root_dev=${DEST_DEVICE}2 ; else die "Could not find sd-card partition 2" ; fi
mkdir -p mnt/sd_boot mnt/sd_root
mkfs.vfat >/dev/null -n RASPBIAN_BOOT -F 32 $sd_boot_dev -m - <<<"This is the boot partition of a Raspbian image intended for a Raspberry Pi" || die "Could not create boot partition"
mkfs.ext4 -q -L raspbian_root -E discard $sd_root_dev || die "Could not create root partition"
tune2fs >/dev/null $sd_root_dev -o journal_data,discard || die "Could not tune2fs $sd_root_dev"
mount -o data=writeback,nobarrier -t ext4 $sd_root_dev mnt/sd_root || die "Could not mount $sd_boot_dev mnt/sd_boot"
mkdir -p mnt/sd_root/boot || die "Could not mkdir boot"
mount -t vfat $sd_boot_dev mnt/sd_root/boot || die "Could not mount $sd_boot_dev mnt/sd_root/boot"
echo "Copying files to SD card."
cp -a mnt/img_root/* mnt/sd_root/ || die "Could not copy root fs"
echo "SD Card Details:"
_op parted -s $DEST_DEVICE print
df -h mnt/sd_root/boot mnt/sd_root | sed -e "s#$(pwd)/##"
sed -i -e 's/#//' mnt/sd_root/etc/ld.so.preload || die "Could not enable ld.so.preload"
echo
echo "SD Card Creation finished, please wait for script to complete."
}
export LANG="C" LANGUAGE="C" LC_ALL="C.UTF-8"
shopt -s nullglob
DESTDEVICE=
if [[ -b "${1:-}" ]] ; then
DESTDEVICE="$1"
fi
if [[ $# -eq 0 || "$*" == *-h* ]] ; then
echo "
Usage: $0 <--chroot|/dev/mmcblk0>
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
"
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
rm -Rf mnt temp
mkdir -p temp
function exittrap {
set +u +e
_umount 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 temp/*.img >/dev/null
echo "Script execution time: $SECONDS seconds"
}
trap exittrap 0
trap exittrap ERR
_get_image
_open_image
_modify_image
if [[ "$DESTDEVICE" ]] ; then
_create_sdcard "$DESTDEVICE"
elif [[ "$1" == "--chroot" ]] ; then
echo "Starting interactive Shell in image chroot"
chroot mnt/img_root bash -i
exit 0
else
die "Usage error. Try $0 --help"
fi
# vim:autoindent:tabstop=2:shiftwidth=2:expandtab:softtabstop=2: