tazlito view tazlito @ rev 385

tazlito: typo
author Pascal Bellard <pascal.bellard@slitaz.org>
date Mon May 18 15:20:12 2015 +0200 (2015-05-18)
parents 3f451953e917
children efc6181ad217
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.
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 -c $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 > /rootfs.gz
369 lzma_set_size /rootfs.gz
370 elif [ "$COMPRESSION" = "gzip" ]; then
371 echo "Creating rootfs.gz with gzip compression... "
372 cpio -o -H newc | gzip -9 > /rootfs.gz
373 else
374 # align='y'
375 echo "Creating rootfs.gz without compression... "
376 cpio -o -H newc > /rootfs.gz
377 fi < /tmp/list
378 # [ $align == '1' ] && align_to_32bits /rootfs.gz
379 # 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 -c $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 while [ ! -f /lib/modules/$version/kernel/fs/aufs/aufs.ko.?z ]; do
806 install_package aufs $version || return 1
807 done
808 cp /init $TMP_DIR/initfs/
809 # bootfloppybox will need floppy.ko.?z, /dev/fd0, /dev/tty0
810 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.?z \
811 $TMP_DIR/initfs/lib/modules 2> /dev/null
812 cp -a /dev/tty0 /dev/fd0 $TMP_DIR/initfs/dev 2> /dev/null
813 cp /lib/modules/$version/kernel/fs/aufs/aufs.ko.?z \
814 $TMP_DIR/initfs/lib/modules
815 if [ "$1" == "cdrom" ]; then
816 sed -i '/mod squashfs/d' $TMP_DIR/initfs/init
817 else
818 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
819 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z ]; do
820 install_package linux-squashfs $version || return 1
821 done
822 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.?z \
823 $TMP_DIR/initfs/lib/modules
824 ls /sbin/unsquashfs /usr/lib/liblzma.so* $INSTALLED/squashfs/* | \
825 cpio -o -H newc > $TMP_DIR/initfs/extractfs.cpio
826 fi
827 for i in $(ls /dev/[hs]d[a-f]*); do
828 cp -a $i $TMP_DIR/initfs/dev
829 done
830 if [ "$1" == "http" ]; then
831 mkdir $TMP_DIR/initfs/etc
832 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
833 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
834 sed -i 's|/sbin/||' $TMP_DIR/initfs/lib/udhcpc
835 cp -a /dev/fuse $TMP_DIR/initfs/dev
836 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
837 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/httpfs
838 else
839 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
840 need_lib=true
841 fi
842 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
843 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
844 else
845 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
846 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
847 cp -a /lib/librt* $TMP_DIR/initfs/lib
848 cp -a /lib/libdl* $TMP_DIR/initfs/lib
849 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
850 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
851 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
852 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
853 need_lib=true
854 fi
855 cd $TMP_DIR/initfs
856 echo "Getting slitaz-release..."
857 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
858 ( zcat $i 2> /dev/null || unlzma -c $i) | \
859 cpio -idmu etc/slitaz-release > /dev/null
860 done
861 cd - > /dev/null
862 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"
863 echo -n "List of urls to insert: "
864 read -t 30 urliso2
865 urliso="$urliso2 $urliso"
866 fi
867 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
868 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
869 sed -i 's/LD_T.*ot/newline/;s/".*ld-.*) /"/' $TMP_DIR/initfs/init
870 else
871 cp /bin/busybox $TMP_DIR/initfs/bin
872 need_lib=true
873 fi
874 for i in $($TMP_DIR/initfs/bin/busybox | awk \
875 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
876 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
877 done
878 for i in /dev/console /dev/loop* /dev/null /dev/tty /dev/zero \
879 /dev/kmem /dev/mem /dev/random /dev/urandom; do
880 cp -a $i $TMP_DIR/initfs/dev
881 done
882 $need_lib && for i in /lib/ld-* /lib/lib[cm].so* /lib/lib[cm]-* ; do
883 cp -a $i $TMP_DIR/initfs/lib
884 done
885 [ "$1" == "http" ] && cat > $TMP_DIR/initfs/init <<EOTEOT
886 #!/bin/sh
888 getarg()
889 {
890 grep -q " \$1=" /proc/cmdline || return 1
891 eval \$2=\$(sed "s/.* \$1=\\\\([^ ]*\\\\).*/\\\\1/" < /proc/cmdline)
892 return 0
893 }
895 copy_rootfs()
896 {
897 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
898 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
899 [ \$(( \$total / \$need )) -gt 1 ] || return 1
900 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
901 path=/mnt/
902 return 0
903 else
904 rm -f /mnt/rootfs*
905 return 1
906 fi
907 }
909 echo "Switching / to tmpfs..."
910 mount -t proc proc /proc
911 size="\$(grep rootfssize= < /proc/cmdline | \\
912 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
913 [ -n "\$size" ] || size="-o size=90%"
915 while read var default; do
916 eval \$var=\$default
917 getarg \$var \$var
918 done <<EOT
919 eth eth0
920 dns 208.67.222.222,208.67.220.220
921 netmask 255.255.255.0
922 gw
923 ip
924 EOT
925 if [ -n "\$ip" ]; then
926 ifconfig \$eth \$ip netmask \$netmask up
927 route add default gateway \$gw
928 for i in \$(echo \$dns | sed 's/,/ /g'); do
929 echo "nameserver \$i" >> /etc/resolv.conf
930 done
931 else
932 udhcpc -f -q -s /lib/udhcpc -i \$eth
933 fi
934 for i in $urliso ; do
935 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
936 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"
937 done
938 getarg urliso URLISO
939 DIR=fs
940 if getarg loram DIR; then
941 DEVICE=\${DIR%,*}
942 DIR=/\${DIR#*,}
943 fi
944 mount -t tmpfs \$size tmpfs /mnt
945 path2=/mnt/.httpfs/
946 path=/mnt/.cdrom/
947 mkdir -p /mnt/.rw \$path \$path2
948 while [ ! -d \$path/boot ]; do
949 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
950 httpfs \$i \$path2 && break
951 done
952 mount -o loop,ro -t iso9660 \$path2/*.iso \$path
953 done
955 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
956 umount /proc
957 branch=br=/mnt/.rw:/mnt/.cdrom/\$DIR
958 if [ ! -d /mnt/.cdrom/\$DIR/etc ]; then
959 branch=br=/mnt/.rw
960 for i in \${path}rootfs* ; do
961 fs=\${i#*root}
962 branch=\$branch:/mnt/.\$fs
963 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs /mnt/.rw/mnt/.cdrom
964 insmod /lib/squashfs.ko.gz 2> /dev/null
965 mount -o loop,ro -t squashfs \${path}root\$fs /mnt/.\$fs
966 done
967 else
968 mkdir -p /mnt/.rw/mnt/.httpfs
969 fi
970 insmod /lib/aufs.ko.gz
971 mount -t aufs -o \$branch none /mnt
972 [ -x /bin/httpfs ] && sed -i 's/DHCP="yes"/DHCP="no"/' /mnt/etc/network.conf
973 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
974 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
975 EOTEOT
976 chmod +x $TMP_DIR/initfs/init
977 for i in $TMP_DIR/initfs/lib/modules/*z ; do
978 unxz $i || gunzip $i || lzma d $i ${i%.gz}
979 rm -f $i
980 gzip -9 ${i%.gz}
981 done 2> /dev/null
982 ( cd $TMP_DIR/initfs ; find | busybox cpio -o -H newc 2> /dev/null) | \
983 lzma e $TMP_DIR/initfs.gz -si
984 lzma_set_size $TMP_DIR/initfs.gz
985 rm -rf $TMP_DIR/initfs
986 align_to_32bits $TMP_DIR/initfs.gz
987 return 0
988 }
990 # Move each initramfs to squashfs
991 build_loram_rootfs()
992 {
993 rootfs_sizes=""
994 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
995 mkdir -p $TMP_DIR/fs
996 cd $TMP_DIR/fs
997 ( zcat $i 2> /dev/null || unlzma -c $i) | cpio -idm
998 cd - > /dev/null
999 rootfs=$TMP_DIR/$(basename $i)
1000 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp xz -Xbcj x86
1001 cd $TMP_DIR
1002 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
1003 ( cd $(dirname $rootfs); echo $(basename $rootfs) | \
1004 cpio -o -H newc ) > $rootfs.cpio
1005 rm -f $rootfs
1006 mv $rootfs.cpio $rootfs
1007 cd - > /dev/null
1008 rm -rf $TMP_DIR/fs
1009 done
1012 # Move meta boot configuration files to basic configuration files
1013 # because meta loram flavor is useless when rootfs is not loaded in ram
1014 unmeta_boot()
1016 local root=${1:-$TMP_DIR/loramiso}
1017 if [ -f $root/boot/isolinux/noram.cfg ]; then
1018 # We keep enough information to do unloram...
1019 [ -s $root/boot/isolinux/common.cfg ] &&
1020 sed -i 's/label slitaz/label orgslitaz/' \
1021 $root/boot/isolinux/common.cfg
1022 set -- $(grep 'append ifmem [0-9]' $root/boot/isolinux/isolinux.cfg)
1023 shift
1024 sed -i '/ifmem/{NNNNNNNNd};/^LABEL/{N;/LABEL SliTaz [^L]/{NNNd}}' \
1025 $root/boot/isolinux/isolinux.cfg
1026 [ -n "$3" ] || set -- $(grep 'append [0-9]' $root/boot/isolinux/common.cfg)
1027 sed -i "s/label $3\$/label slitaz/;s|=/boot/rootfs\(.*\).gz |=/boot/rootfs.gz |" \
1028 $root/boot/isolinux/*.cfg
1029 fi
1032 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs.
1033 # These squashfs may be loaded in ram at boot time.
1034 # Rootfs are also copied to cdrom for tiny ramsize systems.
1035 # Meta flavors are converted to normal flavors.
1036 build_loram_cdrom()
1038 build_initfs cdrom || return 1
1039 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1040 mkdir $TMP_DIR/loramiso/fs
1041 cd $TMP_DIR/loramiso/fs
1042 for i in $( ls ../boot/root* | sort -r ) ; do
1043 ( zcat $i 2> /dev/null || unlzma -c $i ) | cpio -idmu
1044 rm -f $i
1045 done
1046 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
1047 cd - > /dev/null
1048 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1049 unmeta_boot
1050 VOLUM_NAME="SliTaz_LoRAM_CDROM"
1051 sed -i "s|root=|isofs= rodev=/dev/cdrom/fs &|;s/.ive/cdrom/" \
1052 $TMP_DIR/loramiso/boot/isolinux/*.cfg
1053 create_iso $OUTPUT $TMP_DIR/loramiso
1056 # Create http bootstrap to load and remove loram_cdrom
1057 # Meta flavors are converted to normal flavors.
1058 build_loram_http()
1060 build_initfs http || return 1
1061 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1062 rm -f $TMP_DIR/loramiso/boot/rootfs*
1063 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1064 unmeta_boot
1065 create_iso $OUTPUT $TMP_DIR/loramiso
1068 # Update meta flavor selection sizes.
1069 # Reduce sizes with rootfs gains.
1070 update_metaiso_sizes()
1072 for cfg in $(grep -El '(append|ifmem) [0-9]' $TMP_DIR/loramiso/boot/isolinux/*.cfg)
1073 do
1074 local append="$(grep -E '(append|ifmem) [0-9]' $cfg)"
1075 local sizes="$rootfs_sizes"
1076 local new
1077 set -- $append
1078 shift
1079 [ "$1" == "ifmem" ] && shift
1080 new=""
1081 while [ -n "$2" ]; do
1082 local s
1083 case "$1" in
1084 *G) s=$(( ${1%G} * 1024 * 1024 ));;
1085 *M) s=$(( ${1%M} * 1024 ));;
1086 *) s=${1%K};;
1087 esac
1088 sizes=${sizes#* }
1089 for i in $sizes ; do
1090 s=$(( $s - $i ))
1091 done
1092 new="$new $s $2"
1093 shift 2
1094 done
1095 sed -i -e "/append [0-9]/s/append .*/append$new $1/" -e \
1096 "/append ifmem [0-9]/s/append .*/append ifmem$new $1/" $cfg
1097 sed -i 's|\(initrd=\)\(/boot/rootfs.\.gz\)|\1/boot/rootfs.gz,\2|' $cfg
1098 sed -i '/LABEL base/{NNNNp;s|base .ive|cdrom|;s|base|cdrom|;s|,[^ ]*||}' $cfg
1099 done
1102 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs.
1103 # Meta flavor selection sizes are updated.
1104 build_loram_ram()
1106 build_initfs ram || return 1
1107 build_loram_rootfs
1108 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
1109 make_bzImage_hardlink $TMP_DIR/loramiso/boot
1110 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
1111 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
1112 update_metaiso_sizes
1113 create_iso $OUTPUT $TMP_DIR/loramiso
1116 # Remove files installed by packages
1117 find_flavor_rootfs()
1119 for i in $1/etc/tazlito/*.extract; do
1120 [ -e $i ] || continue
1121 chroot $1 /bin/sh ${i#$1}
1122 done
1124 # Clean hardlinks and files patched by genisofs in /boot
1125 for i in isolinux/isolinux.bin isolinux/boot.cat bzImage ; do
1126 rm -f $1/boot/$i*
1127 done
1129 # Clean files generated in post_install
1130 rm -f $1/lib/modules/*/modules.* $1/etc/mtab \
1131 $1/dev/core $1/dev/fd $1/dev/std*
1133 # Verify md5
1134 cat $1$INSTALLED/*/md5sum | \
1135 while read md5 file; do
1136 [ -e $1$file ] || continue
1137 [ "$(md5sum < $1$file)" == "$md5 -" ] &&
1138 rm -f $1$file
1139 done
1141 # Check configuration files
1142 for i in $1$INSTALLED/*/volatile.cpio.gz; do
1143 [ -e $i ] || continue
1144 mkdir /tmp/volatile$$
1145 zcat $i | ( cd /tmp/volatile$$ ; cpio -idmu > /dev/null 2>&1 )
1146 ( cd /tmp/volatile$$ ; find * -type f 2> /dev/null) | \
1147 while read file ; do
1148 [ -e $1/$file ] || continue
1149 cmp -s /tmp/volatile$$/$file $1/$file && rm -f $1/$file
1150 done
1151 rm -rf /tmp/volatile$$
1152 done
1154 # Remove other files blindly
1155 for i in $1$INSTALLED/*/files.list; do
1156 for file in $(cat $i); do
1157 [ $1$file -nt $i ] && continue
1158 [ -f $1$file -a ! -L $1$file ] && continue
1159 [ -d $1$file ] || rm -f $1$file
1160 done
1161 done
1163 # Remove tazpkg files and tmp files
1164 rm -rf $1$INSTALLED* $1/tmp $1/var/tmp
1165 rm -f $1$LOCALSTATE/*packages* $1$LOCALSTATE/files.list.lzma \
1166 $1$LOCALSTATE/mirror* $1/var/cache/*/* \
1167 $1/var/lock/* $1/var/log/* $1/var/run/* $1/var/run/*/* \
1168 $1/var/lib/* $1/var/lib/dbus/* 2> /dev/null
1170 # Cleanup directory tree
1171 cd $1
1172 find * -type d | sort -r | while read dir; do
1173 rmdir $dir 2> /dev/null
1174 done
1175 cd - > /dev/null
1178 ####################
1179 # Tazlito commands #
1180 ####################
1182 case "$0" in
1183 *reduplicate)
1184 find ${@:-.} ! -type d -links +1 \
1185 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
1186 exit 0 ;;
1187 *deduplicate)
1188 deduplicate "$@"
1189 exit 0 ;;
1190 esac
1192 case "$COMMAND" in
1193 stats)
1194 # Tazlito general statistics from the config file.
1196 newline
1197 boldify "Tazlito statistics"
1198 separator
1199 echo "\
1200 Config file : $CONFIG_FILE
1201 ISO name : $ISO_NAME.iso
1202 Volume name : $VOLUM_NAME
1203 Prepared : $PREPARED
1204 Packages repository : $PACKAGES_REPOSITORY
1205 Distro directory : $DISTRO"
1206 if [ ! "$ADDFILES" = "" ] ; then
1207 echo -e "Additional files : $ADDFILES"
1208 fi
1209 separator && newline ;;
1211 list-addfiles)
1212 # Simple list of additional files in the rootfs
1213 newline
1214 cd $ADDFILES
1215 find rootfs -type f
1216 newline ;;
1218 gen-config)
1219 # Generate a new config file in the current dir or the specified
1220 # directory by $2.
1222 if [ -n "$2" ] ; then
1223 mkdir -p $2 && cd $2
1224 fi
1225 echo -n "Generating empty tazlito.conf..."
1226 empty_config_file
1227 status
1228 newline
1229 if [ -f "tazlito.conf" ] ; then
1230 echo "Configuration file is ready to edit."
1231 echo "File location : `pwd`/tazlito.conf"
1232 newline
1233 fi ;;
1235 configure)
1236 # Configure a tazlito.conf config file. Start by getting
1237 # a empty config file and sed it.
1239 if [ -f "tazlito.conf" ] ; then
1240 rm tazlito.conf
1241 else
1242 if test $(id -u) = 0 ; then
1243 cd /etc
1244 else
1245 echo "You must be root to configure the main config file or in"
1246 echo "the same directory of the file you want to configure."
1247 exit 0
1248 fi
1249 fi
1250 empty_config_file
1251 echo""
1252 echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
1253 separator
1254 # ISO name.
1255 echo -n "ISO name : " ; read answer
1256 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1257 # Volume name.
1258 echo -n "Volume name : " ; read answer
1259 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1260 # Packages repository.
1261 echo -n "Packages repository : " ; read answer
1262 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1263 # Distro path.
1264 echo -n "Distro path : " ; read answer
1265 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1266 separator
1267 echo "Config file is ready to use."
1268 echo "You can now extract an ISO or generate a distro."
1269 newline ;;
1271 gen-iso)
1272 # Simply generate a new iso.
1274 check_root
1275 verify_rootcd
1276 gen_livecd_isolinux
1277 distro_stats ;;
1279 gen-initiso)
1280 # Simply generate a new initramfs with a new iso.
1282 check_root
1283 verify_rootcd
1284 gen_initramfs $ROOTFS
1285 gen_livecd_isolinux
1286 distro_stats ;;
1288 extract-distro)
1289 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1291 check_root
1292 ISO_IMAGE=$2
1293 if [ -z "$ISO_IMAGE" ] ; then
1294 echo -e "\nPlease specify the path to the ISO image."
1295 echo -e "Example : `basename $0` image.iso /path/target\n"
1296 exit 0
1297 fi
1298 # Set the distro path by checking for $3 on cmdline.
1299 if [ -n "$3" ] ; then
1300 TARGET=$3
1301 else
1302 TARGET=$DISTRO
1303 fi
1304 # Exit if existing distro is found.
1305 if [ -d "$TARGET/rootfs" ] ; then
1306 echo -e "\nA rootfs exists in : $TARGET"
1307 echo -e "Please clean the distro tree or change directory path.\n"
1308 exit 0
1309 fi
1310 newline
1311 echo -e "\033[1mTazlito extracting :\033[0m `basename $ISO_IMAGE`"
1312 separator
1313 # Start to mount the ISO.
1314 newline
1315 echo "Mounting ISO image..."
1316 mkdir -p $TMP_DIR
1317 # Get ISO file size.
1318 isosize=`du -sh $ISO_IMAGE | cut -f1`
1319 mount -o loop $ISO_IMAGE $TMP_DIR
1320 sleep 2
1321 # Prepare target dir, copy the kernel and the rootfs.
1322 mkdir -p $TARGET/rootfs
1323 mkdir -p $TARGET/rootcd/boot
1324 echo -n "Copying the Linux kernel..."
1325 if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
1326 make_bzImage_hardlink $TARGET/rootcd/boot
1327 else
1328 cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
1329 fi
1330 status
1331 echo -n "Copying isolinux files..."
1332 cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
1333 for i in $(ls $TMP_DIR); do
1334 [ "$i" = "boot" ] && continue
1335 cp -a $TMP_DIR/$i $TARGET/rootcd
1336 done
1337 status
1338 if [ -d $TMP_DIR/boot/syslinux ]; then
1339 echo -n "Copying syslinux files..."
1340 cp -a $TMP_DIR/boot/syslinux $TARGET/rootcd/boot
1341 status
1342 fi
1343 if [ -d $TMP_DIR/boot/extlinux ]; then
1344 echo -n "Copying extlinux files..."
1345 cp -a $TMP_DIR/boot/extlinux $TARGET/rootcd/boot
1346 status
1347 fi
1348 if [ -d $TMP_DIR/boot/grub ]; then
1349 echo -n "Copying GRUB files..."
1350 cp -a $TMP_DIR/boot/grub $TARGET/rootcd/boot
1351 status
1352 fi
1354 echo -n "Copying the rootfs..."
1355 cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
1356 status
1357 # Extract initramfs.
1358 cd $TARGET/rootfs
1359 echo -n "Extracting the rootfs... "
1360 extract_rootfs ../rootcd/boot/rootfs.gz $TARGET/rootfs
1361 # unpack /usr
1362 for i in etc/tazlito/*.extract; do
1363 [ -f "$i" ] && . $i ../rootcd
1364 done
1365 # Umount and remove temp directory and cd to $TARGET to get stats.
1366 umount $TMP_DIR && rm -rf $TMP_DIR
1367 cd ..
1368 newline
1369 separator
1370 echo "Extracted : `basename $ISO_IMAGE` ($isosize)"
1371 echo "Distro tree : `pwd`"
1372 echo "Rootfs size : `du -sh rootfs`"
1373 echo "Rootcd size : `du -sh rootcd`"
1374 separator
1375 newline ;;
1377 list-flavors)
1378 # Show available flavors.
1379 if [ ! -s /etc/tazlito/flavors.list -o "$2" == "--recharge" ]; then
1380 download flavors.list -O - > /etc/tazlito/flavors.list
1381 fi
1382 newline
1383 boldify "List of flavors"
1384 separator
1385 cat /etc/tazlito/flavors.list
1386 newline ;;
1388 show-flavor)
1389 # Show flavor description.
1390 FLAVOR=${2%.flavor}
1391 if [ ! -f "$FLAVOR.flavor" ]; then
1392 echo "File $FLAVOR.flavor not found."
1393 exit 1
1394 fi
1395 mkdir $TMP_DIR
1396 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i > /dev/null)
1397 if [ "$3" = "--brief" ]; then
1398 if [ "$4" != "--noheader" ]; then
1399 echo "Name ISO Rootfs Description"
1400 separator
1401 fi
1402 printf "%-16.16s %6.6s %6.6s %s\n" "$FLAVOR" \
1403 "$(field ISO $TMP_DIR/$FLAVOR.desc)" \
1404 "$(field 'Rootfs size' $TMP_DIR/$FLAVOR.desc)" \
1405 "$(grep ^Description $TMP_DIR/$FLAVOR.desc | cut -d: -f2)"
1406 else
1407 separator
1408 cat $TMP_DIR/$FLAVOR.desc
1409 fi
1410 rm -Rf $TMP_DIR ;;
1412 gen-liveflavor)
1413 # Generate a new flavor from the live system.
1414 FLAVOR=${2%.flavor}
1415 DESC=""
1416 case "$FLAVOR" in
1417 '') echo -n "Flavor name : "
1418 read FLAVOR
1419 [ -z "$FLAVOR" ] && exit 1;;
1420 -?|-h*|--help) echo -e "
1422 SliTaz Live Tool - Version: $VERSION
1423 \033[1mUsage: \033[0m `basename $0` gen-liveflavor flavor-name [flavor-patch-file]
1424 \033[1mflavor-patch-file format: \033[0m
1425 code data
1426 + package to add
1427 - package to remove
1428 ! non-free package to add
1429 ? display message
1430 @ flavor description
1432 \033[1mExample: \033[0m
1433 @ Developer tools for slitaz maintainers
1434 + slitaz-toolchain
1435 + mercurial
1437 exit 1;;
1438 esac
1439 mv /etc/tazlito/distro-packages.list \
1440 /etc/tazlito/distro-packages.list.$$ 2> /dev/null
1441 rm -f distro-packages.list non-free.list 2> /dev/null
1442 tazpkg recharge
1443 [ -n "$3" ] && while read action pkg; do
1444 case "$action" in
1445 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
1446 -) yes | tazpkg remove $pkg ;;
1447 !) echo $pkg >> non-free.list ;;
1448 @) DESC="$pkg" ;;
1449 \?) echo -en "$pkg"; read action ;;
1450 esac
1451 done < $3
1452 yes '' | tazlito gen-distro
1453 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
1454 mv /etc/tazlito/distro-packages.list.$$ \
1455 /etc/tazlito/distro-packages.list 2> /dev/null ;;
1457 gen-flavor)
1458 # Generate a new flavor from the last iso image generated.
1459 FLAVOR=${2%.flavor}
1460 newline
1461 boldify "Flavor generation"
1462 separator
1463 if [ -z "$FLAVOR" ]; then
1464 echo -n "Flavor name : "
1465 read FLAVOR
1466 [ -z "$FLAVOR" ] && exit 1
1467 fi
1468 check_rootfs
1469 FILES="$FLAVOR.pkglist"
1470 echo -n "Creating file $FLAVOR.flavor..."
1471 for i in rootcd rootfs; do
1472 if [ -d "$ADDFILES/$i" ] ; then
1473 FILES="$FILES\n$FLAVOR.$i"
1474 ( cd "$ADDFILES/$i"; find . | \
1475 cpio -o -H newc 2> /dev/null | gzip -9 ) > $FLAVOR.$i
1476 fi
1477 done
1478 status
1479 answer=`grep -s ^Description $FLAVOR.desc`
1480 answer=${answer#Description : }
1481 if [ -z "$answer" ]; then
1482 echo -n "Description : "
1483 read answer
1484 fi
1485 echo -n "Compressing flavor $FLAVOR..."
1486 echo "Flavor : $FLAVOR" > $FLAVOR.desc
1487 echo "Description : $answer" >> $FLAVOR.desc
1488 ( cd $DISTRO; distro_sizes) >> $FLAVOR.desc
1489 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2> /dev/null
1490 for i in $(ls $ROOTFS$INSTALLED); do
1491 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
1492 EXTRAVERSION=""
1493 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
1494 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
1495 if [ "$CATEGORY" = "non-free" -a "${i%%-*}" != "get" ]
1496 then
1497 echo "$i" >> $FLAVOR.nonfree
1498 else
1499 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
1500 fi
1501 done
1502 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
1503 for i in $LOCALSTATE/undigest/*/mirror ; do
1504 [ -s $i ] && cat $i >> $FLAVOR.mirrors
1505 done
1506 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
1507 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | \
1508 gzip -9 > $FLAVOR.flavor
1509 rm `echo -e $FILES`
1510 status
1511 separator
1512 echo "Flavor size : `du -sh $FLAVOR.flavor`"
1513 newline ;;
1515 upgrade-flavor)
1516 # Update package list to the latest versions available.
1517 FLAVOR=${2%.flavor}
1518 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1519 mkdir $TMP_DIR
1520 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1521 echo -n "Updating $FLAVOR package list..."
1522 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1523 packed_size=0; unpacked_size=0
1524 while read org; do
1525 i=0
1526 pkg=$org
1527 while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
1528 pkg=${pkg%-*}
1529 i=$(($i + 1))
1530 [ $i -gt 5 ] && break;
1531 done
1532 set -- $(get_size $pkg)
1533 packed_size=$(( $packed_size + $1 ))
1534 unpacked_size=$(( $unpacked_size + $2 ))
1535 for i in $(grep ^$pkg $LOCALSTATE/packages.list); do
1536 echo $i
1537 break
1538 done
1539 done < $TMP_DIR/$FLAVOR.pkglist \
1540 > $TMP_DIR/$FLAVOR.pkglist.$$
1541 mv -f $TMP_DIR/$FLAVOR.pkglist.$$ $TMP_DIR/$FLAVOR.pkglist
1542 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1543 packed_size=$(($packed_size \
1544 + $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
1545 unpacked_size=$(($unpacked_size \
1546 + $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1547 fi
1548 # Estimate lzma
1549 packed_size=$(($packed_size * 2 / 3))
1550 iso_size=$(( $packed_size + 26000 ))
1551 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1552 iso_size=$(($iso_size \
1553 + $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1554 fi
1555 sed -i -e '/Image is ready/d' \
1556 -e "s/Rootfs size\( *:\) \(.*\)/Rootfs size\1 $(cent2human $unpacked_size) (estimated)/" \
1557 -e "s/Initramfs size\( *:\) \(.*\)/Initramfs size\1 $(cent2human $packed_size) (estimated)/" \
1558 -e "s/ISO image size\( *:\) \(.*\)/ISO image size\1 $(cent2human $iso_size) (estimated)/" \
1559 -e "s/date\( *:\) \(.*\)/date\1 $(date +%Y%m%d\ \at\ \%H:%M:%S)/" \
1560 $TMP_DIR/$FLAVOR.desc
1561 ( cd $TMP_DIR ; ls | cpio -o -H newc ) | gzip -9 > \
1562 $FLAVOR.flavor
1563 status
1564 rm -Rf $TMP_DIR
1565 fi ;;
1567 extract-flavor)
1568 # Extract a flavor into $FLAVORS_REPOSITORY.
1569 FLAVOR=${2%.flavor}
1570 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1571 mkdir $TMP_DIR
1572 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1573 echo -n "Extracting $FLAVOR..."
1574 rm -rf $FLAVORS_REPOSITORY/$FLAVOR 2> /dev/null
1575 mkdir -p $FLAVORS_REPOSITORY/$FLAVOR
1576 cp $TMP_DIR/$FLAVOR.receipt $FLAVORS_REPOSITORY/$FLAVOR/receipt
1577 #~ echo "FLAVOR=\"$FLAVOR\"" > $FLAVORS_REPOSITORY/$FLAVOR/receipt
1578 #~ grep ^Description $TMP_DIR/$FLAVOR.desc | \
1579 #~ sed 's/.*: \(.*\)$/SHORT_DESC="\1"/' >> \
1580 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1581 #~ grep ^Version $TMP_DIR/$FLAVOR.desc | \
1582 #~ sed 's/.*: \(.*\)$/VERSION="\1"/' >> \
1583 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1584 #~ grep ^Maintainer $TMP_DIR/$FLAVOR.desc | \
1585 #~ sed 's/.*: \(.*\)$/MAINTAINER="\1"/' >> \
1586 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1587 #~ grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc && \
1588 #~ grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1589 #~ sed 's/.*: \(.*\)$/ROOTFS_SELECTION="\1"/' >> \
1590 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1591 #~ grep '^Rootfs size' $TMP_DIR/$FLAVOR.desc | \
1592 #~ sed 's/.*: \(.*\)$/ROOTFS_SIZE="\1"/' >> \
1593 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1594 #~ grep ^Initramfs $TMP_DIR/$FLAVOR.desc | \
1595 #~ sed 's/.*: \(.*\)$/INITRAMFS_SIZE="\1"/' >> \
1596 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1597 #~ grep ^ISO $TMP_DIR/$FLAVOR.desc | \
1598 #~ sed 's/.*: \(.*\)$/ISO_SIZE="\1"/' >> \
1599 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1600 for i in rootcd rootfs; do
1601 [ -f $TMP_DIR/$FLAVOR.$i ] || continue
1602 mkdir $FLAVORS_REPOSITORY/$FLAVOR/$i
1603 zcat < $TMP_DIR/$FLAVOR.$i | \
1604 (cd $FLAVORS_REPOSITORY/$FLAVOR/$i; \
1605 cpio -idm > /dev/null)
1606 done
1607 [ -s $TMP_DIR/$FLAVOR.mirrors ] &&
1608 cp $TMP_DIR/$FLAVOR.mirrors \
1609 $FLAVORS_REPOSITORY/$FLAVOR/mirrors
1610 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1611 while read org; do
1612 i=0
1613 pkg=$org
1614 while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
1615 pkg=${pkg%-*}
1616 i=$(($i + 1))
1617 [ $i -gt 5 ] && break;
1618 done
1619 echo $pkg
1620 done < $TMP_DIR/$FLAVOR.pkglist \
1621 > $FLAVORS_REPOSITORY/$FLAVOR/packages.list
1622 status
1623 rm -Rf $TMP_DIR
1624 fi ;;
1626 pack-flavor)
1627 # Create a flavor from $FLAVORS_REPOSITORY.
1628 FLAVOR=${2%.flavor}
1629 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1630 mkdir $TMP_DIR
1631 echo -n "Creating flavor $FLAVOR..."
1632 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1633 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/mirrors ]; then
1634 cp $FLAVORS_REPOSITORY/$FLAVOR/mirrors \
1635 $TMP_DIR/$FLAVOR.mirrors
1636 for i in $(cat $TMP_DIR/$FLAVOR.mirrors); do
1637 wget -O - $i/packages.list >> $TMP_DIR/packages.list
1638 done
1639 fi
1640 # add distro.sh if exists
1641 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/distro.sh ]; then
1642 cp $FLAVORS_REPOSITORY/$FLAVOR/distro.sh $TMP_DIR/$FLAVOR-distro.sh
1643 fi
1645 # Get receipt in .flavor
1646 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1647 cp $FLAVORS_REPOSITORY/$FLAVOR/receipt $TMP_DIR/$FLAVOR.receipt
1648 fi
1650 # Build the package list.
1652 # On peut inclure une liste venant d'une autre saveur avec le mot clé @include
1653 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ]; then
1654 INCLUDE=$(grep '^@include' $FLAVORS_REPOSITORY/$FLAVOR/packages.list)
1655 if [ ! -z "$INCLUDE" ]; then
1656 INCLUDE=${INCLUDE#@include }
1657 [ -s "$FLAVORS_REPOSITORY/$INCLUDE/packages.list" ] && \
1658 get_pkglist $INCLUDE > $TMP_DIR/$FLAVOR.pkglist || \
1659 echo -e "\nERROR: Can't find include package list from $INCLUDE\n"
1660 fi
1661 # Generate the final/initial package list
1662 [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ] && \
1663 get_pkglist $FLAVOR >> $TMP_DIR/$FLAVOR.pkglist
1664 fi
1665 if grep -q ^ROOTFS_SELECTION \
1666 $FLAVORS_REPOSITORY/$FLAVOR/receipt; then
1667 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1668 set -- $ROOTFS_SELECTION
1669 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
1670 [ -f $FLAVORS_REPOSITORY/$2/packages.list ] ||
1671 tazlito extract-flavor $2
1672 get_pkglist $2 > $TMP_DIR/$FLAVOR.pkglist
1673 for i in rootcd rootfs; do
1674 mkdir $TMP_DIR/$i
1675 # Copy extra files from the first flavor
1676 [ -d $FLAVORS_REPOSITORY/$2/$i ] &&
1677 cp -a $FLAVORS_REPOSITORY/$2/$i $TMP_DIR
1678 # Overload extra files by meta flavor
1679 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] &&
1680 cp -a $FLAVORS_REPOSITORY/$FLAVOR/$i $TMP_DIR
1681 [ -n "$(ls $TMP_DIR/$i)" ] &&
1682 ( cd $TMP_DIR/$i ; find . | cpio -o -H newc 2> /dev/null ) | \
1683 gzip -9 >$TMP_DIR/$FLAVOR.$i
1684 rm -rf $TMP_DIR/$i
1685 done
1686 else
1687 for i in rootcd rootfs; do
1688 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] || \
1689 continue
1690 ( cd $FLAVORS_REPOSITORY/$FLAVOR/$i ; \
1691 find . | cpio -o -H newc 2> /dev/null ) | \
1692 gzip -9 >$TMP_DIR/$FLAVOR.$i
1693 done
1694 fi
1695 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1696 packed_size=$(($packed_size \
1697 + $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
1698 unpacked_size=$(($unpacked_size \
1699 + $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1700 fi
1701 # Estimate lzma
1702 packed_size=$(($packed_size * 2 / 3))
1703 iso_size=$(( $packed_size + 26000 ))
1704 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1705 iso_size=$(($iso_size \
1706 + $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1707 fi
1708 VERSION=""
1709 MAINTAINER=""
1710 ROOTFS_SELECTION=""
1711 ROOTFS_SIZE="$(cent2human $unpacked_size) (estimated)"
1712 INITRAMFS_SIZE="$(cent2human $packed_size) (estimated)"
1713 ISO_SIZE="$(cent2human $iso_size) (estimated)"
1714 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1715 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1716 Flavor : $FLAVOR
1717 Description : $SHORT_DESC
1718 EOT
1719 [ -n "$VERSION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1720 Version : $VERSION
1721 EOT
1722 [ -n "$MAINTAINER" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1723 Maintainer : $MAINTAINER
1724 EOT
1725 [ -n "$FRUGAL_RAM" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1726 LiveCD RAM size : $FRUGAL_RAM
1727 EOT
1728 [ -n "$ROOTFS_SELECTION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1729 Rootfs list : $ROOTFS_SELECTION
1730 EOT
1731 cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1732 Build date : $(date +%Y%m%d\ \at\ \%H:%M:%S)
1733 Packages : $(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l)
1734 Rootfs size : $ROOTFS_SIZE
1735 Initramfs size : $INITRAMFS_SIZE
1736 ISO image size : $ISO_SIZE
1737 ================================================================================
1739 EOT
1740 rm -f $TMP_DIR/packages.list
1741 ( cd $TMP_DIR ; ls | cpio -o -H newc 2> /dev/null) | \
1742 gzip -9 > $FLAVOR.flavor
1743 status
1744 rm -Rf $TMP_DIR
1745 else
1746 echo "No $FLAVOR flavor in $FLAVORS_REPOSITORY."
1747 fi ;;
1749 get-flavor)
1750 # Get a flavor's files and prepare for gen-distro.
1751 FLAVOR=${2%.flavor}
1752 echo -e "\n\033[1mPreparing $FLAVOR distro flavor\033[0m"
1753 separator
1754 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1755 echo -n "Cleaning $DISTRO..."
1756 rm -R $DISTRO 2> /dev/null
1757 mkdir -p $DISTRO
1758 status
1759 mkdir $TMP_DIR
1760 echo -n "Extracting flavor $FLAVOR.flavor... "
1761 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i --quiet >/dev/null )
1762 status
1763 echo -n "Creating distro-packages.list..."
1764 mv $TMP_DIR/$FLAVOR.nonfree non-free.list 2> /dev/null
1765 mv $TMP_DIR/$FLAVOR.pkglist distro-packages.list
1766 status
1767 if [ -f "$TMP_DIR/$FLAVOR-distro.sh" ]; then
1768 echo -n "Extracting distro.sh... "
1769 mv $TMP_DIR/$FLAVOR-distro.sh distro.sh 2> /dev/null
1770 status
1771 fi
1772 if [ -f "$TMP_DIR/$FLAVOR.receipt" ]; then
1773 echo -n "Extracting receipt... "
1774 mv $TMP_DIR/$FLAVOR.receipt receipt 2> /dev/null
1775 status
1776 fi
1777 infos="$FLAVOR.desc"
1778 for i in rootcd rootfs; do
1779 if [ -f $TMP_DIR/$FLAVOR.$i ]; then
1780 echo -n "Adding $i files... "
1781 mkdir -p "$ADDFILES/$i"
1782 zcat < $TMP_DIR/$FLAVOR.$i | \
1783 ( cd "$ADDFILES/$i"; cpio -id --quiet > /dev/null)
1784 zcat < $TMP_DIR/$FLAVOR.$i | cpio -tv 2> /dev/null \
1785 > $TMP_DIR/$FLAVOR.list$i
1786 infos="$infos\n$FLAVOR.list$i"
1787 status
1788 fi
1789 done
1790 if [ -s $TMP_DIR/$FLAVOR.mirrors ]; then
1791 n=""
1792 while read line; do
1793 mkdir -p $LOCALSTATE/undigest/$FLAVOR$n
1794 echo "$line" > $LOCALSTATE/undigest/$FLAVOR$n/mirror
1795 n=$(( $n + 1 ))
1796 done < $TMP_DIR/$FLAVOR.mirrors
1797 infos="$infos\n$FLAVOR.mirrors"
1798 tazpkg recharge
1799 fi
1800 rm -f /etc/tazlito/rootfs.list
1801 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc &&
1802 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1803 sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
1804 echo -n "Updating tazlito.conf..."
1805 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
1806 grep -v "^#VOLUM_NAME" < tazlito.conf | \
1807 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $FLAVOR\"\\n#VOLUM_NA/" \
1808 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
1809 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$FLAVOR\"/" tazlito.conf
1810 status
1811 ( cd $TMP_DIR ; echo -e $infos | cpio -o -H newc ) | \
1812 gzip -9 > /etc/tazlito/info
1813 rm -Rf $TMP_DIR
1814 fi
1815 separator
1816 echo -e "Flavor is ready to be generated by: tazlito gen-distro\n" ;;
1818 iso2flavor)
1819 if [ -z "$3" -o ! -s "$2" ]; then
1820 cat <<EOT
1821 Usage : tazlito iso2flavor image.iso flavor_name
1823 Create a file flavor_name.flavor from the cdrom image file image.iso
1824 EOT
1825 exit 1
1826 fi
1827 FLAVOR=${3%.flavor}
1828 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs
1829 mount -o loop,ro $2 $TMP_DIR/iso
1830 if [ -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
1831 echo "META flavors are not supported."
1832 umount -d $TMP_DIR/iso
1833 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz ]; then
1834 echo "No /boot/rootfs.gz in iso image. Needs a SliTaz iso."
1835 umount -d $TMP_DIR/iso
1836 else
1837 ( unlzma -c $TMP_DIR/iso/boot/rootfs.gz || \
1838 zcat $TMP_DIR/iso/boot/rootfs.gz ) | \
1839 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
1840 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
1841 echo "No file /etc/slitaz-release in /boot/rootfs.gz of iso image. Needs a non loram SliTaz iso."
1842 umount -d $TMP_DIR/iso
1843 else
1844 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
1845 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
1846 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
1847 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
1848 BUILD_DATE=$(date +%Y%m%d\ \at\ \%H:%M:%S -r $TMP_DIR/iso/md5sum)
1849 umount -d $TMP_DIR/iso
1850 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs.gz | awk '{ s=$1 } END { print $1 }')
1851 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
1852 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
1853 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
1854 < $TMP_DIR/rootfs$INSTALLED.md5
1855 #[ -s $TMP_DIR/rootfs/etc/tazlito/distro-packages.list ] &&
1856 # mv $TMP_DIR/rootfs/etc/tazlito/distro-packages.list $TMP_DIR/$FLAVOR.pkglist
1857 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
1858 find_flavor_rootfs $TMP_DIR/rootfs
1859 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
1860 [ -n "$(ls $TMP_DIR/rootfs)" ] && ( cd $TMP_DIR/rootfs ; find * | cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.rootfs
1861 [ -n "$(ls $TMP_DIR/rootcd)" ] && ( cd $TMP_DIR/rootcd ; find * | cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.rootcd
1862 rm -rf $TMP_DIR/rootcd $TMP_DIR/rootfs
1863 VERSION=""; MAINTAINER=""
1864 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
1865 if [ -n "$DESCRIPTION" ]; then
1866 echo -en "Flavor version : "; read -t 30 VERSION
1867 echo -en "Flavor maintainer (your email) : "; read -t 30 MAINTAINER
1868 fi
1869 [ -n "$DESCRIPTION" ] || DESCRIPTION="Slitaz $FLAVOR flavor"
1870 [ -n "$VERSION" ] || VERSION="1.0"
1871 [ -n "$MAINTAINER" ] || MAINTAINER="nobody@slitaz.org"
1872 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1873 Flavor : $FLAVOR
1874 Description : $DESCRIPTION
1875 Version : $VERSION
1876 Maintainer : $MAINTAINER
1877 LiveCD RAM size : $RAM_SIZE
1878 Build date : $BUILD_DATE
1879 Packages : $PKGCNT
1880 Rootfs size : $ROOTFS_SIZE
1881 Initramfs size : $INITRAMFS_SIZE
1882 ISO image size : $ISO_SIZE
1883 ================================================================================
1885 EOT
1886 ( cd $TMP_DIR ; ls $FLAVOR.* | cpio -o -H newc ) | gzip -9 > $FLAVOR.flavor
1887 cat <<EOT
1888 Tazlito can't detect each file installed during a package post_install.
1889 You should extract this flavor (tazlito extract-flavor $FLAVOR),
1890 check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs tree and remove
1891 files generated by post_installs.
1892 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and repack the flavor
1893 (tazlito pack-flavor $FLAVOR)
1894 EOT
1895 fi
1896 fi
1897 rm -rf $TMP_DIR ;;
1899 check-list)
1900 # Use current packages list in $PWD by default.
1901 DISTRO_PKGS_LIST=distro-packages.list
1902 [ -d "$2" ] && DISTRO_PKGS_LIST=$2/distro-packages.list
1903 [ -f "$2" ] && DISTRO_PKGS_LIST=$2
1904 [ ! -f $DISTRO_PKGS_LIST ] && echo "No packages list found." && exit 0
1905 newline
1906 boldify "LiveCD packages list check"
1907 separator
1908 for pkg in $(cat $DISTRO_PKGS_LIST)
1909 do
1910 if ! grep -q "$pkg" $LOCALSTATE/packages.list; then
1911 echo "Updating: $pkg"
1912 up=$(($up + 1))
1913 fi
1914 done
1915 [ -z $up ] && echo -e "List is up-to-date\n" && exit 0
1916 separator
1917 echo -e "Updates: $up\n" ;;
1919 gen-distro)
1920 # Generate a live distro tree with a set of packages.
1922 check_root
1923 time=$(date +%s)
1925 # Libtaz will set $iso or $cdrom
1926 CDROM=""
1927 [ "$iso" ] && CDROM="-o loop $iso"
1928 [ "$cdrom" ] && CDROM="/dev/cdrom"
1929 # Check if a package list was specified on cmdline.
1930 if [ -f "$2" ]; then
1931 LIST_NAME=$2
1932 else
1933 LIST_NAME="distro-packages.list"
1934 fi
1936 if [ -d "$ROOTFS" ] ; then
1937 # Delete $ROOTFS if --force is set on command line
1938 if [ "$forced" ]; then
1939 rm -rf $ROOTFS $ROOTCD
1940 else
1941 echo -e "\nA rootfs exists in : $DISTRO"
1942 echo -e "Please clean the distro tree or change directory path.\n"
1943 exit 0
1944 fi
1945 fi
1947 # Build list with installed packages
1948 if [ ! -f "$LIST_NAME" -a -d $INSTALLED ] ; then
1949 for i in $(ls $INSTALLED); do
1950 if grep -q ^_realver $INSTALLED/$i/receipt ; then
1951 VERSION=$(. $INSTALLED/$i/receipt 2>/dev/null ; echo $VERSION)
1952 else
1953 eval $(grep ^VERSION= $INSTALLED/$i/receipt)
1954 fi
1955 EXTRAVERSION=""
1956 eval $(grep ^EXTRAVERSION= $INSTALLED/$i/receipt)
1957 echo "$i-$VERSION$EXTRAVERSION" >> $LIST_NAME
1958 done
1959 fi
1960 # Exit if no list name.
1961 if [ ! -f "$LIST_NAME" ]; then
1962 echo -e "\nNo packages list found or specified. Please read the docs.\n"
1963 exit 0
1964 fi
1965 # Start generation.
1966 newline
1967 boldify "Tazlito generating a distro"
1968 separator
1969 # Misc checks
1970 [ -n "$PACKAGES_REPOSITORY" ] || PACKAGES_REPOSITORY="."
1971 [ -d $PACKAGES_REPOSITORY ] || mkdir -p $PACKAGES_REPOSITORY
1972 # Get the list of packages using cat for a file list.
1973 LIST=`cat $LIST_NAME`
1974 # Verify if all packages in list are present in $PACKAGES_REPOSITORY.
1975 REPACK=""
1976 DOWNLOAD=""
1977 for pkg in $LIST
1978 do
1979 [ "$pkg" = "" ] && continue
1980 pkg=${pkg%.tazpkg}
1981 [ -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] && continue
1982 PACKAGE=$(installed_package_name $pkg)
1983 [ -n "$PACKAGE" -a "$REPACK" = "y" ] && continue
1984 [ -z "$PACKAGE" -a -n "$DOWNLOAD" ] && continue
1985 echo -e "\nUnable to find $pkg in the repository."
1986 echo -e "Path : $PACKAGES_REPOSITORY\n"
1987 if [ -n "$PACKAGE" -a -z "$REPACK" ]; then
1988 yesorno "Repack packages from rootfs (y/N) ? "
1989 REPACK="$answer"
1990 [ "$answer" = "y" ] || REPACK="n"
1991 [ "$DOWNLOAD" = "y" ] && break
1992 fi
1993 if [ -f $MIRROR -a -z "$DOWNLOAD" ]; then
1994 yesorno "Download packages from mirror (Y/n) ? "
1995 DOWNLOAD="$answer"
1996 if [ "$answer" = "n" ]; then
1997 [ -z "$PACKAGE" ] && exit 1
1998 else
1999 DOWNLOAD="y"
2000 [ -n "$REPACK" ] && break
2001 fi
2002 fi
2003 [ "$REPACK" = "n" -a "$DOWNLOAD" = "n" ] && exit 1
2004 done
2006 # Mount cdrom to be able to repack boot-loader packages
2007 if [ ! -e /boot -a -n "$CDROM" ]; then
2008 mkdir $TMP_MNT
2009 if mount -r $CDROM $TMP_MNT 2> /dev/null; then
2010 ln -s $TMP_MNT/boot /
2011 if [ ! -d "$ADDFILES/rootcd" ] ; then
2012 mkdir -p $ADDFILES/rootcd
2013 for i in $(ls $TMP_MNT); do
2014 [ "$i" = "boot" ] && continue
2015 cp -a $TMP_MNT/$i $ADDFILES/rootcd
2016 done
2017 fi
2018 else
2019 rmdir $TMP_MNT
2020 fi
2021 fi
2023 # Rootfs stuff.
2024 echo "Preparing the rootfs directory..."
2025 mkdir -p $ROOTFS
2026 for pkg in $LIST
2027 do
2028 [ "$pkg" = "" ] && continue
2029 # First copy and extract the package in tmp dir.
2030 pkg=${pkg%.tazpkg}
2031 PACKAGE=$(installed_package_name $pkg)
2032 mkdir -p $TMP_DIR
2033 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2034 # Look for package in cache
2035 if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
2036 ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
2037 # Look for package in running distribution
2038 elif [ -n "$PACKAGE" -a "$REPACK" = "y" ]; then
2039 tazpkg repack $PACKAGE && \
2040 mv $pkg.tazpkg $PACKAGES_REPOSITORY
2041 fi
2042 fi
2043 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2044 # Get package from mirror
2045 [ "$DOWNLOAD" = "y" ] && \
2046 download $pkg.tazpkg && \
2047 mv $pkg.tazpkg $PACKAGES_REPOSITORY
2048 fi
2049 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2050 echo "Missing package: $pkg"
2051 cleanup
2052 exit 1
2053 fi
2054 done
2055 if [ -f non-free.list ]; then
2056 echo "Preparing non-free packages..."
2057 cp non-free.list $ROOTFS/etc/tazlito/non-free.list
2058 for pkg in $(cat non-free.list); do
2059 if [ ! -d $INSTALLED/$pkg ]; then
2060 if [ ! -d $INSTALLED/get-$pkg ]; then
2061 tazpkg get-install get-$pkg
2062 fi
2063 get-$pkg
2064 fi
2065 tazpkg repack $pkg
2066 pkg=$(ls $pkg*.tazpkg)
2067 grep -q "^$pkg$" $LIST_NAME || \
2068 echo $pkg >>$LIST_NAME
2069 mv $pkg $PACKAGES_REPOSITORY
2070 done
2071 fi
2072 cp $LIST_NAME $DISTRO/distro-packages.list
2073 sed 's/\(.*\)/\1.tazpkg/' < $DISTRO/distro-packages.list > $DISTRO/list-packages
2074 cd $PACKAGES_REPOSITORY
2075 for pkg in $(cat $DISTRO/list-packages)
2076 do
2077 echo -n "Installing package: $pkg"
2078 yes y | tazpkg -i $pkg --root=$ROOTFS 2>&1 >> $log || exit 1
2079 status
2080 done
2081 rm -f $ROOTFS/var/lib/tazpkg/packages.*
2082 cd $DISTRO
2083 cp distro-packages.list $ROOTFS/etc/tazlito
2084 # Copy all files from $ADDFILES/rootfs to the rootfs.
2085 if [ -d "$ADDFILES/rootfs" ] ; then
2086 echo -n "Copying addfiles content to the rootfs... "
2087 cp -a $ADDFILES/rootfs/* $ROOTFS
2088 status
2089 fi
2090 echo -n "Root filesystem is generated..." && status
2091 # Root CD part.
2092 echo -n "Preparing the rootcd directory..."
2093 mkdir -p $ROOTCD
2094 status
2095 # Move the boot dir with the Linux kernel from rootfs.
2096 # The boot dir goes directly on the CD.
2097 if [ -d "$ROOTFS/boot" ] ; then
2098 echo -n "Moving the boot directory..."
2099 mv $ROOTFS/boot $ROOTCD
2100 cd $ROOTCD/boot
2101 make_bzImage_hardlink
2102 status
2103 fi
2104 cd $DISTRO
2105 # Copy all files from $ADDFILES/rootcd to the rootcd.
2106 if [ -d "$ADDFILES/rootcd" ] ; then
2107 echo -n "Copying addfiles content to the rootcd... "
2108 cp -a $ADDFILES/rootcd/* $ROOTCD
2109 status
2110 fi
2111 # Execute the distro script used to perform tasks in the rootfs
2112 # before compression. Give rootfs path in arg
2113 [ -z $DISTRO_SCRIPT ] && DISTRO_SCRIPT=$TOP_DIR/distro.sh
2114 if [ -x $DISTRO_SCRIPT ]; then
2115 echo "Executing distro script..."
2116 sh $DISTRO_SCRIPT $DISTRO
2117 fi
2119 # Execute the custom_rules found in receipt.
2120 if [ -s $TOP_DIR/receipt ]; then
2121 if grep -q ^custom_rules $TOP_DIR/receipt; then
2122 echo -e "Executing: custom_rules\n"
2123 . $TOP_DIR/receipt
2124 custom_rules || echo -e "\nERROR: custom_rules failed\n"
2125 fi
2126 fi
2128 # Multi-rootfs
2129 if [ -s /etc/tazlito/rootfs.list ]; then
2130 FLAVOR_LIST="$(awk '{ for (i = 2; i <= NF; i+=2) \
2131 printf("%s ",$i) }' < /etc/tazlito/rootfs.list)"
2132 [ -s $ROOTCD/boot/isolinux/isolinux.msg ] &&
2133 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2134 $ROOTCD/boot/isolinux/isolinux.msg 2> /dev/null
2135 [ -f $ROOTCD/boot/isolinux/ifmem.c32 -o \
2136 -f $ROOTCD/boot/isolinux/c32box.c32 ] ||
2137 cp /boot/isolinux/c32box.c32 $ROOTCD/boot/isolinux 2> /dev/null ||
2138 cp /boot/isolinux/ifmem.c32 $ROOTCD/boot/isolinux
2139 n=0
2140 last=$ROOTFS
2141 while read flavor; do
2142 n=$(($n+1))
2143 newline
2144 boldify "Building $flavor rootfs..."
2145 [ -s $TOP_DIR/$flavor.flavor ] &&
2146 cp $TOP_DIR/$flavor.flavor .
2147 if [ ! -s $flavor.flavor ]; then
2148 # We may have it in $FLAVORS_REPOSITORY
2149 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2150 tazlito pack-flavor $flavor
2151 else
2152 download $flavor.flavor
2153 fi
2154 fi
2155 echo -n "Extracting $flavor.pkglist and $flavor.rootfs..."
2156 zcat < $flavor.flavor | cpio -i --quiet \
2157 $flavor.pkglist $flavor.rootfs
2158 sed 's/.*/&.tazpkg/' < $flavor.pkglist \
2159 > $DISTRO/list-packages0$n
2160 status
2161 mkdir ${ROOTFS}0$n
2162 # Install packages
2163 cd ${PACKAGES_REPOSITORY}
2164 for pkg in $(cat $DISTRO/list-packages0$n)
2165 do
2166 echo -n "Installing package: $pkg"
2167 yes y | tazpkg -i $pkg --root=${ROOTFS}0$n 2>&1 >> $log || exit 1
2168 status
2169 done
2170 rm -rf ${ROOTFS}0$n/boot ${ROOTFS}0$n/var/lib/tazpkg/packages.*
2171 cd $DISTRO
2172 if [ -s $flavor.rootfs ]; then
2173 echo -n "Adding $flavor rootfs extra files..."
2174 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2175 fi
2176 echo -n "Moving list-packages0$n to rootfs0$n"
2177 mv $DISTRO/list-packages0$n ${ROOTFS}0$n/etc/tazlito/distro-packages.list
2178 status
2179 rm -f $flavor.flavor install-list
2180 mergefs ${ROOTFS}0$n $last
2181 last=${ROOTFS}0$n
2182 done <<EOT
2183 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2184 EOT
2185 #'
2186 i=$(($n+1))
2187 while [ $n -gt 0 ]; do
2188 mv ${ROOTFS}0$n ${ROOTFS}$i
2189 echo "Compressing ${ROOTFS}0$n ($(du -hs ${ROOTFS}$i | awk '{ print $1 }'))..."
2190 gen_initramfs ${ROOTFS}$i
2191 n=$(($n-1))
2192 i=$(($i-1))
2193 done
2194 mv $ROOTFS ${ROOTFS}$i
2195 gen_initramfs ${ROOTFS}$i
2196 update_bootconfig $ROOTCD/boot/isolinux \
2197 "$(cat /etc/tazlito/rootfs.list)"
2198 else
2199 # Initramfs and ISO image stuff.
2200 gen_initramfs $ROOTFS
2201 fi
2202 gen_livecd_isolinux
2203 distro_stats
2204 cleanup ;;
2206 clean-distro)
2207 # Remove old distro tree.
2209 check_root
2210 newline
2211 boldify "Cleaning : $DISTRO"
2212 separator
2213 if [ -d "$DISTRO" ] ; then
2214 if [ -d "$ROOTFS" ] ; then
2215 echo -n "Removing the rootfs..."
2216 rm -f $DISTRO/$INITRAMFS
2217 rm -rf $ROOTFS
2218 status
2219 fi
2220 if [ -d "$ROOTCD" ] ; then
2221 echo -n "Removing the rootcd..."
2222 rm -rf $ROOTCD
2223 status
2224 fi
2225 echo -n "Removing eventual ISO image..."
2226 rm -f $DISTRO/$ISO_NAME.iso
2227 rm -f $DISTRO/$ISO_NAME.md5
2228 status
2229 fi
2230 separator
2231 newline ;;
2233 check-distro)
2234 # Check for a few LiveCD needed files not installed by packages.
2236 check_rootfs
2237 newline
2238 echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
2239 separator
2240 # SliTaz release info.
2241 if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
2242 echo "Missing release info : /etc/slitaz-release"
2243 else
2244 release=`cat $ROOTFS/etc/slitaz-release`
2245 echo -n "Release : $release"
2246 status
2247 fi
2248 # Tazpkg mirror.
2249 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2250 echo -n "Mirror URL : Missing $LOCALSTATE/mirror"
2251 todomsg
2252 else
2253 echo -n "Mirror configuration exists..."
2254 status
2255 fi
2256 # Isolinux msg
2257 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2258 echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
2259 todomsg
2260 else
2261 echo -n "Isolinux message seems good..."
2262 status
2263 fi
2264 separator
2265 newline ;;
2267 writeiso)
2268 # Writefs to ISO image including /home unlike gen-distro we dont use
2269 # packages to generate a rootfs, we build a compressed rootfs with all
2270 # the current filesystem similar to 'tazusb writefs'.
2272 DISTRO="/home/slitaz/distro"
2273 ROOTCD="$DISTRO/rootcd"
2274 if [ -z $2 ]; then
2275 COMPRESSION=none
2276 else
2277 COMPRESSION=$2
2278 fi
2279 if [ -z $3 ]; then
2280 ISO_NAME="slitaz"
2281 else
2282 ISO_NAME="$3"
2283 fi
2284 check_root
2285 # Start info
2286 newline
2287 boldify "Write filesystem to ISO"
2288 separator
2289 cat << EOT
2290 The command writeiso will write the current filesystem into a suitable cpio
2291 archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso).
2293 $(boldify "Archive compression:") $(colorize 36 "$COMPRESSION")
2295 EOT
2296 # Save some space
2297 rm /var/cache/tazpkg/* -r -f
2298 rm /var/lib/tazpkg/*.bak -f
2299 rm -rf /home/slitaz/distro
2301 # Optionally remove sound card selection and screen resolution.
2302 if [ -z $LaunchedByTazpanel ]; then
2303 echo "Do you wish to remove the sound card and screen configs ? "
2304 echo -n "Press ENTER to keep or answer (No|yes|exit): "
2305 read anser
2306 case $anser in
2307 e|E|"exit"|Exit)
2308 exit 0 ;;
2309 y|Y|yes|Yes)
2310 echo -n "Removing current sound card and screen configurations..."
2311 rm -f /var/lib/sound-card-driver
2312 rm -f /var/lib/alsa/asound.state
2313 rm -f /etc/X11/xorg.conf ;;
2314 *)
2315 echo -n "Keeping current sound card and screen configurations..." ;;
2316 esac
2317 status && newline
2319 # Optionally remove i18n settings
2320 echo "Do you wish to remove local/keymap settings ? "
2321 echo -n "Press ENTER to keep or answer (No|yes|exit): "
2322 read anser
2323 case $anser in
2324 e|E|"exit"|Exit)
2325 exit 0 ;;
2326 y|Y|yes|Yes)
2327 echo "Removing current locale/keymap settings..."
2328 newline > /etc/locale.conf
2329 newline > /etc/keymap.conf ;;
2330 *)
2331 echo "Keeping current locale/keymap settings..." ;;
2332 esac
2333 status
2334 fi
2336 # Clean-up files by default
2337 if [ ! $(find /var/log/wtmp -size +4k) = "" ]; then
2338 mv -f /var/log/wtmp /tmp/tazlito-wtmp
2339 touch /var/log/wtmp
2340 fi
2341 newline > /etc/udev/rules.d/70-persistent-net.rules
2342 newline > /etc/udev/rules.d/70-persistant-cd.rules
2344 # Create list of files including default user files since it is defined in /etc/passwd
2345 # and some new users might have been added.
2346 cd /
2347 echo 'init' > /tmp/list
2348 for dir in bin etc sbin var dev lib root usr home opt
2349 do
2350 [ -d $dir ] && find $dir
2351 done >>/tmp/list
2353 for dir in proc sys tmp mnt media media/cdrom media/flash \
2354 media/usbdisk run run/udev
2355 do
2356 [ -d $dir ] && echo $dir
2357 done >>/tmp/list
2359 sed -i '/var\/run\/.*pid$/d' /tmp/list
2360 sed -i '/var\/run\/utmp/d' /tmp/list
2361 sed -i '/.*\/.gvfs/d' /tmp/list
2363 for removelog in auth boot messages dmesg daemon slim .*old Xorg; do
2364 sed -i "/var\/log\/$removelog/d" /tmp/list
2365 done
2367 # Generate initramfs with specified compression and display rootfs
2368 # size in realtime.
2369 rm -f /tmp/.write-iso* 2> /dev/null
2370 rm -f /tmp/rootfs 2> /dev/null
2372 write_initramfs &
2373 sleep 2
2374 cd - > /dev/null
2375 echo -en "\nFilesystem size:"
2376 while [ ! -f /tmp/rootfs ]
2377 do
2378 sleep 1
2379 echo -en "\\033[18G`du -sh /rootfs.gz | awk '{print $1}'` "
2380 done
2381 [ -f /tmp/tazlito-wtmp ] && \
2382 mv -f /tmp/tazlito-wtmp /var/log/wtmp
2383 echo -e "\n"
2384 rm -f /tmp/rootfs
2386 # Move freshly generated rootfs to the cdrom.
2387 mkdir -p $ROOTCD/boot
2388 mv -f /rootfs.gz $ROOTCD/boot
2389 echo "Located in: $ROOTCD/boot/rootfs.gz"
2391 # Now we need the kernel and isolinux files.
2392 copy_from_cd()
2394 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
2395 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
2396 unmeta_boot $ROOTCD
2397 umount /media/cdrom
2399 bootloader="/var/lib/tazpkg/installed/syslinux/volatile.cpio.gz"
2400 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
2401 copy_from_cd;
2402 elif mount |grep /media/cdrom; then
2403 copy_from_cd;
2404 elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
2405 cp $bootloader $ROOTCD
2406 cd $ROOTCD
2407 zcat volatile.cpio.gz | cpio -id
2408 rm -f volatile.cpio.gz
2409 [ -f /boot/*slitaz ] && \
2410 cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
2411 [ -f /boot/*slitaz64 ] && \
2412 cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
2413 else
2414 touch /tmp/.write-iso-error
2415 echo -e "
2416 When SliTaz is running in RAM the kernel and bootloader files are kept
2417 on the cdrom. Please insert a LiveCD or loop mount the slitaz.iso to
2418 /media/cdrom (run # mount -o loop slitaz-rolling.iso /media/cdrom )
2419 to let Tazlito copy the files.\n"
2420 echo -en "----\nENTER to continue..."; read i
2421 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
2422 copy_from_cd
2423 fi
2425 # Generate the iso image.
2426 touch /tmp/.write-iso
2427 newline
2428 cd $DISTRO
2429 echo "Generating ISO image..."
2430 genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
2431 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
2432 -V "SliTaz" -p "$(id -un)" -input-charset iso8859-1 \
2433 -P "$(hostname)" -boot-info-table $ROOTCD
2434 if [ -x /usr/bin/isohybrid ]; then
2435 echo -n "Creating hybrid ISO..."
2436 /usr/bin/isohybrid $ISO_NAME.iso -entry 2 2> /dev/null
2437 status
2438 fi
2439 echo -n "Creating the ISO md5sum..."
2440 md5sum $ISO_NAME.iso > $ISO_NAME.md5
2441 status
2443 separator
2444 echo "ISO image: $(du -sh /home/slitaz/distro/$ISO_NAME.iso)"
2445 rm -f /tmp/.write-iso
2446 newline
2447 if [ -z $LaunchedByTazpanel ]; then
2448 echo -n "Exit or burn ISO to cdrom (Exit|burn)? "; read anser
2449 case $anser in
2450 burn)
2451 umount /dev/cdrom 2> /dev/null
2452 eject
2453 echo -n "Please insert a blank cdrom and press ENTER..."
2454 read i && sleep 2
2455 tazlito burn-iso /home/slitaz/distro/$ISO_NAME.iso
2456 echo -en "----\nENTER to continue..."; read i ;;
2457 *)
2458 exit 0 ;;
2459 esac
2460 fi ;;
2462 burn-iso)
2463 # Guess cdrom device, ask user and burn the ISO.
2465 check_root
2466 DRIVE_NAME=$(grep "drive name" < /proc/sys/dev/cdrom/info | cut -f 3)
2467 DRIVE_SPEED=$(grep "drive speed" < /proc/sys/dev/cdrom/info | cut -f 3)
2468 # We can specify an alternative ISO from the cmdline.
2469 if [ -n "$2" ] ; then
2470 iso=$2
2471 else
2472 iso=$DISTRO/$ISO_NAME.iso
2473 fi
2474 if [ ! -f "$iso" ]; then
2475 echo -e "\nUnable to find ISO : $iso\n"
2476 exit 0
2477 fi
2478 newline
2479 boldify "Tazlito burn ISO"
2480 separator
2481 echo "Cdrom device : /dev/$DRIVE_NAME"
2482 echo "Drive speed : $DRIVE_SPEED"
2483 echo "ISO image : $iso"
2484 separator
2485 newline
2486 yesorno "Burn ISO image (y/N) ? "
2487 if [ "$answer" == "y" ]; then
2488 newline
2489 echo "Starting Wodim to burn the iso..." && sleep 2
2490 separator
2491 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
2492 separator
2493 echo "ISO image is burned to cdrom."
2494 else
2495 echo -e "\nExiting. No ISO burned."
2496 fi
2497 newline ;;
2499 merge)
2500 # Merge multiple rootfs into one iso.
2502 if [ -z "$2" ]; then
2503 cat << EOT
2504 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
2506 Merge multiple rootfs into one iso. Rootfs are like russian dolls
2507 i.e: rootfsN is a subset of rootfsN-1
2508 rootfs1 is found in iso, sizeN is the RAM size needed to launch rootfsN.
2509 The boot loader will select the rootfs according to the RAM size detected.
2511 Example:
2512 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
2514 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
2515 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
2517 EOT
2518 exit 2
2519 fi
2521 shift # skip merge
2522 append="$1 slitaz1"
2523 shift # skip size1
2524 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
2526 ISO=$1.merged
2527 # Extract filesystems
2528 echo -n "Mounting $1"
2529 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
2530 status || cleanup_merge
2531 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2532 make_bzImage_hardlink $TMP_DIR/iso/boot
2533 umount -d $TMP_DIR/mnt
2534 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
2535 echo "$1 is already a merged iso. Aborting."
2536 cleanup_merge
2537 fi
2538 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
2539 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
2540 if [ ! -f /boot/isolinux/ifmem.c32 -a
2541 ! -f /boot/isolinux/c32box.c32 ]; then
2542 cat <<EOT
2543 No file /boot/isolinux/ifmem.c32
2544 Please install syslinux package !
2545 EOT
2546 rm -rf $TMP_DIR
2547 exit 1
2548 fi
2549 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
2550 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
2551 fi
2553 echo -n "Extracting iso/rootfs.gz"
2554 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
2555 [ -d $TMP_DIR/rootfs1/etc ]
2556 status || cleanup_merge
2557 n=1
2558 while [ -n "$2" ]; do
2559 shift # skip rootfs N-1
2560 p=$n
2561 n=$(($n + 1))
2562 append="$append $1 slitaz$n"
2563 shift # skip size N
2564 mkdir -p $TMP_DIR/rootfs$n
2565 echo -n "Extracting $1"
2566 extract_rootfs $1 $TMP_DIR/rootfs$n &&
2567 [ -d $TMP_DIR/rootfs$n/etc ]
2568 status || cleanup_merge
2569 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
2570 echo "Creating rootfs$p.gz"
2571 pack_rootfs $TMP_DIR/rootfs$p $TMP_DIR/iso/boot/rootfs$p.gz
2572 status
2573 done
2574 echo "Creating rootfs$n.gz"
2575 pack_rootfs $TMP_DIR/rootfs$n $TMP_DIR/iso/boot/rootfs$n.gz
2576 status
2577 rm -f $TMP_DIR/iso/boot/rootfs.gz
2578 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
2579 create_iso $ISO $TMP_DIR/iso
2580 rm -rf $TMP_DIR ;;
2582 repack)
2583 # Repack an iso with maximum lzma compression ratio.
2585 ISO=$2
2586 mkdir -p $TMP_DIR/mnt
2588 # Extract filesystems
2589 echo -n "Mounting $ISO"
2590 mount -o loop,ro $ISO $TMP_DIR/mnt 2> /dev/null
2591 status || cleanup_merge
2592 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2593 umount -d $TMP_DIR/mnt
2595 for i in $TMP_DIR/iso/boot/rootfs* ; do
2596 echo -n "Repacking $(basename $i)"
2597 (zcat $i 2> /dev/null || unlzma -c $i || cat $i) \
2598 2>/dev/null > $TMP_DIR/rootfs
2599 lzma e $TMP_DIR/rootfs $i \
2600 $(lzma_switches $TMP_DIR/rootfs)
2601 align_to_32bits $i
2602 status
2603 done
2605 create_iso $ISO $TMP_DIR/iso
2606 rm -rf $TMP_DIR ;;
2608 build-loram)
2609 # Build a Live CD for low ram systems.
2611 ISO=$2
2612 OUTPUT=$3
2613 if [ -z "$3" ]; then
2614 echo "Usage: tazlito $1 input.iso output.iso [cdrom|smallcdrom|http|ram]"
2615 exit 1
2616 fi
2617 mkdir -p $TMP_DIR/iso
2618 mount -o loop,ro -t iso9660 $ISO $TMP_DIR/iso
2619 loopdev=$( (losetup -a 2>/dev/null || losetup) | grep $ISO | cut -d: -f1)
2620 if ! check_iso_for_loram ; then
2621 echo "$2 is not a valid SliTaz live CD. Abort."
2622 umount -d $TMP_DIR/iso
2623 rm -rf $TMP_DIR
2624 exit 1
2625 fi
2626 case "$4" in
2627 cdrom) build_loram_cdrom ;;
2628 http) build_loram_http ;;
2629 *) build_loram_ram ;;
2630 esac
2631 umount $TMP_DIR/iso # no -d: needs /proc
2632 losetup -d $loopdev
2633 rm -rf $TMP_DIR ;;
2635 emu-iso)
2636 # Emulate an ISO image with Qemu.
2637 if [ -n "$2" ] ; then
2638 iso=$2
2639 else
2640 iso=$DISTRO/$ISO_NAME.iso
2641 fi
2642 if [ ! -f "$iso" ]; then
2643 echo -e "\nUnable to find ISO : $iso\n"
2644 exit 0
2645 fi
2646 if [ ! -x "/usr/bin/qemu" ]; then
2647 echo -e "\nUnable to find Qemu binary. Please install: qemu\n"
2648 exit 0
2649 fi
2650 echo -e "\nStarting Qemu emulator:\n"
2651 echo -e "qemu $QEMU_OPTS $iso\n"
2652 qemu $QEMU_OPTS $iso ;;
2654 deduplicate)
2655 # Deduplicate files in a tree
2656 shift
2657 deduplicate "$@" ;;
2659 usage|*)
2660 # Print usage also for all unknown commands.
2661 usage ;;
2662 esac
2664 exit 0