1 | #!/bin/bash -e |
---|
2 | |
---|
3 | # Turn an ubuntu Karmic Koala live cd into one for Debathena |
---|
4 | # See https://help.ubuntu.com/community/LiveCDCustomization |
---|
5 | # Running this script itself on a machine running the same |
---|
6 | # distro helps. |
---|
7 | |
---|
8 | function usage () { |
---|
9 | echo "Usage: $0 [--dvd] [--aptitude '<package1> <package2>...'] [--tempdir /tmp/whatever] ubuntu-11.04-desktop-i386.iso debathena-i386.iso" > /dev/stderr |
---|
10 | exit |
---|
11 | } |
---|
12 | |
---|
13 | args="$(getopt -o da:t:h --long dvd,aptitude:,tempdir:,help -n debathena-livecd-convert -- "$@")" |
---|
14 | |
---|
15 | eval set -- "$args" |
---|
16 | |
---|
17 | CD="CD" |
---|
18 | CDDESC="" |
---|
19 | aptmods="" |
---|
20 | |
---|
21 | while true ; do |
---|
22 | case "$1" in |
---|
23 | -d|--dvd) CD="DVD" ; shift ;; |
---|
24 | -a|--aptitude) aptmods="$aptmods $2" ; CDDESC="Unofficial "; shift 2 ;; |
---|
25 | -t|--tempdir) TMP="$2" ; dontrmtmp=1 ; shift 2 ;; |
---|
26 | -h|--help) usage; shift ;; |
---|
27 | --) shift ; break ;; |
---|
28 | *) echo "Internal error!" ; exit 1 ;; |
---|
29 | esac |
---|
30 | done |
---|
31 | |
---|
32 | if [[ $# -ne 2 ]] ; then |
---|
33 | usage |
---|
34 | fi |
---|
35 | |
---|
36 | # Set vars |
---|
37 | if [[ -z "$TMP" ]] ; then |
---|
38 | TMP=$(mktemp -dt debathena-livecd-XXXXXX) |
---|
39 | fi |
---|
40 | MNT="$TMP/mnt" |
---|
41 | EXCD="$TMP/extract-cd" |
---|
42 | EDIT="$TMP/edit" |
---|
43 | |
---|
44 | CDNAME="Debathena" |
---|
45 | |
---|
46 | if [ "$CD" = "DVD" ] ; then |
---|
47 | echo "Using packages for Live DVD." |
---|
48 | EXTRA_PACKAGES=' |
---|
49 | debathena-extra-software |
---|
50 | bind9-host' |
---|
51 | EXTRA_NO_RECOMMENDS=' |
---|
52 | debathena-network-manager-config' |
---|
53 | PURGE='' |
---|
54 | else |
---|
55 | EXTRA_PACKAGES=' |
---|
56 | bind9-host |
---|
57 | emacs |
---|
58 | vim-gnome |
---|
59 | hesiod |
---|
60 | krb5-clients |
---|
61 | remctl-client |
---|
62 | screen |
---|
63 | rcs |
---|
64 | cvs |
---|
65 | subversion |
---|
66 | git-core |
---|
67 | tree' |
---|
68 | EXTRA_NO_RECOMMENDS=' |
---|
69 | texlive-base |
---|
70 | texlive-latex-base debathena-tex-config |
---|
71 | texlive-latex-recommended texlive-latex-extra latex-beamer prosper |
---|
72 | debathena-network-manager-config' |
---|
73 | PURGE=' |
---|
74 | ^diveintopython$ |
---|
75 | ~nbogofilter |
---|
76 | ~ngnome-games |
---|
77 | ^ekiga$ |
---|
78 | ^tomboy$ |
---|
79 | ^f-spot$ |
---|
80 | ~n^mono- |
---|
81 | ~n^libmono- |
---|
82 | ~n^openoffice.org-help- |
---|
83 | ~ngimp-help |
---|
84 | en-gb$ |
---|
85 | en-au$ |
---|
86 | en-za$ |
---|
87 | ^wbritish$ |
---|
88 | ^python-uno$ |
---|
89 | gnome-user-guide |
---|
90 | ^example-content$ |
---|
91 | ^language-pack-bn$ ^language-pack-bn-base$ |
---|
92 | ^language-pack-de$ ^language-pack-de-base$ ^language-pack-es$ |
---|
93 | ^language-pack-es-base$ ^language-pack-fr$ ^language-pack-fr-base$ |
---|
94 | ^language-pack-gnome-bn$ ^language-pack-gnome-bn-base$ |
---|
95 | ^language-pack-gnome-de$ ^language-pack-gnome-de-base$ |
---|
96 | ^language-pack-gnome-es$ ^language-pack-gnome-es-base$ |
---|
97 | ^language-pack-gnome-fr$ ^language-pack-gnome-fr-base$ |
---|
98 | ^language-pack-gnome-pt$ ^language-pack-gnome-pt-base$ |
---|
99 | ^language-pack-gnome-xh$ ^language-pack-gnome-xh-base$ ^language-pack-pt$ |
---|
100 | ^language-pack-pt-base$ ^language-pack-xh$ ^language-pack-xh-base$' |
---|
101 | fi |
---|
102 | |
---|
103 | # Having this mounted by accident is /very bad/ (you end up removing files |
---|
104 | # from the real /dev/), so double check. |
---|
105 | umount -l "$EDIT/dev" 2> /dev/null || : |
---|
106 | |
---|
107 | function cleanup { |
---|
108 | echo "Cleaning up..." |
---|
109 | umount -l "$EDIT/dev" || : |
---|
110 | umount -dl "$MNT" || : |
---|
111 | # These shouldn't be necessary (and shouldn't break a busy loop device), |
---|
112 | # but seem to be for some reason. |
---|
113 | # The -d switch to umount should be sufficient, but it's not |
---|
114 | losetup -d /dev/loop7 || : |
---|
115 | losetup -d /dev/loop6 || : |
---|
116 | losetup -d /dev/loop5 || : |
---|
117 | losetup -d /dev/loop4 || : |
---|
118 | losetup -d /dev/loop3 || : |
---|
119 | losetup -d /dev/loop2 || : |
---|
120 | losetup -d /dev/loop1 || : |
---|
121 | losetup -d /dev/loop0 || : |
---|
122 | |
---|
123 | # Clean intermediate files |
---|
124 | # If an explicit tempdir was given, don't remove it for debugging |
---|
125 | if [[ -z "$dontrmtmp" ]] ; then |
---|
126 | rm -Rf "$TMP" |
---|
127 | else |
---|
128 | echo "Not removing $TMP." |
---|
129 | fi |
---|
130 | } |
---|
131 | trap cleanup EXIT SIGINT SIGTERM |
---|
132 | |
---|
133 | # Simple rsync equivalent that shows progress based on file count |
---|
134 | # Don't include switches that affect output or w/e |
---|
135 | # The -pte options to pv prevent it from printing the total number of |
---|
136 | # lines (i.e., files) and the number of lines/files per second, because |
---|
137 | # those look too much like byte counts. |
---|
138 | function rsync_p { |
---|
139 | set -e |
---|
140 | l=`rsync "$@" -n --out-format='%n' | wc -l` |
---|
141 | rsync "$@" --out-format='%n' | pv -lpte -s $l > /dev/null |
---|
142 | } |
---|
143 | |
---|
144 | # Make sure we have necessary packages -- these are now dependencies |
---|
145 | #apt-get install squashfs-tools genisoimage pv syslinux netpbm |
---|
146 | |
---|
147 | # Make sure the module is loaded |
---|
148 | if ! grep -q squashfs /proc/filesystems ; then |
---|
149 | echo "Filesystem 'squashfs' not found in /proc/filesystems." >/dev/stderr |
---|
150 | echo "Try 'modprobe squashfs'?" > /dev/stderr |
---|
151 | exit 1 |
---|
152 | fi |
---|
153 | |
---|
154 | # Mount CD image |
---|
155 | echo "Mounting CD image." |
---|
156 | mkdir -p "$MNT" |
---|
157 | mount -o loop "$1" "$MNT" |
---|
158 | |
---|
159 | # Extract CD contents for modification |
---|
160 | echo "Extracting CD contents for modification." |
---|
161 | mkdir -p "$EXCD" |
---|
162 | rsync_p --exclude=/casper/filesystem.squashfs -a --delete "$MNT/" "$EXCD/" |
---|
163 | |
---|
164 | # Extract squashfs for mods |
---|
165 | echo "Unpack squashfs for modification." |
---|
166 | mkdir -p "$EDIT" |
---|
167 | unsquashfs -d "$EDIT" -f "$MNT/casper/filesystem.squashfs" |
---|
168 | |
---|
169 | # Modifying boot scripts |
---|
170 | echo "Modifying boot scripts..." |
---|
171 | rm -f "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/02timezone" |
---|
172 | rm -f "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/15autologin" |
---|
173 | cp "/usr/share/debathena-livecd-tools/casper-bottom/"*[!~] "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/" |
---|
174 | # for now, remove ubiquity mods since it won't be on the DVD |
---|
175 | rm -f "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/50mod_ubiquity" |
---|
176 | |
---|
177 | VERSION="$CDDESC$CD $(dpkg-query -W -f '${Version}\n' debathena-livecd-tools) $(date +%F)" |
---|
178 | sed -ri "s/VERSION=unknown/VERSION=\"$VERSION\"/" "$EDIT/usr/share/initramfs-tools/scripts/casper-bottom/50mod_athinfo" |
---|
179 | |
---|
180 | # Mod boot screen |
---|
181 | if [[ -e "$EXCD/isolinux/isolinux.txt" ]] ; then |
---|
182 | menu="$EXCD/isolinux/isolinux.txt" |
---|
183 | else |
---|
184 | menu="$EXCD/isolinux/txt.cfg" |
---|
185 | fi |
---|
186 | sed -ri "s/Ubuntu/$CDNAME/g" "$menu" "$EXCD/isolinux/isolinux.cfg" |
---|
187 | pngtopnm < "/usr/share/debathena-livecd-tools/splash/splash1.png" | ppmquant 256 | ppmtopcx > "$EXCD/isolinux/splash.pcx" |
---|
188 | # Force this one to no more than 16 colors |
---|
189 | pngtopnm < "/usr/share/debathena-livecd-tools/splash/splash2.png" | ppmquant 16 | ppmtolss16 "#000000=0" "#ffffff=7" > "$EXCD/isolinux/splash.rle" |
---|
190 | |
---|
191 | # Mod language |
---|
192 | echo 'en' > "$EXCD/isolinux/lang" |
---|
193 | |
---|
194 | # Mod README.diskdefines |
---|
195 | sed -ri 's/^(\#define DISKNAME\s+)(.+)$/\1'"$CDDESC$CDNAME"' \2/' "$EXCD/README.diskdefines" |
---|
196 | |
---|
197 | # Copy ubiquity mod files |
---|
198 | cp -a "/usr/share/debathena-livecd-tools/oncd" "$EDIT/oncd" |
---|
199 | # We need this for our aptitude |
---|
200 | # success_cmd to not fail horribly, because ubiquity |
---|
201 | # gets rid of its version too soon. |
---|
202 | cp "/usr/lib/debathena-livecd-tools/bin/policy-rc.d" "$EDIT/oncd/" |
---|
203 | |
---|
204 | # Prep chroot |
---|
205 | echo "Preparing for chroot..." |
---|
206 | # We'll need network |
---|
207 | cp /etc/resolv.conf "$EDIT/etc/" |
---|
208 | cp /etc/hosts "$EDIT/etc/" |
---|
209 | # Put a script named /usr/sbin/policy-rc.d that exits with code 101 |
---|
210 | # This prevents init scripts from being run by installed software |
---|
211 | cp "/usr/lib/debathena-livecd-tools/bin/policy-rc.d" "$EDIT/usr/sbin/" |
---|
212 | |
---|
213 | # Debathena key |
---|
214 | cp "/usr/share/keyrings/debathena-archive-keyring.gpg" "$EDIT/tmp/" |
---|
215 | |
---|
216 | echo "$EXTRA_PACKAGES" > "$EDIT/tmp/extra-packages" |
---|
217 | echo "$EXTRA_NO_RECOMMENDS" > "$EDIT/tmp/extra-no-recommends" |
---|
218 | echo "$PURGE" > "$EDIT/tmp/purge" |
---|
219 | echo "$aptmods" > "$EDIT/tmp/aptmods" |
---|
220 | |
---|
221 | mount --rbind /dev "$EDIT/dev" |
---|
222 | |
---|
223 | # stop cups since if it is running the |
---|
224 | # the install will try to add printers |
---|
225 | if [ $(pidof cupsd) ]; then |
---|
226 | service cups stop |
---|
227 | restart_cups=true |
---|
228 | fi |
---|
229 | |
---|
230 | # Set up the chroot script |
---|
231 | cp "/usr/lib/debathena-livecd-tools/bin/part2" "$EDIT/tmp/" |
---|
232 | |
---|
233 | # Chroot |
---|
234 | echo "Chroot!" |
---|
235 | unset SUDO_USER |
---|
236 | unset SUDO_UID |
---|
237 | unset SUDO_GID |
---|
238 | chroot "$EDIT" /tmp/part2 |
---|
239 | echo "End Chroot." |
---|
240 | |
---|
241 | if [ ! -e "$EDIT/tmp/success" ] ; then |
---|
242 | echo "Chroot part2 failed." > /dev/stderr |
---|
243 | exit 1 |
---|
244 | fi |
---|
245 | |
---|
246 | if [ $restart_cups ]; then |
---|
247 | service cups restart |
---|
248 | fi |
---|
249 | |
---|
250 | |
---|
251 | |
---|
252 | # Back from the chroot |
---|
253 | |
---|
254 | # Keep regenerated boot image |
---|
255 | cp "$EDIT/initrd.img" "$EXCD/casper/initrd.gz" |
---|
256 | # Karmic uses initrd.lz |
---|
257 | gzip -dc "$EXCD/casper/initrd.gz" | lzma -7 > "$EXCD/casper/initrd.lz" |
---|
258 | # And use the upgraded kernel, if we did an upgrade |
---|
259 | if [[ -e "$(readlink -f "$EDIT/vmlinuz")" ]] ; then |
---|
260 | echo "Using kernel $(readlink -f "$EDIT/vmlinuz")." |
---|
261 | mv "$(readlink -f "$EDIT/vmlinuz")" "$EXCD/casper/vmlinuz" |
---|
262 | fi |
---|
263 | |
---|
264 | # Clean up |
---|
265 | rm -Rf "$EDIT/tmp/"* # This includes part2 |
---|
266 | rm "$EDIT/etc/resolv.conf" |
---|
267 | rm "$EDIT/etc/hosts" |
---|
268 | rm "$EDIT/usr/sbin/policy-rc.d" |
---|
269 | |
---|
270 | # Regenerate manifest |
---|
271 | echo "Generating manifest." |
---|
272 | chroot "$EDIT" dpkg-query -W --showformat='${Package} ${Version}\n' > "$EXCD/casper/filesystem.manifest" |
---|
273 | cp "$EXCD/casper/filesystem.manifest" "$EXCD/casper/filesystem.manifest-desktop" |
---|
274 | sed -i '/ubiquity/d' "$EXCD/casper/filesystem.manifest-desktop" |
---|
275 | |
---|
276 | # Compress filesystem |
---|
277 | echo "Compressing filesystem." |
---|
278 | rm -f "$EXCD/casper/filesystem.squashfs" |
---|
279 | # Needed -nolzma pre-Karmic |
---|
280 | mksquashfs "$EDIT" "$EXCD/casper/filesystem.squashfs" |
---|
281 | |
---|
282 | # Calc md5sums |
---|
283 | echo "Calcualting checksums." |
---|
284 | rm "$EXCD/md5sum.txt" |
---|
285 | (cd "$EXCD" && find . -type f -print0 | xargs -0 md5sum > md5sum.txt) |
---|
286 | |
---|
287 | # Create ISO |
---|
288 | echo "Building ISO." |
---|
289 | genisoimage -r -V "$CDNAME Live" -cache-inodes -J -l -b "isolinux/isolinux.bin" -c "isolinux/boot.cat" -no-emul-boot -boot-load-size 4 -boot-info-table -o "$2" "$EXCD" |
---|
290 | |
---|
291 | # Now test it with VMware or something |
---|
292 | echo "Done!" |
---|