tazlito view tazlito @ rev 190

tazlito: use xz compressor for mksquashfs
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Dec 15 10:24:06 2010 +0100 (2010-12-15)
parents bac6501cea49
children 21ba70c9bd53
line source
1 #!/bin/sh
2 # TazLito - SliTaz Live Tool.
3 #
4 # Tazlito is a tool to help generate and configure SliTaz LiveCD
5 # ISO images. You can create a custom distro in one command from a list of
6 # packages, extract an existing ISO image to hack it, create a new initramfs
7 # and/or a new ISO. Most commands must be run by root, except the stats
8 # and the configuration file manipulation.
9 #
10 # (C) 2007-2010 SliTaz - GNU General Public License.
11 #
12 # Authors : Christophe Lincoln <pankso@slitaz.org>
13 # Pascal Bellard <pascal.bellard@slitaz.org>
14 #
15 VERSION=3.2
17 # Tazlito configuration variables to be shorter
18 # and to use words rather than numbers.
19 COMMAND=$1
20 LIST_NAME=$2
21 TMP_DIR=/tmp/tazlito-$$-$RANDOM
22 TMP_MNT=/media/tazlito-$$-$RANDOM
23 TOP_DIR=`pwd`
24 INITRAMFS=rootfs.gz
25 LOCALSTATE=/var/lib/tazpkg
26 INSTALLED=$LOCALSTATE/installed
27 CACHE_DIR=/var/cache/tazpkg
28 MIRROR=$LOCALSTATE/mirror
29 DEFAULT_MIRROR="http://mirror.slitaz.org/packages/`cat /etc/slitaz-release`/"
31 # Try to include config file, continue if command is gen-config or exit.
32 # The main config used by default is in /etc/tazlito.
33 if [ -f "/etc/tazlito/tazlito.conf" ] ; then
34 CONFIG_FILE="/etc/tazlito/tazlito.conf"
35 fi
36 # Specific distro config file can be put in a distro tree.
37 if [ -f "$TOP_DIR/tazlito.conf" ] ; then
38 CONFIG_FILE="$TOP_DIR/tazlito.conf"
39 fi
40 if [ ! "$CONFIG_FILE" = "" ] ; then
41 . $CONFIG_FILE
42 else
43 if [ "$COMMAND" = "gen-config" ] ; then
44 continue
45 else
46 echo "Unable to find any configuration file. Please read the docs"
47 echo "or run '`basename $0` gen-config' to get an empty config file."
48 exit 0
49 fi
50 fi
52 # While Tazpkg is not used the default mirror url file does not exist
53 # and user can't recharge the list of flavors.
54 if test $(id -u) = 0 ; then
55 if [ ! -f "$MIRROR" ]; then
56 echo "$DEFAULT_MIRROR" > $MIRROR
57 fi
58 fi
60 # Set the rootfs and rootcd path with $DISTRO
61 # configuration variable.
62 ROOTFS=$DISTRO/rootfs
63 ROOTCD=$DISTRO/rootcd
64 FLAVORS_REPOSITORY=/home/slitaz/flavors
66 #####################
67 # Tazlito functions #
68 #####################
70 # Print the usage.
71 usage ()
72 {
73 echo -e "\nSliTaz Live Tool - Version: $VERSION\n
74 \033[1mUsage: \033[0m `basename $0` [command] [list|iso|flavor|compression] [dir|iso]
75 \033[1mCommands: \033[0m\n
76 usage Print this short usage.
77 stats View Tazlito and distro configuration statistics.
78 gen-config Generate a new configuration file for a distro.
79 configure Configure the main config file or a specific tazlito.conf.
80 gen-iso Generate a new ISO from a distro tree.
81 gen-initiso Generate a new initramfs and ISO from the distro tree.
82 list-flavors List all available package lists on the mirror.
83 gen-flavor Generate a new live-CD description.
84 gen-liveflavor Generate a live-CD description from current system.
85 show-flavor Show live-CD description.
86 get-flavor Get a flavor's list of packages.
87 upgrade-flavor Update package list to the latest available versions.
88 extract-flavor Extract a (*.flavor) flavor into $FLAVORS_REPOSITORY.
89 pack-flavor Pack (and update) a flavor from $FLAVORS_REPOSITORY.
90 check-list Check a distro-packages.list for updates.
91 extract-distro Extract an ISO to a directory and rebuild LiveCD tree.
92 gen-distro Generate a Live distro and ISO from a list of packages.
93 clean-distro Remove all files generated by gen-distro.
94 check-distro Help to check if distro is ready to release.
95 writeiso Use running system to generate a bootable ISO (with /home).
96 merge Merge multiple rootfs into one iso.
97 repack Recompress rootfs into iso with maximum ratio.
98 build-loram Generate a live-CD for low ram systems.
99 frugal-install Frugal install in /boot/frugal from a distro or ISO.
100 emu-iso Emulate an ISO image with Qemu.
101 burn-iso Burn ISO image to a cdrom using Wodim.\n"
102 }
104 # Status function.
105 status()
106 {
107 local CHECK=$?
108 echo -en "\\033[70G[ "
109 if [ $CHECK = 0 ]; then
110 echo -en "\\033[1;33mOK"
111 else
112 echo -en "\\033[1;31mFailed"
113 fi
114 echo -e "\\033[0;39m ]"
115 return $CHECK
116 }
118 yesorno()
119 {
120 echo -n "$1"
121 case "$DEFAULT_ANSWER" in
122 Y|y) answer="y";;
123 N|n) answer="n";;
124 *) read answer;;
125 esac
126 }
128 field()
129 {
130 grep "^$1" "$2" | sed 's/.*: \([0-9KMG\.]*\).*/\1/'
131 }
133 todomsg()
134 {
135 echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
136 }
138 # Download a file from this mirror
139 download_from()
140 {
141 local i
142 local mirrors
143 mirrors="$1"
144 shift
145 for i in $mirrors; do
146 case "$i" in
147 http://*|ftp://*) wget -c $i$@ && break;;
148 *) cp $i/$1 . && break;;
149 esac
150 done
151 }
153 # Download a file trying all mirrors
154 download()
155 {
156 local i
157 for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2> /dev/null); do
158 download_from "$i" "$@" && break
159 done
160 }
162 # Execute hooks provided by some packages
163 genisohooks()
164 {
165 local here=`pwd`
166 for i in $(ls $ROOTFS/etc/tazlito/*.$1 2> /dev/null); do
167 cd $ROOTFS
168 . $i $ROOTCD
169 done
170 cd $here
171 }
173 cleanup()
174 {
175 if [ -d $TMP_MNT ]; then
176 umount $TMP_MNT
177 rmdir $TMP_MNT
178 rm -f /boot
179 fi
180 }
182 # Echo the package name if the tazpkg is already installed
183 installed_package_name()
184 {
185 local tazpkg
186 local package
187 local VERSION
188 local EXTRAVERSION
189 tazpkg=$1
190 # Try to find package name and version to be able
191 # to repack it from installation
192 # A dash (-) can exist in name *and* in version
193 package=${tazpkg%-*}
194 i=$package
195 while true; do
196 VERSION=""
197 eval $(grep -s ^VERSION= $INSTALLED/$i/receipt)
198 EXTRAVERSION=""
199 eval $(grep -s ^EXTRAVERSION= $INSTALLED/$i/receipt)
200 if [ "$i-$VERSION$EXTRAVERSION" = "$tazpkg" ]; then
201 echo $i
202 break
203 fi
204 case "$i" in
205 *-*);;
206 *) break;;
207 esac
208 i=${i%-*}
209 done
210 }
212 # Check if user is root.
213 check_root()
214 {
215 if test $(id -u) != 0 ; then
216 echo -e "\nYou must be root to run `basename $0` with this option."
217 echo -e "Please type 'su' and root password to become super-user.\n"
218 exit 0
219 fi
220 }
222 # Check for the rootfs tree.
223 check_rootfs()
224 {
225 if [ ! -d "$ROOTFS/etc" ] ; then
226 echo -e "\nUnable to find a distro rootfs...\n"
227 exit 0
228 fi
229 }
231 # Check for the boot dir into the root CD tree.
232 verify_rootcd()
233 {
234 if [ ! -d "$ROOTCD/boot" ] ; then
235 echo -e "\nUnable to find the rootcd boot directory...\n"
236 exit 0
237 fi
238 }
240 create_iso()
241 {
242 echo "Generating $1"
243 genisoimage -R -o $1 -b boot/isolinux/isolinux.bin \
244 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
245 -V "$VOLUM_NAME" -p "$PREPARED" -input-charset iso8859-1 \
246 -boot-info-table $2
247 if [ -x /usr/bin/isohybrid ]; then
248 echo -n "Creating hybrid ISO..."
249 /usr/bin/isohybrid $1 2> /dev/null
250 status
251 fi
252 }
254 # Generate a new ISO image using isolinux.
255 gen_livecd_isolinux()
256 {
257 # Some packages may want to alter iso
258 genisohooks iso
259 if [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ]; then
260 echo -e "\nUnable to find isolinux binary.\n"
261 cleanup
262 exit 0
263 fi
264 # Set date for boot msg.
265 if grep -q 'XXXXXXXX' $ROOTCD/boot/isolinux/isolinux.msg; then
266 DATE=`date +%Y%m%d`
267 echo -n "Setting build date to: $DATE..."
268 sed -i s/'XXXXXXXX'/"$DATE"/ $ROOTCD/boot/isolinux/isolinux.msg
269 status
270 fi
271 cd $ROOTCD
272 echo -n "Computing md5..."
273 find * -type f ! -name md5sum -exec md5sum {} \; > md5sum
274 sed -i '/ boot\/isolinux\/isolinux.bin$/d' md5sum
275 status
276 cd $DISTRO
277 echo ""
278 echo -e "\033[1mGenerating ISO image\033[0m"
279 echo "================================================================================"
280 create_iso $ISO_NAME.iso $ROOTCD
281 echo -n "Creating the ISO md5sum..."
282 md5sum $ISO_NAME.iso > $ISO_NAME.md5
283 status
284 echo "================================================================================"
285 # Some packages may want to alter final iso
286 genisohooks final
287 }
289 lzma_history_bits()
290 {
291 #
292 # This generates an ISO which boots with Qemu but gives
293 # rootfs errors in frugal or liveUSB mode.
294 #
295 #local n
296 #local sz
297 #n=20 # 1Mb
298 #sz=$(du -sk $1 | cut -f1)
299 #while [ $sz -gt 1024 -a $n -lt 28 ]; do
300 #n=$(( $n + 1 ))
301 #sz=$(( $sz / 2 ))
302 #done
303 #echo $n
304 echo 24
305 }
307 lzma_switches()
308 {
309 echo "-d$(lzma_history_bits $1) -mt$(grep '^processor' < /proc/cpuinfo | wc -l)"
310 }
312 # Pack rootfs
313 pack_rootfs()
314 {
315 ( cd $1 ; find . -print | cpio -o -H newc ) | \
316 if [ "$COMPRESSION" = "none" ]; then
317 echo "Generating uncompressed initramfs... "
318 cat > $2
319 elif [ -x /usr/bin/lzma -a "$COMPRESSION" != "gzip" ]; then
320 echo -n "Generating lzma'ed initramfs... "
321 lzma e -si -so $(lzma_switches $1) > $2
322 else
323 echo "Generating gziped initramfs... "
324 gzip -9 > $2
325 fi
326 echo 1 > /tmp/rootfs
327 }
329 # Compression functions for writeiso.
330 write_initramfs()
331 {
332 if [ "$COMPRESSION" = "lzma" ]; then
333 echo -n "Creating rootfs.gz with lzma compression... "
334 cat /tmp/list | cpio -o -H newc | lzma e -si -so > /rootfs.gz
335 elif [ "$COMPRESSION" = "gzip" ]; then
336 echo "Creating rootfs.gz with gzip compression... "
337 cat /tmp/list | cpio -o -H newc | gzip -9 > /rootfs.gz
338 else
339 echo "Creating rootfs.gz without compression... "
340 cat /tmp/list | cpio -o -H newc > /rootfs.gz
341 fi
342 echo 1 > /tmp/rootfs
343 }
345 # Generate a new initramfs from the root filesystem.
346 gen_initramfs()
347 {
348 # Just in case CTRL+c
349 rm -f $DISTRO/gen
350 # Some packages may want to alter rootfs
351 genisohooks rootfs
352 cd $1
353 echo ""
355 # Link duplicate files
356 find . -type f -size +0c -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | \
357 sort | ( save=0; old_attr=""; old_inode=""; old_link=""; old_file=""
358 while read attr inode link file; do
359 if [ "$attr" = "$old_attr" -a "$inode" != "$old_inode" ]; then
360 if cmp "$file" "$old_file" >/dev/null; then
361 rm -f "$file"
362 ln "$old_file" "$file"
363 inode="$old_inode"
364 [ "$link" = "1" ] && save="$(expr $save + ${attr%%-*})"
365 fi
366 fi
367 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
368 done
369 echo "$save bytes saved in duplicate files."
370 )
372 # Use lzma if installed. Display rootfs size in realtime.
373 rm -f /tmp/rootfs
374 pack_rootfs . $DISTRO/$(basename $1).gz &
375 sleep 2
376 echo -en "\nFilesystem size:"
377 while [ ! -f /tmp/rootfs ]
378 do
379 sleep 1
380 echo -en "\\033[18G`du -sh $DISTRO/$(basename $1).gz | awk '{print $1}'` "
381 done
382 echo -e "\n"
383 cd $DISTRO
384 mv $(basename $1).gz $ROOTCD/boot
385 }
387 distro_sizes()
388 {
389 echo "Build date : `date +%Y%m%d\ \at\ \%H:%M:%S`"
390 echo "Packages : `ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l`"
391 echo "Rootfs size : `du -csh $ROOTFS*/ | awk '{ s=$1 } END { print s }'`"
392 echo "Initramfs size : `du -csh $ROOTCD/boot/rootfs*.gz | awk '{ s=$1 } END { print s }'`"
393 echo "ISO image size : `du -sh $ISO_NAME.iso | awk '{ print $1 }'`"
394 echo "================================================================================"
395 echo "Image is ready: $ISO_NAME.iso"
396 echo ""
397 }
399 # Print ISO and rootfs size.
400 distro_stats()
401 {
402 echo ""
403 echo -e "\033[1mDistro statistics\033[0m ($DISTRO)"
404 echo "================================================================================"
405 distro_sizes
406 }
408 # Create an empty configuration file.
409 empty_config_file()
410 {
411 cat >> tazlito.conf << "EOF"
412 # tazlito.conf: Tazlito (SliTaz Live Tool)
413 # configuration file.
414 #
416 # Name of the ISO image to generate.
417 ISO_NAME=""
419 # ISO image volume name.
420 VOLUM_NAME="SliTaz"
422 # Name of the preparer.
423 PREPARED="$USER"
425 # Path to the packages repository and the packages.list.
426 PACKAGES_REPOSITORY=""
428 # Path to the distro tree to gen-distro from a
429 # list of packages.
430 DISTRO=""
432 # Path to the directory containing additional files
433 # to copy into the rootfs and rootcd of the LiveCD.
434 ADDFILES="$DISTRO/addfiles"
436 # Default answer for binary question (Y or N)
437 DEFAULT_ANSWER="ASK"
439 # Compression utility (lzma, gzip or none)
440 COMPRESSION="lzma"
441 EOF
442 }
444 # extract rootfs.gz somewhere
445 extract_rootfs()
446 {
447 (zcat $1 || unlzma -c $1 || cat $1) 2>/dev/null | \
448 (cd $2; cpio -idm > /dev/null)
449 }
451 # Remove duplicate files
452 mergefs()
453 {
454 echo -n "Merge $(basename $1) ($(du -hs $1 | awk '{ print $1}')) into "
455 echo -n "$(basename $2) ($(du -hs $2 | awk '{ print $1}'))"
456 # merge symlinks files and devices
457 ( cd $1; find ) | while read file; do
458 if [ -L $1/$file ]; then
459 [ -L $2/$file ] &&
460 [ "$(readlink $1/$file)" == "$(readlink $2/$file)" ] &&
461 rm -f $2/$file
462 elif [ -f $1/$file ]; then
463 [ -f $2/$file ] &&
464 cmp $1/$file $2/$file > /dev/null 2>&1 && rm -f $2/$file
465 [ -f $2/$file ] &&
466 [ "$(basename $file)" == "volatile.cpio.gz" ] &&
467 [ "$(dirname $(dirname $file))" == \
468 "./var/lib/tazpkg/installed" ] && rm -f $2/$file
469 elif [ -b $1/$file ]; then
470 [ -b $2/$file ] && rm -f $2/$file
471 elif [ -c $1/$file ]; then
472 [ -c $2/$file ] && rm -f $2/$file
473 fi
474 done
476 # cleanup directories
477 ( cd $1; find ) | while read file; do
478 if [ -d $1/$file ]; then
479 [ -d $2/$file ] && rmdir $2/$file 2> /dev/null
480 fi
481 done
482 true
483 status
484 }
486 cleanup_merge()
487 {
488 rm -rf $TMP_DIR
489 exit 1
490 }
492 human2cent()
493 {
494 case "$1" in
495 *k) echo $1 | sed 's/\(.*\).\(.\)k/\1\2/';;
496 *M) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)M/\1\2/') * 1024));;
497 *G) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)G/\1\2/') * 1024 * 1024));;
498 esac
499 }
501 cent2human()
502 {
503 if [ $1 -lt 10000 ]; then
504 echo "$(($1 / 10)).$(($1 % 10))k"
505 elif [ $1 -lt 10000000 ]; then
506 echo "$(($1 / 10240)).$(( ($1/1024) % 10))M"
507 else
508 echo "$(($1 / 10485760)).$(( ($1/1048576) % 10))G"
509 fi
510 }
512 get_size()
513 {
514 cat /var/lib/tazpkg/packages.list $TMP_DIR/packages.list 2>/dev/null | awk "{ \
515 if (/^$(echo $1 | sed 's/[$+.\]/\\&/g')$/) get=1; \
516 if (/installed/ && get == 1) { print ; get++ } \
517 }
518 END { if (get < 2) print \" 0.0k (0.0k installed)\" }" | \
519 sed 's/ *\(.*\) .\(.*\) installed./\1 \2/' | while read packed unpacked; do
520 echo "$(human2cent $packed) $(human2cent $unpacked)"
521 done
522 }
524 # Display package list with version, set packed_size and unpacked_size
525 get_pkglist()
526 {
527 packed_size=0; unpacked_size=0
528 grep -v ^# $FLAVORS_REPOSITORY/$1/packages.list > $TMP_DIR/flavor.pkg
529 while read pkg; do
530 set -- $(get_size $pkg)
531 packed_size=$(( $packed_size + $1 ))
532 unpacked_size=$(( $unpacked_size + $2 ))
533 for i in $(grep -hs ^$pkg /var/lib/tazpkg/packages.list \
534 $TMP_DIR/packages.list); do
535 echo $i
536 break
537 done
538 done < $TMP_DIR/flavor.pkg
539 rm -f $TMP_DIR/flavor.pkg
540 }
542 # Update isolinux config files for multiple rootfs
543 update_bootconfig()
544 {
545 echo -n "Updating boot config files..."
546 grep -l 'include common' $1/*.cfg | \
547 while read file ; do
548 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
549 if (/label/) label=$0;
550 else if (/kernel/) kernel=$0;
551 else if (/append/) {
552 i=index($0,"rootfs.gz");
553 append=substr($0,i+9);
554 }
555 else if (/include/) {
556 for (i = 1; i <= n; i++) {
557 print label i
558 print kernel;
559 initrd="initrd=/boot/rootfs" n ".gz"
560 for (j = n - 1; j >= i; j--) {
561 initrd=initrd ",/boot/rootfs" j ".gz";
562 }
563 printf "\tappend %s%s\n",initrd,append;
564 print "";
565 }
566 print;
567 }
568 else print;
569 }' < $file > $file.$$
570 mv -f $file.$$ $file
571 done
572 cat >> $1/common.cfg <<EOT
574 label slitaz
575 kernel /boot/isolinux/ifmem.c32
576 append$(echo $2 | awk '{
577 for (i=1; i<=NF; i++)
578 if (i % 2 == 0) printf " slitaz%d",i/2
579 else printf " %s",$i
580 }') noram
582 label noram
583 config noram.cfg
585 EOT
586 cat > $1/noram.cfg <<EOT
587 display isolinux.msg
588 say Not enough RAM to boot slitaz.
589 default reboot
590 label reboot
591 com32 reboot.c32
593 implicit 0
594 prompt 1
595 timeout 80
596 F1 help.txt
597 F2 options.txt
598 F3 isolinux.msg
599 F4 display.txt
600 F5 enhelp.txt
601 F6 enopts.txt
602 EOT
603 # Restore real label names
604 echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
605 while read pat; do
606 sed -i "s/slitaz$pat/" $1/common.cfg \
607 $(grep -l 'include common' $1/*.cfg)
608 done
609 status
610 }
612 # Install a missing package
613 install_package()
614 {
615 echo -n "Install package $1 "
616 [ -n "$2" ] && echo -n "for kernel $2 "
617 echo -n "?"
618 read answer
619 case "$answer" in
620 y*|Y*|o*|O*) yes y | tazpkg get-install $1;;
621 *) return 1;;
622 esac
623 }
625 # Check iso for loram transformation
626 check_iso_for_loram()
627 {
628 [ -s $TMP_DIR/iso/boot/rootfs.gz ] ||
629 [ -s $TMP_DIR/iso/boot/rootfs1.gz ]
630 }
632 # Build initial rootfs for loram ISO ram/cdrom/http
633 build_initfs()
634 {
635 urliso="mirror.slitaz.org mirror.switch.ch/ftp/mirror/slitaz \
636 download.tuxfamily.org/slitaz slitaz.c3sl.ufpr.br"
637 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
638 need_lib=false
639 mkdir -p $TMP_DIR/initfs/bin $TMP_DIR/initfs/dev $TMP_DIR/initfs/lib \
640 $TMP_DIR/initfs/mnt $TMP_DIR/initfs/proc $TMP_DIR/initfs/tmp
641 while [ ! -f /lib/modules/$version/kernel/fs/aufs/aufs.ko.gz ]; do
642 install_package linux-aufs $version || return 1
643 done
644 # bootfloppybox will need floppy.ko.gz, /dev/fd0, /dev/tty0
645 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.gz \
646 $TMP_DIR/initfs/lib 2> /dev/null
647 cp -a /dev/tty0 /dev/fd0 $TMP_DIR/initfs/dev 2> /dev/null
648 cp /lib/modules/$version/kernel/fs/aufs/aufs.ko.gz \
649 $TMP_DIR/initfs/lib
650 if [ -f /bin/cromfs-driver ]; then
651 cp /bin/cromfs-driver $TMP_DIR/initfs/bin
652 else
653 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
654 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.gz ]; do
655 install_package linux-squashfs $version || return 1
656 done
657 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.gz \
658 $TMP_DIR/initfs/lib
659 fi
660 if [ "$1" == "cdrom" ]; then
661 for i in $(ls /dev/[hs]d[a-f]); do
662 cp -a $i $TMP_DIR/initfs/dev
663 done
664 fi
665 if [ "$1" == "http" ]; then
666 mkdir $TMP_DIR/initfs/etc
667 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
668 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
669 sed -i 's|/sbin/||' $TMP_DIR/initfs/lib/udhcpc
670 cp -a /dev/fuse $TMP_DIR/initfs/dev
671 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
672 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/httpfs
673 else
674 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
675 need_lib=true
676 fi
677 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
678 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
679 else
680 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
681 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
682 cp -a /lib/librt* $TMP_DIR/initfs/lib
683 cp -a /lib/libdl* $TMP_DIR/initfs/lib
684 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
685 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
686 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
687 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
688 need_lib=true
689 fi
690 cd $TMP_DIR/initfs
691 echo "Get slitaz-release..."
692 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
693 ( zcat $i 2> /dev/null || unlzma -c $i) | \
694 cpio -idmu etc/slitaz-release > /dev/null
695 done
696 cd - > /dev/null
697 echo "Default urls for /iso/$(cat $TMP_DIR/initfs/etc/slitaz-release)/flavors/slitaz-loram-cdrom.iso /iso/$(cat $TMP_DIR/initfs/etc/slitaz-release)/flavors/slitaz-$(cat $TMP_DIR/initfs/etc/slitaz-release)-loram-cdrom.iso: $urliso"
698 echo -n "List of urls to insert: "
699 read -t 30 urliso2
700 urliso="$urliso2 $urliso"
701 fi
702 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
703 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
704 else
705 cp /bin/busybox $TMP_DIR/initfs/bin
706 need_lib=true
707 fi
708 for i in $($TMP_DIR/initfs/bin/busybox | awk \
709 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
710 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
711 done
712 for i in /dev/console /dev/loop* /dev/null /dev/tty /dev/zero \
713 /dev/kmem /dev/mem /dev/random /dev/urandom; do
714 cp -a $i $TMP_DIR/initfs/dev
715 done
716 $need_lib && for i in /lib/ld-* /lib/lib[cm].so* /lib/lib[cm]-* ; do
717 cp -a $i $TMP_DIR/initfs/lib
718 done
719 cat > $TMP_DIR/initfs/init <<EOTEOT
720 #!/bin/sh
722 getarg()
723 {
724 grep -q " \$1=" /proc/cmdline || return 1
725 eval \$2=\$(sed 's/.* loram=\\([^ ]*\\).*/\\1/' < /proc/cmdline)
726 return 0
727 }
729 copy_rootfs()
730 {
731 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
732 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
733 [ \$(( \$total / \$need )) -gt 1 ] || return 1
734 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
735 path=/mnt/
736 return 0
737 else
738 rm -f /mnt/rootfs*
739 return 1
740 fi
741 }
743 echo "Switching / to tmpfs..."
744 mount -t proc proc /proc
745 size="\$(grep rootfssize= < /proc/cmdline | \\
746 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
747 [ -n "\$size" ] || size="-o size=90%"
749 if [ -x /bin/httpfs ]; then # loram-http
751 while read var default; do
752 eval \$var=\$default
753 getarg \$var \$var
754 done <<EOT
755 eth eth0
756 dns 208.67.222.222,208.67.220.220
757 netmask 255.255.255.0
758 gw
759 ip
760 EOT
761 if [ -n "\$ip" ]; then
762 ifconfig \$eth \$ip netmask \$netmask up
763 route add default gateway \$gw
764 for i in \$(echo \$dns | sed 's/,/ /g'); do
765 echo "nameserver \$i" >> /etc/resolv.conf
766 done
767 else
768 udhcpc -f -q -s /lib/udhcpc -i \$eth
769 fi
770 for i in $urliso ; do
771 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
772 URLISO="\${URLISO}http://\$i/iso/\$(cat /etc/slitaz-release)/flavors/slitaz-loram-cdrom.iso,http://\$i/iso/\$(cat /etc/slitaz-release)/flavors/slitaz-\$(cat /etc/slitaz-release)-loram-cdrom.iso"
773 done
774 getarg urliso URLISO
775 DIR=fs
776 if getarg loram DIR; then
777 DEVICE=\${DIR%,*}
778 DIR=/\${DIR#*,}
779 fi
780 mount -t tmpfs \$size tmpfs /mnt
781 path2=/mnt/.httpfs/
782 path=/mnt/.cdrom/
783 mkdir -p /mnt/.rw \$path \$path2
784 while [ ! -d \$path/boot ]; do
785 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
786 httpfs \$i \$path2 && break
787 done
788 mount -o loop,ro -t iso9660 \$path2/*.iso \$path
789 done
790 #copy_rootfs && umount -d \$path && umount -d \$path2
792 elif [ -f \$(echo /rootfs*.gz | cut -f1 -d' ') ]; then # loram-ram
794 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
795 free=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
796 if [ \$(( \$total/\$free )) -gt 1 ] || ! mount -t tmpfs \$size tmpfs /mnt; then
797 echo "No tmpfs for /mnt"
798 mkdir -p /mnt/.rw
799 mount -t tmpfs tmpfs /mnt/.rw
800 mkdir -p /mnt/.rw/mnt/.rw
801 path=/
802 else
803 mkdir -p /mnt/.rw
804 path=/mnt/.
805 for i in rootfs* ; do
806 mv /\$i \$path\$i
807 done
808 fi
810 else # loram-cdrom
812 getarg cdrom DRIVE_NAME ||
813 DRIVE_NAME=\$(grep "drive name" < /proc/sys/dev/cdrom/info | cut -f 3)
814 DEVICE=/dev/\$DRIVE_NAME
815 DIR=fs
816 if getarg loram DIR; then
817 DEVICE=\${DIR%,*}
818 DIR=/\${DIR#*,}
819 fi
820 mount -t tmpfs \$size tmpfs /mnt
821 mkdir -p /mnt/.rw /mnt/.cdrom /mnt/mnt/.cdrom
822 i=0
823 while [ \$i -lt 5 ] && ! mount -r \$DEVICE /mnt/.cdrom; do
824 case "\$DEVICE" in
825 /dev/sd*|UUID=*|LABEL=*)
826 mount -t sysfs sysfs /sys
827 USBDELAY=\$(cat /sys/module/usb_storage/parameters/delay_use)
828 umount /sys
829 sleep \$((1+\$USBDELAY)) ;;
830 esac
831 i=\$((i+1))
832 done
833 path=/mnt/.cdrom/
834 copy_rootfs && umount -d /mnt/.cdrom
836 fi
838 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
839 umount /proc
840 branch=br=/mnt/.rw:/mnt/.cdrom/\$DIR
841 if [ ! -d /mnt/.cdrom/fs/etc ]; then
842 branch=br=/mnt/.rw
843 for i in \${path}rootfs* ; do
844 fs=\${i#*root}
845 branch=\$branch:/mnt/.\$fs
846 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs
847 if [ -f /bin/cromfs-driver ]; then
848 cromfs-driver \${path}root\$fs /mnt/.\$fs -o ro,dev,suid,allow_other
849 else
850 insmod /lib/squashfs.ko.gz 2> /dev/null
851 mount -o loop,ro -t squashfs \${path}root\$fs /mnt/.\$fs
852 fi
853 done
854 else
855 mkdir -p /mnt/.rw/mnt/.httpfs
856 fi
857 insmod /lib/aufs.ko.gz
858 mount -t aufs -o \$branch none /mnt
859 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
860 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
861 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
862 EOTEOT
863 chmod +x $TMP_DIR/initfs/init
864 ( cd $TMP_DIR/initfs ; find | busybox cpio -o -H newc 2> /dev/null) | \
865 lzma e $TMP_DIR/initfs.gz -si
866 rm -rf $TMP_DIR/initfs
867 rem=$(( $(stat -c "%s" $TMP_DIR/initfs.gz) % 4 ))
868 [ $rem -ne 0 ] &&
869 dd if=/dev/zero bs=1 count=$(( 4 - $rem )) >> $TMP_DIR/initfs.gz 2> /dev/null
870 return 0
871 }
873 # Move each initramfs to squashfs (or cromfs)
874 build_loram_rootfs()
875 {
876 rootfs_sizes=""
877 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
878 mkdir -p $TMP_DIR/fs
879 cd $TMP_DIR/fs
880 ( zcat $i 2> /dev/null || unlzma -c $i) | cpio -idm
881 cd - > /dev/null
882 rootfs=$TMP_DIR/$(basename $i)
883 if [ -x /usr/bin/mkcromfs ]; then
884 /usr/bin/mkcromfs -qq -f 262144 -b 16384 $TMP_DIR/fs $rootfs
885 else
886 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp xz -Xbcj x86
887 fi
888 cd $TMP_DIR
889 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
890 if [ "$1" != "cdrom" ]; then
891 ( cd $(dirname $rootfs); echo $(basename $rootfs) | \
892 cpio -o -H newc ) > $rootfs.cpio
893 rm -f $rootfs
894 mv $rootfs.cpio $rootfs
895 fi
896 cd - > /dev/null
897 rm -rf $TMP_DIR/fs
898 done
899 }
901 # Move meta boot configuration files to basic configuration files
902 # because meta loram flavor is useless when rootfs is not loaded in ram
903 unmeta_boot()
904 {
905 if [ -f $TMP_DIR/loramiso/boot/isolinux/noram.cfg ]; then
906 # We keep enough information to do unloram...
907 sed -i 's/label slitaz/label orgslitaz/' \
908 $TMP_DIR/loramiso/boot/isolinux/common.cfg
909 sed -i -e 's|=/boot/rootfs\(.*\).gz |=/boot/rootfs.gz |' \
910 -e 's|label slitaz1|label slitaz|' \
911 -e '/label slitaz[1-9]/{NNNd}' \
912 $TMP_DIR/loramiso/boot/isolinux/*.cfg
913 fi
914 }
916 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs.
917 # These squashfs may be loaded in ram a boot time.
918 # Rootfs are also copied to cdrom for tiny ramsize systems.
919 # Meta flavors are converted to normal flavors.
920 build_loram_cdrom()
921 {
922 build_initfs cdrom || return 1
923 build_loram_rootfs cdrom
924 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
925 mkdir $TMP_DIR/loramiso/fs
926 cd $TMP_DIR/loramiso/fs
927 for i in $( ls ../boot/root* | sort -r ) ; do
928 ( zcat $i 2> /dev/null || unlzma -c $i ) | cpio -idmu
929 rm -f $i
930 done
931 cd - > /dev/null
932 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
933 mv $TMP_DIR/rootfs*.gz $TMP_DIR/loramiso
934 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
935 unmeta_boot
936 create_iso $OUTPUT $TMP_DIR/loramiso
937 }
939 # Create http bootstrap to load and remove loram_cdrom
940 # Meta flavors are converted to normal flavors.
941 build_loram_http()
942 {
943 build_initfs http || return 1
944 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
945 rm -f $TMP_DIR/loramiso/boot/rootfs*
946 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
947 unmeta_boot
948 create_iso $OUTPUT $TMP_DIR/loramiso
949 }
951 # Update meta flavor selection sizes.
952 # Reduce sizes with rootfs gains.
953 update_metaiso_sizes()
954 {
955 local append="$(grep append $TMP_DIR/loramiso/boot/isolinux/common.cfg)"
956 local new
957 [ -n "$append" ] || return
958 set -- $append
959 shift
960 new=""
961 while [ -n "$2" ]; do
962 local s
963 case "$1" in
964 *G) s=$(( ${1%G} * 1024 * 1024 ));;
965 *M) s=$(( ${1%M} * 1024 ));;
966 *) s=${1%K};;
967 esac
968 rootfs_sizes=${rootfs_sizes#* }
969 for i in $rootfs_sizes ; do
970 s=$(( $s - $i ))
971 done
972 new="$new $s $2"
973 shift 2
974 done
975 sed -i "s/append .*/append$new $1/" $TMP_DIR/loramiso/boot/isolinux/common.cfg
976 }
978 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs.
979 # Meta flavor selection sizes are updated.
980 build_loram_ram()
981 {
982 build_initfs ram || return 1
983 build_loram_rootfs
984 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
985 rm -f $TMP_DIR/loramiso/boot/bzImage
986 ln $TMP_DIR/loramiso/boot/vmlinuz* $TMP_DIR/loramiso/boot/bzImage
987 rootfs=$(ls $TMP_DIR/rootfs* | sort | tail -n 1)
988 cat $rootfs >> $TMP_DIR/initfs.gz
989 mv $TMP_DIR/initfs.gz $rootfs
990 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
991 update_metaiso_sizes
992 create_iso $OUTPUT $TMP_DIR/loramiso
993 }
995 ####################
996 # Tazlito commands #
997 ####################
999 case "$COMMAND" in
1000 stats)
1001 # Tazlito general statistics from the config file.
1003 echo ""
1004 echo -e "\033[1mTazlito statistics\033[0m
1005 ===============================================================================
1006 Config file : $CONFIG_FILE
1007 ISO name : $ISO_NAME.iso
1008 Volume name : $VOLUM_NAME
1009 Prepared : $PREPARED
1010 Packages repository : $PACKAGES_REPOSITORY
1011 Distro directory : $DISTRO"
1012 if [ ! "$ADDFILES" = "" ] ; then
1013 echo -e "Additional files : $ADDFILES"
1014 fi
1015 echo "================================================================================"
1016 echo ""
1017 ;;
1018 list-addfiles)
1019 # Simple list of additional files in the rootfs
1020 echo ""
1021 cd $ADDFILES
1022 find rootfs -type f
1023 echo "" ;;
1024 gen-config)
1025 # Generate a new config file in the current dir or the specified
1026 # directory by $2.
1028 if [ -n "$2" ] ; then
1029 mkdir -p $2 && cd $2
1030 fi
1031 echo -n "Generating empty tazlito.conf..."
1032 empty_config_file
1033 status
1034 echo ""
1035 if [ -f "tazlito.conf" ] ; then
1036 echo "Configuration file is ready to edit."
1037 echo "File location : `pwd`/tazlito.conf"
1038 echo ""
1039 fi
1040 ;;
1041 configure)
1042 # Configure a tazlito.conf config file. Start by getting
1043 # a empty config file and sed it.
1045 if [ -f "tazlito.conf" ] ; then
1046 rm tazlito.conf
1047 else
1048 if test $(id -u) = 0 ; then
1049 cd /etc
1050 else
1051 echo "You must be root to configure the main config file or in"
1052 echo "the same directory of the file you want to configure."
1053 exit 0
1054 fi
1055 fi
1056 empty_config_file
1057 echo""
1058 echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
1059 echo "================================================================================"
1060 # ISO name.
1061 echo -n "ISO name : " ; read answer
1062 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1063 # Volume name.
1064 echo -n "Volume name : " ; read answer
1065 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1066 # Packages repository.
1067 echo -n "Packages repository : " ; read answer
1068 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1069 # Distro path.
1070 echo -n "Distro path : " ; read answer
1071 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1072 echo "================================================================================"
1073 echo "Config file is ready to use."
1074 echo "You can now extract an ISO or generate a distro."
1075 echo ""
1076 ;;
1077 gen-iso)
1078 # Simply generate a new iso.
1080 check_root
1081 verify_rootcd
1082 gen_livecd_isolinux
1083 distro_stats
1084 ;;
1085 gen-initiso)
1086 # Simply generate a new initramfs with a new iso.
1088 check_root
1089 verify_rootcd
1090 gen_initramfs $ROOTFS
1091 gen_livecd_isolinux
1092 distro_stats
1093 ;;
1094 extract-distro)
1095 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1097 check_root
1098 ISO_IMAGE=$2
1099 if [ -z "$ISO_IMAGE" ] ; then
1100 echo -e "\nPlease specify the path to the ISO image."
1101 echo -e "Example : `basename $0` image.iso /path/target\n"
1102 exit 0
1103 fi
1104 # Set the distro path by checking for $3 on cmdline.
1105 if [ -n "$3" ] ; then
1106 TARGET=$3
1107 else
1108 TARGET=$DISTRO
1109 fi
1110 # Exit if existing distro is found.
1111 if [ -d "$TARGET/rootfs" ] ; then
1112 echo -e "\nA rootfs exists in : $TARGET"
1113 echo -e "Please clean the distro tree or change directory path.\n"
1114 exit 0
1115 fi
1116 echo ""
1117 echo -e "\033[1mTazlito extracting :\033[0m `basename $ISO_IMAGE`"
1118 echo "================================================================================"
1119 # Start to mount the ISO.
1120 echo ""
1121 echo "Mounting ISO image..."
1122 mkdir -p $TMP_DIR
1123 # Get ISO file size.
1124 isosize=`du -sh $ISO_IMAGE | cut -f1`
1125 mount -o loop $ISO_IMAGE $TMP_DIR
1126 sleep 2
1127 # Prepare target dir, copy the kernel and the rootfs.
1128 mkdir -p $TARGET/rootfs
1129 mkdir -p $TARGET/rootcd/boot
1130 echo -n "Copying the Linux kernel..."
1131 if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
1132 ln $TARGET/rootcd/boot/vmlinuz* $TARGET/rootcd/boot/bzImage
1133 else
1134 cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
1135 fi
1136 status
1137 echo -n "Copying isolinux files..."
1138 cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
1139 for i in $(ls $TMP_DIR); do
1140 [ "$i" = "boot" ] && continue
1141 cp -a $TMP_DIR/$i $TARGET/rootcd
1142 done
1143 status
1144 if [ -d $TMP_DIR/boot/syslinux ]; then
1145 echo -n "Copying syslinux files..."
1146 cp -a $TMP_DIR/boot/syslinux $TARGET/rootcd/boot
1147 status
1148 fi
1149 if [ -d $TMP_DIR/boot/extlinux ]; then
1150 echo -n "Copying extlinux files..."
1151 cp -a $TMP_DIR/boot/extlinux $TARGET/rootcd/boot
1152 status
1153 fi
1154 if [ -d $TMP_DIR/boot/grub ]; then
1155 echo -n "Copying GRUB files..."
1156 cp -a $TMP_DIR/boot/grub $TARGET/rootcd/boot
1157 status
1158 fi
1160 echo -n "Copying the rootfs..."
1161 cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
1162 status
1163 # Extract initramfs.
1164 cd $TARGET/rootfs
1165 echo -n "Extracting the rootfs... "
1166 extract_rootfs ../rootcd/boot/rootfs.gz $TARGET/rootfs
1167 # unpack /usr
1168 for i in etc/tazlito/*.extract; do
1169 [ -f "$i" ] && . $i ../rootcd
1170 done
1171 # Umount and remove temp directory and cd to $TARGET to get stats.
1172 umount $TMP_DIR && rm -rf $TMP_DIR
1173 cd ..
1174 echo ""
1175 echo "================================================================================"
1176 echo "Extracted : `basename $ISO_IMAGE` ($isosize)"
1177 echo "Distro tree : `pwd`"
1178 echo "Rootfs size : `du -sh rootfs`"
1179 echo "Rootcd size : `du -sh rootcd`"
1180 echo "================================================================================"
1181 echo ""
1182 ;;
1183 list-flavors)
1184 # Show available flavors.
1185 if [ ! -s /etc/tazlito/flavors.list -o "$2" == "--recharge" ]; then
1186 download flavors.list -O - > /etc/tazlito/flavors.list
1187 fi
1188 echo ""
1189 echo -e "\033[1mList of flavors\033[0m"
1190 echo "================================================================================"
1191 cat /etc/tazlito/flavors.list
1192 echo ""
1193 ;;
1194 show-flavor)
1195 # Show flavor description.
1196 FLAVOR=${2%.flavor}
1197 if [ ! -f "$FLAVOR.flavor" ]; then
1198 echo "File $FLAVOR.flavor not found."
1199 exit 1
1200 fi
1201 mkdir $TMP_DIR
1202 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i > /dev/null)
1203 if [ "$3" = "--brief" ]; then
1204 if [ "$4" != "--noheader" ]; then
1205 echo "Name ISO Rootfs Description"
1206 echo "================================================================================"
1207 fi
1208 printf "%-16.16s %6.6s %6.6s %s\n" "$FLAVOR" \
1209 "$(field ISO $TMP_DIR/$FLAVOR.desc)" \
1210 "$(field 'Rootfs size' $TMP_DIR/$FLAVOR.desc)" \
1211 "$(grep ^Description $TMP_DIR/$FLAVOR.desc | cut -d: -f2)"
1212 else
1213 echo "================================================================================"
1214 cat $TMP_DIR/$FLAVOR.desc
1215 fi
1216 rm -Rf $TMP_DIR
1217 ;;
1218 gen-liveflavor)
1219 # Generate a new flavor from the live system.
1220 FLAVOR=${2%.flavor}
1221 DESC=""
1222 case "$FLAVOR" in
1223 '') echo -n "Flavor name : "
1224 read FLAVOR
1225 [ -z "$FLAVOR" ] && exit 1;;
1226 -?|-h*|--help) echo -e "
1228 SliTaz Live Tool - Version: $VERSION
1229 \033[1mUsage: \033[0m `basename $0` gen-liveflavor flavor-name [flavor-patch-file]
1230 \033[1mflavor-patch-file format: \033[0m
1231 code data
1232 + package to add
1233 - package to remove
1234 ! non-free package to add
1235 ? display message
1236 @ flavor description
1238 \033[1mExample: \033[0m
1239 @ Developer tools for slitaz maintainers
1240 + slitaz-toolchain
1241 + mercurial
1243 exit 1;;
1244 esac
1245 mv /etc/tazlito/distro-packages.list \
1246 /etc/tazlito/distro-packages.list.$$ 2> /dev/null
1247 rm -f distro-packages.list non-free.list 2> /dev/null
1248 tazpkg recharge
1249 [ -n "$3" ] && while read action pkg; do
1250 case "$action" in
1251 +) yes | tazpkg get-install $pkg;;
1252 -) yes | tazpkg remove $pkg;;
1253 !) echo $pkg >> non-free.list;;
1254 @) DESC="$pkg";;
1255 \?) echo -en "$pkg"; read action;;
1256 esac
1257 done < $3
1258 yes '' | tazlito gen-distro
1259 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
1260 mv /etc/tazlito/distro-packages.list.$$ \
1261 /etc/tazlito/distro-packages.list 2> /dev/null
1262 ;;
1263 gen-flavor)
1264 # Generate a new flavor from the last iso image generated.
1265 FLAVOR=${2%.flavor}
1266 echo ""
1267 echo -e "\033[1mFlavor generation\033[0m"
1268 echo "================================================================================"
1269 if [ -z "$FLAVOR" ]; then
1270 echo -n "Flavor name : "
1271 read FLAVOR
1272 [ -z "$FLAVOR" ] && exit 1
1273 fi
1274 check_rootfs
1275 FILES="$FLAVOR.pkglist"
1276 echo -n "Creating file $FLAVOR.flavor..."
1277 for i in rootcd rootfs; do
1278 if [ -d "$ADDFILES/$i" ] ; then
1279 FILES="$FILES\n$FLAVOR.$i"
1280 ( cd "$ADDFILES/$i"; find . | \
1281 cpio -o -H newc 2> /dev/null | gzip -9 ) > $FLAVOR.$i
1282 fi
1283 done
1284 status
1285 answer=`grep -s ^Description $FLAVOR.desc`
1286 answer=${answer#Description : }
1287 if [ -z "$answer" ]; then
1288 echo -n "Description : "
1289 read answer
1290 fi
1291 echo -n "Compressing flavor $FLAVOR..."
1292 echo "Flavor : $FLAVOR" > $FLAVOR.desc
1293 echo "Description : $answer" >> $FLAVOR.desc
1294 ( cd $DISTRO; distro_sizes) >> $FLAVOR.desc
1295 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2> /dev/null
1296 for i in $(ls $ROOTFS$INSTALLED); do
1297 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
1298 EXTRAVERSION=""
1299 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
1300 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
1301 if [ "$CATEGORY" = "non-free" -a "${i%%-*}" != "get" ]
1302 then
1303 echo "$i" >> $FLAVOR.nonfree
1304 else
1305 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
1306 fi
1307 done
1308 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
1309 for i in $LOCALSTATE/undigest/*/mirror ; do
1310 [ -s $i ] && cat $i >> $FLAVOR.mirrors
1311 done
1312 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
1313 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | \
1314 gzip -9 > $FLAVOR.flavor
1315 rm `echo -e $FILES`
1316 status
1317 echo "================================================================================"
1318 echo "Flavor size : `du -sh $FLAVOR.flavor`"
1319 echo ""
1320 ;;
1321 upgrade-flavor)
1322 # Update package list to the latest versions available.
1323 FLAVOR=${2%.flavor}
1324 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1325 mkdir $TMP_DIR
1326 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1327 echo -n "Updating $FLAVOR package list..."
1328 [ -s /var/lib/tazpkg/packages.list ] || tazpkg recharge
1329 packed_size=0; unpacked_size=0
1330 while read org; do
1331 i=0
1332 pkg=$org
1333 while ! grep -q ^$pkg$ /var/lib/tazpkg/packages.txt; do
1334 pkg=${pkg%-*}
1335 i=$(($i + 1))
1336 [ $i -gt 5 ] && break;
1337 done
1338 set -- $(get_size $pkg)
1339 packed_size=$(( $packed_size + $1 ))
1340 unpacked_size=$(( $unpacked_size + $2 ))
1341 for i in $(grep ^$pkg /var/lib/tazpkg/packages.list); do
1342 echo $i
1343 break
1344 done
1345 done < $TMP_DIR/$FLAVOR.pkglist \
1346 > $TMP_DIR/$FLAVOR.pkglist.$$
1347 mv -f $TMP_DIR/$FLAVOR.pkglist.$$ $TMP_DIR/$FLAVOR.pkglist
1348 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1349 packed_size=$(($packed_size \
1350 + $(cat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1351 unpacked_size=$(($unpacked_size \
1352 + $(zcat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1353 fi
1354 # Estimate lzma
1355 packed_size=$(($packed_size * 2 / 3))
1356 iso_size=$(( $packed_size + 26000 ))
1357 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1358 iso_size=$(($iso_size \
1359 + $(zcat $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1360 fi
1361 sed -i -e '/Image is ready/d' \
1362 -e "s/Rootfs size\( *:\) \(.*\)/Rootfs size\1 $(cent2human $unpacked_size) (estimated)/" \
1363 -e "s/Initramfs size\( *:\) \(.*\)/Initramfs size\1 $(cent2human $packed_size) (estimated)/" \
1364 -e "s/ISO image size\( *:\) \(.*\)/ISO image size\1 $(cent2human $iso_size) (estimated)/" \
1365 -e "s/date\( *:\) \(.*\)/date\1 $(date +%Y%m%d\ \at\ \%H:%M:%S)/" \
1366 $TMP_DIR/$FLAVOR.desc
1367 ( cd $TMP_DIR ; ls | cpio -o -H newc ) | gzip -9 > \
1368 $FLAVOR.flavor
1369 status
1370 rm -Rf $TMP_DIR
1371 fi
1372 ;;
1373 extract-flavor)
1374 # Extract a flavor into $FLAVORS_REPOSITORY.
1375 FLAVOR=${2%.flavor}
1376 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1377 mkdir $TMP_DIR
1378 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1379 echo -n "Extracting $FLAVOR..."
1380 rm -rf $FLAVORS_REPOSITORY/$FLAVOR 2> /dev/null
1381 mkdir -p $FLAVORS_REPOSITORY/$FLAVOR
1382 echo "FLAVOR=\"$FLAVOR\"" > $FLAVORS_REPOSITORY/$FLAVOR/receipt
1383 grep ^Description $TMP_DIR/$FLAVOR.desc | \
1384 sed 's/.*: \(.*\)$/SHORT_DESC="\1"/' >> \
1385 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1386 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc && \
1387 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1388 sed 's/.*: \(.*\)$/ROOTFS_SELECTION="\1"/' >> \
1389 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1390 grep '^Rootfs size' $TMP_DIR/$FLAVOR.desc | \
1391 sed 's/.*: \(.*\)$/ROOTFS_SIZE="\1"/' >> \
1392 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1393 grep ^Initramfs $TMP_DIR/$FLAVOR.desc | \
1394 sed 's/.*: \(.*\)$/INITRAMFS_SIZE="\1"/' >> \
1395 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1396 grep ^ISO $TMP_DIR/$FLAVOR.desc | \
1397 sed 's/.*: \(.*\)$/ISO_SIZE="\1"/' >> \
1398 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1399 for i in rootcd rootfs; do
1400 [ -f $TMP_DIR/$FLAVOR.$i ] || continue
1401 mkdir $FLAVORS_REPOSITORY/$FLAVOR/$i
1402 zcat $TMP_DIR/$FLAVOR.$i | \
1403 (cd $FLAVORS_REPOSITORY/$FLAVOR/$i; \
1404 cpio -idm > /dev/null)
1405 done
1406 [ -s $TMP_DIR/$FLAVOR.mirrors ] &&
1407 cp $TMP_DIR/$FLAVOR.mirrors \
1408 $FLAVORS_REPOSITORY/$FLAVOR/mirrors
1409 [ -s /var/lib/tazpkg/packages.list ] || tazpkg recharge
1410 while read org; do
1411 i=0
1412 pkg=$org
1413 while ! grep -q ^$pkg$ /var/lib/tazpkg/packages.txt; do
1414 pkg=${pkg%-*}
1415 i=$(($i + 1))
1416 [ $i -gt 5 ] && break;
1417 done
1418 echo $pkg
1419 done < $TMP_DIR/$FLAVOR.pkglist \
1420 > $FLAVORS_REPOSITORY/$FLAVOR/packages.list
1421 status
1422 rm -Rf $TMP_DIR
1423 fi
1424 ;;
1425 pack-flavor)
1426 # Create a flavor from $FLAVORS_REPOSITORY.
1427 FLAVOR=${2%.flavor}
1428 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1429 mkdir $TMP_DIR
1430 echo -n "Creating flavor $FLAVOR..."
1431 [ -s /var/lib/tazpkg/packages.list ] || tazpkg recharge
1432 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/mirrors ]; then
1433 cp $FLAVORS_REPOSITORY/$FLAVOR/mirrors \
1434 $TMP_DIR/$FLAVOR.mirrors
1435 for i in $(cat $TMP_DIR/$FLAVOR.mirrors); do
1436 wget -O - $i/packages.list >> $TMP_DIR/packages.list
1437 done
1438 fi
1439 [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ] &&
1440 get_pkglist $FLAVOR > $TMP_DIR/$FLAVOR.pkglist
1441 if grep -q ^ROOTFS_SELECTION \
1442 $FLAVORS_REPOSITORY/$FLAVOR/receipt; then
1443 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1444 set -- $ROOTFS_SELECTION
1445 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
1446 [ -f $FLAVORS_REPOSITORY/$2/packages.list ] ||
1447 tazlito extract-flavor $2
1448 get_pkglist $2 > $TMP_DIR/$FLAVOR.pkglist
1449 for i in rootcd rootfs; do
1450 mkdir $TMP_DIR/$i
1451 # Copy extra files from the first flavor
1452 [ -d $FLAVORS_REPOSITORY/$2/$i ] &&
1453 cp -a $FLAVORS_REPOSITORY/$2/$i $TMP_DIR
1454 # Overload extra files by meta flavor
1455 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] &&
1456 cp -a $FLAVORS_REPOSITORY/$FLAVOR/$i $TMP_DIR
1457 [ -n "$(ls $TMP_DIR/$i)" ] &&
1458 ( cd $TMP_DIR/$i ; find . | cpio -o -H newc 2> /dev/null ) | \
1459 gzip -9 >$TMP_DIR/$FLAVOR.$i
1460 rm -rf $TMP_DIR/$i
1461 done
1462 else
1463 for i in rootcd rootfs; do
1464 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] || \
1465 continue
1466 ( cd $FLAVORS_REPOSITORY/$FLAVOR/$i ; \
1467 find . | cpio -o -H newc 2> /dev/null ) | \
1468 gzip -9 >$TMP_DIR/$FLAVOR.$i
1469 done
1470 fi
1471 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1472 packed_size=$(($packed_size \
1473 + $(cat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1474 unpacked_size=$(($unpacked_size \
1475 + $(zcat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1476 fi
1477 # Estimate lzma
1478 packed_size=$(($packed_size * 2 / 3))
1479 iso_size=$(( $packed_size + 26000 ))
1480 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1481 iso_size=$(($iso_size \
1482 + $(zcat $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1483 fi
1484 VERSION=""
1485 MAINTAINER=""
1486 ROOTFS_SELECTION=""
1487 ROOTFS_SIZE="$(cent2human $unpacked_size) (estimated)"
1488 INITRAMFS_SIZE="$(cent2human $packed_size) (estimated)"
1489 ISO_SIZE="$(cent2human $iso_size) (estimated)"
1490 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1491 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1492 Flavor : $FLAVOR
1493 Description : $SHORT_DESC
1494 EOT
1495 [ -n "$VERSION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1496 Version : $VERSION
1497 EOT
1498 [ -n "$MAINTAINER" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1499 Maintainer : $MAINTAINER
1500 EOT
1501 [ -n "$FRUGAL_RAM" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1502 LiveCD RAM size : $FRUGAL_RAM
1503 EOT
1504 [ -n "$ROOTFS_SELECTION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1505 Rootfs list : $ROOTFS_SELECTION
1506 EOT
1507 cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1508 Build date : $(date +%Y%m%d\ \at\ \%H:%M:%S)
1509 Packages : $(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l)
1510 Rootfs size : $ROOTFS_SIZE
1511 Initramfs size : $INITRAMFS_SIZE
1512 ISO image size : $ISO_SIZE
1513 ================================================================================
1515 EOT
1516 rm -f $TMP_DIR/packages.list
1517 ( cd $TMP_DIR ; ls | cpio -o -H newc 2> /dev/null) | \
1518 gzip -9 > $FLAVOR.flavor
1519 status
1520 rm -Rf $TMP_DIR
1521 else
1522 echo "No $FLAVOR flavor in $FLAVORS_REPOSITORY."
1523 fi
1524 ;;
1525 get-flavor)
1526 # Get a flavor's files and prepare for gen-distro.
1527 FLAVOR=${2%.flavor}
1528 echo ""
1529 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1530 echo -n "Cleaning $DISTRO..."
1531 rm -R $DISTRO 2> /dev/null
1532 mkdir -p $DISTRO
1533 status
1534 mkdir $TMP_DIR
1535 echo -n "Extracting flavor $FLAVOR.flavor... "
1536 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1537 echo -n "Creating distro-packages.list..."
1538 mv $TMP_DIR/$FLAVOR.nonfree non-free.list 2> /dev/null
1539 mv $TMP_DIR/$FLAVOR.pkglist distro-packages.list
1540 status
1541 for i in rootcd rootfs; do
1542 if [ -f $TMP_DIR/$FLAVOR.$i ]; then
1543 echo -n "Adding $i... "
1544 mkdir -p "$ADDFILES/$i"
1545 zcat $TMP_DIR/$FLAVOR.$i | \
1546 ( cd "$ADDFILES/$i"; cpio -id > /dev/null)
1547 fi
1548 done
1549 if [ -s $TMP_DIR/$FLAVOR.mirrors ]; then
1550 n=""
1551 while read line; do
1552 mkdir -p $LOCALSTATE/undigest/$FLAVOR$n
1553 echo "$line" > $LOCALSTATE/undigest/$FLAVOR$n/mirror
1554 n=$(( $n + 1 ))
1555 done < $TMP_DIR/$FLAVOR.mirrors
1556 tazpkg recharge
1557 fi
1558 rm -f /etc/tazlito/rootfs.list
1559 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc &&
1560 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1561 sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
1562 echo -n "Updating tazlito.conf..."
1563 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
1564 cat tazlito.conf | grep -v "^#VOLUM_NAME" | \
1565 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $FLAVOR\"\\n#VOLUM_NA/" \
1566 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
1567 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$FLAVOR\"/" tazlito.conf
1568 status
1569 rm -Rf $TMP_DIR
1570 fi
1571 echo ""
1572 ;;
1573 check-list)
1574 # Use current packages list in $PWD by default.
1575 DISTRO_PKGS_LIST=distro-packages.list
1576 [ -d "$2" ] && DISTRO_PKGS_LIST=$2/distro-packages.list
1577 [ -f "$2" ] && DISTRO_PKGS_LIST=$2
1578 [ ! -f $DISTRO_PKGS_LIST ] && echo "No packages list found." && exit 0
1579 echo ""
1580 echo -e "\033[1mLiveCD packages list check\033[0m"
1581 echo "================================================================================"
1582 for pkg in `cat $DISTRO_PKGS_LIST`
1583 do
1584 if ! grep -q "$pkg" /var/lib/tazpkg/packages.list; then
1585 echo "Update: $pkg"
1586 up=$(($up + 1))
1587 fi
1588 done
1589 [ -z $up ] && echo -e "List is up-to-date\n" && exit 0
1590 echo "================================================================================"
1591 echo -e "Updates: $up\n" ;;
1592 gen-distro)
1593 # Generate a live distro tree with a set of packages.
1595 check_root
1597 # Check if a package list was specified on cmdline.
1598 LIST_NAME="distro-packages.list"
1599 CDROM=""
1600 while [ -n "$2" ]; do
1601 case "$2" in
1602 --iso=*)
1603 CDROM="-o loop ${2#--iso=}"
1604 ;;
1605 --cdrom)
1606 CDROM="/dev/cdrom"
1607 ;;
1608 --force)
1609 DELETE_ROOTFS="true"
1610 ;;
1611 *) if [ ! -f "$2" ] ; then
1612 echo -e "\nUnable to find the specified packages list."
1613 echo -e "List name : $2\n"
1614 exit 1
1615 fi
1616 LIST_NAME=$2
1617 ;;
1618 esac
1619 shift
1620 done
1622 if [ -d $ROOTFS ] ; then
1623 # Delete $ROOTFS if --force is set on command line
1624 if [ ! -z $DELETE_ROOTFS ]; then
1625 rm -rf $ROOTFS
1626 unset $DELETE_ROOTFS
1627 else
1628 echo -e "\nA rootfs exists in : $DISTRO"
1629 echo -e "Please clean the distro tree or change directory path.\n"
1630 exit 0
1631 fi
1632 fi
1633 if [ ! -f "$LIST_NAME" -a -d $INSTALLED ] ; then
1634 # Build list with installed packages
1635 for i in $(ls $INSTALLED); do
1636 eval $(grep ^VERSION= $INSTALLED/$i/receipt)
1637 EXTRAVERSION=""
1638 eval $(grep ^EXTRAVERSION= $INSTALLED/$i/receipt)
1639 echo "$i-$VERSION$EXTRAVERSION" >> $LIST_NAME
1640 done
1641 fi
1642 # Exit if no list name.
1643 if [ ! -f "$LIST_NAME" ]; then
1644 echo -e "\nNo packages list found or specified. Please read the docs.\n"
1645 exit 0
1646 fi
1647 # Start generation.
1648 echo ""
1649 echo -e "\033[1mTazlito generating a distro\033[0m"
1650 echo "================================================================================"
1651 # Misc checks
1652 [ -n "$PACKAGES_REPOSITORY" ] || PACKAGES_REPOSITORY="."
1653 [ -d $PACKAGES_REPOSITORY ] || mkdir -p $PACKAGES_REPOSITORY
1654 # Get the list of packages using cat for a file list.
1655 LIST=`cat $LIST_NAME`
1656 # Verify if all packages in list are present in $PACKAGES_REPOSITORY.
1657 REPACK=""
1658 DOWNLOAD=""
1659 for pkg in $LIST
1660 do
1661 [ "$pkg" = "" ] && continue
1662 pkg=${pkg%.tazpkg}
1663 [ -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] && continue
1664 PACKAGE=$(installed_package_name $pkg)
1665 [ -n "$PACKAGE" -a "$REPACK" = "y" ] && continue
1666 [ -z "$PACKAGE" -a -n "$DOWNLOAD" ] && continue
1667 echo -e "\nUnable to find $pkg in the repository."
1668 echo -e "Path : $PACKAGES_REPOSITORY\n"
1669 if [ -n "$PACKAGE" -a -z "$REPACK" ]; then
1670 yesorno "Repack packages from rootfs (y/N) ? "
1671 REPACK="$answer"
1672 [ "$answer" = "y" ] || REPACK="n"
1673 [ "$DOWNLOAD" = "y" ] && break
1674 fi
1675 if [ -f $MIRROR -a -z "$DOWNLOAD" ]; then
1676 yesorno "Download packages from mirror (Y/n) ? "
1677 DOWNLOAD="$answer"
1678 if [ "$answer" = "n" ]; then
1679 [ -z "$PACKAGE" ] && exit 1
1680 else
1681 DOWNLOAD="y"
1682 [ -n "$REPACK" ] && break
1683 fi
1684 fi
1685 [ "$REPACK" = "n" -a "$DOWNLOAD" = "n" ] && exit 1
1686 done
1688 # Mount cdrom to be able to repack boot-loader packages
1689 if [ ! -e /boot -a -n "$CDROM" ]; then
1690 mkdir $TMP_MNT
1691 if mount -r $CDROM $TMP_MNT 2> /dev/null; then
1692 ln -s $TMP_MNT/boot /
1693 if [ ! -d "$ADDFILES/rootcd" ] ; then
1694 mkdir -p $ADDFILES/rootcd
1695 for i in $(ls $TMP_MNT); do
1696 [ "$i" = "boot" ] && continue
1697 cp -a $TMP_MNT/$i $ADDFILES/rootcd
1698 done
1699 fi
1700 else
1701 rmdir $TMP_MNT
1702 fi
1703 fi
1705 # Root fs stuff.
1706 echo "Preparing the rootfs directory..."
1707 mkdir -p $ROOTFS
1708 sleep 2
1709 for pkg in $LIST
1710 do
1711 [ "$pkg" = "" ] && continue
1712 # First copy and extract the package in tmp dir.
1713 pkg=${pkg%.tazpkg}
1714 PACKAGE=$(installed_package_name $pkg)
1715 mkdir -p $TMP_DIR
1716 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1717 # Look for package in cache
1718 if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
1719 ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
1720 # Look for package in running distribution
1721 elif [ -n "$PACKAGE" -a "$REPACK" = "y" ]; then
1722 tazpkg repack $PACKAGE && \
1723 mv $pkg.tazpkg $PACKAGES_REPOSITORY
1724 fi
1725 fi
1726 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1727 # Get package from mirror
1728 [ "$DOWNLOAD" = "y" ] && \
1729 download $pkg.tazpkg && \
1730 mv $pkg.tazpkg $PACKAGES_REPOSITORY
1731 fi
1732 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1733 echo "Missing package $pkg."
1734 cleanup
1735 exit 1
1736 fi
1737 done
1738 if [ -f non-free.list ]; then
1739 echo "Preparing non-free packages..."
1740 cp non-free.list $ROOTFS/etc/tazlito/non-free.list
1741 for pkg in $(cat non-free.list); do
1742 if [ ! -d $INSTALLED/$pkg ]; then
1743 if [ ! -d $INSTALLED/get-$pkg ]; then
1744 tazpkg get-install get-$pkg
1745 fi
1746 get-$pkg
1747 fi
1748 tazpkg repack $pkg
1749 pkg=$(ls $pkg*.tazpkg)
1750 grep -q "^$pkg$" $LIST_NAME || \
1751 echo $pkg >>$LIST_NAME
1752 mv $pkg $PACKAGES_REPOSITORY
1753 done
1754 fi
1755 echo ""
1756 cp $LIST_NAME $DISTRO/distro-packages.list
1757 sed 's/\(.*\)/\1.tazpkg/' < $DISTRO/distro-packages.list > $DISTRO/list-packages
1758 cd $PACKAGES_REPOSITORY
1759 yes y | tazpkg install-list \
1760 $DISTRO/list-packages --root=$ROOTFS
1761 cd $DISTRO
1762 cp distro-packages.list $ROOTFS/etc/tazlito
1763 # Copy all files from $ADDFILES/rootfs to the rootfs.
1764 if [ -d "$ADDFILES/rootfs" ] ; then
1765 echo -n "Copying addfiles content to the rootfs... "
1766 cp -a $ADDFILES/rootfs/* $ROOTFS
1767 status
1768 fi
1769 echo "Root file system is generated..."
1770 # Root CD part.
1771 echo -n "Preparing the rootcd directory..."
1772 mkdir -p $ROOTCD
1773 status
1774 # Move the boot dir with the Linux kernel from rootfs.
1775 # The boot dir goes directly on the CD.
1776 if [ -d "$ROOTFS/boot" ] ; then
1777 echo -n "Moving the boot directory..."
1778 mv $ROOTFS/boot $ROOTCD
1779 cd $ROOTCD/boot
1780 ln vmlinuz-* bzImage
1781 status
1782 fi
1783 cd $DISTRO
1784 # Copy all files from $ADDFILES/rootcd to the rootcd.
1785 if [ -d "$ADDFILES/rootcd" ] ; then
1786 echo -n "Copying addfiles content to the rootcd... "
1787 cp -a $ADDFILES/rootcd/* $ROOTCD
1788 status
1789 fi
1790 # Execute the distro script used to perform tasks in the rootfs
1791 # before compression. Give rootfs path in arg
1792 [ -z $DISTRO_SCRIPT ] && DISTRO_SCRIPT=$TOP_DIR/distro.sh
1793 if [ -x $DISTRO_SCRIPT ]; then
1794 echo "Executing distro script..."
1795 sh $DISTRO_SCRIPT $DISTRO
1796 fi
1797 if [ -s /etc/tazlito/rootfs.list ]; then
1798 [ -f $ROOTCD/boot/isolinux/ifmem.c32 ] ||
1799 cp /boot/isolinux/ifmem.c32 $ROOTCD/boot/isolinux
1800 n=0
1801 last=$ROOTFS
1802 while read flavor; do
1803 n=$(($n+1))
1804 echo "Building $flavor rootfs..."
1805 download $flavor.flavor
1806 zcat $flavor.flavor | cpio -i \
1807 $flavor.pkglist $flavor.rootfs
1808 sed 's/.*/&.tazpkg/' < $flavor.pkglist \
1809 > $DISTRO/list-packages0$n
1810 mkdir ${ROOTFS}0$n
1811 cd $PACKAGES_REPOSITORY
1812 yes y | tazpkg install-list \
1813 $DISTRO/list-packages0$n --root=${ROOTFS}0$n
1814 rm -rf ${ROOTFS}0$n/boot
1815 status
1816 cd $DISTRO
1817 if [ -s $flavor.rootfs ]; then
1818 echo "Add $flavor rootfs extra files..."
1819 zcat $flavor.rootfs | \
1820 ( cd ${ROOTFS}0$n ; cpio -idmu )
1821 fi
1822 mv $flavor.pkglist ${ROOTFS}0$n/etc/tazlito/distro-packages.list
1823 rm -f $flavor.flavor install-list
1824 mergefs ${ROOTFS}0$n $last
1825 last=${ROOTFS}0$n
1826 done <<EOT
1827 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
1828 EOT
1829 i=$(($n+1))
1830 while [ $n -gt 0 ]; do
1831 mv ${ROOTFS}0$n ${ROOTFS}$i
1832 echo "Compression ${ROOTFS}0$n ($(du -hs ${ROOTFS}$i | awk '{ print $1 }')) ..."
1833 gen_initramfs ${ROOTFS}$i
1834 n=$(($n-1))
1835 i=$(($i-1))
1836 done
1837 mv $ROOTFS ${ROOTFS}$i
1838 gen_initramfs ${ROOTFS}$i
1839 update_bootconfig $ROOTCD/boot/isolinux \
1840 "$(cat /etc/tazlito/rootfs.list)"
1841 else
1842 # Initramfs and ISO image stuff.
1843 gen_initramfs $ROOTFS
1844 fi
1845 gen_livecd_isolinux
1846 distro_stats
1847 cleanup
1848 ;;
1849 clean-distro)
1850 # Remove old distro tree.
1852 check_root
1853 echo ""
1854 echo -e "\033[1mCleaning :\033[0m $DISTRO"
1855 echo "================================================================================"
1856 if [ -d "$DISTRO" ] ; then
1857 if [ -d "$ROOTFS" ] ; then
1858 echo -n "Removing the rootfs..."
1859 rm -f $DISTRO/$INITRAMFS
1860 rm -rf $ROOTFS
1861 status
1862 fi
1863 if [ -d "$ROOTCD" ] ; then
1864 echo -n "Removing the rootcd..."
1865 rm -rf $ROOTCD
1866 status
1867 fi
1868 echo -n "Removing eventual ISO image..."
1869 rm -f $DISTRO/$ISO_NAME.iso
1870 rm -f $DISTRO/$ISO_NAME.md5
1871 status
1872 fi
1873 echo "================================================================================"
1874 echo ""
1875 ;;
1876 check-distro)
1877 # Check for a few LiveCD needed files not installed by packages.
1879 check_rootfs
1880 echo ""
1881 echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
1882 echo "================================================================================"
1883 # SliTaz release info.
1884 if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
1885 echo "Missing release info : /etc/slitaz-release"
1886 else
1887 release=`cat $ROOTFS/etc/slitaz-release`
1888 echo -n "Release : $release"
1889 status
1890 fi
1891 # Tazpkg mirror.
1892 if [ ! -f "$ROOTFS/var/lib/tazpkg/mirror" ]; then
1893 echo -n "Mirror URL : Missing /var/lib/tazpkg/mirror"
1894 todomsg
1895 else
1896 echo -n "Mirror configuration exists..."
1897 status
1898 fi
1899 # Isolinux msg
1900 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.msg; then
1901 echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
1902 todomsg
1903 else
1904 echo -n "Isolinux message seems good..."
1905 status
1906 fi
1907 echo "================================================================================"
1908 echo ""
1909 ;;
1910 writeiso)
1911 # Writefs to ISO image including /home unlike gen-distro we dont use
1912 # packages to generate a rootfs, we build a compressed rootfs with all
1913 # the current filesystem similar to 'tazusb writefs'.
1915 DISTRO="/home/slitaz/distro"
1916 ROOTCD="$DISTRO/rootcd"
1917 if [ -z $2 ]; then
1918 COMPRESSION=none
1919 else
1920 COMPRESSION=$2
1921 fi
1922 if [ -z $3 ]; then
1923 ISO_NAME="slitaz"
1924 else
1925 ISO_NAME="$3"
1926 fi
1927 check_root
1928 # Start info
1929 echo ""
1930 echo -e "\033[1mWrite filesystem to ISO\033[0m
1931 ===============================================================================
1932 The command writeiso will write the current filesystem into a suitable cpio
1933 archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso).
1935 Archive compression: $COMPRESSION"
1936 echo ""
1938 # Save some space
1939 rm /var/cache/tazpkg/* -r -f
1940 rm -rf /home/slitaz/distro
1942 # Optionally remove sound card selection and screen resolution.
1943 echo "Do you wish to remove the sound card and screen configs ? "
1944 echo -n "Press ENTER to keep or answer (No|yes|exit): "
1945 read anser
1946 case $anser in
1947 e|E|"exit"|Exit)
1948 exit 0 ;;
1949 y|Y|yes|Yes)
1950 echo -n "Removing current sound card and screen configurations..."
1951 rm -f /var/lib/sound-card-driver
1952 rm -f /etc/asound.state
1953 rm -f /etc/X11/screen.conf
1954 rm -f /etc/X11/xorg.conf ;;
1955 *)
1956 echo -n "Keeping current sound card and screen configurations..." ;;
1957 esac
1958 status
1960 # Create list of files including default user files since it is defined in /etc/passwd
1961 # and some new users might have been added.
1962 find /bin /etc /init /sbin /var /dev /lib /root /usr /home >/tmp/list
1964 for dir in /proc /sys /tmp /mnt /media /media/cdrom /media/flash /media/usbdisk
1965 do
1966 echo $dir >>/tmp/list
1967 done
1969 # Generate initramfs with specified compression and display rootfs
1970 # size in realtime.
1971 rm -f /tmp/rootfs
1972 write_initramfs &
1973 sleep 2
1974 echo -en "\nFilesystem size:"
1975 while [ ! -f /tmp/rootfs ]
1976 do
1977 sleep 1
1978 echo -en "\\033[18G`du -sh /rootfs.gz | awk '{print $1}'` "
1979 done
1980 echo -e "\n"
1982 # Move freshly generated rootfs to the cdrom.
1983 mkdir -p $ROOTCD/boot
1984 mv -f /rootfs.gz $ROOTCD/boot
1986 # Now we need the kernel and isolinux files.
1987 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
1988 cp /media/cdrom/boot/bzImage $ROOTCD/boot
1989 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
1990 umount /media/cdrom
1991 else
1992 echo -e "
1993 Unable to mount the cdrom to copy the Kernel and needed files. When SliTaz
1994 is running in RAM the kernel and bootloader files are kept on the cdrom.
1995 Please insert a LiveCD or unmount the current cdrom to let Tazlito handle
1996 the media.\n"
1997 echo -en "----\nENTER to continue..."; read i
1998 exit 1
1999 fi
2001 # Generate the iso image.
2002 cd $DISTRO
2003 echo "Generating ISO image..."
2004 genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
2005 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
2006 -V "SliTaz" -input-charset iso8859-1 -boot-info-table $ROOTCD
2007 if [ -x /usr/bin/isohybrid ]; then
2008 echo -n "Creating hybrid ISO..."
2009 /usr/bin/isohybrid $ISO_NAME.iso 2> /dev/null
2010 status
2011 fi
2012 echo -n "Creating the ISO md5sum..."
2013 md5sum $ISO_NAME.iso > $ISO_NAME.md5
2014 status
2016 echo "==============================================================================="
2017 echo "ISO image: `du -sh /home/slitaz/distro/$ISO_NAME.iso`"
2018 echo ""
2019 echo -n "Exit or burn ISO to cdrom (Exit|burn)? "; read anser
2020 case $anser in
2021 burn)
2022 eject
2023 echo -n "Please insert a blank cdrom and press ENTER..."
2024 read i && sleep 2
2025 tazlito burn-iso /home/slitaz/distro/$ISO_NAME.iso
2026 echo -en "----\nENTER to continue..."; read i ;;
2027 *)
2028 exit 0 ;;
2029 esac ;;
2030 burn-iso)
2031 # Guess cdrom device, ask user and burn the ISO.
2033 check_root
2034 DRIVE_NAME=`cat /proc/sys/dev/cdrom/info | grep "drive name" | cut -f 3`
2035 DRIVE_SPEED=`cat /proc/sys/dev/cdrom/info | grep "drive speed" | cut -f 3`
2036 # We can specify an alternative ISO from the cmdline.
2037 if [ -n "$2" ] ; then
2038 iso=$2
2039 else
2040 iso=$DISTRO/$ISO_NAME.iso
2041 fi
2042 if [ ! -f "$iso" ]; then
2043 echo -e "\nUnable to find ISO : $iso\n"
2044 exit 0
2045 fi
2046 echo ""
2047 echo -e "\033[1mTazlito burn ISO\033[0m "
2048 echo "================================================================================"
2049 echo "Cdrom device : /dev/$DRIVE_NAME"
2050 echo "Drive speed : $DRIVE_SPEED"
2051 echo "ISO image : $iso"
2052 echo "================================================================================"
2053 echo ""
2054 yesorno "Burn ISO image (y/N) ? "
2055 if [ "$answer" == "y" ]; then
2056 echo ""
2057 echo "Starting Wodim to burn the iso..." && sleep 2
2058 echo "================================================================================"
2059 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
2060 echo "================================================================================"
2061 echo "ISO image is burned to cdrom."
2062 else
2063 echo -e "\nExiting. No ISO burned."
2064 fi
2065 echo ""
2066 ;;
2067 merge)
2068 # Merge multiple rootfs into one iso.
2070 if [ -z "$2" ]; then
2071 cat << EOT
2072 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
2074 Merge multiple rootfs into one iso. Rootfs are like russian dolls
2075 i.e: rootfsN is a subset of rootfsN-1
2076 rootfs1 is found in iso, sizeN is the RAM size need to launch rootfsN.
2077 The boot loader will select the rootfs according to the RAM size detected.
2079 Example:
2080 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
2082 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
2083 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
2084 EOT
2085 exit 2
2086 fi
2088 shift # skip merge
2089 append="$1 slitaz1"
2090 shift # skip size1
2091 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
2093 ISO=$1.merged
2094 # Extract filesystems
2095 echo -n "Mounting $1"
2096 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
2097 status || cleanup_merge
2098 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2099 rm -f $TMP_DIR/iso/boot/bzImage
2100 ln $TMP_DIR/iso/boot/vmlinuz* $TMP_DIR/iso/boot/bzImage
2101 umount -d $TMP_DIR/mnt
2102 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
2103 echo "$1 is already a merged iso. Aborting."
2104 cleanup_merge
2105 fi
2106 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 ]; then
2107 if [ ! -f /boot/isolinux/ifmem.c32 ]; then
2108 cat <<EOT
2109 No file /boot/isolinux/ifmem.c32
2110 Please install syslinux package !
2111 EOT
2112 rm -rf $TMP_DIR
2113 exit 1
2114 fi
2115 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
2116 fi
2118 echo -n "Extracting iso/rootfs.gz"
2119 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
2120 [ -d $TMP_DIR/rootfs1/etc ]
2121 status || cleanup_merge
2122 n=1
2123 while [ -n "$2" ]; do
2124 shift # skip rootfs N-1
2125 p=$n
2126 n=$(($n + 1))
2127 append="$append $1 slitaz$n"
2128 shift # skip size N
2129 mkdir -p $TMP_DIR/rootfs$n
2130 echo -n "Extracting $1"
2131 extract_rootfs $1 $TMP_DIR/rootfs$n &&
2132 [ -d $TMP_DIR/rootfs$n/etc ]
2133 status || cleanup_merge
2134 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
2135 echo "Creating rootfs$p.gz"
2136 pack_rootfs $TMP_DIR/rootfs$p $TMP_DIR/iso/boot/rootfs$p.gz
2137 status
2138 done
2139 echo "Creating rootfs$n.gz"
2140 pack_rootfs $TMP_DIR/rootfs$n $TMP_DIR/iso/boot/rootfs$n.gz
2141 status
2142 rm -f $TMP_DIR/iso/boot/rootfs.gz
2143 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
2144 create_iso $ISO $TMP_DIR/iso
2145 rm -rf $TMP_DIR
2146 ;;
2148 repack)
2149 # Repack an iso with maximum lzma compression ratio.
2152 ISO=$2
2154 mkdir -p $TMP_DIR/mnt
2155 # Extract filesystems
2156 echo -n "Mounting $ISO"
2157 mount -o loop,ro $ISO $TMP_DIR/mnt 2> /dev/null
2158 status || cleanup_merge
2159 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2160 umount -d $TMP_DIR/mnt
2162 for i in $TMP_DIR/iso/boot/rootfs* ; do
2163 echo -n "Repacking $(basename $i)"
2164 (zcat $i 2> /dev/null || unlzma -c $i || cat $i) \
2165 2>/dev/null > $TMP_DIR/rootfs
2166 lzma e $TMP_DIR/rootfs $i \
2167 $(lzma_switches $TMP_DIR/rootfs)
2168 status
2169 done
2171 create_iso $ISO $TMP_DIR/iso
2172 rm -rf $TMP_DIR ;;
2174 build-loram)
2175 # Build a Live CD for low ram systems.
2178 ISO=$2
2179 OUTPUT=$3
2180 mkdir -p $TMP_DIR/iso
2181 mount -o loop,ro -t iso9660 $ISO $TMP_DIR/iso
2182 if ! check_iso_for_loram ; then
2183 echo "$2 is not a valid SliTaz live CD. Abort."
2184 umount -d $TMP_DIR/iso
2185 rm -rf $TMP_DIR
2186 exit 1
2187 fi
2189 case "$4" in
2190 cdrom) build_loram_cdrom ;;
2191 http) build_loram_http ;;
2192 *) build_loram_ram ;;
2193 esac
2194 umount -d $TMP_DIR/iso
2195 rm -rf $TMP_DIR ;;
2198 frugal-install|-fi)
2199 ISO_IMAGE="$2"
2200 echo ""
2201 mkdir -p /boot/frugal
2202 if [ -f "$ISO_IMAGE" ]; then
2203 echo -n "Using ISO image: $ISO_IMAGE"
2204 mkdir -p /tmp/iso && mount -o loop $ISO_IMAGE /tmp/iso
2205 status
2206 echo -n "Installing the Kernel and rootfs..."
2207 cp -a /tmp/iso/boot/bzImage /boot/frugal
2208 cp -a /tmp/iso/boot/rootfs.gz /boot/frugal
2209 umount /tmp/iso
2210 status
2211 else
2212 echo -n "Using distro: $DISTRO"
2213 cd $DISTRO && status
2214 echo -n "Installing the Kernel and rootfs..."
2215 cp -a $DISTRO/rootcd/boot/bzImage /boot/frugal
2216 cp -a $DISTRO/rootcd/boot/rootfs.gz /boot/frugal
2217 status
2218 fi
2219 # Grub entry
2220 if ! grep -q "^kernel /boot/frugal/bzImage" /boot/grub/menu.lst; then
2221 echo -n "Configuring GRUB menu list..."
2222 cat >> /boot/grub/menu.lst << EOT
2223 title SliTaz GNU/Linux (frugal)
2224 root (hd0,0)
2225 kernel /boot/frugal/bzImage root=/dev/null
2226 initrd /boot/frugal/rootfs.gz
2227 EOT
2228 else
2229 echo -n "GRUB menu list is up-to-date..."
2230 fi
2231 status
2232 echo "" ;;
2234 emu-iso)
2235 # Emulate an ISO image with Qemu.
2236 if [ -n "$2" ] ; then
2237 iso=$2
2238 else
2239 iso=$DISTRO/$ISO_NAME.iso
2240 fi
2241 if [ ! -f "$iso" ]; then
2242 echo -e "\nUnable to find ISO : $iso\n"
2243 exit 0
2244 fi
2245 if [ ! -x "/usr/bin/qemu" ]; then
2246 echo -e "\nUnable to find Qemu binary. Please install: qemu\n"
2247 exit 0
2248 fi
2249 echo -e "\nStarting Qemu emulator:\n"
2250 echo -e "qemu $QEMU_OPTS $iso\n"
2251 qemu $QEMU_OPTS $iso ;;
2253 usage|*)
2254 # Clear and print usage also for all unknown commands.
2256 clear
2257 usage ;;
2258 esac
2260 exit 0