tazlito view tazlito @ rev 402

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