tazlito view tazlito @ rev 392

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