tazlito view tazlito @ rev 363

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