-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpliwixi
executable file
·295 lines (226 loc) · 7.69 KB
/
pliwixi
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
#!/bin/bash
#
# pliwixi: put linux where I can see it
#
# i.e. generate a .zip archive that users can unzip to
# a factory-fresh vfat-formatted SD card. That card will boot directly
# on the Raspberry Pi without repartitioning or reimaging.
#
# This is intended as a simple way to distribute a linux for small computers
# booted from flash storage.
#
# (C) John Brzustowski 2017
#
# Info: https://github.com/jbrzusto/liwixi
#
# License: CC BY-SA or GPL v 2 or later
export AUTO=0
export EXCLUDE_FROM="$LIWIXI_EXCLUDE_FROM"
while [[ "$1" != "" ]]; do
case $1 in
-a)
export AUTO=1
shift
;;
-e)
export EXCLUDE_FROM="$2"
shift 2
;;
*)
break
;;
esac
done
export BRAND=$1
export DEST=$2
export TEMP=$3
if [[ -z "$TEMP" ]]; then
export TEMP=$DEST
fi
export TEMPSUB=$TEMP/liwixi
mkdir $TEMPSUB
if [[ -z "$DEST" || ! -z "$4" || "$USER" != "root" || ( $EXCLUDE_FROM && ! -f $EXCLUDE_FROM ) ]]; then
cat <<EOF
Usage:
pliwixi [-a] [-e EXCLUDE] BRAND DEST [TEMP]
create a .zip archive with a bootable linux image and associated
files that a user can copy to a VFAT SD card to boot a Raspberry Pi.
The file will be called \$DEST/\${BRAND}_LIWIXI.ZIP, where
- BRAND: a string identifying your linux distribution; whitespace
is probably toxic
- DEST: path to a folder on a device with enough room to store
your compressed image plus boot files
- TEMP: optional path to a folder on a device with enough room to
store your *uncompressed* image plus boot files;
defaults to $DEST, which must then have enough room for both the
compressed and uncompressed images combined.
Options:
-a: automatic creation; don't pause for user input
-e: EXCLUDE is a path to a file containing files and paths to exclude
from the image; see the documentation for '--exclude-from' in
"man rsync"
Environment Variables:
LIWIXI_EXCLUDE_FROM: specifies a file for exclusions, just like
the "-e EXCLUDE" option. The command-line EXCLUDE option, if
specified, overrides the environment variable.
This script must be run as root.
EOF
exit 1;
fi
cat <<EOF
I'll make the image big enough to hold the storage *used* by the
current root file system, with an additional 25% to accomodate logfile
growth etc.
EOF
if [[ ! -z "$EXCLUDE_FROM" ]]; then
cat <<EOF
I will exclude files and paths from '$EXCLUDE_FROM'
EOF
fi
export IMAGE_MB=$(( `df -BM --output=used / | tail -1l | tr -d 'M'` * 5 / 4))
cat <<EOF
This image will occupy $IMAGE_MB M (M = 1024 * 1024 bytes).
Hit enter to continue, or Ctrl-C to quit and do something else...
EOF
if [[ $AUTO ]]; then
echo "Skipping due to automatic mode."
else
read _ignore_
fi
cat <<EOF
Modifying the liwixi script so that it points to your images's
eventual location on the SD card. The whole initramfs has the simple
job of setting up /dev/loop0 on that image.
EOF
export IMAGE_FILENAME=${BRAND}_LIWIXI_IMAGE_DO_NOT_DELETE
cat ./liwixi | sed -e "s/@@LIWIXI_IMAGE_FILENAME@@/$IMAGE_FILENAME/;/@@REMOVE@@/d" > /etc/initramfs-tools/scripts/local-premount/liwixi
echo "Generating an initramfs in $TEMPSUB"
export INITRAMFS=${BRAND}_LIWIXI_INITRAMFS_DO_NOT_DELETE
mkinitramfs -o $TEMPSUB/$INITRAMFS
echo "Generating the image file in $TEMPSUB"
dd if=/dev/zero bs=1M count=${IMAGE_MB} of=$TEMPSUB/$IMAGE_FILENAME
export LOOPDEV=`losetup -f`
losetup $LOOPDEV $TEMPSUB/$IMAGE_FILENAME
mkfs -t ext4 $LOOPDEV
mkdir /tmp/$IMAGE_FILENAME
export IMAGE_MOUNT_POINT=/tmp/$IMAGE_FILENAME
echo "Mounting the image file on $LOOPDEV"
mount $LOOPDEV $IMAGE_MOUNT_POINT
if [[ $EXCLUDE_FROM ]]; then
export EXCLUDE_FROM_CLAUSE="--exclude-from $EXCLUDE_FROM"
fi;
echo "Copying this machine's root filesystem to the image on $LOOPDEV"
rsync -a --exclude='/proc/**' --exclude='/sys/**' --exclude='/var/run/**' \
--exclude='/tmp/**' --exclude='/boot/**' --exclude='/media/**' \
--exclude='/mnt/**' --exclude='/run/**' --exclude='/dev/**' \
$EXCLUDE_FROM_CLAUSE \
/ $IMAGE_MOUNT_POINT/
export SG_VERSION=``
cat <<EOF
I'm making a few changes to the new image:
- create a symlink from /boot to /dev/sdcard
- set etc/bootcount to 0
- set etc/beaglebone_id, etc/rpi_id, etc/hostname to "not_set"
and setting /etc/bootcount to 0
EOF
pushd $IMAGE_MOUNT_POINT
rmdir boot
ln -s /dev/sdcard boot
echo 0 > etc/bootcount
for f in etc/beaglebone_id etc/rpi_id etc/hostname; do
echo not_set > $f
done
popd
cat <<EOF
Fixing the fstab entry for the root device, and removing
the entry for /dev/mmcblk0p1
EOF
sed -i -e '/ \/ /s/^[^ ]*/\/dev\/loop0/;/\/dev\/mmcblk0p1/d' $IMAGE_MOUNT_POINT/etc/fstab
cat <<EOF
Delete any active initramfs lines from config.txt in
$TEMPSUB then add a line so that it loads the initramfs
EOF
grep -v "^initramfs " /boot/config.txt > $TEMPSUB/config.txt
echo "initramfs $INITRAMFS" >> $TEMPSUB/config.txt
cat <<EOF
Changing the kernel command line in cmdline.txt in $TEMPSUB
so it that uses the new image as its root filesystem.
EOF
cat /boot/cmdline.txt | sed -e 's/ root=[^ ]+ / root=\/dev\/loop0 /' > $TEMPSUB/cmdline.txt
cat <<EOF
You will now be dropped into a bash shell at the top-level of the
uncompressed image, so you can verify and customize it.
For example:
- does etc/fstab show /dev/loop0 as being mounted on '/'
- are you accidentally distributing any private ssh keys in home/*/.ssh ?
When you wish to leave the shell and continue creating the image, hit
Ctrl-D or type 'exit'.
To leave the shell and cancel the image creation, type 'exit 1'.
EOF
if [[ $AUTO ]]; then
echo "Skipping due to automatic mode."
else
pushd $IMAGE_MOUNT_POINT
bash
RV=$?
popd
if (( $RV != 0 )); then
cat <<EOF
Compression of image into .zip archive cancelled, leaving the
uncompressed image mounted at $IMAGE_MOUNT_POINT. To unmount and
delete the uncompressed image and other files just created, do:
umount $IMAGE_MOUNT_POINT
losetup -d $LOOPDEV
rmdir /tmp/$IMAGE_FILENAME
rm $TEMPSUB/$IMAGE_FILENAME
rm $TEMPSUB/$INITRAMFS
rm $TEMPSUB/config.txt
rm $TEMPSUB/cmdline.txt
rmdir $TEMPSUB
EOF
exit 1
fi
fi
cat <<EOF
Creating the liwixi archive using zip; you're of course free to use a
better program to create a smaller archive if you are willing to teach
your users how to extract it!
EOF
export ARCHIVE=${BRAND}_LIWIXI.ZIP
## grab any excluded paths/files that begin with /boot, and write them
## to a file appropriate for use with zip's -x@FILE option, relative to
## the /boot directory in which we run zip
export EXCLUDE_FROM_CLAUSE=""
if [[ "$EXCLUDE_FROM" ]]; then
export TMP_EXCLUDE_FILE=`tempfile`
grep ^/boot $EXCLUDE_FROM | sed -e 's/\/boot\///' > $TMP_EXCLUDE_FILE
export EXCLUDE_FROM_CLAUSE="-x @$TMP_EXCLUDE_FILE"
fi
pushd /boot
ZIPCMD="zip -r $DEST/$ARCHIVE . -x ${ARCHIVE} -x cmdline.txt -x config.txt -x \"*liwixi*\" -x \"*LIWIXI*\" $EXCLUDE_FROM_CLAUSE"
cat <<EOF
1. Archiving files from the /boot directory, except for cmdline.txt and
config.txt for which we already have modified copies,
and liwixi, in case you're using /boot as temporary storage, and
any exclusions specified via EXCLUDE or the LIWIXI_EXCLUDE_FROM
environment variable using this command:
$ZIPCMD
EOF
zip -r $DEST/$ARCHIVE . -x ${ARCHIVE} -x cmdline.txt -x config.txt -x "*liwixi*" -x "*LIWIXI*" $EXCLUDE_FROM_CLAUSE
rm -f $TMP_EXCLUDE_FILE
cd $TEMPSUB
cat <<EOF
2. Archiving image, initramfs, config.txt, cmdline.txt from $TEMPSUB
EOF
zip -m ${DEST}/$ARCHIVE * -x ${ARCHIVE}
popd
rmdir $TEMPSUB
echo <<EOF
Done. The LIWIXI archive of this OS is here:
EOF
ls -al ${DEST}/$ARCHIVE
umount $IMAGE_MOUNT_POINT
losetup -d $LOOPDEV
rmdir /tmp/$IMAGE_FILENAME
cat <<EOF
EOF