tazlito view tazlito @ rev 390

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