tazlito view tazlito @ rev 361

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