tazusb view tazusb @ rev 78

Add many-in-one support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Apr 21 11:13:11 2011 +0200 (2011-04-21)
parents 671df117fb6f
children 0cd9974cbf41
line source
1 #!/bin/sh
2 # Tazusb - SliTaz LiveUSB
3 #
4 # Tazusb is an utility to generate, configure and manipulate SliTaz LiveUSB
5 # bootable media and/or USB /home partition, such as flash keys, SD card or
6 # USB harddisk.
7 #
8 # Authors : Christophe Lincoln (Pankso) <pankso@slitaz.org>
9 # Andrew Miller (Spode) <spode@spodesabode.com>
10 #
11 VERSION=2.3
13 COMMAND=$1
14 TARGET_ROOT=/media/flash
15 DRIVE_NAME=`cat /proc/sys/dev/cdrom/info | grep "drive name" | cut -f 3`
16 CDROM=/dev/$DRIVE_NAME
17 LOG=/tmp/$(basename $0).log
19 #
20 # Tazusb functions
21 #
23 # Print the usage.
24 usage ()
25 {
26 echo -e "\nSliTaz Live USB - Version: $VERSION\n
27 \033[1mUsage: \033[0m `basename $0` [command] [compression|device]
28 \033[1mCommands: \033[0m\n
29 usage Print this short usage.
30 writefs Write the current filesystem to rootfs.gz.
31 tazSupported compression: lzma. gzip, none.
32 format Format and label device with ext3, ext2 or fat32 filesystem
33 (for LiveUSB or /home). Default is ext3.
34 gen-liveusb Generate a bootable LiveUSB using files from the LiveCD.
35 gen-swap Create or recreate and activate additional swap memory.
36 gen-iso2usb Generate a bootable LiveUSB using files from ISO file.
37 clean Remove old backup filesystems to free disk space.\n"
38 }
40 # Status function.
41 status()
42 {
43 local CHECK=$?
44 echo -en "\\033[70G[ "
45 if [ $CHECK = 0 ]; then
46 echo -en "\\033[1;33mOK"
47 else
48 echo -en "\\033[1;31mFailed"
49 fi
50 echo -e "\\033[0;39m ]"
51 }
53 # Exit if user is not root.
54 check_root()
55 {
56 if test $(id -u) != 0 ; then
57 echo -e "\nThis program requires being run as root.\n"
58 exit 0
59 fi
60 }
62 # Display a list of available partitions.
63 fdisk_list()
64 {
65 echo "----"
66 fdisk -l | grep ^/dev/sd*
67 echo "----"
68 }
70 # We need a USB media to install.
71 ask_for_device()
72 {
73 echo -n "\
74 Please specify the target USB device to $COMMAND. You can type 'list' to
75 get a list of devices, type 'exit' or give an empty value to exit.
77 Device to use : "; read anser
78 while [ "$anser" == "list" ]; do
79 fdisk_list
80 echo -n "Device to use : "; read anser
81 done
82 if [ "$anser" = "" -o "$anser" = "exit" ]; then
83 echo -e "\nNo specified device or exit.\n"
84 exit 0
85 else
86 DEVICE=$anser
87 fi
88 }
90 # Verify a device exists before format or install
91 check_for_device()
92 {
93 IFDEV=`fdisk -l | grep $DEVICE`
94 if [ -z "$IFDEV" ]; then
95 echo -e "\nUnable to find device: $DEVICE\n"
96 exit 0
97 fi
98 }
100 # gets the UUID and filesystem type
101 get_part_info()
102 {
103 UUID=`blkid -s UUID -o value $DEVICE`
104 FSTYPE=`blkid -s TYPE -o value $DEVICE`
105 }
107 # Format target device and label partition.
108 mkfs_ext3()
109 {
110 echo -n "Please specify a label for the partition (TazUSB): "
111 read label
113 if [ -z $label ]; then
114 label=TazUSB
115 fi
117 echo "Label : $label"
118 echo "Mkfs : mkfs.ext3 -L \"$label\" $DEVICE"
119 echo "" && sleep 2
120 mkfs.ext3 -L "$label" $DEVICE
122 }
124 # Get label for device
125 get_label()
126 {
127 echo -n "Please specify a label for the partition (TazUSB): "
128 read label
130 if [ -z $label ]; then
131 label=TazUSB
132 fi
133 }
135 # Get fs type. Supported fs are ext3, ext2, fat32
136 get_fs_type()
137 {
138 echo -n "Please specify a filesystem type ext2, ext3 or fat32 (ext3): "
139 read fs_type
141 if [ -z $fs_type ]; then
142 fs_type=ext3
143 fi
144 }
146 # We can chose the filesystem type.
147 ask_for_fs_type()
148 {
149 echo -n "\
150 Please specify the filesystem type to $COMMAND.
151 Available formats are ext3(default), ext2 or fat32.
152 Press enter to keep the default value.
154 File system type : "; read anser
155 if [ "$anser" = "" ]; then
156 FS_TYPE=ext3
157 else
158 FS_TYPE=$anser
159 fi
160 }
162 # Format target device in ext3, ext2 or fat32.
163 # Usage: make_fs ext2|fat32|ext3 (default)
164 make_fs()
165 {
166 local answer
168 FS=$(echo $fs_type | tr [A-Z] [a-z])
169 case "$FS" in
170 ext3|ext2)
171 echo -e "\nProcessing..."
172 echo "Label : $label"
173 echo "Mkfs : mkfs.$FS -L \"$label\" $DEVICE"
174 echo "" && sleep 2
175 mkfs.$@ -L "$label" $DEVICE > $LOG 2>&1
176 ;;
177 [Ff]at32)
178 if [ -x /sbin/mkdosfs ];then
179 echo -e "\nProcessing..."
180 echo "Label : $label"
181 echo "Mkfs : mkdosfs -F 32 -n \"$label\" $DEVICE"
182 echo "" && sleep 2
183 mkdosfs -F 32 -n "$label" $DEVICE
184 else
185 echo -ne "Can't find mkdosfs tool.\nWould you like to install dosfstools from repository [y/N] ? "; read answer
186 case $answer in
187 y|Y)
188 yes | tazpkg get-install dosfstools && make_fs fat32;;
189 *)
190 exit 1 ;;
191 esac
192 fi
193 ;;
194 *)
195 echo "Sorry. Filesystem $FS is not supported."
196 exit
197 esac
198 }
200 # Mount an existing USB device.
201 unmount_target_usb()
202 {
203 # If mount point is in use, unmount
204 if mount | grep -q $TARGET_ROOT; then
205 umount $TARGET_ROOT
206 fi
208 # Device could be mounted elsewhere, so unmount
209 if mount | grep -q $DEVICE; then
210 echo "Unmounting USB target device..."
211 umount $DEVICE
212 fi
213 }
215 # Mount an existing USB device.
216 mount_target_usb()
217 {
218 echo "Mounting USB target device..."
219 mkdir -p $TARGET_ROOT
220 mount $DEVICE $TARGET_ROOT 2>/dev/null
221 }
223 # Mount SliTaz LiveCD to get needed files.
224 mount_cdrom()
225 {
226 echo "Mounting cdrom device..."
228 if mount | grep /media/cdrom; then
229 umount /media/cdrom
230 fi
232 mkdir -p /media/cdrom
233 mount -r -t iso9660 $CDROM /media/cdrom 2>/dev/null
235 if [ ! -f /media/cdrom/boot/rootfs.gz -a \
236 ! -f /media/cdrom/boot/rootfs1.gz ]; then
237 echo -e "\nUnable to mount cdrom or to find a filesystem on it (rootfs.gz).\n"
238 exit 0
239 fi
240 }
242 # Mount SliTaz ISO to get needed files.
243 mount_iso()
244 {
245 if mount | grep /media/cdrom ; then
246 umount /media/cdrom
247 fi
249 test -d /media/cdrom || mkdir -p /media/cdrom
251 # Add support to other distros.
252 if [ ! -f /etc/slitaz-version ]; then
253 OPTIONS="-o loop"
254 else
255 OPTIONS=""
256 fi
258 echo "Mounting `basename $ISO`..."
259 mount $OPTIONS $ISO /media/cdrom 2>/dev/null
261 if [ ! -f /media/cdrom/boot/rootfs.gz -a \
262 ! -f /media/cdrom/boot/rootfs1.gz ]; then
263 echo -e "\nUnable to mount iso or to find a filesystem on it (rootfs.gz).\n"
264 exit 0
265 fi
266 }
268 # All needed files are in the boot directory of the cdrom.
269 copy_cdrom_files()
270 {
271 echo -n "Copying needed files from cdrom..."
272 mkdir -p $TARGET_ROOT/boot
273 cp /media/cdrom/boot/bzImage $TARGET_ROOT/boot
274 rem=0
275 for i in $(ls /media/cdrom/boot/rootfs*.gz | sort -r); do
276 [ $rem -ne 0 ] &&
277 dd if=/dev/zero bs=1 count=$((4 - $rem)) 2> /dev/null
278 cat $i
279 rem=$(stat -c %s $i)
280 rem=$(($rem % 4))
281 done > $TARGET_ROOT/boot/rootfs.gz
282 status
283 }
285 install_mbr()
286 {
287 # MBR
288 DISK=${DEVICE%[1-99]}
289 if [ -f /usr/share/boot/mbr.bin ]; then
290 echo -n "Installing a new MBR to: $DISK"
291 cat /usr/share/boot/mbr.bin > $DISK
292 status
293 else
294 # Skip MBR install (tazpkg get-install syslinux-extra ? and then cat)
295 echo "No new MBR installed to: $DISK"
296 fi
297 }
299 # ext/syslinux install
300 install_boot()
301 {
302 # Decide if we're installing syslinux or extlinux
303 if [ "$FSTYPE" = "vfat" ]; then
304 ST=syslinux
305 STC="syslinux --install -d /boot/syslinux/ $DEVICE"
306 STE=cfg
307 else
308 ST=extlinux
309 STC="extlinux --install $TARGET_ROOT/boot/$ST"
310 STE=conf
311 fi
313 echo "Installing bootloader: $ST"
314 mkdir -p $TARGET_ROOT/boot/$ST
315 $STC
317 # Use existing isolinux.cfg for extlinux.conf or syslinux.cfg
318 cp /media/cdrom/boot/isolinux/isolinux.cfg $TARGET_ROOT/boot/$ST/$ST.$STE
319 sed -i "s/isolinux.msg/$ST.msg/" $TARGET_ROOT/boot/$ST/$ST.$STE
321 # Add home= to append in extlinux or syslinux.cfg
322 sed -i -e "s/\(append.*\)/\1 home=$UUID/" $(grep -l append $TARGET_ROOT/boot/$ST/*)
324 # Splash screen and help files.
325 cp /media/cdrom/boot/isolinux/isolinux.msg $TARGET_ROOT/boot/$ST/$ST.msg
326 sed -i s/'SliTaz GNU\/Linux'/'SliTaz GNU\/Linux LiveUSB'/ $TARGET_ROOT/boot/$ST/$ST.msg
327 cp /media/cdrom/boot/isolinux/splash.lss $TARGET_ROOT/boot/$ST
328 cp /media/cdrom/boot/isolinux/*.txt $TARGET_ROOT/boot/$ST
329 cp /media/cdrom/boot/isolinux/*.cfg $TARGET_ROOT/boot/$ST
330 cp /media/cdrom/boot/isolinux/*.kbd $TARGET_ROOT/boot/$ST
331 cp /media/cdrom/boot/isolinux/*.c32 $TARGET_ROOT/boot/$ST
333 # Modifing all cfg files.
334 for cfg in $TARGET_ROOT/boot/$ST/*.cfg
335 do
336 sed -i s/isolinux.msg/$ST.msg/ $cfg
337 done
339 # Modifing include file if exists.
340 if [ -f $TARGET_ROOT/boot/$ST/common.inc ]; then
341 sed -i -e "s/isolinux.msg/$ST.msg/" $TARGET_ROOT/boot/$ST/common.inc
342 fi
344 # Un-meta-ize a multi-in-one flavor
345 sed -i "s/isolinux/$ST/;s/label slitaz/label multi/" $TARGET_ROOT/boot/$ST/common.cfg
346 sed -i 's/\(.*\), flavors.*/ \1/' \
347 $TARGET_ROOT/boot/$ST/$ST.msg
348 for i in $TARGET_ROOT/boot/$ST/$ST.$STE $TARGET_ROOT/boot/$ST/??.$STE \
349 $TARGET_ROOT/boot/$ST/??_??.$STE; do
350 sed '/label /!d;/label /{s/label .*/label slitaz/;NN;s/rootfs..gz.*gz /rootfs.gz /;N;q}' \
351 < $i >> $i
352 done
354 }
356 # Let user exit or reboot.
357 exit_or_reboot()
358 {
359 echo "==============================================================================="
360 echo ""
361 echo -n "Do you want to exit Tazusb or reboot system (Exit/reboot) ? "
362 read anser
363 if [ "$anser" == "reboot" ]; then
364 umount $TARGET_ROOT
365 umount /media/cdrom
366 reboot || reboot -f
367 else
368 umount $TARGET_ROOT
369 umount /media/cdrom
370 echo ""
371 exit 0
372 fi
373 }
375 set_bootable()
376 {
377 # As the boot flag is toggable, need to check it before hand
378 DISK=${DEVICE%[1-99]}
379 ISSET=`fdisk -l $DISK | grep $DEVICE | grep "\*"`
381 # If not set, set bootable
382 if [ "$ISSET" == "" ]; then
383 umount $TARGET_ROOT 2>/dev/null
384 echo -n "Setting $DEVICE as bootable..."
385 fdisk $DISK >/dev/null << EOF
386 a
387 1
388 w
389 EOF
390 status
391 fi
392 }
394 # Generate a virtual swap file in /home/swap. SliTaz boot scripts
395 # will activate it, useful for low memory systems
396 gen_swap_file()
397 {
398 echo ""
399 echo -en "\033[1mGen swap\033[0m
400 ===============================================================================
401 Generate a swap file in /home/swap that will be activated on each boot to have
402 more memory available (Empty value to exit).
404 Swap file in Mb : "
405 read size
406 if [ -z "$size" ]; then
407 echo -e "\nEmpty value. Exiting...\n"
408 exit 0
409 fi
410 cd /home
411 # Sanity check
412 if [ -f swap ]; then
413 swapoff swap 2>/dev/null
414 fi
415 # DD to gen a virtual disk.
416 dd if=/dev/zero of=swap bs=1M count=$size
417 # Make swap filesystem.
418 mkswap swap
419 swapon swap
420 echo ""
421 }
423 # Clean out old backups to save disk space
424 clean_usb()
425 {
426 echo ""
427 echo -en "\033[1mClean\033[0m
428 ===============================================================================
429 Remove old rootfs.gz.unixtimestamp backup filesystems to free up disk space.\n\n"
430 # Locate and interactively remove old filesystems from /home directory
431 for file in `find /home/boot/rootfs.gz.[0-9]*`
432 do
433 echo -n "Do you wish to remove: `basename $file` (Yes/no/exit) ? "
434 read answer
435 case $answer in
436 e|E|"exit"|Exit)
437 exit 0 ;;
438 y|Y|yes|Yes)
439 rm -f $file ;;
440 *)
441 echo -en "No filesystems selected, exiting...\n" ;;
442 esac
443 done
444 }
446 #
447 # Tazusb sequence
448 #
450 case $COMMAND in
451 writefs)
452 # Writefs to rootfs.gz
453 check_root
454 if [ -z $2 ]; then
455 COMPRESSION=none
456 else
457 COMPRESSION=$2
458 fi
459 # Start info
460 echo ""
461 echo -e "\033[1mWrite filesystem\033[0m
462 ===============================================================================
463 The command writefs will write all the current filesystem into a suitable cpio
464 archive (rootfs.gz) usable on a bootable LiveUSB media.
466 Archive compression: $COMPRESSION"
467 echo ""
469 # Clear out tazpkg cache
470 rm /var/cache/tazpkg/* -r -f
472 # Optionally remove sound card selection
473 echo -n "Do you wish to remove the sound card selection (No/yes/exit) ? "
474 read anser
475 case $anser in
476 e|E|"exit"|Exit)
477 exit 0 ;;
478 y|Y|yes|Yes)
479 echo -n "Removing current sound card selection..."
480 rm -f /var/lib/sound-card-driver
481 rm -f /etc/asound.state ;;
482 *)
483 echo -n "Keeping current sound card selection..." ;;
484 esac
485 status
486 # Optionally remove screen resolution
487 echo -n "Do you wish to remove the screen resolution (No/yes/exit) ? "
488 read anser
489 case $anser in
490 e|E|"exit"|Exit)
491 exit 0 ;;
492 y|Y|yes|Yes)
493 echo -n "Removing current screen resolution..."
494 rm -f /etc/X11/screen.conf ;;
495 *)
496 echo -n "Keeping current screen resolution..." ;;
497 esac
498 status
500 # Create list of files
501 find /bin /etc /init /sbin /var /dev /lib /root /usr >/tmp/list
503 for dir in /home /proc /sys /tmp /mnt /media /media/cdrom /media/flash /media/usbdisk
504 do
505 echo $dir >>/tmp/list
506 done
508 # Generate initramfs with specified compression
509 if [ "$COMPRESSION" = "lzma" ]; then
510 echo -n "Creating rootfs.gz with lzma compression... "
511 cat /tmp/list | cpio -o -H newc | lzma e -si -so > /rootfs.gz
513 elif [ "$COMPRESSION" = "gzip" ]; then
514 echo -n "Creating rootfs.gz with gzip compression... "
515 cat /tmp/list | cpio -o -H newc | gzip -9 > /rootfs.gz
517 else
518 echo -n "Creating rootfs.gz without compression... "
519 cat /tmp/list | cpio -o -H newc > /rootfs.gz
520 fi
522 # Get initramfs size
523 size=`du -sh /rootfs.gz | cut -f 1`
525 # If the bootable medium is where it should be, copy across
526 if (test -e /home/boot/bzImage); then
527 echo "Moving rootfs.gz to media. Remember to unmount for delayed writes!"
529 # Move the old filesystem with the unix timestamp for reference
530 if (test -e /home/boot/previous.gz); then
531 mv /home/boot/previous.gz /home/boot/rootfs.gz.$(date +%s)
532 fi
534 mv /home/boot/rootfs.gz /home/boot/previous.gz
535 mv /rootfs.gz /home/boot/.
536 else
537 echo "rootfs.gz is located in /"
538 fi
540 echo "==============================================================================="
541 echo "Root filesystem size: $size"
542 echo ""
543 echo -en "----\nENTER to continue..."; read i
544 ;;
545 format)
546 # Format a partition.
547 check_root
548 echo ""
549 echo -e "\033[1mFormat a device\033[0m"
550 echo "==============================================================================="
551 DEVICE=$2
552 label=$3
553 fs_type=$4
554 if [ -z $DEVICE ]; then
555 ask_for_device
556 check_for_device
557 else
558 echo "Device : $DEVICE"
559 fi
560 test -z $fs_type && get_fs_type
561 get_label
562 unmount_target_usb
563 make_fs "$fs_type"
564 # mkfs_ext3
565 echo "==============================================================================="
566 echo "Device $label ($DEVICE) is ready to use as LiveUSB and/or /home partition."
567 echo ""
568 ;;
569 gen-liveusb)
570 # Generate a LiveUSB media using files from a LiveCD.
571 check_root
572 echo ""
573 echo -e "\033[1mGen a LiveUSB media\033[0m"
574 echo "==============================================================================="
575 DEVICE=$2
576 if [ -z $DEVICE ]; then
577 ask_for_device
578 fi
580 check_for_device
581 mount_cdrom
582 get_part_info
583 unmount_target_usb
584 install_mbr
585 set_bootable
586 mount_target_usb
587 copy_cdrom_files
588 install_boot
589 exit_or_reboot
590 ;;
591 gen-swap)
592 check_root
593 gen_swap_file
594 ;;
595 gen-iso2usb|iso2usb)
596 check_root
598 # Check if file exists
599 ISO=$2
600 if [ -z $ISO ] || [ ! -f $ISO ]; then
601 echo -e "\nPlease specify a valid filename on the command line.\n"
602 exit 1
603 fi
604 echo ""
605 echo -e "\033[1mCopy ISO file to SliTaz LiveUSB media\033[0m"
606 echo "==============================================================================="
607 echo ""
608 DEVICE=$3
609 if [ -z $DEVICE ]; then
610 ask_for_device
611 fi
612 check_for_device
613 mount_iso
614 get_part_info
615 unmount_target_usb
616 install_mbr
617 set_bootable
618 mount_target_usb
619 copy_cdrom_files
620 install_boot
621 umount /dev/cdrom
622 losetup -d /dev/loop0
623 exit_or_reboot
624 ;;
625 clean)
626 check_root
627 clean_usb
628 ;;
629 usage|*)
630 # Display usage by default.
631 usage
632 ;;
633 esac
635 exit 0