tazlito view tazlito @ rev 408

tazlito build-loram: typo
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Dec 06 20:08:51 2015 +0100 (2015-12-06)
parents 5dba07072fd7
children b75c89be345f
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 $aufs $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 # get byte(s) form a binary file
1189 get()
1191 od -v -j $1 -N ${3:-2} -t u${3:-2} -w${3:-2} -An $2 2>/dev/null
1194 # get cpio flavor info from the ISO image
1195 flavordata()
1197 [ $(get 1024 $1) -eq 35615 ] && n=2 || n=$((1+$(get 417 $1 1)))
1198 dd if=$1 bs=512 skip=$n count=20 2>/dev/null | zcat 2>/dev/null
1202 ####################
1203 # Tazlito commands #
1204 ####################
1206 case "$0" in
1207 *reduplicate)
1208 find ${@:-.} ! -type d -links +1 \
1209 -exec cp -a {} {}$$ \; -exec mv {}$$ {} \;
1210 exit 0 ;;
1211 *deduplicate)
1212 deduplicate "$@"
1213 exit 0 ;;
1214 esac
1216 case "$COMMAND" in
1217 stats)
1218 # Tazlito general statistics from the config file.
1220 newline
1221 boldify "Tazlito statistics"
1222 separator
1223 echo "\
1224 Config file : $CONFIG_FILE
1225 ISO name : $ISO_NAME.iso
1226 Volume name : $VOLUM_NAME
1227 Prepared : $PREPARED
1228 Packages repository : $PACKAGES_REPOSITORY
1229 Distro directory : $DISTRO"
1230 if [ ! "$ADDFILES" = "" ] ; then
1231 echo -e "Additional files : $ADDFILES"
1232 fi
1233 separator && newline ;;
1235 list-addfiles)
1236 # Simple list of additional files in the rootfs
1237 newline
1238 cd $ADDFILES
1239 find rootfs -type f
1240 newline ;;
1242 gen-config)
1243 # Generate a new config file in the current dir or the specified
1244 # directory by $2.
1246 if [ -n "$2" ] ; then
1247 mkdir -p $2 && cd $2
1248 fi
1249 echo -n "Generating empty tazlito.conf..."
1250 empty_config_file
1251 status
1252 newline
1253 if [ -f "tazlito.conf" ] ; then
1254 echo "Configuration file is ready to edit."
1255 echo "File location : `pwd`/tazlito.conf"
1256 newline
1257 fi ;;
1259 configure)
1260 # Configure a tazlito.conf config file. Start by getting
1261 # a empty config file and sed it.
1263 if [ -f "tazlito.conf" ] ; then
1264 rm tazlito.conf
1265 else
1266 if test $(id -u) = 0 ; then
1267 cd /etc
1268 else
1269 echo "You must be root to configure the main config file or in"
1270 echo "the same directory of the file you want to configure."
1271 exit 0
1272 fi
1273 fi
1274 empty_config_file
1275 echo""
1276 echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
1277 separator
1278 # ISO name.
1279 echo -n "ISO name : " ; read answer
1280 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1281 # Volume name.
1282 echo -n "Volume name : " ; read answer
1283 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1284 # Packages repository.
1285 echo -n "Packages repository : " ; read answer
1286 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1287 # Distro path.
1288 echo -n "Distro path : " ; read answer
1289 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1290 separator
1291 echo "Config file is ready to use."
1292 echo "You can now extract an ISO or generate a distro."
1293 newline ;;
1295 gen-iso)
1296 # Simply generate a new iso.
1298 check_root
1299 verify_rootcd
1300 gen_livecd_isolinux
1301 distro_stats ;;
1303 gen-initiso)
1304 # Simply generate a new initramfs with a new iso.
1306 check_root
1307 verify_rootcd
1308 gen_initramfs $ROOTFS
1309 gen_livecd_isolinux
1310 distro_stats ;;
1312 extract-distro)
1313 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1315 check_root
1316 ISO_IMAGE=$2
1317 if [ -z "$ISO_IMAGE" ] ; then
1318 echo -e "\nPlease specify the path to the ISO image."
1319 echo -e "Example : `basename $0` image.iso /path/target\n"
1320 exit 0
1321 fi
1322 # Set the distro path by checking for $3 on cmdline.
1323 if [ -n "$3" ] ; then
1324 TARGET=$3
1325 else
1326 TARGET=$DISTRO
1327 fi
1328 # Exit if existing distro is found.
1329 if [ -d "$TARGET/rootfs" ] ; then
1330 echo -e "\nA rootfs exists in : $TARGET"
1331 echo -e "Please clean the distro tree or change directory path.\n"
1332 exit 0
1333 fi
1334 newline
1335 echo -e "\033[1mTazlito extracting :\033[0m `basename $ISO_IMAGE`"
1336 separator
1337 # Start to mount the ISO.
1338 newline
1339 echo "Mounting ISO image..."
1340 mkdir -p $TMP_DIR
1341 # Get ISO file size.
1342 isosize=`du -sh $ISO_IMAGE | cut -f1`
1343 mount -o loop $ISO_IMAGE $TMP_DIR
1344 sleep 2
1345 # Prepare target dir, copy the kernel and the rootfs.
1346 mkdir -p $TARGET/rootfs
1347 mkdir -p $TARGET/rootcd/boot
1348 echo -n "Copying the Linux kernel..."
1349 if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
1350 make_bzImage_hardlink $TARGET/rootcd/boot
1351 else
1352 cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
1353 fi
1354 status
1355 echo -n "Copying isolinux files..."
1356 cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
1357 for i in $(ls $TMP_DIR); do
1358 [ "$i" = "boot" ] && continue
1359 cp -a $TMP_DIR/$i $TARGET/rootcd
1360 done
1361 status
1362 if [ -d $TMP_DIR/boot/syslinux ]; then
1363 echo -n "Copying syslinux files..."
1364 cp -a $TMP_DIR/boot/syslinux $TARGET/rootcd/boot
1365 status
1366 fi
1367 if [ -d $TMP_DIR/boot/extlinux ]; then
1368 echo -n "Copying extlinux files..."
1369 cp -a $TMP_DIR/boot/extlinux $TARGET/rootcd/boot
1370 status
1371 fi
1372 if [ -d $TMP_DIR/boot/grub ]; then
1373 echo -n "Copying GRUB files..."
1374 cp -a $TMP_DIR/boot/grub $TARGET/rootcd/boot
1375 status
1376 fi
1378 echo -n "Copying the rootfs..."
1379 cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
1380 status
1381 # Extract initramfs.
1382 cd $TARGET/rootfs
1383 echo -n "Extracting the rootfs... "
1384 extract_rootfs ../rootcd/boot/rootfs.gz $TARGET/rootfs
1385 # unpack /usr
1386 for i in etc/tazlito/*.extract; do
1387 [ -f "$i" ] && . $i ../rootcd
1388 done
1389 # Umount and remove temp directory and cd to $TARGET to get stats.
1390 umount $TMP_DIR && rm -rf $TMP_DIR
1391 cd ..
1392 newline
1393 separator
1394 echo "Extracted : `basename $ISO_IMAGE` ($isosize)"
1395 echo "Distro tree : `pwd`"
1396 echo "Rootfs size : `du -sh rootfs`"
1397 echo "Rootcd size : `du -sh rootcd`"
1398 separator
1399 newline ;;
1401 list-flavors)
1402 # Show available flavors.
1403 if [ ! -s /etc/tazlito/flavors.list -o "$2" == "--recharge" ]; then
1404 download flavors.list -O - > /etc/tazlito/flavors.list
1405 fi
1406 newline
1407 boldify "List of flavors"
1408 separator
1409 cat /etc/tazlito/flavors.list
1410 newline ;;
1412 show-flavor)
1413 # Show flavor description.
1414 FLAVOR=${2%.flavor}
1415 if [ ! -f "$FLAVOR.flavor" ]; then
1416 echo "File $FLAVOR.flavor not found."
1417 exit 1
1418 fi
1419 mkdir $TMP_DIR
1420 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i > /dev/null)
1421 if [ "$3" = "--brief" ]; then
1422 if [ "$4" != "--noheader" ]; then
1423 echo "Name ISO Rootfs Description"
1424 separator
1425 fi
1426 printf "%-16.16s %6.6s %6.6s %s\n" "$FLAVOR" \
1427 "$(field ISO $TMP_DIR/$FLAVOR.desc)" \
1428 "$(field 'Rootfs size' $TMP_DIR/$FLAVOR.desc)" \
1429 "$(grep ^Description $TMP_DIR/$FLAVOR.desc | cut -d: -f2)"
1430 else
1431 separator
1432 cat $TMP_DIR/$FLAVOR.desc
1433 fi
1434 rm -Rf $TMP_DIR ;;
1436 gen-liveflavor)
1437 # Generate a new flavor from the live system.
1438 FLAVOR=${2%.flavor}
1439 DESC=""
1440 case "$FLAVOR" in
1441 '') echo -n "Flavor name : "
1442 read FLAVOR
1443 [ -z "$FLAVOR" ] && exit 1;;
1444 -?|-h*|--help) echo -e "
1446 SliTaz Live Tool - Version: $VERSION
1447 \033[1mUsage: \033[0m `basename $0` gen-liveflavor flavor-name [flavor-patch-file]
1448 \033[1mflavor-patch-file format: \033[0m
1449 code data
1450 + package to add
1451 - package to remove
1452 ! non-free package to add
1453 ? display message
1454 @ flavor description
1456 \033[1mExample: \033[0m
1457 @ Developer tools for slitaz maintainers
1458 + slitaz-toolchain
1459 + mercurial
1461 exit 1;;
1462 esac
1463 mv /etc/tazlito/distro-packages.list \
1464 /etc/tazlito/distro-packages.list.$$ 2> /dev/null
1465 rm -f distro-packages.list non-free.list 2> /dev/null
1466 tazpkg recharge
1467 [ -n "$3" ] && while read action pkg; do
1468 case "$action" in
1469 +) yes | tazpkg get-install $pkg 2>&1 >> $log || exit 1 ;;
1470 -) yes | tazpkg remove $pkg ;;
1471 !) echo $pkg >> non-free.list ;;
1472 @) DESC="$pkg" ;;
1473 \?) echo -en "$pkg"; read action ;;
1474 esac
1475 done < $3
1476 yes '' | tazlito gen-distro
1477 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
1478 mv /etc/tazlito/distro-packages.list.$$ \
1479 /etc/tazlito/distro-packages.list 2> /dev/null ;;
1481 gen-flavor)
1482 # Generate a new flavor from the last iso image generated.
1483 FLAVOR=${2%.flavor}
1484 newline
1485 boldify "Flavor generation"
1486 separator
1487 if [ -z "$FLAVOR" ]; then
1488 echo -n "Flavor name : "
1489 read FLAVOR
1490 [ -z "$FLAVOR" ] && exit 1
1491 fi
1492 check_rootfs
1493 FILES="$FLAVOR.pkglist"
1494 echo -n "Creating file $FLAVOR.flavor..."
1495 for i in rootcd rootfs; do
1496 if [ -d "$ADDFILES/$i" ] ; then
1497 FILES="$FILES\n$FLAVOR.$i"
1498 ( cd "$ADDFILES/$i"; find . | \
1499 cpio -o -H newc 2> /dev/null | gzip -9 ) > $FLAVOR.$i
1500 fi
1501 done
1502 status
1503 answer=`grep -s ^Description $FLAVOR.desc`
1504 answer=${answer#Description : }
1505 if [ -z "$answer" ]; then
1506 echo -n "Description : "
1507 read answer
1508 fi
1509 echo -n "Compressing flavor $FLAVOR..."
1510 echo "Flavor : $FLAVOR" > $FLAVOR.desc
1511 echo "Description : $answer" >> $FLAVOR.desc
1512 ( cd $DISTRO; distro_sizes) >> $FLAVOR.desc
1513 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2> /dev/null
1514 for i in $(ls $ROOTFS$INSTALLED); do
1515 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
1516 EXTRAVERSION=""
1517 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
1518 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
1519 if [ "$CATEGORY" = "non-free" -a "${i%%-*}" != "get" ]
1520 then
1521 echo "$i" >> $FLAVOR.nonfree
1522 else
1523 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
1524 fi
1525 done
1526 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
1527 for i in $LOCALSTATE/undigest/*/mirror ; do
1528 [ -s $i ] && cat $i >> $FLAVOR.mirrors
1529 done
1530 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
1531 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | \
1532 gzip -9 > $FLAVOR.flavor
1533 rm `echo -e $FILES`
1534 status
1535 separator
1536 echo "Flavor size : `du -sh $FLAVOR.flavor`"
1537 newline ;;
1539 upgrade-flavor)
1540 # Update package list to the latest versions available.
1541 [ -s /home/slitaz/packages/packages.list -a -z $systemrepos ] && \
1542 LOCALSTATE='/home/slitaz/packages'
1543 FLAVOR=${2%.flavor}
1544 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1545 mkdir $TMP_DIR
1546 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1547 echo -n "Updating $FLAVOR package list..."
1548 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1549 packed_size=0; unpacked_size=0
1550 while read org; do
1551 i=0
1552 pkg=$org
1553 while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
1554 pkg=${pkg%-*}
1555 i=$(($i + 1))
1556 [ $i -gt 5 ] && break;
1557 done
1558 set -- $(get_size $pkg)
1559 packed_size=$(( $packed_size + $1 ))
1560 unpacked_size=$(( $unpacked_size + $2 ))
1561 for i in $(grep ^$pkg $LOCALSTATE/packages.list); do
1562 echo $i
1563 break
1564 done
1565 done < $TMP_DIR/$FLAVOR.pkglist \
1566 > $TMP_DIR/$FLAVOR.pkglist.$$
1567 mv -f $TMP_DIR/$FLAVOR.pkglist.$$ $TMP_DIR/$FLAVOR.pkglist
1568 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1569 packed_size=$(($packed_size \
1570 + $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
1571 unpacked_size=$(($unpacked_size \
1572 + $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1573 fi
1574 # Estimate lzma
1575 packed_size=$(($packed_size * 2 / 3))
1576 iso_size=$(( $packed_size + 26000 ))
1577 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1578 iso_size=$(($iso_size \
1579 + $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1580 fi
1581 sed -i -e '/Image is ready/d' \
1582 -e "s/Rootfs size\( *:\) \(.*\)/Rootfs size\1 $(cent2human $unpacked_size) (estimated)/" \
1583 -e "s/Initramfs size\( *:\) \(.*\)/Initramfs size\1 $(cent2human $packed_size) (estimated)/" \
1584 -e "s/ISO image size\( *:\) \(.*\)/ISO image size\1 $(cent2human $iso_size) (estimated)/" \
1585 -e "s/date\( *:\) \(.*\)/date\1 $(date +%Y%m%d\ \at\ \%H:%M:%S)/" \
1586 $TMP_DIR/$FLAVOR.desc
1587 ( cd $TMP_DIR ; ls | cpio -o -H newc ) | gzip -9 > \
1588 $FLAVOR.flavor
1589 status
1590 rm -Rf $TMP_DIR
1591 fi ;;
1593 extract-flavor)
1594 # Extract a flavor into $FLAVORS_REPOSITORY.
1595 FLAVOR=${2%.flavor}
1596 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1597 mkdir $TMP_DIR
1598 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1599 echo -n "Extracting $FLAVOR..."
1600 rm -rf $FLAVORS_REPOSITORY/$FLAVOR 2> /dev/null
1601 mkdir -p $FLAVORS_REPOSITORY/$FLAVOR
1602 cp $TMP_DIR/$FLAVOR.receipt $FLAVORS_REPOSITORY/$FLAVOR/receipt
1603 #~ echo "FLAVOR=\"$FLAVOR\"" > $FLAVORS_REPOSITORY/$FLAVOR/receipt
1604 #~ grep ^Description $TMP_DIR/$FLAVOR.desc | \
1605 #~ sed 's/.*: \(.*\)$/SHORT_DESC="\1"/' >> \
1606 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1607 #~ grep ^Version $TMP_DIR/$FLAVOR.desc | \
1608 #~ sed 's/.*: \(.*\)$/VERSION="\1"/' >> \
1609 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1610 #~ grep ^Maintainer $TMP_DIR/$FLAVOR.desc | \
1611 #~ sed 's/.*: \(.*\)$/MAINTAINER="\1"/' >> \
1612 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1613 #~ grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc && \
1614 #~ grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1615 #~ sed 's/.*: \(.*\)$/ROOTFS_SELECTION="\1"/' >> \
1616 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1617 #~ grep '^Rootfs size' $TMP_DIR/$FLAVOR.desc | \
1618 #~ sed 's/.*: \(.*\)$/ROOTFS_SIZE="\1"/' >> \
1619 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1620 #~ grep ^Initramfs $TMP_DIR/$FLAVOR.desc | \
1621 #~ sed 's/.*: \(.*\)$/INITRAMFS_SIZE="\1"/' >> \
1622 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1623 #~ grep ^ISO $TMP_DIR/$FLAVOR.desc | \
1624 #~ sed 's/.*: \(.*\)$/ISO_SIZE="\1"/' >> \
1625 #~ $FLAVORS_REPOSITORY/$FLAVOR/receipt
1626 for i in rootcd rootfs; do
1627 [ -f $TMP_DIR/$FLAVOR.$i ] || continue
1628 mkdir $FLAVORS_REPOSITORY/$FLAVOR/$i
1629 zcat < $TMP_DIR/$FLAVOR.$i | \
1630 (cd $FLAVORS_REPOSITORY/$FLAVOR/$i; \
1631 cpio -idm > /dev/null)
1632 done
1633 [ -s $TMP_DIR/$FLAVOR.mirrors ] &&
1634 cp $TMP_DIR/$FLAVOR.mirrors \
1635 $FLAVORS_REPOSITORY/$FLAVOR/mirrors
1636 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1637 while read org; do
1638 i=0
1639 pkg=$org
1640 while ! grep -q ^$pkg$ $LOCALSTATE/packages.txt; do
1641 pkg=${pkg%-*}
1642 i=$(($i + 1))
1643 [ $i -gt 5 ] && break;
1644 done
1645 echo $pkg
1646 done < $TMP_DIR/$FLAVOR.pkglist \
1647 > $FLAVORS_REPOSITORY/$FLAVOR/packages.list
1648 status
1649 rm -Rf $TMP_DIR
1650 fi ;;
1652 pack-flavor)
1653 # Create a flavor from $FLAVORS_REPOSITORY.
1654 FLAVOR=${2%.flavor}
1655 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1656 mkdir $TMP_DIR
1657 echo -n "Creating flavor $FLAVOR..."
1659 # Use latest local packages if possible (don't download from unsynced mirror)
1660 [ -s /home/slitaz/packages/packages.list -a -z $systemrepos ] && \
1661 LOCALSTATE='/home/slitaz/packages'
1663 [ -s $LOCALSTATE/packages.list ] || tazpkg recharge
1664 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/mirrors ]; then
1665 cp $FLAVORS_REPOSITORY/$FLAVOR/mirrors \
1666 $TMP_DIR/$FLAVOR.mirrors
1667 for i in $(cat $TMP_DIR/$FLAVOR.mirrors); do
1668 wget -O - $i/packages.list >> $TMP_DIR/packages.list
1669 done
1670 fi
1671 # add distro.sh if exists
1672 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/distro.sh ]; then
1673 cp $FLAVORS_REPOSITORY/$FLAVOR/distro.sh $TMP_DIR/$FLAVOR-distro.sh
1674 fi
1676 # Get receipt in .flavor
1677 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1678 cp $FLAVORS_REPOSITORY/$FLAVOR/receipt $TMP_DIR/$FLAVOR.receipt
1679 fi
1681 # Build the package list.
1683 # On peut inclure une liste venant d'une autre saveur avec le mot clé @include
1684 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ]; then
1685 INCLUDE=$(grep '^@include' $FLAVORS_REPOSITORY/$FLAVOR/packages.list)
1686 if [ ! -z "$INCLUDE" ]; then
1687 INCLUDE=${INCLUDE#@include }
1688 [ -s "$FLAVORS_REPOSITORY/$INCLUDE/packages.list" ] && \
1689 get_pkglist $INCLUDE > $TMP_DIR/$FLAVOR.pkglist || \
1690 echo -e "\nERROR: Can't find include package list from $INCLUDE\n"
1691 fi
1692 # Generate the final/initial package list
1693 [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ] && \
1694 get_pkglist $FLAVOR >> $TMP_DIR/$FLAVOR.pkglist
1695 fi
1696 if grep -q ^ROOTFS_SELECTION \
1697 $FLAVORS_REPOSITORY/$FLAVOR/receipt; then
1698 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1699 set -- $ROOTFS_SELECTION
1700 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
1701 [ -f $FLAVORS_REPOSITORY/$2/packages.list ] ||
1702 tazlito extract-flavor $2
1703 get_pkglist $2 > $TMP_DIR/$FLAVOR.pkglist
1704 for i in rootcd rootfs; do
1705 mkdir $TMP_DIR/$i
1706 # Copy extra files from the first flavor
1707 [ -d $FLAVORS_REPOSITORY/$2/$i ] &&
1708 cp -a $FLAVORS_REPOSITORY/$2/$i $TMP_DIR
1709 # Overload extra files by meta flavor
1710 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] &&
1711 cp -a $FLAVORS_REPOSITORY/$FLAVOR/$i $TMP_DIR
1712 [ -n "$(ls $TMP_DIR/$i)" ] &&
1713 ( cd $TMP_DIR/$i ; find . | cpio -o -H newc 2> /dev/null ) | \
1714 gzip -9 >$TMP_DIR/$FLAVOR.$i
1715 rm -rf $TMP_DIR/$i
1716 done
1717 else
1718 for i in rootcd rootfs; do
1719 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] || \
1720 continue
1721 ( cd $FLAVORS_REPOSITORY/$FLAVOR/$i ; \
1722 find . | cpio -o -H newc 2> /dev/null ) | \
1723 gzip -9 >$TMP_DIR/$FLAVOR.$i
1724 done
1725 fi
1726 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1727 packed_size=$(($packed_size \
1728 + $(wc -c < $TMP_DIR/$FLAVOR.rootfs) / 100 ))
1729 unpacked_size=$(($unpacked_size \
1730 + $(zcat < $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1731 fi
1732 # Estimate lzma
1733 packed_size=$(($packed_size * 2 / 3))
1734 iso_size=$(( $packed_size + 26000 ))
1735 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1736 iso_size=$(($iso_size \
1737 + $(zcat < $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1738 fi
1739 VERSION=""
1740 MAINTAINER=""
1741 ROOTFS_SELECTION=""
1742 ROOTFS_SIZE="$(cent2human $unpacked_size) (estimated)"
1743 INITRAMFS_SIZE="$(cent2human $packed_size) (estimated)"
1744 ISO_SIZE="$(cent2human $iso_size) (estimated)"
1745 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1746 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1747 Flavor : $FLAVOR
1748 Description : $SHORT_DESC
1749 EOT
1750 [ -n "$VERSION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1751 Version : $VERSION
1752 EOT
1753 [ -n "$MAINTAINER" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1754 Maintainer : $MAINTAINER
1755 EOT
1756 [ -n "$FRUGAL_RAM" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1757 LiveCD RAM size : $FRUGAL_RAM
1758 EOT
1759 [ -n "$ROOTFS_SELECTION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1760 Rootfs list : $ROOTFS_SELECTION
1761 EOT
1762 cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1763 Build date : $(date +%Y%m%d\ \at\ \%H:%M:%S)
1764 Packages : $(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l)
1765 Rootfs size : $ROOTFS_SIZE
1766 Initramfs size : $INITRAMFS_SIZE
1767 ISO image size : $ISO_SIZE
1768 ================================================================================
1770 EOT
1771 rm -f $TMP_DIR/packages.list
1772 ( cd $TMP_DIR ; ls | cpio -o -H newc 2> /dev/null) | \
1773 gzip -9 > $FLAVOR.flavor
1774 status
1775 rm -Rf $TMP_DIR
1776 else
1777 echo "No $FLAVOR flavor in $FLAVORS_REPOSITORY."
1778 fi ;;
1780 get-flavor)
1781 # Get a flavor's files and prepare for gen-distro.
1782 FLAVOR=${2%.flavor}
1783 echo -e "\n\033[1mPreparing $FLAVOR distro flavor\033[0m"
1784 separator
1785 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1786 echo -n "Cleaning $DISTRO..."
1787 rm -R $DISTRO 2> /dev/null
1788 mkdir -p $DISTRO
1789 status
1790 mkdir $TMP_DIR
1791 [ -z $noup ] && tazlito upgrade-flavor $FLAVOR.flavor
1792 echo -n "Extracting flavor $FLAVOR.flavor... "
1793 zcat < $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i --quiet >/dev/null )
1794 status
1795 echo -n "Creating distro-packages.list..."
1796 mv $TMP_DIR/$FLAVOR.nonfree non-free.list 2> /dev/null
1797 mv $TMP_DIR/$FLAVOR.pkglist distro-packages.list
1798 status
1799 if [ -f "$TMP_DIR/$FLAVOR-distro.sh" ]; then
1800 echo -n "Extracting distro.sh... "
1801 mv $TMP_DIR/$FLAVOR-distro.sh distro.sh 2> /dev/null
1802 status
1803 fi
1804 if [ -f "$TMP_DIR/$FLAVOR.receipt" ]; then
1805 echo -n "Extracting receipt... "
1806 cp $TMP_DIR/$FLAVOR.receipt receipt 2> /dev/null
1807 status
1808 fi
1809 infos="$FLAVOR.desc"
1810 [ -s $TMP_DIR/$FLAVOR.receipt ] && infos="$infos\n$FLAVOR.receipt"
1811 for i in rootcd rootfs; do
1812 if [ -f $TMP_DIR/$FLAVOR.$i ]; then
1813 echo -n "Adding $i files... "
1814 mkdir -p "$ADDFILES/$i"
1815 zcat < $TMP_DIR/$FLAVOR.$i | \
1816 ( cd "$ADDFILES/$i"; cpio -id --quiet > /dev/null)
1817 zcat < $TMP_DIR/$FLAVOR.$i | cpio -tv 2> /dev/null \
1818 > $TMP_DIR/$FLAVOR.list$i
1819 infos="$infos\n$FLAVOR.list$i"
1820 status
1821 fi
1822 done
1823 if [ -s $TMP_DIR/$FLAVOR.mirrors ]; then
1824 n=""
1825 while read line; do
1826 mkdir -p $LOCALSTATE/undigest/$FLAVOR$n
1827 echo "$line" > $LOCALSTATE/undigest/$FLAVOR$n/mirror
1828 n=$(( $n + 1 ))
1829 done < $TMP_DIR/$FLAVOR.mirrors
1830 infos="$infos\n$FLAVOR.mirrors"
1831 tazpkg recharge
1832 fi
1833 rm -f /etc/tazlito/rootfs.list
1834 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc &&
1835 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1836 sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
1837 echo -n "Updating tazlito.conf..."
1838 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
1839 grep -v "^#VOLUM_NAME" < tazlito.conf | \
1840 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $FLAVOR\"\\n#VOLUM_NA/" \
1841 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
1842 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$FLAVOR\"/" tazlito.conf
1843 status
1844 ( cd $TMP_DIR ; echo -e $infos | cpio -o -H newc ) | \
1845 gzip -9 > /etc/tazlito/info
1846 rm -Rf $TMP_DIR
1847 fi
1848 separator
1849 echo -e "Flavor is ready to be generated by: tazlito gen-distro\n" ;;
1851 iso2flavor)
1852 if [ -z "$3" -o ! -s "$2" ]; then
1853 cat <<EOT
1854 Usage : tazlito iso2flavor image.iso flavor_name
1856 Create a file flavor_name.flavor from the cdrom image file image.iso
1857 EOT
1858 exit 1
1859 fi
1860 FLAVOR=${3%.flavor}
1861 mkdir -p $TMP_DIR/iso $TMP_DIR/rootfs $TMP_DIR/flavor
1862 mount -o loop,ro $2 $TMP_DIR/iso
1863 flavordata $2 | (cd $TMP_DIR/flavor ; cpio -i 2> /dev/null)
1864 if [ -s $TMP_DIR/iso/boot/rootfs1.gz -a \
1865 ! -s $TMP_DIR/flavor/*.desc ]; then
1866 echo "META flavors are not supported."
1867 umount -d $TMP_DIR/iso
1868 elif [ ! -s $TMP_DIR/iso/boot/rootfs.gz -a \
1869 ! -s $TMP_DIR/iso/boot/rootfs1.gz ]; then
1870 echo "No /boot/rootfs.gz in iso image. Needs a SliTaz iso."
1871 umount -d $TMP_DIR/iso
1872 else
1873 for i in $(ls -r $TMP_DIR/iso/boot/rootfs*gz); do
1874 ( zcat < $i || unlzma < $i ) | \
1875 ( cd $TMP_DIR/rootfs ; cpio -idmu > /dev/null 2>&1 )
1876 done
1877 if [ ! -s $TMP_DIR/rootfs/etc/slitaz-release ]; then
1878 echo "No file /etc/slitaz-release in /boot/rootfs.gz of iso image. Needs a non loram SliTaz iso."
1879 umount -d $TMP_DIR/iso
1880 else
1881 ROOTFS_SIZE=$(du -hs $TMP_DIR/rootfs | awk '{ print $1 }')
1882 RAM_SIZE=$(du -s $TMP_DIR/rootfs | awk '{ print 32*int(($1+36000)/32768) "M" }')
1883 cp -a $TMP_DIR/iso $TMP_DIR/rootcd
1884 ISO_SIZE=$(df -h $TMP_DIR/iso | awk 'END { print $2 }')
1885 BUILD_DATE=$(date +%Y%m%d\ \at\ \%H:%M:%S -r $TMP_DIR/iso/md5sum)
1886 umount -d $TMP_DIR/iso
1887 INITRAMFS_SIZE=$(du -chs $TMP_DIR/rootcd/boot/rootfs*.gz | awk 'END { print $1 }')
1888 rm -f $TMP_DIR/rootcd/boot/rootfs.gz $TMP_DIR/rootcd/md5sum
1889 mv $TMP_DIR/rootcd/boot $TMP_DIR/rootfs
1890 sed 's/.* \(.*\).tazpkg*/\1/' > $TMP_DIR/$FLAVOR.pkglist \
1891 < $TMP_DIR/rootfs$INSTALLED.md5
1892 PKGCNT=$(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l | awk '{ print $1 }')
1893 if [ -s $TMP_DIR/flavor/*desc ]; then
1894 cp $TMP_DIR/flavor/*.desc $TMP_DIR/$FLAVOR.desc
1895 [ -s $TMP_DIR/$FLAVOR.receipt ] &&
1896 cp $TMP_DIR/flavor/*.receipt $TMP_DIR/$FLAVOR.receipt
1897 for i in rootfs rootcd ; do
1898 [ -s $TMP_DIR/flavor/*.list$i ] &&
1899 sed 's/.\{1,45\}//;/^\.$/d' $TMP_DIR/flavor/*.list$i | ( cd $TMP_DIR/$i ; cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.$i
1900 done
1901 else
1902 find_flavor_rootfs $TMP_DIR/rootfs
1903 [ -d $TMP_DIR/rootfs/boot ] && mv $TMP_DIR/rootfs/boot $TMP_DIR/rootcd
1904 for i in rootfs rootcd ; do
1905 [ "$(ls $TMP_DIR/$i)" ] &&
1906 ( cd $TMP_DIR/$i ; find * | cpio -o -H newc ) | gzip -9 > $TMP_DIR/$FLAVOR.$i
1907 done
1908 VERSION=""; MAINTAINER=""
1909 echo -en "Flavor short description \007: "; read -t 30 DESCRIPTION
1910 if [ -n "$DESCRIPTION" ]; then
1911 echo -en "Flavor version : "; read -t 30 VERSION
1912 echo -en "Flavor maintainer (your email) : "; read -t 30 MAINTAINER
1913 fi
1914 [ -n "$DESCRIPTION" ] || DESCRIPTION="Slitaz $FLAVOR flavor"
1915 [ -n "$VERSION" ] || VERSION="1.0"
1916 [ -n "$MAINTAINER" ] || MAINTAINER="nobody@slitaz.org"
1917 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1918 Flavor : $FLAVOR
1919 Description : $DESCRIPTION
1920 Version : $VERSION
1921 Maintainer : $MAINTAINER
1922 LiveCD RAM size : $RAM_SIZE
1923 Build date : $BUILD_DATE
1924 Packages : $PKGCNT
1925 Rootfs size : $ROOTFS_SIZE
1926 Initramfs size : $INITRAMFS_SIZE
1927 ISO image size : $ISO_SIZE
1928 ================================================================================
1930 EOT
1931 cat <<EOT
1932 Tazlito can't detect each file installed during a package post_install.
1933 You should extract this flavor (tazlito extract-flavor $FLAVOR),
1934 check the files in /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/rootfs tree and remove
1935 files generated by post_installs.
1936 Check /home/slitaz/flavors/$(cat /etc/slitaz-release)/$FLAVOR/receipt too and repack the flavor
1937 (tazlito pack-flavor $FLAVOR)
1938 EOT
1939 fi
1940 ( cd $TMP_DIR ; ls $FLAVOR.* | cpio -o -H newc ) | gzip -9 > $FLAVOR.flavor
1941 fi
1942 fi
1943 rm -rf $TMP_DIR ;;
1945 check-list)
1946 # Use current packages list in $PWD by default.
1947 DISTRO_PKGS_LIST=distro-packages.list
1948 [ -d "$2" ] && DISTRO_PKGS_LIST=$2/distro-packages.list
1949 [ -f "$2" ] && DISTRO_PKGS_LIST=$2
1950 [ ! -f $DISTRO_PKGS_LIST ] && echo "No packages list found." && exit 0
1951 newline
1952 boldify "LiveCD packages list check"
1953 separator
1954 for pkg in $(cat $DISTRO_PKGS_LIST)
1955 do
1956 if ! grep -q "$pkg" $LOCALSTATE/packages.list; then
1957 echo "Updating: $pkg"
1958 up=$(($up + 1))
1959 fi
1960 done
1961 [ -z $up ] && echo -e "List is up-to-date\n" && exit 0
1962 separator
1963 echo -e "Updates: $up\n" ;;
1965 gen-distro)
1966 # Generate a live distro tree with a set of packages.
1968 check_root
1969 time=$(date +%s)
1971 # Libtaz will set $iso or $cdrom
1972 CDROM=""
1973 [ "$iso" ] && CDROM="-o loop $iso"
1974 [ "$cdrom" ] && CDROM="/dev/cdrom"
1975 # Check if a package list was specified on cmdline.
1976 if [ -f "$2" ]; then
1977 LIST_NAME=$2
1978 else
1979 LIST_NAME="distro-packages.list"
1980 fi
1982 if [ -d "$ROOTFS" ] ; then
1983 # Delete $ROOTFS if --force is set on command line
1984 if [ "$forced" ]; then
1985 rm -rf $ROOTFS $ROOTCD
1986 else
1987 echo -e "\nA rootfs exists in : $DISTRO"
1988 echo -e "Please clean the distro tree or change directory path.\n"
1989 exit 0
1990 fi
1991 fi
1993 # Build list with installed packages
1994 if [ ! -f "$LIST_NAME" -a -d $INSTALLED ] ; then
1995 for i in $(ls $INSTALLED); do
1996 if grep -q ^_realver $INSTALLED/$i/receipt ; then
1997 VERSION=$(. $INSTALLED/$i/receipt 2>/dev/null ; echo $VERSION)
1998 else
1999 eval $(grep ^VERSION= $INSTALLED/$i/receipt)
2000 fi
2001 EXTRAVERSION=""
2002 eval $(grep ^EXTRAVERSION= $INSTALLED/$i/receipt)
2003 echo "$i-$VERSION$EXTRAVERSION" >> $LIST_NAME
2004 done
2005 fi
2006 # Exit if no list name.
2007 if [ ! -f "$LIST_NAME" ]; then
2008 echo -e "\nNo packages list found or specified. Please read the docs.\n"
2009 exit 0
2010 fi
2011 # Start generation.
2012 newline
2013 boldify "Tazlito generating a distro"
2014 separator
2015 # Misc checks
2016 [ -n "$PACKAGES_REPOSITORY" ] || PACKAGES_REPOSITORY="."
2017 [ -d $PACKAGES_REPOSITORY ] || mkdir -p $PACKAGES_REPOSITORY
2018 # Get the list of packages using cat for a file list.
2019 LIST=`cat $LIST_NAME`
2020 # Verify if all packages in list are present in $PACKAGES_REPOSITORY.
2021 REPACK=""
2022 DOWNLOAD=""
2023 for pkg in $LIST
2024 do
2025 [ "$pkg" = "" ] && continue
2026 pkg=${pkg%.tazpkg}
2027 [ -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] && continue
2028 PACKAGE=$(installed_package_name $pkg)
2029 [ -n "$PACKAGE" -a "$REPACK" = "y" ] && continue
2030 [ -z "$PACKAGE" -a -n "$DOWNLOAD" ] && continue
2031 echo -e "\nUnable to find $pkg in the repository."
2032 echo -e "Path : $PACKAGES_REPOSITORY\n"
2033 if [ -n "$PACKAGE" -a -z "$REPACK" ]; then
2034 yesorno "Repack packages from rootfs (y/N) ? "
2035 REPACK="$answer"
2036 [ "$answer" = "y" ] || REPACK="n"
2037 [ "$DOWNLOAD" = "y" ] && break
2038 fi
2039 if [ -f $MIRROR -a -z "$DOWNLOAD" ]; then
2040 yesorno "Download packages from mirror (Y/n) ? "
2041 DOWNLOAD="$answer"
2042 if [ "$answer" = "n" ]; then
2043 [ -z "$PACKAGE" ] && exit 1
2044 else
2045 DOWNLOAD="y"
2046 [ -n "$REPACK" ] && break
2047 fi
2048 fi
2049 [ "$REPACK" = "n" -a "$DOWNLOAD" = "n" ] && exit 1
2050 done
2052 # Mount cdrom to be able to repack boot-loader packages
2053 if [ ! -e /boot -a -n "$CDROM" ]; then
2054 mkdir $TMP_MNT
2055 if mount -r $CDROM $TMP_MNT 2> /dev/null; then
2056 ln -s $TMP_MNT/boot /
2057 if [ ! -d "$ADDFILES/rootcd" ] ; then
2058 mkdir -p $ADDFILES/rootcd
2059 for i in $(ls $TMP_MNT); do
2060 [ "$i" = "boot" ] && continue
2061 cp -a $TMP_MNT/$i $ADDFILES/rootcd
2062 done
2063 fi
2064 else
2065 rmdir $TMP_MNT
2066 fi
2067 fi
2069 # Rootfs stuff.
2070 echo "Preparing the rootfs directory..."
2071 mkdir -p $ROOTFS
2072 for pkg in $LIST
2073 do
2074 [ "$pkg" = "" ] && continue
2075 # First copy and extract the package in tmp dir.
2076 pkg=${pkg%.tazpkg}
2077 PACKAGE=$(installed_package_name $pkg)
2078 mkdir -p $TMP_DIR
2079 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2080 # Look for package in cache
2081 if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
2082 ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
2083 # Look for package in running distribution
2084 elif [ -n "$PACKAGE" -a "$REPACK" = "y" ]; then
2085 tazpkg repack $PACKAGE && \
2086 mv $pkg.tazpkg $PACKAGES_REPOSITORY
2087 fi
2088 fi
2089 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2090 # Get package from mirror
2091 [ "$DOWNLOAD" = "y" ] && \
2092 download $pkg.tazpkg && \
2093 mv $pkg.tazpkg $PACKAGES_REPOSITORY
2094 fi
2095 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
2096 echo "Missing package: $pkg"
2097 cleanup
2098 exit 1
2099 fi
2100 done
2101 if [ -f non-free.list ]; then
2102 echo "Preparing non-free packages..."
2103 cp non-free.list $ROOTFS/etc/tazlito/non-free.list
2104 for pkg in $(cat non-free.list); do
2105 if [ ! -d $INSTALLED/$pkg ]; then
2106 if [ ! -d $INSTALLED/get-$pkg ]; then
2107 tazpkg get-install get-$pkg
2108 fi
2109 get-$pkg
2110 fi
2111 tazpkg repack $pkg
2112 pkg=$(ls $pkg*.tazpkg)
2113 grep -q "^$pkg$" $LIST_NAME || \
2114 echo $pkg >>$LIST_NAME
2115 mv $pkg $PACKAGES_REPOSITORY
2116 done
2117 fi
2118 cp $LIST_NAME $DISTRO/distro-packages.list
2119 sed 's/\(.*\)/\1.tazpkg/' < $DISTRO/distro-packages.list > $DISTRO/list-packages
2120 cd $PACKAGES_REPOSITORY
2122 # Use packages repository as mirror, don't download unsynced packages from mirror server
2123 mkdir -p $ROOTFS/home/slitaz; ln -s ../../../../packages $ROOTFS/home/slitaz/packages
2124 mkdir -p "$ROOTFS/var/lib/tazpkg"; echo '/home/slitaz/packages' > "$ROOTFS/var/lib/tazpkg/mirror"
2125 tazpkg --root=$ROOTFS >/dev/null 2>&1 # initial tazpkg setup in empty rootfs
2127 for pkg in $(cat $DISTRO/list-packages)
2128 do
2129 echo -n "Installing package: $pkg"
2130 yes y | tazpkg -i $pkg --root=$ROOTFS 2>&1 >> $log || exit 1
2131 status
2132 done
2134 # Clean packages cache
2135 find $ROOTFS/var/cache/tazpkg -name '*.tazpkg' -delete
2136 # Clean /var/lib/tazpkg
2137 rm $ROOTFS/var/lib/tazpkg/ID* $ROOTFS/var/lib/tazpkg/descriptions.txt \
2138 $ROOTFS/var/lib/tazpkg/extra.list $ROOTFS/var/lib/tazpkg/files* \
2139 $ROOTFS/var/lib/tazpkg/packages* 2>/dev/null
2140 # Back to default mirror
2141 rm -rf $ROOTFS/home/slitaz
2142 echo "$DEFAULT_MIRROR" > $ROOTFS/var/lib/tazpkg/mirror
2144 cd $DISTRO
2145 cp distro-packages.list $ROOTFS/etc/tazlito
2146 # Copy all files from $ADDFILES/rootfs to the rootfs.
2147 if [ -d "$ADDFILES/rootfs" ] ; then
2148 echo -n "Copying addfiles content to the rootfs... "
2149 cp -a $ADDFILES/rootfs/* $ROOTFS
2150 status
2151 fi
2152 echo -n "Root filesystem is generated..." && status
2153 # Root CD part.
2154 echo -n "Preparing the rootcd directory..."
2155 mkdir -p $ROOTCD
2156 status
2157 # Move the boot dir with the Linux kernel from rootfs.
2158 # The boot dir goes directly on the CD.
2159 if [ -d "$ROOTFS/boot" ] ; then
2160 echo -n "Moving the boot directory..."
2161 mv $ROOTFS/boot $ROOTCD
2162 cd $ROOTCD/boot
2163 make_bzImage_hardlink
2164 status
2165 fi
2166 cd $DISTRO
2167 # Copy all files from $ADDFILES/rootcd to the rootcd.
2168 if [ -d "$ADDFILES/rootcd" ] ; then
2169 echo -n "Copying addfiles content to the rootcd... "
2170 cp -a $ADDFILES/rootcd/* $ROOTCD
2171 status
2172 fi
2173 # Execute the distro script used to perform tasks in the rootfs
2174 # before compression. Give rootfs path in arg
2175 [ -z $DISTRO_SCRIPT ] && DISTRO_SCRIPT=$TOP_DIR/distro.sh
2176 if [ -x $DISTRO_SCRIPT ]; then
2177 echo "Executing distro script..."
2178 sh $DISTRO_SCRIPT $DISTRO
2179 fi
2181 # Execute the custom_rules found in receipt.
2182 if [ -s $TOP_DIR/receipt ]; then
2183 if grep -q ^custom_rules $TOP_DIR/receipt; then
2184 echo -e "Executing: custom_rules\n"
2185 . $TOP_DIR/receipt
2186 custom_rules || echo -e "\nERROR: custom_rules failed\n"
2187 fi
2188 fi
2190 # Multi-rootfs
2191 if [ -s /etc/tazlito/rootfs.list ]; then
2193 FLAVOR_LIST="$(awk '{ for (i = 2; i <= NF; i+=2) \
2194 printf("%s ",$i) }' < /etc/tazlito/rootfs.list)"
2196 [ -s $ROOTCD/boot/isolinux/isolinux.msg ] &&
2197 sed -i "s/ *//;s/)/), flavors $FLAVOR_LIST/" \
2198 $ROOTCD/boot/isolinux/isolinux.msg 2> /dev/null
2200 [ -f $ROOTCD/boot/isolinux/ifmem.c32 -o \
2201 -f $ROOTCD/boot/isolinux/c32box.c32 ] ||
2202 cp /boot/isolinux/c32box.c32 $ROOTCD/boot/isolinux 2> /dev/null ||
2203 cp /boot/isolinux/ifmem.c32 $ROOTCD/boot/isolinux
2205 n=0
2206 last=$ROOTFS
2207 while read flavor; do
2208 n=$(($n+1))
2209 newline
2210 boldify "Building $flavor rootfs..."
2212 [ -s $TOP_DIR/$flavor.flavor ] &&
2213 cp $TOP_DIR/$flavor.flavor .
2215 if [ ! -s $flavor.flavor ]; then
2216 # We may have it in $FLAVORS_REPOSITORY
2217 if [ -d "$FLAVORS_REPOSITORY/$flavor" ]; then
2218 tazlito pack-flavor $flavor
2219 else
2220 download $flavor.flavor
2221 fi
2222 fi
2224 echo -n "Extracting $flavor.pkglist and $flavor.rootfs..."
2225 zcat < $flavor.flavor | cpio -i --quiet \
2226 $flavor.pkglist $flavor.rootfs
2227 sed 's/.*/&.tazpkg/' < $flavor.pkglist \
2228 > $DISTRO/list-packages0$n
2229 status
2231 mkdir ${ROOTFS}0$n
2232 # Install packages
2233 cd ${PACKAGES_REPOSITORY}
2235 # Use packages repository as mirror, don't download unsynced packages from mirror server
2236 mkdir -p ${ROOTFS}0$n/home/slitaz; ln -s ../../../../packages ${ROOTFS}0$n/home/slitaz/packages
2237 mkdir -p "${ROOTFS}0$n/var/lib/tazpkg"
2238 echo '/home/slitaz/packages' > "${ROOTFS}0$n/var/lib/tazpkg/mirror"
2239 tazpkg --root=${ROOTFS}0$n >/dev/null 2>&1 # initial tazpkg setup in empty rootfs
2241 for pkg in $(cat $DISTRO/list-packages0$n)
2242 do
2243 echo -n "Installing package: $pkg"
2244 yes y | tazpkg -i $pkg --root=${ROOTFS}0$n 2>&1 >> $log || exit 1
2245 status
2246 done
2248 rm -rf ${ROOTFS}0$n/boot ${ROOTFS}0$n/var/lib/tazpkg/packages.*
2249 # Clean packages cache
2250 find ${ROOTFS}0$n/var/cache/tazpkg -name '*.tazpkg' -delete
2251 # Clean /var/lib/tazpkg
2252 rm ${ROOTFS}0$n/var/lib/tazpkg/ID* ${ROOTFS}0$n/var/lib/tazpkg/descriptions.txt \
2253 ${ROOTFS}0$n/var/lib/tazpkg/extra.list ${ROOTFS}0$n/var/lib/tazpkg/files* \
2254 2>/dev/null
2255 # Back to default mirror
2256 rm -rf ${ROOTFS}0$n/home/slitaz
2257 echo "$DEFAULT_MIRROR" > ${ROOTFS}0$n/var/lib/tazpkg/mirror
2259 cd $DISTRO
2260 if [ -s $flavor.rootfs ]; then
2261 echo -n "Adding $flavor rootfs extra files..."
2262 zcat < $flavor.rootfs | ( cd ${ROOTFS}0$n ; cpio -idmu )
2263 fi
2264 echo -n "Moving list-packages0$n to rootfs0$n"
2265 mv $DISTRO/list-packages0$n ${ROOTFS}0$n/etc/tazlito/distro-packages.list
2266 status
2267 rm -f $flavor.flavor install-list
2268 mergefs ${ROOTFS}0$n $last
2269 last=${ROOTFS}0$n
2270 done <<EOT
2271 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
2272 EOT
2273 #'
2274 i=$(($n+1))
2275 while [ $n -gt 0 ]; do
2276 mv ${ROOTFS}0$n ${ROOTFS}$i
2277 echo "Compressing ${ROOTFS}0$n ($(du -hs ${ROOTFS}$i | awk '{ print $1 }'))..."
2278 gen_initramfs ${ROOTFS}$i
2279 n=$(($n-1))
2280 i=$(($i-1))
2281 done
2282 mv $ROOTFS ${ROOTFS}$i
2283 gen_initramfs ${ROOTFS}$i
2284 update_bootconfig $ROOTCD/boot/isolinux \
2285 "$(cat /etc/tazlito/rootfs.list)"
2286 else
2287 # Initramfs and ISO image stuff.
2288 gen_initramfs $ROOTFS
2289 fi
2290 gen_livecd_isolinux
2291 distro_stats
2292 cleanup ;;
2294 clean-distro)
2295 # Remove old distro tree.
2297 check_root
2298 newline
2299 boldify "Cleaning : $DISTRO"
2300 separator
2301 if [ -d "$DISTRO" ] ; then
2302 if [ -d "$ROOTFS" ] ; then
2303 echo -n "Removing the rootfs..."
2304 rm -f $DISTRO/$INITRAMFS
2305 rm -rf $ROOTFS
2306 status
2307 fi
2308 if [ -d "$ROOTCD" ] ; then
2309 echo -n "Removing the rootcd..."
2310 rm -rf $ROOTCD
2311 status
2312 fi
2313 echo -n "Removing eventual ISO image..."
2314 rm -f $DISTRO/$ISO_NAME.iso
2315 rm -f $DISTRO/$ISO_NAME.md5
2316 status
2317 fi
2318 separator
2319 newline ;;
2321 check-distro)
2322 # Check for a few LiveCD needed files not installed by packages.
2324 check_rootfs
2325 newline
2326 echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
2327 separator
2328 # SliTaz release info.
2329 if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
2330 echo "Missing release info : /etc/slitaz-release"
2331 else
2332 release=`cat $ROOTFS/etc/slitaz-release`
2333 echo -n "Release : $release"
2334 status
2335 fi
2336 # Tazpkg mirror.
2337 if [ ! -f "$ROOTFS$LOCALSTATE/mirror" ]; then
2338 echo -n "Mirror URL : Missing $LOCALSTATE/mirror"
2339 todomsg
2340 else
2341 echo -n "Mirror configuration exists..."
2342 status
2343 fi
2344 # Isolinux msg
2345 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.*g; then
2346 echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
2347 todomsg
2348 else
2349 echo -n "Isolinux message seems good..."
2350 status
2351 fi
2352 separator
2353 newline ;;
2355 writeiso)
2356 # Writefs to ISO image including /home unlike gen-distro we dont use
2357 # packages to generate a rootfs, we build a compressed rootfs with all
2358 # the current filesystem similar to 'tazusb writefs'.
2360 DISTRO="/home/slitaz/distro"
2361 ROOTCD="$DISTRO/rootcd"
2362 if [ -z $2 ]; then
2363 COMPRESSION=none
2364 else
2365 COMPRESSION=$2
2366 fi
2367 if [ -z $3 ]; then
2368 ISO_NAME="slitaz"
2369 else
2370 ISO_NAME="$3"
2371 fi
2372 check_root
2373 # Start info
2374 newline
2375 boldify "Write filesystem to ISO"
2376 separator
2377 cat <<EOT
2378 The command writeiso will write the current filesystem into a suitable cpio
2379 archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso).
2381 $(boldify "Archive compression:") $(colorize 36 "$COMPRESSION")
2383 EOT
2384 [ $COMPRESSION == "gzip" ] && colorize 31 "gzip-compressed rootfs unsupported and may fail to boot"
2385 # Save some space
2386 rm /var/cache/tazpkg/* -r -f
2387 rm /var/lib/tazpkg/*.bak -f
2388 rm -rf $DISTRO
2390 # Optionally remove sound card selection and screen resolution.
2391 if [ -z $LaunchedByTazpanel ]; then
2392 echo "Do you wish to remove the sound card and screen configs ? "
2393 echo -n "Press ENTER to keep or answer (No|yes|exit): "
2394 read anser
2395 case $anser in
2396 e|E|"exit"|Exit)
2397 exit 0 ;;
2398 y|Y|yes|Yes)
2399 echo -n "Removing current sound card and screen configurations..."
2400 rm -f /var/lib/sound-card-driver
2401 rm -f /var/lib/alsa/asound.state
2402 rm -f /etc/X11/xorg.conf ;;
2403 *)
2404 echo -n "Keeping current sound card and screen configurations..." ;;
2405 esac
2406 status && newline
2408 # Optionally remove i18n settings
2409 echo "Do you wish to remove local/keymap settings ? "
2410 echo -n "Press ENTER to keep or answer (No|yes|exit): "
2411 read anser
2412 case $anser in
2413 e|E|"exit"|Exit)
2414 exit 0 ;;
2415 y|Y|yes|Yes)
2416 echo "Removing current locale/keymap settings..."
2417 newline > /etc/locale.conf
2418 newline > /etc/keymap.conf ;;
2419 *)
2420 echo "Keeping current locale/keymap settings..." ;;
2421 esac
2422 status
2423 fi
2425 # Clean-up files by default
2426 newline > /etc/udev/rules.d/70-persistent-net.rules
2427 newline > /etc/udev/rules.d/70-persistant-cd.rules
2429 # Create list of files including default user files since it is defined in /etc/passwd
2430 # and some new users might have been added.
2431 cd /
2432 echo 'init' > /tmp/list
2433 for dir in bin etc sbin var dev lib root usr home opt
2434 do
2435 [ -d $dir ] && find $dir
2436 done >>/tmp/list
2438 for dir in proc sys tmp mnt media media/cdrom media/flash \
2439 media/usbdisk run run/udev
2440 do
2441 [ -d $dir ] && echo $dir
2442 done >>/tmp/list
2444 sed '/var\/run\/.*pid$/d ; /var\/run\/utmp/d ; /.*\/.gvfs/d ; /home\/.*\/.cache\/.*/d' -i /tmp/list
2446 #if [ ! $(find /var/log/slitaz/tazpkg.log -size +4k) = "" ]; then
2447 # sed -i "/var\/log\/slitaz\/tazpkg.log/d" /tmp/list
2448 #fi
2449 mv -f /var/log/wtmp /tmp/tazlito-wtmp
2450 touch /var/log/wtmp
2452 for removelog in \
2453 auth boot messages dmesg daemon slim .*old Xorg tazpanel cups; do
2454 sed -i "/var\/log\/$removelog/d" /tmp/list
2455 done
2457 # Generate initramfs with specified compression and display rootfs
2458 # size in realtime.
2459 rm -f /tmp/.write-iso* /tmp/rootfs 2>/dev/null
2461 write_initramfs &
2462 sleep 2
2463 cd - > /dev/null
2464 echo -en "\nFilesystem size:"
2465 while [ ! -f /tmp/rootfs ]
2466 do
2467 sleep 1
2468 echo -en "\\033[18G`du -sh /rootfs.gz | awk '{print $1}'` "
2469 done
2470 mv -f /tmp/tazlito-wtmp /var/log/wtmp
2471 echo -e "\n"
2472 rm -f /tmp/rootfs
2474 # Move freshly generated rootfs to the cdrom.
2475 mkdir -p $ROOTCD/boot
2476 mv -f /rootfs.gz $ROOTCD/boot
2477 echo "Located in: $ROOTCD/boot/rootfs.gz"
2479 # Now we need the kernel and isolinux files.
2480 copy_from_cd()
2482 cp /media/cdrom/boot/bzImage* $ROOTCD/boot
2483 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
2484 unmeta_boot $ROOTCD
2485 umount /media/cdrom
2487 bootloader="/var/lib/tazpkg/installed/syslinux/volatile.cpio.gz"
2488 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
2489 copy_from_cd;
2490 elif mount |grep /media/cdrom; then
2491 copy_from_cd;
2492 elif [ -f "$bootloader" -a -f /boot/vmlinuz*slitaz* ]; then
2493 cp $bootloader $ROOTCD
2494 cd $ROOTCD
2495 zcat volatile.cpio.gz | cpio -id
2496 rm -f volatile.cpio.gz
2497 [ -f /boot/*slitaz ] && \
2498 cp /boot/vmlinuz*slitaz $ROOTCD/boot/bzImage
2499 [ -f /boot/*slitaz64 ] && \
2500 cp /boot/vmlinuz*slitaz64 $ROOTCD/boot/bzImage64
2501 else
2502 touch /tmp/.write-iso-error
2503 echo -e "
2504 When SliTaz is running in RAM the kernel and bootloader files are kept
2505 on the cdrom. Please insert a LiveCD or loop mount the slitaz.iso to
2506 /media/cdrom (run # mount -o loop slitaz-rolling.iso /media/cdrom )
2507 or # (tazpkg -gi linux --forced) to let Tazlito copy the files.\n"
2508 echo -en "----\nENTER to continue..."; read i
2509 [ ! -d /media/cdrom/boot/isolinux ] && exit 1
2510 copy_from_cd
2511 fi
2513 # Generate the iso image.
2514 touch /tmp/.write-iso
2515 newline
2516 cd $DISTRO
2517 echo "Generating ISO image..."
2518 genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
2519 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
2520 -V "SliTaz" -p "$(id -un)" -input-charset iso8859-1 \
2521 -P "$(hostname)" -boot-info-table $ROOTCD
2522 if [ -x /usr/bin/isohybrid ]; then
2523 echo -n "Creating hybrid ISO..."
2524 /usr/bin/isohybrid $ISO_NAME.iso -entry 2 2> /dev/null
2525 status
2526 fi
2527 echo -n "Creating the ISO md5sum..."
2528 md5sum $ISO_NAME.iso > $ISO_NAME.md5
2529 status
2531 separator
2532 echo "ISO image: $(du -sh $DISTRO/$ISO_NAME.iso)"
2533 rm -f /tmp/.write-iso
2534 newline
2535 if [ -z $LaunchedByTazpanel ]; then
2536 echo -n "Exit or burn ISO to cdrom (Exit|burn)? "; read anser
2537 case $anser in
2538 burn)
2539 umount /dev/cdrom 2> /dev/null
2540 eject
2541 echo -n "Please insert a blank cdrom and press ENTER..."
2542 read i && sleep 2
2543 tazlito burn-iso $DISTRO/$ISO_NAME.iso
2544 echo -en "----\nENTER to continue..."; read i ;;
2545 *)
2546 exit 0 ;;
2547 esac
2548 fi ;;
2550 burn-iso)
2551 # Guess cdrom device, ask user and burn the ISO.
2553 check_root
2554 DRIVE_NAME=$(grep "drive name" < /proc/sys/dev/cdrom/info | cut -f 3)
2555 DRIVE_SPEED=$(grep "drive speed" < /proc/sys/dev/cdrom/info | cut -f 3)
2556 # We can specify an alternative ISO from the cmdline.
2557 if [ -n "$2" ] ; then
2558 iso=$2
2559 else
2560 iso=$DISTRO/$ISO_NAME.iso
2561 fi
2562 if [ ! -f "$iso" ]; then
2563 echo -e "\nUnable to find ISO : $iso\n"
2564 exit 0
2565 fi
2566 newline
2567 boldify "Tazlito burn ISO"
2568 separator
2569 echo "Cdrom device : /dev/$DRIVE_NAME"
2570 echo "Drive speed : $DRIVE_SPEED"
2571 echo "ISO image : $iso"
2572 separator
2573 newline
2574 yesorno "Burn ISO image (y/N) ? "
2575 if [ "$answer" == "y" ]; then
2576 newline
2577 echo "Starting Wodim to burn the iso..." && sleep 2
2578 separator
2579 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
2580 separator
2581 echo "ISO image is burned to cdrom."
2582 else
2583 echo -e "\nExiting. No ISO burned."
2584 fi
2585 newline ;;
2587 merge)
2588 # Merge multiple rootfs into one iso.
2590 if [ -z "$2" ]; then
2591 cat <<EOT
2592 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
2594 Merge multiple rootfs into one iso. Rootfs are like russian dolls
2595 i.e: rootfsN is a subset of rootfsN-1
2596 rootfs1 is found in iso, sizeN is the RAM size needed to launch rootfsN.
2597 The boot loader will select the rootfs according to the RAM size detected.
2599 Example:
2600 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
2602 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
2603 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
2605 EOT
2606 exit 2
2607 fi
2609 shift # skip merge
2610 append="$1 slitaz1"
2611 shift # skip size1
2612 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
2614 ISO=$1.merged
2615 # Extract filesystems
2616 echo -n "Mounting $1"
2617 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
2618 status || cleanup_merge
2619 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2620 make_bzImage_hardlink $TMP_DIR/iso/boot
2621 umount -d $TMP_DIR/mnt
2622 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
2623 echo "$1 is already a merged iso. Aborting."
2624 cleanup_merge
2625 fi
2626 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 -a
2627 ! -f $TMP_DIR/iso/boot/isolinux/c32box.c32 ]; then
2628 if [ ! -f /boot/isolinux/ifmem.c32 -a
2629 ! -f /boot/isolinux/c32box.c32 ]; then
2630 cat <<EOT
2631 No file /boot/isolinux/ifmem.c32
2632 Please install syslinux package !
2633 EOT
2634 rm -rf $TMP_DIR
2635 exit 1
2636 fi
2637 cp /boot/isolinux/c32box.c32 $TMP_DIR/iso/boot/isolinux 2> /dev/null ||
2638 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
2639 fi
2641 echo -n "Extracting iso/rootfs.gz"
2642 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
2643 [ -d $TMP_DIR/rootfs1/etc ]
2644 status || cleanup_merge
2645 n=1
2646 while [ -n "$2" ]; do
2647 shift # skip rootfs N-1
2648 p=$n
2649 n=$(($n + 1))
2650 append="$append $1 slitaz$n"
2651 shift # skip size N
2652 mkdir -p $TMP_DIR/rootfs$n
2653 echo -n "Extracting $1"
2654 extract_rootfs $1 $TMP_DIR/rootfs$n &&
2655 [ -d $TMP_DIR/rootfs$n/etc ]
2656 status || cleanup_merge
2657 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
2658 echo "Creating rootfs$p.gz"
2659 pack_rootfs $TMP_DIR/rootfs$p $TMP_DIR/iso/boot/rootfs$p.gz
2660 status
2661 done
2662 echo "Creating rootfs$n.gz"
2663 pack_rootfs $TMP_DIR/rootfs$n $TMP_DIR/iso/boot/rootfs$n.gz
2664 status
2665 rm -f $TMP_DIR/iso/boot/rootfs.gz
2666 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
2667 create_iso $ISO $TMP_DIR/iso
2668 rm -rf $TMP_DIR ;;
2670 repack)
2671 # Repack an iso with maximum lzma compression ratio.
2673 ISO=$2
2674 mkdir -p $TMP_DIR/mnt
2676 # Extract filesystems
2677 echo -n "Mounting $ISO"
2678 mount -o loop,ro $ISO $TMP_DIR/mnt 2> /dev/null
2679 status || cleanup_merge
2680 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2681 umount -d $TMP_DIR/mnt
2683 for i in $TMP_DIR/iso/boot/rootfs* ; do
2684 echo -n "Repacking $(basename $i)"
2685 (zcat $i 2> /dev/null || unlzma < $i || cat $i) \
2686 2>/dev/null > $TMP_DIR/rootfs
2687 lzma e $TMP_DIR/rootfs $i \
2688 $(lzma_switches $TMP_DIR/rootfs)
2689 align_to_32bits $i
2690 status
2691 done
2693 create_iso $ISO $TMP_DIR/iso
2694 rm -rf $TMP_DIR ;;
2696 build-loram)
2697 # Build a Live CD for low ram systems.
2699 ISO=$2
2700 OUTPUT=$3
2701 if [ -z "$3" ]; then
2702 echo "Usage: tazlito $1 input.iso output.iso [cdrom|smallcdrom|http|ram]"
2703 exit 1
2704 fi
2705 mkdir -p $TMP_DIR/iso
2706 mount -o loop,ro -t iso9660 $ISO $TMP_DIR/iso
2707 loopdev=$( (losetup -a 2>/dev/null || losetup) | sed "/$ISO$/!d;s/:.*//;q")
2708 if ! check_iso_for_loram ; then
2709 echo "$2 is not a valid SliTaz live CD. Abort."
2710 umount -d $TMP_DIR/iso
2711 rm -rf $TMP_DIR
2712 exit 1
2713 fi
2714 case "$4" in
2715 cdrom) build_loram_cdrom ;;
2716 http) build_loram_http ;;
2717 *) build_loram_ram ;;
2718 esac
2719 umount $TMP_DIR/iso # no -d: needs /proc
2720 losetup -d $loopdev
2721 rm -rf $TMP_DIR ;;
2723 emu-iso)
2724 # Emulate an ISO image with Qemu.
2725 if [ -n "$2" ] ; then
2726 iso=$2
2727 else
2728 iso=$DISTRO/$ISO_NAME.iso
2729 fi
2730 if [ ! -f "$iso" ]; then
2731 echo -e "\nUnable to find ISO : $iso\n"
2732 exit 0
2733 fi
2734 if [ ! -x "/usr/bin/qemu" ]; then
2735 echo -e "\nUnable to find Qemu binary. Please install: qemu\n"
2736 exit 0
2737 fi
2738 echo -e "\nStarting Qemu emulator:\n"
2739 echo -e "qemu $QEMU_OPTS $iso\n"
2740 qemu $QEMU_OPTS $iso ;;
2742 deduplicate)
2743 # Deduplicate files in a tree
2744 shift
2745 deduplicate "$@" ;;
2747 usage|*)
2748 # Print usage also for all unknown commands.
2749 usage ;;
2750 esac
2752 exit 0