tazlito view tazlito @ rev 360

tazlito: deduplicate iso
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Aug 26 11:35:08 2014 +0200 (2014-08-26)
parents a4483ebf3c6f
children 90ccc147f462
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-2014 SliTaz - GNU General Public License.
11 #
12 # Authors : Christophe Lincoln <pankso@slitaz.org>
13 # Pascal Bellard <pascal.bellard@slitaz.org>
14 #
15 VERSION=5.2.3
17 . /lib/libtaz.sh
19 # Tazlito configuration variables to be shorter
20 # and to use words rather than numbers.
21 COMMAND=$1
22 LIST_NAME=$2
23 TMP_DIR=/tmp/tazlito-$$-$RANDOM
24 TMP_MNT=/media/tazlito-$$-$RANDOM
25 TOP_DIR=`pwd`
26 INITRAMFS=rootfs.gz
27 LOCALSTATE=/var/lib/tazpkg
28 INSTALLED=$LOCALSTATE/installed
29 CACHE_DIR=/var/cache/tazpkg
30 MIRROR=$LOCALSTATE/mirror
31 DEFAULT_MIRROR="http://mirror.slitaz.org/packages/`cat /etc/slitaz-release`/"
33 log=/var/log/tazlito.log
34 if check_root; then
35 newline > $log
36 fi
38 # Try to include config file, continue if command is gen-config or exit.
39 # The main config used by default is in /etc/tazlito.
40 if [ -f "/etc/tazlito/tazlito.conf" ] ; then
41 CONFIG_FILE="/etc/tazlito/tazlito.conf"
42 fi
43 # Specific distro config file can be put in a distro tree.
44 if [ -f "$TOP_DIR/tazlito.conf" ] ; then
45 CONFIG_FILE="$TOP_DIR/tazlito.conf"
46 fi
47 if [ ! "$CONFIG_FILE" = "" ] ; then
48 . $CONFIG_FILE
49 else
50 if [ "$COMMAND" = "gen-config" ] ; then
51 continue
52 else
53 echo "Unable to find any configuration file. Please read the docs"
54 echo "or run '`basename $0` gen-config' to get an empty config file."
55 exit 0
56 fi
57 fi
59 # While Tazpkg is not used the default mirror url file does not exist
60 # and user can't recharge the list of flavors.
61 if test $(id -u) = 0 ; then
62 if [ ! -f "$MIRROR" ]; then
63 echo "$DEFAULT_MIRROR" > $MIRROR
64 fi
65 fi
67 # Set the rootfs and rootcd path with $DISTRO
68 # configuration variable.
69 ROOTFS=$DISTRO/rootfs
70 ROOTCD=$DISTRO/rootcd
72 #####################
73 # Tazlito functions #
74 #####################
76 # Print the usage.
77 usage () {
78 cat << EOT
80 SliTaz Live Tool - Version: $(colorize 34 "$VERSION")
82 $(boldify "Usage:") $(basename $0) [command] [list|iso|flavor|compression] [dir|iso]
84 $(boldify "Commands:")
85 usage Print this short usage.
86 stats View Tazlito and distro configuration statistics.
87 gen-config Generate a new configuration file for a distro.
88 configure Configure the main config file or a specific tazlito.conf.
89 gen-iso Generate a new ISO from a distro tree.
90 gen-initiso Generate a new initramfs and ISO from the distro tree.
91 list-flavors List all available package lists on the mirror.
92 gen-flavor Generate a new live-CD description.
93 gen-liveflavor Generate a live-CD description from current system.
94 show-flavor Show live-CD description.
95 get-flavor Get a flavor's list of packages.
96 upgrade-flavor Update package list to the latest available versions.
97 extract-flavor Extract a (*.flavor) flavor into $FLAVORS_REPOSITORY.
98 pack-flavor Pack (and update) a flavor from $FLAVORS_REPOSITORY.
99 iso2flavor Create a flavor file from a SliTaz iso image.
100 check-list Check a distro-packages.list for updates.
101 extract-distro Extract an ISO to a directory and rebuild LiveCD tree.
102 gen-distro Generate a Live distro and ISO from a list of packages.
103 clean-distro Remove all files generated by gen-distro.
104 check-distro Help to check if distro is ready to release.
105 writeiso Use running system to generate a bootable ISO (with /home).
106 merge Merge multiple rootfs into one iso.
107 deduplicate Deduplicate files in a tree.
108 repack Recompress rootfs into iso with maximum ratio.
109 build-loram Generate a live-CD for low ram systems.
110 emu-iso Emulate an ISO image with Qemu.
111 burn-iso Burn ISO image to a cdrom using Wodim.
113 EOT
114 }
116 yesorno() {
117 echo -n "$1"
118 case "$DEFAULT_ANSWER" in
119 Y|y) answer="y";;
120 N|n) answer="n";;
121 *) read answer;;
122 esac
123 }
125 field() {
126 grep "^$1" "$2" | sed 's/.*: \([0-9KMG\.]*\).*/\1/'
127 }
129 todomsg() {
130 echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
131 }
133 # Download a file from this mirror
134 download_from() {
135 local i
136 local mirrors
137 mirrors="$1"
138 shift
139 for i in $mirrors; do
140 case "$i" in
141 http://*|ftp://*) busybox wget -c $i$@ && break;;
142 *) cp $i/$1 . && break;;
143 esac
144 done
145 }
147 # Download a file trying all mirrors
148 download() {
149 local i
150 for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2> /dev/null); do
151 download_from "$i" "$@" && break
152 done
153 }
155 # Execute hooks provided by some packages
156 genisohooks() {
157 local here=`pwd`
158 for i in $(ls $ROOTFS/etc/tazlito/*.$1 2> /dev/null); do
159 cd $ROOTFS
160 . $i $ROOTCD
161 done
162 cd $here
163 }
165 cleanup() {
166 if [ -d $TMP_MNT ]; then
167 umount $TMP_MNT
168 rmdir $TMP_MNT
169 rm -f /boot
170 fi
171 }
173 # Echo the package name if the tazpkg is already installed
174 installed_package_name() {
175 local tazpkg
176 local package
177 local VERSION
178 local EXTRAVERSION
179 tazpkg=$1
180 # Try to find package name and version to be able
181 # to repack it from installation
182 # A dash (-) can exist in name *and* in version
183 package=${tazpkg%-*}
184 i=$package
185 while true; do
186 VERSION=""
187 eval $(grep -s ^VERSION= $INSTALLED/$i/receipt)
188 EXTRAVERSION=""
189 eval $(grep -s ^EXTRAVERSION= $INSTALLED/$i/receipt)
190 if [ "$i-$VERSION$EXTRAVERSION" = "$tazpkg" ]; then
191 echo $i
192 break
193 fi
194 case "$i" in
195 *-*);;
196 *) break;;
197 esac
198 i=${i%-*}
199 done
200 }
202 # Check for the rootfs tree.
203 check_rootfs() {
204 if [ ! -d "$ROOTFS/etc" ] ; then
205 echo -e "\nUnable to find a distro rootfs...\n"
206 exit 0
207 fi
208 }
210 # Check for the boot dir into the root CD tree.
211 verify_rootcd()
212 {
213 if [ ! -d "$ROOTCD/boot" ] ; then
214 echo -e "\nUnable to find the rootcd boot directory...\n"
215 exit 0
216 fi
217 }
219 create_iso()
220 {
221 cd $2
222 deduplicate .
223 echo -n "Computing md5..."
224 find * -type f ! -name md5sum ! -name 'vmlinuz*' -exec md5sum {} \; > md5sum
225 sed -i -e '/ boot\/isolinux\/isolinux.bin$/d' \
226 -e '/ boot\/isolinux\/boot.cat$/d' md5sum
227 status
228 cd - > /dev/null
229 newline
230 boldify "Generating ISO image"
231 separator
232 echo "Generating $1"
233 if [ $(ls $2/boot/vmlinuz* $2/boot/bzImage | wc -l) -eq 2 ]; then
234 if cmp $2/boot/vmlinuz* $2/boot/bzImage > /dev/null; then
235 rm -f $2/boot/bzImage
236 ln $2/boot/vmlinuz* $2/boot/bzImage
237 fi
238 fi
239 genisoimage -R -o $1 -b boot/isolinux/isolinux.bin \
240 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
241 -V "$VOLUM_NAME" -p "$PREPARED" -input-charset iso8859-1 \
242 -copyright README -P "www.slitaz.org" -boot-info-table $2
243 if [ -x /usr/bin/isohybrid ]; then
244 echo -n "Creating hybrid ISO..."
245 /usr/bin/isohybrid $1 -entry 2 2> /dev/null
246 status
247 fi
248 if [ -s /etc/tazlito/info ]; then
249 if [ $(stat -c %s /etc/tazlito/info) -lt $(( 31*1024 )) ]; then
250 echo -n "Storing ISO info..."
251 dd if=/etc/tazlito/info bs=1k seek=1 of=$1 \
252 conv=notrunc 2> /dev/null
253 status
254 fi
255 fi
256 if [ -x /usr/bin/iso2exe ]; then
257 echo "Creating EXE header..."
258 /usr/bin/iso2exe $1 2> /dev/null
259 fi
260 }
262 # Generate a new ISO image using isolinux.
263 gen_livecd_isolinux()
264 {
265 # Some packages may want to alter iso
266 genisohooks iso
267 if [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ]; then
268 echo -e "\nUnable to find isolinux binary.\n"
269 cleanup
270 exit 0
271 fi
272 # Set date for boot msg.
273 if grep -q 'XXXXXXXX' $ROOTCD/boot/isolinux/isolinux.*g; then
274 DATE=`date +%Y%m%d`
275 echo -n "Setting build date to: $DATE..."
276 sed -i "s/XXXXXXXX/$DATE/" $ROOTCD/boot/isolinux/isolinux.*g
277 status
278 fi
279 cd $DISTRO
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 separator
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 local proc=$(grep -s '^processor' < /proc/cpuinfo | wc -l)
310 echo "-d$(lzma_history_bits $1) -mt${proc:-1}"
311 }
313 lzma_set_size()
314 {
315 # Update size field for lzma'd file packed using -si switch
316 local n
317 local i
318 return # Need to fix kernel code ?
319 n=$(unlzma -c $1 | wc -c)
320 for i in $(seq 1 8); do
321 printf '\\\\x%02X' $(($n & 255))
322 n=$(($n >> 8))
323 done | xargs echo -en | dd of=$1 conv=notrunc bs=1 seek=5 2> /dev/null
324 }
326 align_to_32bits()
327 {
328 local size
329 size=$(stat -c %s ${1:-/dev/null})
330 [ $((${size:-0} & 3)) -ne 0 ] &&
331 dd if=/dev/zero bs=1 count=$((4 - ($size & 3))) >> $1 2> /dev/null
332 }
334 # Pack rootfs
335 pack_rootfs()
336 {
337 ( cd $1 ; find . -print | cpio -o -H newc ) | \
338 if [ "$COMPRESSION" = "none" ]; then
339 echo "Generating uncompressed initramfs... "
340 cat > $2
341 elif [ -x /usr/bin/lzma -a "$COMPRESSION" != "gzip" ]; then
342 echo -n "Generating lzma'ed initramfs... "
343 lzma e -si -so $(lzma_switches $1) > $2
344 lzma_set_size $2
345 else
346 echo "Generating gziped initramfs... "
347 gzip -9 > $2
348 fi
349 align_to_32bits $2
350 echo 1 > /tmp/rootfs
351 }
353 # Compression functions for writeiso.
354 write_initramfs()
355 {
356 if [ "$COMPRESSION" = "lzma" ]; then
357 echo -n "Creating rootfs.gz with lzma compression... "
358 cpio -o -H newc | lzma e -si -so > /rootfs.gz
359 lzma_set_size /rootfs.gz
360 elif [ "$COMPRESSION" = "gzip" ]; then
361 echo "Creating rootfs.gz with gzip compression... "
362 cpio -o -H newc | gzip -9 > /rootfs.gz
363 else
364 echo "Creating rootfs.gz without compression... "
365 cpio -o -H newc > /rootfs.gz
366 fi < /tmp/list
367 align_to_32bits /rootfs.gz
368 echo 1 > /tmp/rootfs
369 }
371 # Deduplicate files (MUST be on the same filesystem).
372 deduplicate()
373 {
374 find "$@" -type f -size +0c -xdev \
375 -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | sort | \
376 ( save=0; old_attr=""; old_inode=""; old_link=""; old_file=""
377 while read attr inode link file; do
378 [ -L "$file" ] && continue
379 if [ "$attr" = "$old_attr" -a "$inode" != "$old_inode" ]; then
380 if cmp "$file" "$old_file" >/dev/null 2>&1 ; then
381 rm -f "$file"
382 if ln "$old_file" "$file" 2> /dev/null; then
383 inode="$old_inode"
384 [ "$link" = "1" ] &&
385 save="$(($save+(${attr%%-*}+512)/1024))"
386 else
387 cp "$old_file" "$file"
388 fi
389 fi
390 fi
391 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
392 done
393 echo "$save Kbytes saved in duplicate files."
394 )
395 }
397 # Generate a new initramfs from the root filesystem.
398 gen_initramfs()
399 {
400 # Just in case CTRL+c
401 rm -f $DISTRO/gen
403 # Some packages may want to alter rootfs
404 genisohooks rootfs
405 cd $1
407 # Link duplicate files
408 deduplicate .
410 # Use lzma if installed. Display rootfs size in realtime.
411 rm -f /tmp/rootfs
412 pack_rootfs . $DISTRO/$(basename $1).gz &
413 sleep 2
414 echo -en "\nFilesystem size:"
415 while [ ! -f /tmp/rootfs ]
416 do
417 sleep 1
418 echo -en "\\033[18G`du -sh $DISTRO/$(basename $1).gz | awk '{print $1}'` "
419 done
420 echo -e "\n"
421 cd $DISTRO
422 mv $(basename $1).gz $ROOTCD/boot
423 }
425 distro_sizes() {
426 if [ "$time" ]; then
427 time=$(($(date +%s) - $time))
428 sec=$time
429 div=$(( ($time + 30) / 60))
430 [ "$div" != 0 ] && min="~ ${div}m"
431 echo "Build time : ${sec}s $min"
432 fi
433 cat << EOT
434 Build date : $(date +%Y%m%d)
435 Packages : $(ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l)
436 Rootfs size : $(du -csh $ROOTFS*/ | awk '{ s=$1 } END { print s }')
437 Initramfs size : $(du -csh $ROOTCD/boot/rootfs*.gz | awk '{ s=$1 } END { print s }')
438 ISO image size : $(du -sh $ISO_NAME.iso | awk '{ print $1 }')
439 EOT
440 separator
441 echo "Image is ready: $ISO_NAME.iso"
442 newline
443 }
445 # Print ISO and rootfs size.
446 distro_stats() {
447 newline
448 echo "$(boldify 'Distro statistics:') $DISTRO"
449 separator
450 distro_sizes
451 }
453 # Create an empty configuration file.
454 empty_config_file()
455 {
456 cat >> tazlito.conf << "EOF"
457 # tazlito.conf: Tazlito (SliTaz Live Tool) configuration file.
458 #
460 # Name of the ISO image to generate.
461 ISO_NAME=""
463 # ISO image volume name.
464 VOLUM_NAME="SliTaz"
466 # Name of the preparer.
467 PREPARED="$USER"
469 # Path to the packages repository and the packages.list.
470 PACKAGES_REPOSITORY=""
472 # Path to the distro tree to gen-distro from a
473 # list of packages.
474 DISTRO=""
476 # Path to the directory containing additional files
477 # to copy into the rootfs and rootcd of the LiveCD.
478 ADDFILES="$DISTRO/addfiles"
480 # Default answer for binary question (Y or N)
481 DEFAULT_ANSWER="ASK"
483 # Compression utility (lzma, gzip or none)
484 COMPRESSION="lzma"
485 EOF
486 }
488 # extract rootfs.gz somewhere
489 extract_rootfs()
490 {
491 (zcat $1 || unlzma -c $1 || cat $1) 2>/dev/null | \
492 (cd $2; cpio -idm > /dev/null)
493 }
495 # Remove duplicate files
496 mergefs()
497 {
498 echo -n "Merge $(basename $1) ($(du -hs $1 | awk '{ print $1}')) into "
499 echo -n "$(basename $2) ($(du -hs $2 | awk '{ print $1}'))"
500 # merge symlinks files and devices
501 ( cd $1; find ) | while read file; do
502 if [ -L $1/$file ]; then
503 [ -L $2/$file ] &&
504 [ "$(readlink $1/$file)" == "$(readlink $2/$file)" ] &&
505 rm -f $2/$file
506 elif [ -f $1/$file ]; then
507 [ -f $2/$file ] &&
508 cmp $1/$file $2/$file > /dev/null 2>&1 && rm -f $2/$file
509 [ -f $2/$file ] &&
510 [ "$(basename $file)" == "volatile.cpio.gz" ] &&
511 [ "$(dirname $(dirname $file))" == \
512 ".$INSTALLED" ] && rm -f $2/$file
513 elif [ -b $1/$file ]; then
514 [ -b $2/$file ] &&
515 [ "$(stat -c '%a:%u:%g:%t:%T' $1/$file)" == \
516 "$(stat -c '%a:%u:%g:%t:%T' $2/$file)" ] &&
517 rm -f $2/$file
518 elif [ -c $1/$file ]; then
519 [ -c $2/$file ] &&
520 [ "$(stat -c '%a:%u:%g:%t:%T' $1/$file)" == \
521 "$(stat -c '%a:%u:%g:%t:%T' $2/$file)" ] &&
522 rm -f $2/$file
523 fi
524 done
526 # cleanup directories
527 ( cd $1; find . -type d ) | sed '1!G;h;$!d' | while read file; do
528 [ -d $2/$file ] && rmdir $2/$file 2> /dev/null
529 done
530 true
531 status
532 }
534 cleanup_merge()
535 {
536 rm -rf $TMP_DIR
537 exit 1
538 }
540 human2cent()
541 {
542 case "$1" in
543 *k) echo $1 | sed 's/\(.*\).\(.\)k/\1\2/';;
544 *M) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)M/\1\2/') * 1024));;
545 *G) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)G/\1\2/') * 1024 * 1024));;
546 esac
547 }
549 cent2human()
550 {
551 if [ $1 -lt 10000 ]; then
552 echo "$(($1 / 10)).$(($1 % 10))k"
553 elif [ $1 -lt 10000000 ]; then
554 echo "$(($1 / 10240)).$(( ($1/1024) % 10))M"
555 else
556 echo "$(($1 / 10485760)).$(( ($1/1048576) % 10))G"
557 fi
558 }
560 get_size()
561 {
562 cat $LOCALSTATE/packages.list $TMP_DIR/packages.list 2>/dev/null | awk "{ \
563 if (/^$(echo $1 | sed 's/[$+.\]/\\&/g')$/) get=1; \
564 if (/installed/ && get == 1) { print ; get++ } \
565 }
566 END { if (get < 2) print \" 0.0k (0.0k installed)\" }" | \
567 sed 's/ *\(.*\) .\(.*\) installed./\1 \2/' | while read packed unpacked; do
568 echo "$(human2cent $packed) $(human2cent $unpacked)"
569 done
570 }
572 # Display package list with version, set packed_size and unpacked_size
573 get_pkglist()
574 {
575 packed_size=0; unpacked_size=0
576 grep -v ^# $FLAVORS_REPOSITORY/$1/packages.list > $TMP_DIR/flavor.pkg
577 while read pkg; do
578 set -- $(get_size $pkg)
579 packed_size=$(( $packed_size + $1 ))
580 unpacked_size=$(( $unpacked_size + $2 ))
581 for i in $(grep -hs ^$pkg $LOCALSTATE/packages.list \
582 $TMP_DIR/packages.list); do
583 echo $i
584 break
585 done
586 done < $TMP_DIR/flavor.pkg
587 rm -f $TMP_DIR/flavor.pkg
588 }
590 # Update isolinux config files for multiple rootfs
591 update_bootconfig()
592 {
593 local files
594 echo -n "Updating boot config files..."
595 files="$(grep -l 'include common' $1/*.cfg)"
596 for file in $files ; do
597 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
598 if (/label/) label=$0;
599 else if (/kernel/) kernel=$0;
600 else if (/append/) {
601 i=index($0,"rootfs.gz");
602 append=substr($0,i+9);
603 }
604 else if (/include/) {
605 for (i = 1; i <= n; i++) {
606 print label i
607 print kernel;
608 initrd="initrd=/boot/rootfs" n ".gz"
609 for (j = n - 1; j >= i; j--) {
610 initrd=initrd ",/boot/rootfs" j ".gz";
611 }
612 printf "\tappend %s%s\n",initrd,append;
613 print "";
614 }
615 print;
616 }
617 else print;
618 }' < $file > $file.$$
619 mv -f $file.$$ $file
620 done
621 sel="$(echo $2 | awk '{
622 for (i=1; i<=NF; i++)
623 if (i % 2 == 0) printf " slitaz%d",i/2
624 else printf " %s",$i
625 }')"
626 [ -s $1/common.cfg ] && cat >> $1/common.cfg <<EOT
628 label slitaz
629 kernel /boot/isolinux/ifmem.c32
630 append$sel noram
632 label noram
633 config noram.cfg
635 EOT
636 # Update vesamenu
637 if [ -s $1/isolinux.cfg ]; then
638 files="$files $1/isolinux.cfg"
639 awk -v n=$(echo $2 | awk '{ print NF/2 }') -v "sel=$sel" '
640 BEGIN {
641 kernel=" COM32 c32box.c32"
642 }
643 {
644 if (/ROWS/) print "MENU ROW " n+$3;
645 else if (/TIMEOUTROW/) print "MENU TIMEOUTROW " n+$3;
646 else if (/TABMSGROW/) print "MENU TABMSGROW " n+$3;
647 else if (/CMDLINEROW/) print "MENU CMDLINEROW " n+$3;
648 else if (/VSHIFT/) {
649 x=$3-n;
650 if (x < 0) x=0;
651 print "MENU VSHIFT " x;
652 }
653 else if (/rootfs.gz/) {
654 linux=""
655 if (/bzImage/) {
656 linux="linux /boot/bzImage "
657 }
658 i=index($0,"rootfs.gz");
659 append=substr($0,i+9);
660 print " kernel /boot/isolinux/ifmem.c32"
661 print " append" sel " noram"
662 print ""
663 print "label noram"
664 print " MENU HIDE"
665 print " config noram.cfg"
666 print ""
667 for (i = 1; i <= n; i++) {
668 print "LABEL slitaz" i
669 print " MENU LABEL SliTaz slitaz" i " Live"
670 print kernel;
671 initrd="initrd=/boot/rootfs" n ".gz"
672 for (j = n - 1; j >= i; j--) {
673 initrd=initrd ",/boot/rootfs" j ".gz";
674 }
675 printf "\tappend %s%s%s\n",linux,initrd,append;
676 print "";
677 }
678 }
679 else if (/bzImage/) kernel=$0;
680 else print;
681 }' < $1/isolinux.cfg > $1/isolinux.cfg.$$
682 mv $1/isolinux.cfg.$$ $1/isolinux.cfg
683 fi
684 [ -s $1/c32box.c32 ] && sed -i -e '/kernel.*ifmem/d' \
685 -e 's/append \([0-9]\)/append ifmem \1/' $1/isolinux.cfg
686 cat > $1/noram.cfg <<EOT
687 implicit 0
688 prompt 1
689 timeout 80
690 $(grep '^F[0-9]' $1/isolinux.cfg)
692 $([ -s $1/isolinux.msg ] && echo display isolinux.msg)
693 say Not enough RAM to boot slitaz. Trying hacker mode...
694 default hacker
695 label hacker
696 KERNEL /boot/bzImage
697 append rw root=/dev/null vga=normal
699 label reboot
700 EOT
701 if [ -s $1/c32box.c32 ]; then
702 cat >> $1/noram.cfg <<EOT
703 COM32 c32box.c32
704 append reboot
706 label poweroff
707 COM32 c32box.c32
708 append poweroff
710 EOT
711 else
712 echo " com32 reboot.c32" >> $1/noram.cfg
713 fi
714 # Restore real label names
715 [ -s $1/common.cfg ] && files="$1/common.cfg $files"
716 echo $2 | awk '{ for (i=NF; i>1; i-=2) printf "%d/%s\n",i/2,$i }' | \
717 while read pat; do
718 sed -i "s/slitaz$pat/" $files
719 done
720 status
721 }
723 # Install a missing package
724 install_package()
725 {
726 echo -n "Install package $1 "
727 [ -n "$2" ] && echo -n "for kernel $2 "
728 echo -n "?"
729 read answer
730 case "$answer" in
731 y*|Y*|o*|O*)
732 # We dont want package on host cache.
733 echo -n "Getting and installing package: $1"
734 yes y | tazpkg get-install $1 2>&1 >> $log || exit 1
735 status ;;
736 *)
737 return 1 ;;
738 esac
739 }
741 # Check iso for loram transformation
742 check_iso_for_loram()
743 {
744 [ -s $TMP_DIR/iso/boot/rootfs.gz ] ||
745 [ -s $TMP_DIR/iso/boot/rootfs1.gz ]
746 }
748 # Build initial rootfs for loram ISO ram/cdrom/http
749 build_initfs()
750 {
751 urliso="mirror.slitaz.org mirror.switch.ch/ftp/mirror/slitaz \
752 download.tuxfamily.org/slitaz slitaz.c3sl.ufpr.br"
753 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
754 if [ -z "$version" ]; then
755 cat <<EOT
756 Can't find the kernel version.
757 No file /boot/vmlinuz-<version> in ISO image.
758 Abort.
759 EOT
760 exit 1
761 fi
762 [ -s /usr/share/boot/busybox-static ] || install_package busybox-static
763 need_lib=false
764 mkdir -p $TMP_DIR/initfs/bin $TMP_DIR/initfs/dev $TMP_DIR/initfs/run \
765 $TMP_DIR/initfs/mnt $TMP_DIR/initfs/proc $TMP_DIR/initfs/tmp \
766 $TMP_DIR/initfs/sys $TMP_DIR/initfs/lib/modules
767 ln -s bin $TMP_DIR/initfs/sbin
768 ln -s . $TMP_DIR/initfs/usr
769 while [ ! -f /lib/modules/$version/kernel/fs/aufs/aufs.ko.?z ]; do
770 install_package aufs $version || return 1
771 done
772 cp /init $TMP_DIR/initfs/
773 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
774 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
775 $TMP_DIR/initfs/lib/modules 2> /dev/null
776 cp -a /dev/tty0 /dev/fd0 $TMP_DIR/initfs/dev 2> /dev/null
777 cp /lib/modules/$version/kernel/fs/aufs/aufs.ko.?z \
778 $TMP_DIR/initfs/lib/modules
779 if [ "$1" == "cdrom" ]; then
780 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
781 else
782 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
783 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
784 install_package linux-squashfs $version || return 1
785 done
786 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
787 $TMP_DIR/initfs/lib/modules
788 ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
789 cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
790 fi
791 for i in $(ls /dev/[hs]d[a-f]*); do
792 cp -a $i $TMP_DIR/initfs/dev
793 done
794 if [ "$1" == "http" ]; then
795 mkdir $TMP_DIR/initfs/etc
796 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
797 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
798 sed -i 's|/sbin/||' $TMP_DIR/initfs/lib/udhcpc
799 cp -a /dev/fuse $TMP_DIR/initfs/dev
800 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
801 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/httpfs
802 else
803 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
804 need_lib=true
805 fi
806 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
807 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
808 else
809 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
810 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
811 cp -a /lib/librt* $TMP_DIR/initfs/lib
812 cp -a /lib/libdl* $TMP_DIR/initfs/lib
813 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
814 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
815 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
816 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
817 need_lib=true
818 fi
819 cd $TMP_DIR/initfs
820 echo "Getting slitaz-release..."
821 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
822 ( zcat $i 2> /dev/null || unlzma -c $i) | \
823 cpio -idmu etc/slitaz-release > /dev/null
824 done
825 cd - > /dev/null
826 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"
827 echo -n "List of urls to insert: "
828 read -t 30 urliso2
829 urliso="$urliso2 $urliso"
830 fi
831 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
832 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
833 sed -i 's/LD_T.*ot/newline/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
834 else
835 cp /bin/busybox $TMP_DIR/initfs/bin
836 need_lib=true
837 fi
838 for i in $($TMP_DIR/initfs/bin/busybox | awk \
839 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
840 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
841 done
842 for i in /dev/console /dev/loop* /dev/null /dev/tty /dev/zero \
843 /dev/kmem /dev/mem /dev/random /dev/urandom; do
844 cp -a $i $TMP_DIR/initfs/dev
845 done
846 $need_lib && for i in /lib/ld-* /lib/lib[cm].so* /lib/lib[cm]-* ; do
847 cp -a $i $TMP_DIR/initfs/lib
848 done
849 [ "$1" == "http" ] && cat > $TMP_DIR/initfs/init <<EOTEOT
850 #!/bin/sh
852 getarg()
853 {
854 grep -q " \$1=" /proc/cmdline || return 1
855 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
856 return 0
857 }
859 copy_rootfs()
860 {
861 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
862 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
863 [ \$(( \$total / \$need )) -gt 1 ] || return 1
864 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
865 path=/mnt/
866 return 0
867 else
868 rm -f /mnt/rootfs*
869 return 1
870 fi
871 }
873 echo "Switching / to tmpfs..."
874 mount -t proc proc /proc
875 size="\$(grep rootfssize= < /proc/cmdline | \\
876 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
877 [ -n "\$size" ] || size="-o size=90%"
879 while read var default; do
880 eval \$var=\$default
881 getarg \$var \$var
882 done <<EOT
883 eth eth0
884 dns 208.67.222.222,208.67.220.220
885 netmask 255.255.255.0
886 gw
887 ip
888 EOT
889 if [ -n "\$ip" ]; then
890 ifconfig \$eth \$ip netmask \$netmask up
891 route add default gateway \$gw
892 for i in \$(echo \$dns | sed 's/,/ /g'); do
893 echo "nameserver \$i" >> /etc/resolv.conf
894 done
895 else
896 udhcpc -f -q -s /lib/udhcpc -i \$eth
897 fi
898 for i in $urliso ; do
899 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
900 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"
901 done
902 getarg urliso URLISO
903 DIR=fs
904 if getarg loram DIR; then
905 DEVICE=\${DIR%,*}
906 DIR=/\${DIR#*,}
907 fi
908 mount -t tmpfs \$size tmpfs /mnt
909 path2=/mnt/.httpfs/
910 path=/mnt/.cdrom/
911 mkdir -p /mnt/.rw \$path \$path2
912 while [ ! -d \$path/boot ]; do
913 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
914 httpfs \$i \$path2 && break
915 done
916 mount -o loop,ro -t iso9660 \$path2/*.iso \$path
917 done
919 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
920 umount /proc
921 branch=br=/mnt/.rw:/mnt/.cdrom/\$DIR
922 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
923 branch=br=/mnt/.rw
924 for i in \${path}rootfs* ; do
925 fs=\${i#*root}
926 branch=\$branch:/mnt/.\$fs
927 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
928 insmod /lib/squashfs.ko.gz 2> /dev/null
929 mount -o loop,ro -t squashfs \${path}root\$fs /mnt/.\$fs
930 done
931 else
932 mkdir -p /mnt/.rw/mnt/.httpfs
933 fi
934 insmod /lib/aufs.ko.gz
935 mount -t aufs -o \$branch none /mnt
936 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
937 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
938 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
939 EOTEOT
940 chmod +x $TMP_DIR/initfs/init
941 for i in $TMP_DIR/initfs/lib/modules/*z ; do
942 unxz $i || gunzip $i || lzma d $i ${i%.gz}
943 rm -f $i
944 gzip -9 ${i%.gz}
945 done 2> /dev/null
946 ( cd $TMP_DIR/initfs ; find | busybox cpio -o -H newc 2> /dev/null) | \
947 lzma e $TMP_DIR/initfs.gz -si
948 lzma_set_size $TMP_DIR/initfs.gz
949 rm -rf $TMP_DIR/initfs
950 align_to_32bits $TMP_DIR/initfs.gz
951 return 0
952 }
954 # Move each initramfs to squashfs
955 build_loram_rootfs()
956 {
957 rootfs_sizes=""
958 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
959 mkdir -p $TMP_DIR/fs
960 cd $TMP_DIR/fs
961 ( zcat $i 2> /dev/null || unlzma -c $i) | cpio -idm
962 cd - > /dev/null
963 rootfs=$TMP_DIR/$(basename $i)
964 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp xz -Xbcj x86
965 cd $TMP_DIR
966 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
967 ( cd $(dirname $rootfs); echo $(basename $rootfs) | \
968 cpio -o -H newc ) > $rootfs.cpio
969 rm -f $rootfs
970 mv $rootfs.cpio $rootfs
971 cd - > /dev/null
972 rm -rf $TMP_DIR/fs
973 done
974 }
976 # Move meta boot configuration files to basic configuration files
977 # because meta loram flavor is useless when rootfs is not loaded in ram
978 unmeta_boot()
979 {
980 local root=${1:-$TMP_DIR/loramiso}
981 if [ -f $root/boot/isolinux/noram.cfg ]; then
982 # We keep enough information to do unloram...
983 [ -s $root/boot/isolinux/common.cfg ] &&
984 sed -i 's/label slitaz/label orgslitaz/' \
985 $root/boot/isolinux/common.cfg
986 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
987 shift
988 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
989 $root/boot/isolinux/isolinux.cfg
990 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
991 sed -i "s/label $3\$/label slitaz/;s|=/boot/rootfs\(.*\).gz |=/boot/rootfs.gz |" \
992 $root/boot/isolinux/*.cfg
993 fi
994 }
996 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs.
997 # These squashfs may be loaded in ram at boot time.
998 # Rootfs are also copied to cdrom for tiny ramsize systems.
999 # Meta flavors are converted to normal flavors.
1000 build_loram_cdrom()
1002 build_initfs cdrom || return 1
1003 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1004 mkdir $TMP_DIR/loramiso/fs
1005 cd $TMP_DIR/loramiso/fs
1006 for i in $( ls ../boot/root* | sort -r ) ; do
1007 ( zcat $i 2> /dev/null || unlzma -c $i ) | cpio -idmu
1008 rm -f $i
1009 done
1010 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1011 cd - > /dev/null
1012 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1013 unmeta_boot
1014 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1015 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1016 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1017 create_iso $OUTPUT $TMP_DIR/loramiso
1020 # Create http bootstrap to load and remove loram_cdrom
1021 # Meta flavors are converted to normal flavors.
1022 build_loram_http()
1024 build_initfs http || return 1
1025 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1026 rm -f $TMP_DIR/loramiso/boot/rootfs*
1027 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1028 unmeta_boot
1029 create_iso $OUTPUT $TMP_DIR/loramiso
1032 # Update meta flavor selection sizes.
1033 # Reduce sizes with rootfs gains.
1034 update_metaiso_sizes()
1036 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1037 do
1038 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1039 local sizes="$rootfs_sizes"
1040 local new
1041 set -- $append
1042 shift
1043 [ "$1" == "ifmem" ] && shift
1044 new=""
1045 while [ -n "$2" ]; do
1046 local s
1047 case "$1" in
1048 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1049 *M) s=$(( ${1%M} * 1024 ));;
1050 *) s=${1%K};;
1051 esac
1052 sizes=${sizes#* }
1053 for i in $sizes ; do
1054 s=$(( $s - $i ))
1055 done
1056 new="$new $s $2"
1057 shift 2
1058 done
1059 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1060 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1061 sed -i 's|\(initrd=\)\(/boot/rootfs.\.gz\)|\1/boot/rootfs.gz,\2|' $cfg
1062 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1063 done
1066 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs.
1067 # Meta flavor selection sizes are updated.
1068 build_loram_ram()
1070 build_initfs ram || return 1
1071 build_loram_rootfs
1072 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1073 rm -f $TMP_DIR/loramiso/boot/bzImage
1074 ln $TMP_DIR/loramiso/boot/vmlinuz* $TMP_DIR/loramiso/boot/bzImage
1075 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1076 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1077 update_metaiso_sizes
1078 create_iso $OUTPUT $TMP_DIR/loramiso
1081 # Remove files installed by packages
1082 find_flavor_rootfs()
1084 for i in $1/etc/tazlito/*.extract; do
1085 [ -e $i ] || continue
1086 chroot $1 /bin/sh ${i#$1}
1087 done
1089 # Clean hardlinks and files patched by genisofs in /boot
1090 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1091 rm -f $1/boot/$i
1092 done
1094 # Clean files generated in post_install
1095 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1096 $1/dev/core $1/dev/fd $1/dev/std*
1098 # Verify md5
1099 cat $1$INSTALLED/*/md5sum | \
1100 while read md5 file; do
1101 [ -e $1$file ] || continue
1102 [ "$(md5sum < $1$file)" == "$md5 -" ] &&
1103 rm -f $1$file
1104 done
1106 # Check configuration files
1107 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1108 [ -e $i ] || continue
1109 mkdir /tmp/volatile$$
1110 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1111 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1112 while read file ; do
1113 [ -e $1/$file ] || continue
1114 cmp -s /tmp/volatile$$/$file $1/$file && rm -f $1/$file
1115 done
1116 rm -rf /tmp/volatile$$
1117 done
1119 # Remove other files blindly
1120 for i in $1$INSTALLED/*/files.list; do
1121 for file in $(cat $i); do
1122 [ $1$file -nt $i ] && continue
1123 [ -f $1$file -a ! -L $1$file ] && continue
1124 [ -d $1$file ] || rm -f $1$file
1125 done
1126 done
1128 # Remove tazpkg files and tmp files
1129 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1130 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1131 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1132 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1133 $1/var/lib/* $1/var/lib/dbus/* 2> /dev/null
1135 # Cleanup directory tree
1136 cd $1
1137 find * -type d | sort -r | while read dir; do
1138 rmdir $dir 2> /dev/null
1139 done
1140 cd - > /dev/null
1143 ####################
1144 # Tazlito commands #
1145 ####################
1147 case "$COMMAND" in
1148 stats)
1149 # Tazlito general statistics from the config file.
1151 newline
1152 boldify "Tazlito statistics"
1153 separator
1154 echo "\
1155 Config file : $CONFIG_FILE
1156 ISO name : $ISO_NAME.iso
1157 Volume name : $VOLUM_NAME
1158 Prepared : $PREPARED
1159 Packages repository : $PACKAGES_REPOSITORY
1160 Distro directory : $DISTRO"
1161 if [ ! "$ADDFILES" = "" ] ; then
1162 echo -e "Additional files : $ADDFILES"
1163 fi
1164 separator && newline ;;
1166 list-addfiles)
1167 # Simple list of additional files in the rootfs
1168 newline
1169 cd $ADDFILES
1170 find rootfs -type f
1171 newline ;;
1173 gen-config)
1174 # Generate a new config file in the current dir or the specified
1175 # directory by $2.
1177 if [ -n "$2" ] ; then
1178 mkdir -p $2 && cd $2
1179 fi
1180 echo -n "Generating empty tazlito.conf..."
1181 empty_config_file
1182 status
1183 newline
1184 if [ -f "tazlito.conf" ] ; then
1185 echo "Configuration file is ready to edit."
1186 echo "File location : `pwd`/tazlito.conf"
1187 newline
1188 fi ;;
1190 configure)
1191 # Configure a tazlito.conf config file. Start by getting
1192 # a empty config file and sed it.
1194 if [ -f "tazlito.conf" ] ; then
1195 rm tazlito.conf
1196 else
1197 if test $(id -u) = 0 ; then
1198 cd /etc
1199 else
1200 echo "You must be root to configure the main config file or in"
1201 echo "the same directory of the file you want to configure."
1202 exit 0
1203 fi
1204 fi
1205 empty_config_file
1206 echo""
1207 echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
1208 separator
1209 # ISO name.
1210 echo -n "ISO name : " ; read answer
1211 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1212 # Volume name.
1213 echo -n "Volume name : " ; read answer
1214 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1215 # Packages repository.
1216 echo -n "Packages repository : " ; read answer
1217 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1218 # Distro path.
1219 echo -n "Distro path : " ; read answer
1220 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1221 separator
1222 echo "Config file is ready to use."
1223 echo "You can now extract an ISO or generate a distro."
1224 newline ;;
1226 gen-iso)
1227 # Simply generate a new iso.
1229 check_root
1230 verify_rootcd
1231 gen_livecd_isolinux
1232 distro_stats ;;
1234 gen-initiso)
1235 # Simply generate a new initramfs with a new iso.
1237 check_root
1238 verify_rootcd
1239 gen_initramfs $ROOTFS
1240 gen_livecd_isolinux
1241 distro_stats ;;
1243 extract-distro)
1244 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1246 check_root
1247 ISO_IMAGE=$2
1248 if [ -z "$ISO_IMAGE" ] ; then
1249 echo -e "\nPlease specify the path to the ISO image."
1250 echo -e "Example : `basename $0` image.iso /path/target\n"
1251 exit 0
1252 fi
1253 # Set the distro path by checking for $3 on cmdline.
1254 if [ -n "$3" ] ; then
1255 TARGET=$3
1256 else
1257 TARGET=$DISTRO
1258 fi
1259 # Exit if existing distro is found.
1260 if [ -d "$TARGET/rootfs" ] ; then
1261 echo -e "\nA rootfs exists in : $TARGET"
1262 echo -e "Please clean the distro tree or change directory path.\n"
1263 exit 0
1264 fi
1265 newline
1266 echo -e "\033[1mTazlito extracting :\033[0m `basename $ISO_IMAGE`"
1267 separator
1268 # Start to mount the ISO.
1269 newline
1270 echo "Mounting ISO image..."
1271 mkdir -p $TMP_DIR
1272 # Get ISO file size.
1273 isosize=`du -sh $ISO_IMAGE | cut -f1`
1274 mount -o loop $ISO_IMAGE $TMP_DIR
1275 sleep 2
1276 # Prepare target dir, copy the kernel and the rootfs.
1277 mkdir -p $TARGET/rootfs
1278 mkdir -p $TARGET/rootcd/boot
1279 echo -n "Copying the Linux kernel..."
1280 if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
1281 ln $TARGET/rootcd/boot/vmlinuz* $TARGET/rootcd/boot/bzImage
1282 else
1283 cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
1284 fi
1285 status
1286 echo -n "Copying isolinux files..."
1287 cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
1288 for i in $(ls $TMP_DIR); do
1289 [ "$i" = "boot" ] && continue
1290 cp -a $TMP_DIR/$i $TARGET/rootcd
1291 done
1292 status
1293 if [ -d $TMP_DIR/boot/syslinux ]; then
1294 echo -n "Copying syslinux files..."
1295 cp -a $TMP_DIR/boot/syslinux $TARGET/rootcd/boot
1296 status
1297 fi
1298 if [ -d $TMP_DIR/boot/extlinux ]; then
1299 echo -n "Copying extlinux files..."
1300 cp -a $TMP_DIR/boot/extlinux $TARGET/rootcd/boot
1301 status
1302 fi
1303 if [ -d $TMP_DIR/boot/grub ]; then
1304 echo -n "Copying GRUB files..."
1305 cp -a $TMP_DIR/boot/grub $TARGET/rootcd/boot
1306 status
1307 fi
1309 echo -n "Copying the rootfs..."
1310 cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
1311 status
1312 # Extract initramfs.
1313 cd $TARGET/rootfs
1314 echo -n "Extracting the rootfs... "
1315 extract_rootfs ../rootcd/boot/rootfs.gz $TARGET/rootfs
1316 # unpack /usr
1317 for i in etc/tazlito/*.extract; do
1318 [ -f "$i" ] && . $i ../rootcd
1319 done
1320 # Umount and remove temp directory and cd to $TARGET to get stats.
1321 umount $TMP_DIR && rm -rf $TMP_DIR
1322 cd ..
1323 newline
1324 separator
1325 echo "Extracted : `basename $ISO_IMAGE` ($isosize)"
1326 echo "Distro tree : `pwd`"
1327 echo "Rootfs size : `du -sh rootfs`"
1328 echo "Rootcd size : `du -sh rootcd`"
1329 separator
1330 newline ;;
1332 list-flavors)
1333 # Show available flavors.
1334 if [ ! -s /etc/tazlito/flavors.list -o "$2" == "--recharge" ]; then
1335 download flavors.list -O - > /etc/tazlito/flavors.list
1336 fi
1337 newline
1338 boldify "List of flavors"
1339 separator
1340 cat /etc/tazlito/flavors.list
1341 newline ;;
1343 show-flavor)
1344 # Show flavor description.
1345 FLAVOR=${2%.flavor}
1346 if [ ! -f "$FLAVOR.flavor" ]; then
1347 echo "File $FLAVOR.flavor not found."
1348 exit 1
1349 fi
1350 mkdir $TMP_DIR
1351 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i > /dev/null)
1352 if [ "$3" = "--brief" ]; then
1353 if [ "$4" != "--noheader" ]; then
1354 echo "Name ISO Rootfs Description"
1355 separator
1356 fi
1357 printf "%-16.16s %6.6s %6.6s %s\n" "$FLAVOR" \
1358 "$(field ISO $TMP_DIR/$FLAVOR.desc)" \
1359 "$(field 'Rootfs size' $TMP_DIR/$FLAVOR.desc)" \
1360 "$(grep ^Description $TMP_DIR/$FLAVOR.desc | cut -d: -f2)"
1361 else
1362 separator
1363 cat $TMP_DIR/$FLAVOR.desc
1364 fi
1365 rm -Rf $TMP_DIR ;;
1367 gen-liveflavor)
1368 # Generate a new flavor from the live system.
1369 FLAVOR=${2%.flavor}
1370 DESC=""
1371 case "$FLAVOR" in
1372 '') echo -n "Flavor name : "
1373 read FLAVOR
1374 [ -z "$FLAVOR" ] && exit 1;;
1375 -?|-h*|--help) echo -e "
1377 SliTaz Live Tool - Version: $VERSION
1378 \033[1mUsage: \033[0m `basename $0` gen-liveflavor flavor-name [flavor-patch-file]
1379 \033[1mflavor-patch-file format: \033[0m
1380 code data
1381 + package to add
1382 - package to remove
1383 ! non-free package to add
1384 ? display message
1385 @ flavor description
1387 \033[1mExample: \033[0m
1388 @ Developer tools for slitaz maintainers
1389 + slitaz-toolchain
1390 + mercurial
1392 exit 1;;
1393 esac
1394 mv /etc/tazlito/distro-packages.list \
1395 /etc/tazlito/distro-packages.list.$$ 2> /dev/null
1396 rm -f distro-packages.list non-free.list 2> /dev/null
1397 tazpkg recharge
1398 [ -n "$3" ] && while read action pkg; do
1399 case "$action" in
1400 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
1401 -) yes | tazpkg remove $pkg ;;
1402 !) echo $pkg >> non-free.list ;;
1403 @) DESC="$pkg" ;;
1404 \?) echo -en "$pkg"; read action ;;
1405 esac
1406 done < $3
1407 yes '' | tazlito gen-distro
1408 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
1409 mv /etc/tazlito/distro-packages.list.$$ \
1410 /etc/tazlito/distro-packages.list 2> /dev/null ;;
1412 gen-flavor)
1413 # Generate a new flavor from the last iso image generated.
1414 FLAVOR=${2%.flavor}
1415 newline
1416 boldify "Flavor generation"
1417 separator
1418 if [ -z "$FLAVOR" ]; then
1419 echo -n "Flavor name : "
1420 read FLAVOR
1421 [ -z "$FLAVOR" ] && exit 1
1422 fi
1423 check_rootfs
1424 FILES="$FLAVOR.pkglist"
1425 echo -n "Creating file $FLAVOR.flavor..."
1426 for i in rootcd rootfs; do
1427 if [ -d "$ADDFILES/$i" ] ; then
1428 FILES="$FILES\n$FLAVOR.$i"
1429 ( cd "$ADDFILES/$i"; find . | \
1430 cpio -o -H newc 2> /dev/null | gzip -9 ) > $FLAVOR.$i
1431 fi
1432 done
1433 status
1434 answer=`grep -s ^Description $FLAVOR.desc`
1435 answer=${answer#Description : }
1436 if [ -z "$answer" ]; then
1437 echo -n "Description : "
1438 read answer
1439 fi
1440 echo -n "Compressing flavor $FLAVOR..."
1441 echo "Flavor : $FLAVOR" > $FLAVOR.desc
1442 echo "Description : $answer" >> $FLAVOR.desc
1443 ( cd $DISTRO; distro_sizes) >> $FLAVOR.desc
1444 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2> /dev/null
1445 for i in $(ls $ROOTFS$INSTALLED); do
1446 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
1447 EXTRAVERSION=""
1448 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
1449 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
1450 if [ "$CATEGORY" = "non-free" -a "${i%%-*}" != "get" ]
1451 then
1452 echo "$i" >> $FLAVOR.nonfree
1453 else
1454 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
1455 fi
1456 done
1457 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
1458 for i in $LOCALSTATE/undigest/*/mirror ; do
1459 [ -s $i ] && cat $i >> $FLAVOR.mirrors
1460 done
1461 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
1462 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | \
1463 gzip -9 > $FLAVOR.flavor
1464 rm `echo -e $FILES`
1465 status
1466 separator
1467 echo "Flavor size : `du -sh $FLAVOR.flavor`"
1468 newline ;;
1470 upgrade-flavor)
1471 # Update package list to the latest versions available.
1472 FLAVOR=${2%.flavor}
1473 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1474 mkdir $TMP_DIR
1475 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1476 echo -n "Updating $FLAVOR package list..."
1477 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1478 packed_size=0; unpacked_size=0
1479 while read org; do
1480 i=0
1481 pkg=$org
1482 while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
1483 pkg=${pkg%-*}
1484 i=$(($i + 1))
1485 [ $i -gt 5 ] && break;
1486 done
1487 set -- $(get_size $pkg)
1488 packed_size=$(( $packed_size + $1 ))
1489 unpacked_size=$(( $unpacked_size + $2 ))
1490 for i in $(grep ^$pkg $LOCALSTATE/packages.list); do
1491 echo $i
1492 break
1493 done
1494 done < $TMP_DIR/$FLAVOR.pkglist \
1495 > $TMP_DIR/$FLAVOR.pkglist.$$
1496 mv -f $TMP_DIR/$FLAVOR.pkglist.$$ $TMP_DIR/$FLAVOR.pkglist
1497 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1498 packed_size=$(($packed_size \
1499 + $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
1500 unpacked_size=$(($unpacked_size \
1501 + $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1502 fi
1503 # Estimate lzma
1504 packed_size=$(($packed_size * 2 / 3))
1505 iso_size=$(( $packed_size + 26000 ))
1506 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1507 iso_size=$(($iso_size \
1508 + $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1509 fi
1510 sed -i -e '/Image is ready/d' \
1511 -e "s/Rootfs size\( *:\) \(.*\)/Rootfs size\1 $(cent2human $unpacked_size) (estimated)/" \
1512 -e "s/Initramfs size\( *:\) \(.*\)/Initramfs size\1 $(cent2human $packed_size) (estimated)/" \
1513 -e "s/ISO image size\( *:\) \(.*\)/ISO image size\1 $(cent2human $iso_size) (estimated)/" \
1514 -e "s/date\( *:\) \(.*\)/date\1 $(date +%Y%m%d\ \at\ \%H:%M:%S)/" \
1515 $TMP_DIR/$FLAVOR.desc
1516 ( cd $TMP_DIR ; ls | cpio -o -H newc ) | gzip -9 > \
1517 $FLAVOR.flavor
1518 status
1519 rm -Rf $TMP_DIR
1520 fi ;;
1522 extract-flavor)
1523 # Extract a flavor into $FLAVORS_REPOSITORY.
1524 FLAVOR=${2%.flavor}
1525 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1526 mkdir $TMP_DIR
1527 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1528 echo -n "Extracting $FLAVOR..."
1529 rm -rf $FLAVORS_REPOSITORY/$FLAVOR 2> /dev/null
1530 mkdir -p $FLAVORS_REPOSITORY/$FLAVOR
1531 cp $TMP_DIR/$FLAVOR.receipt $FLAVORS_REPOSITORY/$FLAVOR/receipt
1532 #~ echo "FLAVOR=\"$FLAVOR\"" > $FLAVORS_REPOSITORY/$FLAVOR/receipt
1533 #~ grep ^Description $TMP_DIR/$FLAVOR.desc | \
1534 #~ sed 's/.*: \(.*\)$/SHORT_DESC="\1"/' >> \
1535 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1536 #~ grep ^Version $TMP_DIR/$FLAVOR.desc | \
1537 #~ sed 's/.*: \(.*\)$/VERSION="\1"/' >> \
1538 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1539 #~ grep ^Maintainer $TMP_DIR/$FLAVOR.desc | \
1540 #~ sed 's/.*: \(.*\)$/MAINTAINER="\1"/' >> \
1541 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1542 #~ grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc && \
1543 #~ grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1544 #~ sed 's/.*: \(.*\)$/ROOTFS_SELECTION="\1"/' >> \
1545 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1546 #~ grep '^Rootfs size' $TMP_DIR/$FLAVOR.desc | \
1547 #~ sed 's/.*: \(.*\)$/ROOTFS_SIZE="\1"/' >> \
1548 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1549 #~ grep ^Initramfs $TMP_DIR/$FLAVOR.desc | \
1550 #~ sed 's/.*: \(.*\)$/INITRAMFS_SIZE="\1"/' >> \
1551 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1552 #~ grep ^ISO $TMP_DIR/$FLAVOR.desc | \
1553 #~ sed 's/.*: \(.*\)$/ISO_SIZE="\1"/' >> \
1554 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1555 for i in rootcd rootfs; do
1556 [ -f $TMP_DIR/$FLAVOR.$i ] || continue
1557 mkdir $FLAVORS_REPOSITORY/$FLAVOR/$i
1558 zcat < $TMP_DIR/$FLAVOR.$i | \
1559 (cd $FLAVORS_REPOSITORY/$FLAVOR/$i; \
1560 cpio -idm > /dev/null)
1561 done
1562 [ -s $TMP_DIR/$FLAVOR.mirrors ] &&
1563 cp $TMP_DIR/$FLAVOR.mirrors \
1564 $FLAVORS_REPOSITORY/$FLAVOR/mirrors
1565 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1566 while read org; do
1567 i=0
1568 pkg=$org
1569 while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
1570 pkg=${pkg%-*}
1571 i=$(($i + 1))
1572 [ $i -gt 5 ] && break;
1573 done
1574 echo $pkg
1575 done < $TMP_DIR/$FLAVOR.pkglist \
1576 > $FLAVORS_REPOSITORY/$FLAVOR/packages.list
1577 status
1578 rm -Rf $TMP_DIR
1579 fi ;;
1581 pack-flavor)
1582 # Create a flavor from $FLAVORS_REPOSITORY.
1583 FLAVOR=${2%.flavor}
1584 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1585 mkdir $TMP_DIR
1586 echo -n "Creating flavor $FLAVOR..."
1587 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1588 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/mirrors ]; then
1589 cp $FLAVORS_REPOSITORY/$FLAVOR/mirrors \
1590 $TMP_DIR/$FLAVOR.mirrors
1591 for i in $(cat $TMP_DIR/$FLAVOR.mirrors); do
1592 wget -O - $i/packages.list >> $TMP_DIR/packages.list
1593 done
1594 fi
1595 # add distro.sh if exists
1596 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/distro.sh ]; then
1597 cp $FLAVORS_REPOSITORY/$FLAVOR/distro.sh $TMP_DIR/$FLAVOR-distro.sh
1598 fi
1600 # Get receipt in .flavor
1601 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1602 cp $FLAVORS_REPOSITORY/$FLAVOR/receipt $TMP_DIR/$FLAVOR.receipt
1603 fi
1605 # Build the package list.
1607 # On peut inclure une liste venant d'une autre saveur avec le mot clé @include
1608 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ]; then
1609 INCLUDE=$(grep '^@include' $FLAVORS_REPOSITORY/$FLAVOR/packages.list)
1610 if [ ! -z "$INCLUDE" ]; then
1611 INCLUDE=${INCLUDE#@include }
1612 [ -s "$FLAVORS_REPOSITORY/$INCLUDE/packages.list" ] && \
1613 get_pkglist $INCLUDE > $TMP_DIR/$FLAVOR.pkglist || \
1614 echo -e "\nERROR: Can't find include package list from $INCLUDE\n"
1615 fi
1616 # Generate the final/initial package list
1617 [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ] && \
1618 get_pkglist $FLAVOR >> $TMP_DIR/$FLAVOR.pkglist
1619 fi
1620 if grep -q ^ROOTFS_SELECTION \
1621 $FLAVORS_REPOSITORY/$FLAVOR/receipt; then
1622 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1623 set -- $ROOTFS_SELECTION
1624 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
1625 [ -f $FLAVORS_REPOSITORY/$2/packages.list ] ||
1626 tazlito extract-flavor $2
1627 get_pkglist $2 > $TMP_DIR/$FLAVOR.pkglist
1628 for i in rootcd rootfs; do
1629 mkdir $TMP_DIR/$i
1630 # Copy extra files from the first flavor
1631 [ -d $FLAVORS_REPOSITORY/$2/$i ] &&
1632 cp -a $FLAVORS_REPOSITORY/$2/$i $TMP_DIR
1633 # Overload extra files by meta flavor
1634 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] &&
1635 cp -a $FLAVORS_REPOSITORY/$FLAVOR/$i $TMP_DIR
1636 [ -n "$(ls $TMP_DIR/$i)" ] &&
1637 ( cd $TMP_DIR/$i ; find . | cpio -o -H newc 2> /dev/null ) | \
1638 gzip -9 >$TMP_DIR/$FLAVOR.$i
1639 rm -rf $TMP_DIR/$i
1640 done
1641 else
1642 for i in rootcd rootfs; do
1643 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] || \
1644 continue
1645 ( cd $FLAVORS_REPOSITORY/$FLAVOR/$i ; \
1646 find . | cpio -o -H newc 2> /dev/null ) | \
1647 gzip -9 >$TMP_DIR/$FLAVOR.$i
1648 done
1649 fi
1650 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1651 packed_size=$(($packed_size \
1652 + $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
1653 unpacked_size=$(($unpacked_size \
1654 + $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1655 fi
1656 # Estimate lzma
1657 packed_size=$(($packed_size * 2 / 3))
1658 iso_size=$(( $packed_size + 26000 ))
1659 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1660 iso_size=$(($iso_size \
1661 + $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1662 fi
1663 VERSION=""
1664 MAINTAINER=""
1665 ROOTFS_SELECTION=""
1666 ROOTFS_SIZE="$(cent2human $unpacked_size) (estimated)"
1667 INITRAMFS_SIZE="$(cent2human $packed_size) (estimated)"
1668 ISO_SIZE="$(cent2human $iso_size) (estimated)"
1669 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1670 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1671 Flavor : $FLAVOR
1672 Description : $SHORT_DESC
1673 EOT
1674 [ -n "$VERSION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1675 Version : $VERSION
1676 EOT
1677 [ -n "$MAINTAINER" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1678 Maintainer : $MAINTAINER
1679 EOT
1680 [ -n "$FRUGAL_RAM" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1681 LiveCD RAM size : $FRUGAL_RAM
1682 EOT
1683 [ -n "$ROOTFS_SELECTION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1684 Rootfs list : $ROOTFS_SELECTION
1685 EOT
1686 cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1687 Build date : $(date +%Y%m%d\ \at\ \%H:%M:%S)
1688 Packages : $(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l)
1689 Rootfs size : $ROOTFS_SIZE
1690 Initramfs size : $INITRAMFS_SIZE
1691 ISO image size : $ISO_SIZE
1692 ================================================================================
1694 EOT
1695 rm -f $TMP_DIR/packages.list
1696 ( cd $TMP_DIR ; ls | cpio -o -H newc 2> /dev/null) | \
1697 gzip -9 > $FLAVOR.flavor
1698 status
1699 rm -Rf $TMP_DIR
1700 else
1701 echo "No $FLAVOR flavor in $FLAVORS_REPOSITORY."
1702 fi ;;
1704 get-flavor)
1705 # Get a flavor's files and prepare for gen-distro.
1706 FLAVOR=${2%.flavor}
1707 echo -e "\n\033[1mPreparing $FLAVOR distro flavor\033[0m"
1708 separator
1709 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1710 echo -n "Cleaning $DISTRO..."
1711 rm -R $DISTRO 2> /dev/null
1712 mkdir -p $DISTRO
1713 status
1714 mkdir $TMP_DIR
1715 echo -n "Extracting flavor $FLAVOR.flavor... "
1716 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i --quiet >/dev/null )
1717 status
1718 echo -n "Creating distro-packages.list..."
1719 mv $TMP_DIR/$FLAVOR.nonfree non-free.list 2> /dev/null
1720 mv $TMP_DIR/$FLAVOR.pkglist distro-packages.list
1721 status
1722 if [ -f "$TMP_DIR/$FLAVOR-distro.sh" ]; then
1723 echo -n "Extracting distro.sh... "
1724 mv $TMP_DIR/$FLAVOR-distro.sh distro.sh 2> /dev/null
1725 status
1726 fi
1727 if [ -f "$TMP_DIR/$FLAVOR.receipt" ]; then
1728 echo -n "Extracting receipt... "
1729 mv $TMP_DIR/$FLAVOR.receipt receipt 2> /dev/null
1730 status
1731 fi
1732 infos="$FLAVOR.desc"
1733 for i in rootcd rootfs; do
1734 if [ -f $TMP_DIR/$FLAVOR.$i ]; then
1735 echo -n "Adding $i files... "
1736 mkdir -p "$ADDFILES/$i"
1737 zcat < $TMP_DIR/$FLAVOR.$i | \
1738 ( cd "$ADDFILES/$i"; cpio -id --quiet > /dev/null)
1739 zcat < $TMP_DIR/$FLAVOR.$i | cpio -tv 2> /dev/null \
1740 > $TMP_DIR/$FLAVOR.list$i
1741 infos="$infos\n$FLAVOR.list$i"
1742 status
1743 fi
1744 done
1745 if [ -s $TMP_DIR/$FLAVOR.mirrors ]; then
1746 n=""
1747 while read line; do
1748 mkdir -p $LOCALSTATE/undigest/$FLAVOR$n
1749 echo "$line" > $LOCALSTATE/undigest/$FLAVOR$n/mirror
1750 n=$(( $n + 1 ))
1751 done < $TMP_DIR/$FLAVOR.mirrors
1752 infos="$infos\n$FLAVOR.mirrors"
1753 tazpkg recharge
1754 fi
1755 rm -f /etc/tazlito/rootfs.list
1756 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc &&
1757 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1758 sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
1759 echo -n "Updating tazlito.conf..."
1760 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
1761 grep -v "^#VOLUM_NAME" < tazlito.conf | \
1762 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $FLAVOR\"\\n#VOLUM_NA/" \
1763 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
1764 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$FLAVOR\"/" tazlito.conf
1765 status
1766 ( cd $TMP_DIR ; echo -e $infos | cpio -o -H newc ) | \
1767 gzip -9 > /etc/tazlito/info
1768 rm -Rf $TMP_DIR
1769 fi
1770 separator
1771 echo -e "Flavor is ready to be generated by: tazlito gen-distro\n" ;;
1773 iso2flavor)
1774 if [ -z "$3" -o ! -s "$2" ]; then
1775 cat <<EOT
1776 Usage : tazlito iso2flavor image.iso flavor_name
1778 Create a file flavor_name.flavor from the cdrom image file image.iso
1779 EOT
1780 exit 1
1781 fi
1782 FLAVOR=${3%.flavor}
1783 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs
1784 mount -o loop,ro $2 $TMP_DIR/iso
1785 if [ -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
1786 echo "META flavors are not supported."
1787 umount -d $TMP_DIR/iso
1788 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz ]; then
1789 echo "No /boot/rootfs.gz in iso image. Needs a SliTaz iso."
1790 umount -d $TMP_DIR/iso
1791 else
1792 ( unlzma -c $TMP_DIR/iso/boot/rootfs.gz || \
1793 zcat $TMP_DIR/iso/boot/rootfs.gz ) | \
1794 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
1795 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
1796 echo "No file /etc/slitaz-release in /boot/rootfs.gz of iso image. Needs a non loram SliTaz iso."
1797 umount -d $TMP_DIR/iso
1798 else
1799 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
1800 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
1801 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
1802 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
1803 BUILD_DATE=$(date +%Y%m%d\ \at\ \%H:%M:%S -r $TMP_DIR/iso/md5sum)
1804 umount -d $TMP_DIR/iso
1805 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs.gz | awk '{ s=$1 } END { print $1 }')
1806 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
1807 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
1808 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
1809 < $TMP_DIR/rootfs$INSTALLED.md5
1810 #[ -s $TMP_DIR/rootfs/etc/tazlito/distro-packages.list ] &&
1811 # mv $TMP_DIR/rootfs/etc/tazlito/distro-packages.list $TMP_DIR/$FLAVOR.pkglist
1812 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
1813 find_flavor_rootfs $TMP_DIR/rootfs
1814 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
1815 [ -n "$(ls $TMP_DIR/rootfs)" ] && ( cd $TMP_DIR/rootfs ; find * | cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.rootfs
1816 [ -n "$(ls $TMP_DIR/rootcd)" ] && ( cd $TMP_DIR/rootcd ; find * | cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.rootcd
1817 rm -rf $TMP_DIR/rootcd $TMP_DIR/rootfs
1818 VERSION=""; MAINTAINER=""
1819 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
1820 if [ -n "$DESCRIPTION" ]; then
1821 echo -en "Flavor version : "; read -t 30 VERSION
1822 echo -en "Flavor maintainer (your email) : "; read -t 30 MAINTAINER
1823 fi
1824 [ -n "$DESCRIPTION" ] || DESCRIPTION="Slitaz $FLAVOR flavor"
1825 [ -n "$VERSION" ] || VERSION="1.0"
1826 [ -n "$MAINTAINER" ] || MAINTAINER="nobody@slitaz.org"
1827 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1828 Flavor : $FLAVOR
1829 Description : $DESCRIPTION
1830 Version : $VERSION
1831 Maintainer : $MAINTAINER
1832 LiveCD RAM size : $RAM_SIZE
1833 Build date : $BUILD_DATE
1834 Packages : $PKGCNT
1835 Rootfs size : $ROOTFS_SIZE
1836 Initramfs size : $INITRAMFS_SIZE
1837 ISO image size : $ISO_SIZE
1838 ================================================================================
1840 EOT
1841 ( cd $TMP_DIR ; ls $FLAVOR.* | cpio -o -H newc ) | gzip -9 > $FLAVOR.flavor
1842 cat <<EOT
1843 Tazlito can't detect each file installed during a package post_install.
1844 You should extract this flavor (tazlito extract-flavor $FLAVOR),
1845 check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs tree and remove
1846 files generated by post_installs.
1847 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and repack the flavor
1848 (tazlito pack-flavor $FLAVOR)
1849 EOT
1850 fi
1851 fi
1852 rm -rf $TMP_DIR ;;
1854 check-list)
1855 # Use current packages list in $PWD by default.
1856 DISTRO_PKGS_LIST=distro-packages.list
1857 [ -d "$2" ] && DISTRO_PKGS_LIST=$2/distro-packages.list
1858 [ -f "$2" ] && DISTRO_PKGS_LIST=$2
1859 [ ! -f $DISTRO_PKGS_LIST ] && echo "No packages list found." && exit 0
1860 newline
1861 boldify "LiveCD packages list check"
1862 separator
1863 for pkg in $(cat $DISTRO_PKGS_LIST)
1864 do
1865 if ! grep -q "$pkg" $LOCALSTATE/packages.list; then
1866 echo "Updating: $pkg"
1867 up=$(($up + 1))
1868 fi
1869 done
1870 [ -z $up ] && echo -e "List is up-to-date\n" && exit 0
1871 separator
1872 echo -e "Updates: $up\n" ;;
1874 gen-distro)
1875 # Generate a live distro tree with a set of packages.
1877 check_root
1878 time=$(date +%s)
1880 # Libtaz will set $iso or $cdrom
1881 CDROM=""
1882 [ "$iso" ] && CDROM="-o loop $iso"
1883 [ "$cdrom" ] && CDROM="/dev/cdrom"
1884 # Check if a package list was specified on cmdline.
1885 if [ -f "$2" ]; then
1886 LIST_NAME=$2
1887 else
1888 LIST_NAME="distro-packages.list"
1889 fi
1891 if [ -d "$ROOTFS" ] ; then
1892 # Delete $ROOTFS if --force is set on command line
1893 if [ "$forced" ]; then
1894 rm -rf $ROOTFS $ROOTCD
1895 else
1896 echo -e "\nA rootfs exists in : $DISTRO"
1897 echo -e "Please clean the distro tree or change directory path.\n"
1898 exit 0
1899 fi
1900 fi
1902 # Build list with installed packages
1903 if [ ! -f "$LIST_NAME" -a -d $INSTALLED ] ; then
1904 for i in $(ls $INSTALLED); do
1905 if grep -q ^_realver $INSTALLED/$i/receipt ; then
1906 VERSION=$(. $INSTALLED/$i/receipt 2>/dev/null ; echo $VERSION)
1907 else
1908 eval $(grep ^VERSION= $INSTALLED/$i/receipt)
1909 fi
1910 EXTRAVERSION=""
1911 eval $(grep ^EXTRAVERSION= $INSTALLED/$i/receipt)
1912 echo "$i-$VERSION$EXTRAVERSION" >> $LIST_NAME
1913 done
1914 fi
1915 # Exit if no list name.
1916 if [ ! -f "$LIST_NAME" ]; then
1917 echo -e "\nNo packages list found or specified. Please read the docs.\n"
1918 exit 0
1919 fi
1920 # Start generation.
1921 newline
1922 boldify "Tazlito generating a distro"
1923 separator
1924 # Misc checks
1925 [ -n "$PACKAGES_REPOSITORY" ] || PACKAGES_REPOSITORY="."
1926 [ -d $PACKAGES_REPOSITORY ] || mkdir -p $PACKAGES_REPOSITORY
1927 # Get the list of packages using cat for a file list.
1928 LIST=`cat $LIST_NAME`
1929 # Verify if all packages in list are present in $PACKAGES_REPOSITORY.
1930 REPACK=""
1931 DOWNLOAD=""
1932 for pkg in $LIST
1933 do
1934 [ "$pkg" = "" ] && continue
1935 pkg=${pkg%.tazpkg}
1936 [ -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] && continue
1937 PACKAGE=$(installed_package_name $pkg)
1938 [ -n "$PACKAGE" -a "$REPACK" = "y" ] && continue
1939 [ -z "$PACKAGE" -a -n "$DOWNLOAD" ] && continue
1940 echo -e "\nUnable to find $pkg in the repository."
1941 echo -e "Path : $PACKAGES_REPOSITORY\n"
1942 if [ -n "$PACKAGE" -a -z "$REPACK" ]; then
1943 yesorno "Repack packages from rootfs (y/N) ? "
1944 REPACK="$answer"
1945 [ "$answer" = "y" ] || REPACK="n"
1946 [ "$DOWNLOAD" = "y" ] && break
1947 fi
1948 if [ -f $MIRROR -a -z "$DOWNLOAD" ]; then
1949 yesorno "Download packages from mirror (Y/n) ? "
1950 DOWNLOAD="$answer"
1951 if [ "$answer" = "n" ]; then
1952 [ -z "$PACKAGE" ] && exit 1
1953 else
1954 DOWNLOAD="y"
1955 [ -n "$REPACK" ] && break
1956 fi
1957 fi
1958 [ "$REPACK" = "n" -a "$DOWNLOAD" = "n" ] && exit 1
1959 done
1961 # Mount cdrom to be able to repack boot-loader packages
1962 if [ ! -e /boot -a -n "$CDROM" ]; then
1963 mkdir $TMP_MNT
1964 if mount -r $CDROM $TMP_MNT 2> /dev/null; then
1965 ln -s $TMP_MNT/boot /
1966 if [ ! -d "$ADDFILES/rootcd" ] ; then
1967 mkdir -p $ADDFILES/rootcd
1968 for i in $(ls $TMP_MNT); do
1969 [ "$i" = "boot" ] && continue
1970 cp -a $TMP_MNT/$i $ADDFILES/rootcd
1971 done
1972 fi
1973 else
1974 rmdir $TMP_MNT
1975 fi
1976 fi
1978 # Rootfs stuff.
1979 echo "Preparing the rootfs directory..."
1980 mkdir -p $ROOTFS
1981 for pkg in $LIST
1982 do
1983 [ "$pkg" = "" ] && continue
1984 # First copy and extract the package in tmp dir.
1985 pkg=${pkg%.tazpkg}
1986 PACKAGE=$(installed_package_name $pkg)
1987 mkdir -p $TMP_DIR
1988 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1989 # Look for package in cache
1990 if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
1991 ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
1992 # Look for package in running distribution
1993 elif [ -n "$PACKAGE" -a "$REPACK" = "y" ]; then
1994 tazpkg repack $PACKAGE && \
1995 mv $pkg.tazpkg $PACKAGES_REPOSITORY
1996 fi
1997 fi
1998 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1999 # Get package from mirror
2000 [ "$DOWNLOAD" = "y" ] && \
2001 download $pkg.tazpkg && \
2002 mv $pkg.tazpkg $PACKAGES_REPOSITORY
2003 fi
2004 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2005 echo "Missing package: $pkg"
2006 cleanup
2007 exit 1
2008 fi
2009 done
2010 if [ -f non-free.list ]; then
2011 echo "Preparing non-free packages..."
2012 cp non-free.list $ROOTFS/etc/tazlito/non-free.list
2013 for pkg in $(cat non-free.list); do
2014 if [ ! -d $INSTALLED/$pkg ]; then
2015 if [ ! -d $INSTALLED/get-$pkg ]; then
2016 tazpkg get-install get-$pkg
2017 fi
2018 get-$pkg
2019 fi
2020 tazpkg repack $pkg
2021 pkg=$(ls $pkg*.tazpkg)
2022 grep -q "^$pkg$" $LIST_NAME || \
2023 echo $pkg >>$LIST_NAME
2024 mv $pkg $PACKAGES_REPOSITORY
2025 done
2026 fi
2027 cp $LIST_NAME $DISTRO/distro-packages.list
2028 sed 's/\(.*\)/\1.tazpkg/' < $DISTRO/distro-packages.list > $DISTRO/list-packages
2029 cd $PACKAGES_REPOSITORY
2030 for pkg in $(cat $DISTRO/list-packages)
2031 do
2032 echo -n "Installing package: $pkg"
2033 yes y | tazpkg -i $pkg --root=$ROOTFS 2>&1 >> $log || exit 1
2034 status
2035 done
2036 rm -f $ROOTFS/var/lib/tazpkg/packages.*
2037 cd $DISTRO
2038 cp distro-packages.list $ROOTFS/etc/tazlito
2039 # Copy all files from $ADDFILES/rootfs to the rootfs.
2040 if [ -d "$ADDFILES/rootfs" ] ; then
2041 echo -n "Copying addfiles content to the rootfs... "
2042 cp -a $ADDFILES/rootfs/* $ROOTFS
2043 status
2044 fi
2045 echo -n "Root filesystem is generated..." && status
2046 # Root CD part.
2047 echo -n "Preparing the rootcd directory..."
2048 mkdir -p $ROOTCD
2049 status
2050 # Move the boot dir with the Linux kernel from rootfs.
2051 # The boot dir goes directly on the CD.
2052 if [ -d "$ROOTFS/boot" ] ; then
2053 echo -n "Moving the boot directory..."
2054 mv $ROOTFS/boot $ROOTCD
2055 cd $ROOTCD/boot
2056 ln vmlinuz-* bzImage
2057 status
2058 fi
2059 cd $DISTRO
2060 # Copy all files from $ADDFILES/rootcd to the rootcd.
2061 if [ -d "$ADDFILES/rootcd" ] ; then
2062 echo -n "Copying addfiles content to the rootcd... "
2063 cp -a $ADDFILES/rootcd/* $ROOTCD
2064 status
2065 fi
2066 # Execute the distro script used to perform tasks in the rootfs
2067 # before compression. Give rootfs path in arg
2068 [ -z $DISTRO_SCRIPT ] && DISTRO_SCRIPT=$TOP_DIR/distro.sh
2069 if [ -x $DISTRO_SCRIPT ]; then
2070 echo "Executing distro script..."
2071 sh $DISTRO_SCRIPT $DISTRO
2072 fi
2074 # Execute the custom_rules found in receipt.
2075 if [ -s $TOP_DIR/receipt ]; then
2076 if grep -q ^custom_rules $TOP_DIR/receipt; then
2077 echo -e "Executing: custom_rules\n"
2078 . $TOP_DIR/receipt
2079 custom_rules || echo -e "\nERROR: custom_rules failed\n"
2080 fi
2081 fi
2083 # Multi-rootfs
2084 if [ -s /etc/tazlito/rootfs.list ]; then
2085 FLAVOR_LIST="$(awk '{ for (i = 2; i <= NF; i+=2) \
2086 printf("%s ",$i) }' < /etc/tazlito/rootfs.list)"
2087 [ -s $ROOTCD/boot/isolinux/isolinux.msg ] &&
2088 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2089 $ROOTCD/boot/isolinux/isolinux.msg 2> /dev/null
2090 [ -f $ROOTCD/boot/isolinux/ifmem.c32 -o \
2091 -f $ROOTCD/boot/isolinux/c32box.c32 ] ||
2092 cp /boot/isolinux/c32box.c32 $ROOTCD/boot/isolinux 2> /dev/null ||
2093 cp /boot/isolinux/ifmem.c32 $ROOTCD/boot/isolinux
2094 n=0
2095 last=$ROOTFS
2096 while read flavor; do
2097 n=$(($n+1))
2098 newline
2099 boldify "Building $flavor rootfs..."
2100 [ -s $TOP_DIR/$flavor.flavor ] &&
2101 cp $TOP_DIR/$flavor.flavor .
2102 if [ ! -s $flavor.flavor ]; then
2103 # We may have it in $FLAVORS_REPOSITORY
2104 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2105 tazlito pack-flavor $flavor
2106 else
2107 download $flavor.flavor
2108 fi
2109 fi
2110 echo -n "Extracting $flavor.pkglist and $flavor.rootfs..."
2111 zcat < $flavor.flavor | cpio -i --quiet \
2112 $flavor.pkglist $flavor.rootfs
2113 sed 's/.*/&.tazpkg/' < $flavor.pkglist \
2114 > $DISTRO/list-packages0$n
2115 status
2116 mkdir ${ROOTFS}0$n
2117 # Install packages
2118 cd ${PACKAGES_REPOSITORY}
2119 for pkg in $(cat $DISTRO/list-packages0$n)
2120 do
2121 echo -n "Installing package: $pkg"
2122 yes y | tazpkg -i $pkg --root=${ROOTFS}0$n 2>&1 >> $log || exit 1
2123 status
2124 done
2125 rm -rf ${ROOTFS}0$n/boot ${ROOTFS}0$n/var/lib/tazpkg/packages.*
2126 cd $DISTRO
2127 if [ -s $flavor.rootfs ]; then
2128 echo -n "Adding $flavor rootfs extra files..."
2129 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2130 fi
2131 echo -n "Moving list-packages0$n to rootfs0$n"
2132 mv $DISTRO/list-packages0$n ${ROOTFS}0$n/etc/tazlito/distro-packages.list
2133 status
2134 rm -f $flavor.flavor install-list
2135 mergefs ${ROOTFS}0$n $last
2136 last=${ROOTFS}0$n
2137 done <<EOT
2138 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2139 EOT
2140 i=$(($n+1))
2141 while [ $n -gt 0 ]; do
2142 mv ${ROOTFS}0$n ${ROOTFS}$i
2143 echo "Compressing ${ROOTFS}0$n ($(du -hs ${ROOTFS}$i | awk '{ print $1 }'))..."
2144 gen_initramfs ${ROOTFS}$i
2145 n=$(($n-1))
2146 i=$(($i-1))
2147 done
2148 mv $ROOTFS ${ROOTFS}$i
2149 gen_initramfs ${ROOTFS}$i
2150 update_bootconfig $ROOTCD/boot/isolinux \
2151 "$(cat /etc/tazlito/rootfs.list)"
2152 else
2153 # Initramfs and ISO image stuff.
2154 gen_initramfs $ROOTFS
2155 fi
2156 gen_livecd_isolinux
2157 distro_stats
2158 cleanup ;;
2160 clean-distro)
2161 # Remove old distro tree.
2163 check_root
2164 newline
2165 boldify "Cleaning : $DISTRO"
2166 separator
2167 if [ -d "$DISTRO" ] ; then
2168 if [ -d "$ROOTFS" ] ; then
2169 echo -n "Removing the rootfs..."
2170 rm -f $DISTRO/$INITRAMFS
2171 rm -rf $ROOTFS
2172 status
2173 fi
2174 if [ -d "$ROOTCD" ] ; then
2175 echo -n "Removing the rootcd..."
2176 rm -rf $ROOTCD
2177 status
2178 fi
2179 echo -n "Removing eventual ISO image..."
2180 rm -f $DISTRO/$ISO_NAME.iso
2181 rm -f $DISTRO/$ISO_NAME.md5
2182 status
2183 fi
2184 separator
2185 newline ;;
2187 check-distro)
2188 # Check for a few LiveCD needed files not installed by packages.
2190 check_rootfs
2191 newline
2192 echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
2193 separator
2194 # SliTaz release info.
2195 if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
2196 echo "Missing release info : /etc/slitaz-release"
2197 else
2198 release=`cat $ROOTFS/etc/slitaz-release`
2199 echo -n "Release : $release"
2200 status
2201 fi
2202 # Tazpkg mirror.
2203 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2204 echo -n "Mirror URL : Missing $LOCALSTATE/mirror"
2205 todomsg
2206 else
2207 echo -n "Mirror configuration exists..."
2208 status
2209 fi
2210 # Isolinux msg
2211 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2212 echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
2213 todomsg
2214 else
2215 echo -n "Isolinux message seems good..."
2216 status
2217 fi
2218 separator
2219 newline ;;
2221 writeiso)
2222 # Writefs to ISO image including /home unlike gen-distro we dont use
2223 # packages to generate a rootfs, we build a compressed rootfs with all
2224 # the current filesystem similar to 'tazusb writefs'.
2226 DISTRO="/home/slitaz/distro"
2227 ROOTCD="$DISTRO/rootcd"
2228 if [ -z $2 ]; then
2229 COMPRESSION=none
2230 else
2231 COMPRESSION=$2
2232 fi
2233 if [ -z $3 ]; then
2234 ISO_NAME="slitaz"
2235 else
2236 ISO_NAME="$3"
2237 fi
2238 check_root
2239 # Start info
2240 newline
2241 boldify "Write filesystem to ISO"
2242 separator
2243 cat << EOT
2244 The command writeiso will write the current filesystem into a suitable cpio
2245 archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso).
2247 $(boldify "Archive compression:") $(colorize 36 "$COMPRESSION")
2249 EOT
2250 # Save some space
2251 rm /var/cache/tazpkg/* -r -f
2252 rm -rf /home/slitaz/distro
2254 # Optionally remove sound card selection and screen resolution.
2255 echo "Do you wish to remove the sound card and screen configs ? "
2256 echo -n "Press ENTER to keep or answer (No|yes|exit): "
2257 read anser
2258 case $anser in
2259 e|E|"exit"|Exit)
2260 exit 0 ;;
2261 y|Y|yes|Yes)
2262 echo -n "Removing current sound card and screen configurations..."
2263 rm -f /var/lib/sound-card-driver
2264 rm -f /var/lib/alsa/asound.state
2265 rm -f /etc/X11/xorg.conf ;;
2266 *)
2267 echo -n "Keeping current sound card and screen configurations..." ;;
2268 esac
2269 status && newline
2271 # Optionally remove i18n settings
2272 echo "Do you wish to remove local/keymap settings ? "
2273 echo -n "Press ENTER to keep or answer (No|yes|exit): "
2274 read anser
2275 case $anser in
2276 e|E|"exit"|Exit)
2277 exit 0 ;;
2278 y|Y|yes|Yes)
2279 echo "Removing current locale/keymap settings..."
2280 newline > /etc/locale.conf
2281 newline > /etc/keymap.conf ;;
2282 *)
2283 echo "Keeping current locale/keymap settings..." ;;
2284 esac
2285 status
2287 # Clean-up files by default
2288 newline > /etc/udev/rules.d/70-persistent-net.rules
2289 newline > /etc/udev/rules.d/70-persistant-cd.rules
2291 # Create list of files including default user files since it is defined in /etc/passwd
2292 # and some new users might have been added.
2293 cd /
2294 find bin etc init sbin var dev lib root usr home >/tmp/list
2296 for dir in proc sys tmp mnt media media/cdrom media/flash \
2297 media/usbdisk run run/udev
2298 do
2299 echo $dir >>/tmp/list
2300 done
2301 sed -i '\/var\/run\/.*pid$/d' /tmp/list
2303 # Generate initramfs with specified compression and display rootfs
2304 # size in realtime.
2305 rm -f /tmp/rootfs
2306 write_initramfs &
2307 sleep 2
2308 cd - > /dev/null
2309 echo -en "\nFilesystem size:"
2310 while [ ! -f /tmp/rootfs ]
2311 do
2312 sleep 1
2313 echo -en "\\033[18G`du -sh /rootfs.gz | awk '{print $1}'` "
2314 done
2315 echo -e "\n"
2317 # Move freshly generated rootfs to the cdrom.
2318 mkdir -p $ROOTCD/boot
2319 mv -f /rootfs.gz $ROOTCD/boot
2321 # Now we need the kernel and isolinux files.
2322 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
2323 cp /media/cdrom/boot/bzImage $ROOTCD/boot
2324 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
2325 unmeta_boot $ROOTCD
2326 umount /media/cdrom
2327 elif mount |grep /media/cdrom; then
2328 cp /media/cdrom/boot/bzImage $ROOTCD/boot
2329 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
2330 unmeta_boot $ROOTCD
2331 umount /media/cdrom;
2332 else
2333 echo -e "
2334 When SliTaz is running in RAM the kernel and bootloader files are kept
2335 on the cdrom. Please insert a LiveCD or loop mount the slitaz.iso to
2336 /media/cdrom to let Tazlito copy the files.\n"
2337 echo -en "----\nENTER to continue..."; read i
2338 exit 1
2339 fi
2341 # Generate the iso image.
2342 cd $DISTRO
2343 echo "Generating ISO image..."
2344 genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
2345 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
2346 -V "SliTaz" -p "$(id -un)" -input-charset iso8859-1 \
2347 -P "$(hostname)" -boot-info-table $ROOTCD
2348 if [ -x /usr/bin/isohybrid ]; then
2349 echo -n "Creating hybrid ISO..."
2350 /usr/bin/isohybrid $ISO_NAME.iso -entry 2 2> /dev/null
2351 status
2352 fi
2353 echo -n "Creating the ISO md5sum..."
2354 md5sum $ISO_NAME.iso > $ISO_NAME.md5
2355 status
2357 separator
2358 echo "ISO image: $(du -sh /home/slitaz/distro/$ISO_NAME.iso)"
2359 newline
2360 echo -n "Exit or burn ISO to cdrom (Exit|burn)? "; read anser
2361 case $anser in
2362 burn)
2363 umount /dev/cdrom 2> /dev/null
2364 eject
2365 echo -n "Please insert a blank cdrom and press ENTER..."
2366 read i && sleep 2
2367 tazlito burn-iso /home/slitaz/distro/$ISO_NAME.iso
2368 echo -en "----\nENTER to continue..."; read i ;;
2369 *)
2370 exit 0 ;;
2371 esac ;;
2373 burn-iso)
2374 # Guess cdrom device, ask user and burn the ISO.
2376 check_root
2377 DRIVE_NAME=$(grep "drive name" < /proc/sys/dev/cdrom/info | cut -f 3)
2378 DRIVE_SPEED=$(grep "drive speed" < /proc/sys/dev/cdrom/info | cut -f 3)
2379 # We can specify an alternative ISO from the cmdline.
2380 if [ -n "$2" ] ; then
2381 iso=$2
2382 else
2383 iso=$DISTRO/$ISO_NAME.iso
2384 fi
2385 if [ ! -f "$iso" ]; then
2386 echo -e "\nUnable to find ISO : $iso\n"
2387 exit 0
2388 fi
2389 newline
2390 boldify "Tazlito burn ISO"
2391 separator
2392 echo "Cdrom device : /dev/$DRIVE_NAME"
2393 echo "Drive speed : $DRIVE_SPEED"
2394 echo "ISO image : $iso"
2395 separator
2396 newline
2397 yesorno "Burn ISO image (y/N) ? "
2398 if [ "$answer" == "y" ]; then
2399 newline
2400 echo "Starting Wodim to burn the iso..." && sleep 2
2401 separator
2402 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
2403 separator
2404 echo "ISO image is burned to cdrom."
2405 else
2406 echo -e "\nExiting. No ISO burned."
2407 fi
2408 newline ;;
2410 merge)
2411 # Merge multiple rootfs into one iso.
2413 if [ -z "$2" ]; then
2414 cat << EOT
2415 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
2417 Merge multiple rootfs into one iso. Rootfs are like russian dolls
2418 i.e: rootfsN is a subset of rootfsN-1
2419 rootfs1 is found in iso, sizeN is the RAM size needed to launch rootfsN.
2420 The boot loader will select the rootfs according to the RAM size detected.
2422 Example:
2423 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
2425 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
2426 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
2428 EOT
2429 exit 2
2430 fi
2432 shift # skip merge
2433 append="$1 slitaz1"
2434 shift # skip size1
2435 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
2437 ISO=$1.merged
2438 # Extract filesystems
2439 echo -n "Mounting $1"
2440 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
2441 status || cleanup_merge
2442 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2443 rm -f $TMP_DIR/iso/boot/bzImage
2444 ln $TMP_DIR/iso/boot/vmlinuz* $TMP_DIR/iso/boot/bzImage
2445 umount -d $TMP_DIR/mnt
2446 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
2447 echo "$1 is already a merged iso. Aborting."
2448 cleanup_merge
2449 fi
2450 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
2451 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
2452 if [ ! -f /boot/isolinux/ifmem.c32 -a
2453 ! -f /boot/isolinux/c32box.c32 ]; then
2454 cat <<EOT
2455 No file /boot/isolinux/ifmem.c32
2456 Please install syslinux package !
2457 EOT
2458 rm -rf $TMP_DIR
2459 exit 1
2460 fi
2461 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
2462 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
2463 fi
2465 echo -n "Extracting iso/rootfs.gz"
2466 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
2467 [ -d $TMP_DIR/rootfs1/etc ]
2468 status || cleanup_merge
2469 n=1
2470 while [ -n "$2" ]; do
2471 shift # skip rootfs N-1
2472 p=$n
2473 n=$(($n + 1))
2474 append="$append $1 slitaz$n"
2475 shift # skip size N
2476 mkdir -p $TMP_DIR/rootfs$n
2477 echo -n "Extracting $1"
2478 extract_rootfs $1 $TMP_DIR/rootfs$n &&
2479 [ -d $TMP_DIR/rootfs$n/etc ]
2480 status || cleanup_merge
2481 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
2482 echo "Creating rootfs$p.gz"
2483 pack_rootfs $TMP_DIR/rootfs$p $TMP_DIR/iso/boot/rootfs$p.gz
2484 status
2485 done
2486 echo "Creating rootfs$n.gz"
2487 pack_rootfs $TMP_DIR/rootfs$n $TMP_DIR/iso/boot/rootfs$n.gz
2488 status
2489 rm -f $TMP_DIR/iso/boot/rootfs.gz
2490 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
2491 create_iso $ISO $TMP_DIR/iso
2492 rm -rf $TMP_DIR ;;
2494 repack)
2495 # Repack an iso with maximum lzma compression ratio.
2497 ISO=$2
2498 mkdir -p $TMP_DIR/mnt
2500 # Extract filesystems
2501 echo -n "Mounting $ISO"
2502 mount -o loop,ro $ISO $TMP_DIR/mnt 2> /dev/null
2503 status || cleanup_merge
2504 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2505 umount -d $TMP_DIR/mnt
2507 for i in $TMP_DIR/iso/boot/rootfs* ; do
2508 echo -n "Repacking $(basename $i)"
2509 (zcat $i 2> /dev/null || unlzma -c $i || cat $i) \
2510 2>/dev/null > $TMP_DIR/rootfs
2511 lzma e $TMP_DIR/rootfs $i \
2512 $(lzma_switches $TMP_DIR/rootfs)
2513 align_to_32bits $i
2514 status
2515 done
2517 create_iso $ISO $TMP_DIR/iso
2518 rm -rf $TMP_DIR ;;
2520 build-loram)
2521 # Build a Live CD for low ram systems.
2523 ISO=$2
2524 OUTPUT=$3
2525 if [ -z "$3" ]; then
2526 echo "Usage: tazlito $1 input.iso output.iso [cdrom|smallcdrom|http|ram]"
2527 exit 1
2528 fi
2529 mkdir -p $TMP_DIR/iso
2530 mount -o loop,ro -t iso9660 $ISO $TMP_DIR/iso
2531 loopdev=$( (losetup -a 2>/dev/null || losetup) | grep $ISO | cut -d: -f1)
2532 if ! check_iso_for_loram ; then
2533 echo "$2 is not a valid SliTaz live CD. Abort."
2534 umount -d $TMP_DIR/iso
2535 rm -rf $TMP_DIR
2536 exit 1
2537 fi
2538 case "$4" in
2539 cdrom) build_loram_cdrom ;;
2540 http) build_loram_http ;;
2541 *) build_loram_ram ;;
2542 esac
2543 umount $TMP_DIR/iso # no -d: needs /proc
2544 losetup -d $loopdev
2545 rm -rf $TMP_DIR ;;
2547 emu-iso)
2548 # Emulate an ISO image with Qemu.
2549 if [ -n "$2" ] ; then
2550 iso=$2
2551 else
2552 iso=$DISTRO/$ISO_NAME.iso
2553 fi
2554 if [ ! -f "$iso" ]; then
2555 echo -e "\nUnable to find ISO : $iso\n"
2556 exit 0
2557 fi
2558 if [ ! -x "/usr/bin/qemu" ]; then
2559 echo -e "\nUnable to find Qemu binary. Please install: qemu\n"
2560 exit 0
2561 fi
2562 echo -e "\nStarting Qemu emulator:\n"
2563 echo -e "qemu $QEMU_OPTS $iso\n"
2564 qemu $QEMU_OPTS $iso ;;
2566 deduplicate)
2567 # Deduplicate files in a tree
2568 shift
2569 deduplicate "$@" ;;
2571 usage|*)
2572 # Print usage also for all unknown commands.
2573 usage ;;
2574 esac
2576 exit 0