tazlito view tazlito @ rev 178

tazlito: be bootfloppybox compatible
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Mar 28 18:30:39 2010 +0200 (2010-03-28)
parents ca84d0c664e1
children 6bc53204ac6d
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-2010 SliTaz - GNU General Public License.
11 #
12 # Authors : Christophe Lincoln <pankso@slitaz.org>
13 # Pascal Bellard <pascal.bellard@slitaz.org>
14 #
15 VERSION=3.0
17 # Tazlito configuration variables to be shorter
18 # and to use words rather than numbers.
19 COMMAND=$1
20 LIST_NAME=$2
21 TMP_DIR=/tmp/tazlito-$$-$RANDOM
22 TMP_MNT=/media/tazlito-$$-$RANDOM
23 TOP_DIR=`pwd`
24 INITRAMFS=rootfs.gz
25 LOCALSTATE=/var/lib/tazpkg
26 INSTALLED=$LOCALSTATE/installed
27 CACHE_DIR=/var/cache/tazpkg
28 MIRROR=$LOCALSTATE/mirror
29 DEFAULT_MIRROR="http://mirror.slitaz.org/packages/`cat /etc/slitaz-release`/"
31 # Try to include config file, continue if command is gen-config or exit.
32 # The main config used by default is in /etc/tazlito.
33 if [ -f "/etc/tazlito/tazlito.conf" ] ; then
34 CONFIG_FILE="/etc/tazlito/tazlito.conf"
35 fi
36 # Specific distro config file can be put in a distro tree.
37 if [ -f "$TOP_DIR/tazlito.conf" ] ; then
38 CONFIG_FILE="$TOP_DIR/tazlito.conf"
39 fi
40 if [ ! "$CONFIG_FILE" = "" ] ; then
41 . $CONFIG_FILE
42 else
43 if [ "$COMMAND" = "gen-config" ] ; then
44 continue
45 else
46 echo "Unable to find any configuration file. Please read the docs"
47 echo "or run '`basename $0` gen-config' to get an empty config file."
48 exit 0
49 fi
50 fi
52 # While Tazpkg is not used the default mirror url file does not exist
53 # and user can't recharge the list of flavors.
54 if test $(id -u) = 0 ; then
55 if [ ! -f "$MIRROR" ]; then
56 echo "$DEFAULT_MIRROR" > $MIRROR
57 fi
58 fi
60 # Set the rootfs and rootcd path with $DISTRO
61 # configuration variable.
62 ROOTFS=$DISTRO/rootfs
63 ROOTCD=$DISTRO/rootcd
64 FLAVORS_REPOSITORY=/home/slitaz/flavors
66 #####################
67 # Tazlito functions #
68 #####################
70 # Print the usage.
71 usage ()
72 {
73 echo -e "\nSliTaz Live Tool - Version: $VERSION\n
74 \033[1mUsage: \033[0m `basename $0` [command] [list|iso|flavor|compression] [dir|iso]
75 \033[1mCommands: \033[0m\n
76 usage Print this short usage.
77 stats View Tazlito and distro configuration statistics.
78 gen-config Generate a new configuration file for a distro.
79 configure Configure the main config file or a specific tazlito.conf.
80 gen-iso Generate a new ISO from a distro tree.
81 gen-initiso Generate a new initramfs and ISO from the distro tree.
82 list-flavors List all available package lists on the mirror.
83 gen-flavor Generate a new live-CD description.
84 gen-liveflavor Generate a live-CD description from current system.
85 show-flavor Show live-CD description.
86 get-flavor Get a flavor's list of packages.
87 upgrade-flavor Update package list to the latest available versions.
88 extract-flavor Extract a (*.flavor) flavor into $FLAVORS_REPOSITORY.
89 pack-flavor Pack (and update) a flavor from $FLAVORS_REPOSITORY.
90 check-list Check a distro-packages.list for updates.
91 extract-distro Extract an ISO to a directory and rebuild LiveCD tree.
92 gen-distro Generate a Live distro and ISO from a list of packages.
93 clean-distro Remove all files generated by gen-distro.
94 check-distro Help to check if distro is ready to release.
95 writeiso Use running system to generate a bootable ISO (with /home).
96 merge Merge multiple rootfs into one iso.
97 repack Recompress rootfs into iso with maximum ratio.
98 build-loram Generate a live-CD for low ram systems.
99 frugal-install Frugal install in /boot/frugal from a distro or ISO.
100 emu-iso Emulate an ISO image with Qemu.
101 burn-iso Burn ISO image to a cdrom using Wodim.\n"
102 }
104 # Status function.
105 status()
106 {
107 local CHECK=$?
108 echo -en "\\033[70G[ "
109 if [ $CHECK = 0 ]; then
110 echo -en "\\033[1;33mOK"
111 else
112 echo -en "\\033[1;31mFailed"
113 fi
114 echo -e "\\033[0;39m ]"
115 return $CHECK
116 }
118 yesorno()
119 {
120 echo -n "$1"
121 case "$DEFAULT_ANSWER" in
122 Y|y) answer="y";;
123 N|n) answer="n";;
124 *) read answer;;
125 esac
126 }
128 field()
129 {
130 grep "^$1" "$2" | sed 's/.*: \([0-9KMG\.]*\).*/\1/'
131 }
133 todomsg()
134 {
135 echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
136 }
138 # Download a file from this mirror
139 download_from()
140 {
141 local i
142 local mirrors
143 mirrors="$1"
144 shift
145 for i in $mirrors; do
146 case "$i" in
147 http://*|ftp://*) wget -c $i$@ && break;;
148 *) cp $i/$1 . && break;;
149 esac
150 done
151 }
153 # Download a file trying all mirrors
154 download()
155 {
156 local i
157 for i in $(cat $MIRROR $LOCALSTATE/undigest/*/mirror 2> /dev/null); do
158 download_from "$i" "$@" && break
159 done
160 }
162 # Execute hooks provided by some packages
163 genisohooks()
164 {
165 local here=`pwd`
166 for i in $(ls $ROOTFS/etc/tazlito/*.$1 2> /dev/null); do
167 cd $ROOTFS
168 . $i $ROOTCD
169 done
170 cd $here
171 }
173 cleanup()
174 {
175 if [ -d $TMP_MNT ]; then
176 umount $TMP_MNT
177 rmdir $TMP_MNT
178 rm -f /boot
179 fi
180 }
182 # Echo the package name if the tazpkg is already installed
183 installed_package_name()
184 {
185 local tazpkg
186 local package
187 local VERSION
188 local EXTRAVERSION
189 tazpkg=$1
190 # Try to find package name and version to be able
191 # to repack it from installation
192 # A dash (-) can exist in name *and* in version
193 package=${tazpkg%-*}
194 i=$package
195 while true; do
196 VERSION=""
197 eval $(grep -s ^VERSION= $INSTALLED/$i/receipt)
198 EXTRAVERSION=""
199 eval $(grep -s ^EXTRAVERSION= $INSTALLED/$i/receipt)
200 if [ "$i-$VERSION$EXTRAVERSION" = "$tazpkg" ]; then
201 echo $i
202 break
203 fi
204 case "$i" in
205 *-*);;
206 *) break;;
207 esac
208 i=${i%-*}
209 done
210 }
212 # Check if user is root.
213 check_root()
214 {
215 if test $(id -u) != 0 ; then
216 echo -e "\nYou must be root to run `basename $0` with this option."
217 echo -e "Please type 'su' and root password to become super-user.\n"
218 exit 0
219 fi
220 }
222 # Check for the rootfs tree.
223 check_rootfs()
224 {
225 if [ ! -d "$ROOTFS/etc" ] ; then
226 echo -e "\nUnable to find a distro rootfs...\n"
227 exit 0
228 fi
229 }
231 # Check for the boot dir into the root CD tree.
232 verify_rootcd()
233 {
234 if [ ! -d "$ROOTCD/boot" ] ; then
235 echo -e "\nUnable to find the rootcd boot directory...\n"
236 exit 0
237 fi
238 }
240 create_iso()
241 {
242 echo "Generating $1"
243 genisoimage -R -o $1 -b boot/isolinux/isolinux.bin \
244 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
245 -V "$VOLUM_NAME" -p "$PREPARED" -input-charset iso8859-1 \
246 -boot-info-table $2
247 if [ -x /usr/bin/isohybrid ]; then
248 echo -n "Creating hybrid ISO..."
249 /usr/bin/isohybrid $1 2> /dev/null
250 status
251 fi
252 }
254 # Generate a new ISO image using isolinux.
255 gen_livecd_isolinux()
256 {
257 # Some packages may want to alter iso
258 genisohooks iso
259 if [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ]; then
260 echo -e "\nUnable to find isolinux binary.\n"
261 cleanup
262 exit 0
263 fi
264 # Set date for boot msg.
265 if grep -q 'XXXXXXXX' $ROOTCD/boot/isolinux/isolinux.msg; then
266 DATE=`date +%Y%m%d`
267 echo -n "Setting build date to: $DATE..."
268 sed -i s/'XXXXXXXX'/"$DATE"/ $ROOTCD/boot/isolinux/isolinux.msg
269 status
270 fi
271 cd $ROOTCD
272 echo -n "Computing md5..."
273 find * -type f ! -name md5sum -exec md5sum {} \; > md5sum
274 status
275 cd $DISTRO
276 echo ""
277 echo -e "\033[1mGenerating ISO image\033[0m"
278 echo "================================================================================"
279 create_iso $ISO_NAME.iso $ROOTCD
280 echo -n "Creating the ISO md5sum..."
281 md5sum $ISO_NAME.iso > $ISO_NAME.md5
282 status
283 echo "================================================================================"
284 # Some packages may want to alter final iso
285 genisohooks final
286 }
288 lzma_history_bits()
289 {
290 #
291 # This generates an ISO which boots with Qemu but gives
292 # rootfs errors in frugal or liveUSB mode.
293 #
294 #local n
295 #local sz
296 #n=20 # 1Mb
297 #sz=$(du -sk $1 | cut -f1)
298 #while [ $sz -gt 1024 -a $n -lt 28 ]; do
299 #n=$(( $n + 1 ))
300 #sz=$(( $sz / 2 ))
301 #done
302 #echo $n
303 echo 24
304 }
306 lzma_switches()
307 {
308 echo "-d$(lzma_history_bits $1) -mt$(grep ^processor < /proc/cpuinfo | wc -l)"
309 }
311 # Pack rootfs
312 pack_rootfs()
313 {
314 ( cd $1 ; find . -print | cpio -o -H newc ) | \
315 if [ "$COMPRESSION" = "none" ]; then
316 echo "Generating uncompressed initramfs... "
317 cat > $2
318 elif [ -x /usr/bin/lzma -a "$COMPRESSION" != "gzip" ]; then
319 echo -n "Generating lzma'ed initramfs... "
320 lzma e -si -so $(lzma_switches $1) > $2
321 else
322 echo "Generating gziped initramfs... "
323 gzip -9 > $2
324 fi
325 echo 1 > /tmp/rootfs
326 }
328 # Compression functions for writeiso.
329 write_initramfs()
330 {
331 if [ "$COMPRESSION" = "lzma" ]; then
332 echo -n "Creating rootfs.gz with lzma compression... "
333 cat /tmp/list | cpio -o -H newc | lzma e -si -so > /rootfs.gz
334 elif [ "$COMPRESSION" = "gzip" ]; then
335 echo "Creating rootfs.gz with gzip compression... "
336 cat /tmp/list | cpio -o -H newc | gzip -9 > /rootfs.gz
337 else
338 echo "Creating rootfs.gz without compression... "
339 cat /tmp/list | cpio -o -H newc > /rootfs.gz
340 fi
341 echo 1 > /tmp/rootfs
342 }
344 # Generate a new initramfs from the root filesystem.
345 gen_initramfs()
346 {
347 # Just in case CTRL+c
348 rm -f $DISTRO/gen
349 # Some packages may want to alter rootfs
350 genisohooks rootfs
351 cd $1
352 echo ""
354 # Link duplicate files
355 find . -type f -size +0c -exec stat -c '%s-%a-%u-%g %i %h %n' {} \; | \
356 sort | ( save=0; old_attr=""; old_inode=""; old_link=""; old_file=""
357 while read attr inode link file; do
358 if [ "$attr" = "$old_attr" -a "$inode" != "$old_inode" ]; then
359 if cmp "$file" "$old_file" >/dev/null; then
360 rm -f "$file"
361 ln "$old_file" "$file"
362 inode="$old_inode"
363 [ "$link" = "1" ] && save="$(expr $save + ${attr%%-*})"
364 fi
365 fi
366 old_attr="$attr" ; old_inode="$inode" ; old_file="$file"
367 done
368 echo "$save bytes saved in duplicate files."
369 )
371 # Use lzma if installed. Display rootfs size in realtime.
372 rm -f /tmp/rootfs
373 pack_rootfs . $DISTRO/$(basename $1).gz &
374 sleep 2
375 echo -en "\nFilesystem size:"
376 while [ ! -f /tmp/rootfs ]
377 do
378 sleep 1
379 echo -en "\\033[18G`du -sh $DISTRO/$(basename $1).gz | awk '{print $1}'` "
380 done
381 echo -e "\n"
382 cd $DISTRO
383 mv $(basename $1).gz $ROOTCD/boot
384 }
386 distro_sizes()
387 {
388 echo "Build date : `date +%Y%m%d\ \at\ \%H:%M:%S`"
389 echo "Packages : `ls -1 $ROOTFS*$INSTALLED/*/receipt | wc -l`"
390 echo "Rootfs size : `du -csh $ROOTFS*/ | awk '{ s=$1 } END { print s }'`"
391 echo "Initramfs size : `du -csh $ROOTCD/boot/rootfs*.gz | awk '{ s=$1 } END { print s }'`"
392 echo "ISO image size : `du -sh $ISO_NAME.iso | awk '{ print $1 }'`"
393 echo "================================================================================"
394 echo "Image is ready: $ISO_NAME.iso"
395 echo ""
396 }
398 # Print ISO and rootfs size.
399 distro_stats()
400 {
401 echo ""
402 echo -e "\033[1mDistro statistics\033[0m ($DISTRO)"
403 echo "================================================================================"
404 distro_sizes
405 }
407 # Create an empty configuration file.
408 empty_config_file()
409 {
410 cat >> tazlito.conf << "EOF"
411 # tazlito.conf: Tazlito (SliTaz Live Tool)
412 # configuration file.
413 #
415 # Name of the ISO image to generate.
416 ISO_NAME=""
418 # ISO image volume name.
419 VOLUM_NAME="SliTaz"
421 # Name of the preparer.
422 PREPARED="$USER"
424 # Path to the packages repository and the packages.list.
425 PACKAGES_REPOSITORY=""
427 # Path to the distro tree to gen-distro from a
428 # list of packages.
429 DISTRO=""
431 # Path to the directory containing additional files
432 # to copy into the rootfs and rootcd of the LiveCD.
433 ADDFILES="$DISTRO/addfiles"
435 # Default answer for binary question (Y or N)
436 DEFAULT_ANSWER="ASK"
438 # Compression utility (lzma, gzip or none)
439 COMPRESSION="lzma"
440 EOF
441 }
443 # extract rootfs.gz somewhere
444 extract_rootfs()
445 {
446 (zcat $1 || unlzma -c $1 || cat $1) 2>/dev/null | \
447 (cd $2; cpio -idm > /dev/null)
448 }
450 # Remove duplicate files
451 mergefs()
452 {
453 echo -n "Merge $(basename $1) ($(du -hs $1 | awk '{ print $1}')) into "
454 echo -n "$(basename $2) ($(du -hs $2 | awk '{ print $1}'))"
455 # merge symlinks files and devices
456 ( cd $1; find ) | while read file; do
457 if [ -L $1/$file ]; then
458 [ -L $2/$file ] &&
459 [ "$(readlink $1/$file)" == "$(readlink $2/$file)" ] &&
460 rm -f $2/$file
461 elif [ -f $1/$file ]; then
462 [ -f $2/$file ] &&
463 cmp $1/$file $2/$file > /dev/null 2>&1 && rm -f $2/$file
464 [ -f $2/$file ] &&
465 [ "$(basename $file)" == "volatile.cpio.gz" ] &&
466 [ "$(dirname $(dirname $file))" == \
467 "./var/lib/tazpkg/installed" ] && rm -f $2/$file
468 elif [ -b $1/$file ]; then
469 [ -b $2/$file ] && rm -f $2/$file
470 elif [ -c $1/$file ]; then
471 [ -c $2/$file ] && rm -f $2/$file
472 fi
473 done
475 # cleanup directories
476 ( cd $1; find ) | while read file; do
477 if [ -d $1/$file ]; then
478 [ -d $2/$file ] && rmdir $2/$file 2> /dev/null
479 fi
480 done
481 true
482 status
483 }
485 cleanup_merge()
486 {
487 rm -rf $TMP_DIR
488 exit 1
489 }
491 human2cent()
492 {
493 case "$1" in
494 *k) echo $1 | sed 's/\(.*\).\(.\)k/\1\2/';;
495 *M) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)M/\1\2/') * 1024));;
496 *G) echo $(( $(echo $1 | sed 's/\(.*\).\(.\)G/\1\2/') * 1024 * 1024));;
497 esac
498 }
500 cent2human()
501 {
502 if [ $1 -lt 10000 ]; then
503 echo "$(($1 / 10)).$(($1 % 10))k"
504 elif [ $1 -lt 10000000 ]; then
505 echo "$(($1 / 10240)).$(( ($1/1024) % 10))M"
506 else
507 echo "$(($1 / 10485760)).$(( ($1/1048576) % 10))G"
508 fi
509 }
511 get_size()
512 {
513 cat /var/lib/tazpkg/packages.list $TMP_DIR/packages.list 2>/dev/null | awk "{ \
514 if (/^$(echo $1 | sed 's/[$+.\]/\\&/g')$/) get=1; \
515 if (/installed/ && get == 1) { print ; get++ } \
516 }
517 END { if (get < 2) print \" 0.0k (0.0k installed)\" }" | \
518 sed 's/ *\(.*\) .\(.*\) installed./\1 \2/' | while read packed unpacked; do
519 echo "$(human2cent $packed) $(human2cent $unpacked)"
520 done
521 }
523 # Display package list with version, set packed_size and unpacked_size
524 get_pkglist()
525 {
526 packed_size=0; unpacked_size=0
527 grep -v ^# $FLAVORS_REPOSITORY/$1/packages.list > $TMP_DIR/flavor.pkg
528 while read pkg; do
529 set -- $(get_size $pkg)
530 packed_size=$(( $packed_size + $1 ))
531 unpacked_size=$(( $unpacked_size + $2 ))
532 for i in $(grep -hs ^$pkg /var/lib/tazpkg/packages.list \
533 $TMP_DIR/packages.list); do
534 echo $i
535 break
536 done
537 done < $TMP_DIR/flavor.pkg
538 rm -f $TMP_DIR/flavor.pkg
539 }
541 # Update isolinux config files for multiple rootfs
542 update_bootconfig()
543 {
544 echo -n "Updating boot config files..."
545 grep -l 'include common' $1/*.cfg | \
546 while read file ; do
547 awk -v n=$(echo $2 | awk '{ print NF/2 }') '{
548 if (/label/) label=$0;
549 else if (/kernel/) kernel=$0;
550 else if (/append/) {
551 i=index($0,"rootfs.gz");
552 append=substr($0,i+9);
553 }
554 else if (/include/) {
555 for (i = 1; i <= n; i++) {
556 print label i
557 print kernel;
558 initrd="initrd=/boot/rootfs" n ".gz"
559 for (j = n - 1; j >= i; j--) {
560 initrd=initrd ",/boot/rootfs" j ".gz";
561 }
562 printf "\tappend %s%s\n",initrd,append;
563 print "";
564 }
565 print;
566 }
567 else print;
568 }' < $file > $file.$$
569 mv -f $file.$$ $file
570 done
571 cat >> $1/common.cfg <<EOT
573 label slitaz
574 kernel /boot/isolinux/ifmem.c32
575 append$(echo $2 | awk '{
576 for (i=1; i<=NF; i++)
577 if (i % 2 == 0) printf " slitaz%d",i/2
578 else printf " %s",$i
579 }') noram
581 label noram
582 config noram.cfg
584 EOT
585 cat > $1/noram.cfg <<EOT
586 display isolinux.msg
587 say Not enough RAM to boot slitaz.
588 default reboot
589 label reboot
590 com32 reboot.c32
592 implicit 0
593 prompt 1
594 timeout 80
595 F1 help.txt
596 F2 options.txt
597 F3 isolinux.msg
598 F4 display.txt
599 F5 enhelp.txt
600 F6 enopts.txt
601 EOT
602 status
603 }
605 # Install a missing package
606 install_package()
607 {
608 echo -n "Install package $1 "
609 [ -n "$2" ] && echo -n "for kernel $2 "
610 echo -n "?"
611 read answer
612 case "$answer" in
613 y*|Y*|o*|O*) yes y | tazpkg get-install $1;;
614 *) return 1;;
615 esac
616 }
618 # Check iso for loram transformation
619 check_iso_for_loram()
620 {
621 [ -s $TMP_DIR/iso/boot/rootfs.gz ] ||
622 [ -s $TMP_DIR/iso/boot/rootfs1.gz ]
623 }
625 # Build initial rootfs for loram ISO ram/cdrom/http
626 build_initfs()
627 {
628 urliso="mirror.slitaz.org mirror.switch.ch/ftp/mirror/slitaz \
629 download.tuxfamily.org/slitaz slitaz.c3sl.ufpr.br"
630 version=$(ls $TMP_DIR/iso/boot/vmlinuz-* | sed 's/.*vmlinuz-//')
631 need_lib=false
632 mkdir -p $TMP_DIR/initfs/bin $TMP_DIR/initfs/dev $TMP_DIR/initfs/lib \
633 $TMP_DIR/initfs/mnt $TMP_DIR/initfs/proc $TMP_DIR/initfs/tmp
634 while [ ! -f /lib/modules/$version/kernel/fs/aufs/aufs.ko.gz ]; do
635 install_package linux-aufs $version || return 1
636 done
637 # bootfloppybox will need floppy.ko.gz, /dev/fd0, /dev/tty0
638 cp /lib/modules/$version/kernel/drivers/block/floppy.ko.gz \
639 $TMP_DIR/initfs/lib 2> /dev/null
640 cp -a /dev/tty0 /dev/fd0 $TMP_DIR/initfs/dev 2> /dev/null
641 cp /lib/modules/$version/kernel/fs/aufs/aufs.ko.gz \
642 $TMP_DIR/initfs/lib
643 if [ -f /bin/cromfs-driver ]; then
644 cp /bin/cromfs-driver $TMP_DIR/initfs/bin
645 else
646 [ ! -f /usr/sbin/mksquashfs ] && ! install_package squashfs && return 1
647 while [ ! -f /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.gz ]; do
648 install_package linux-squashfs $version || return 1
649 done
650 cp /lib/modules/$version/kernel/fs/squashfs/squashfs.ko.gz \
651 $TMP_DIR/initfs/lib
652 fi
653 if [ "$1" == "cdrom" ]; then
654 for i in $(ls /dev/[hs]d[a-f]); do
655 cp -a $i $TMP_DIR/initfs/dev
656 done
657 fi
658 if [ "$1" == "http" ]; then
659 mkdir $TMP_DIR/initfs/etc
660 ln -s /proc/mounts $TMP_DIR/initfs/etc/mtab
661 cp /usr/share/udhcpc/default.script $TMP_DIR/initfs/lib/udhcpc
662 sed -i 's|/sbin/||' $TMP_DIR/initfs/lib/udhcpc
663 cp -a /dev/fuse $TMP_DIR/initfs/dev
664 if ! $need_lib && [ -x /usr/share/boot/fusermount-static ]; then
665 cp /usr/share/boot/fusermount-static $TMP_DIR/initfs/bin/httpfs
666 else
667 cp /usr/bin/fusermount $TMP_DIR/initfs/bin
668 need_lib=true
669 fi
670 if ! $need_lib && [ -x /usr/share/boot/httpfs-static ]; then
671 cp /usr/share/boot/httpfs-static $TMP_DIR/initfs/bin/httpfs
672 else
673 [ ! -f /usr/bin/httpfs ] && ! install_package httpfs-fuse && return 1
674 cp /usr/bin/httpfs $TMP_DIR/initfs/bin
675 cp -a /lib/librt* $TMP_DIR/initfs/lib
676 cp -a /lib/libdl* $TMP_DIR/initfs/lib
677 cp -a /lib/libpthread* $TMP_DIR/initfs/lib
678 cp -a /usr/lib/libfuse* $TMP_DIR/initfs/lib
679 cp -a /lib/libresolv* $TMP_DIR/initfs/lib
680 cp -a /lib/libnss_dns* $TMP_DIR/initfs/lib
681 need_lib=true
682 fi
683 cd $TMP_DIR/initfs
684 echo "Get slitaz-release..."
685 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
686 ( zcat $i 2> /dev/null || unlzma -c $i) | \
687 cpio -idmu etc/slitaz-release > /dev/null
688 done
689 cd - > /dev/null
690 echo "Default urls for /iso/$(cat $TMP_DIR/initfs/etc/slitaz-release)/flavors/slitaz-loram-cdrom.iso: $urliso"
691 echo -n "List of urls to insert: "
692 read -t 30 urliso2
693 urliso="$urliso2 $urliso"
694 fi
695 if ! $need_lib && [ -x /usr/share/boot/busybox-static ]; then
696 cp /usr/share/boot/busybox-static $TMP_DIR/initfs/bin/busybox
697 else
698 cp /bin/busybox $TMP_DIR/initfs/bin
699 need_lib=true
700 fi
701 for i in $($TMP_DIR/initfs/bin/busybox | awk \
702 '{ if (s) printf "%s",$0 } /Currently/ { s=1 }' | sed 's/,//g'); do
703 ln $TMP_DIR/initfs/bin/busybox $TMP_DIR/initfs/bin/$i
704 done
705 for i in /dev/console /dev/loop* /dev/null /dev/tty /dev/zero \
706 /dev/kmem /dev/mem /dev/random /dev/urandom; do
707 cp -a $i $TMP_DIR/initfs/dev
708 done
709 $need_lib && for i in /lib/ld-* /lib/lib[cm].so* /lib/lib[cm]-* ; do
710 cp -a $i $TMP_DIR/initfs/lib
711 done
712 cat > $TMP_DIR/initfs/init <<EOTEOT
713 #!/bin/sh
715 getarg()
716 {
717 grep -q " \$1=" /proc/cmdline || return 1
718 eval \$2=\$(sed 's/.* loram=\\([^ ]*\\).*/\\1/' < /proc/cmdline)
719 return 0
720 }
722 copy_rootfs()
723 {
724 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
725 need=\$(du -c \${path}rootfs* | tail -n 1 | cut -f1)
726 [ \$(( \$total / \$need )) -gt 1 ] || return 1
727 if ! grep -q " keep-loram" /proc/cmdline && cp \${path}rootfs* /mnt; then
728 path=/mnt/
729 return 0
730 else
731 rm -f /mnt/rootfs*
732 return 1
733 fi
734 }
736 echo "Switching / to tmpfs..."
737 mount -t proc proc /proc
738 size="\$(grep rootfssize= < /proc/cmdline | \\
739 sed 's/.*rootfssize=\\([0-9]*[kmg%]\\).*/-o size=\\1/')"
740 [ -n "\$size" ] || size="-o size=90%"
742 if [ -x /bin/httpfs ]; then # loram-http
744 while read var default; do
745 eval \$var=\$default
746 getarg \$var \$var
747 done <<EOT
748 eth eth0
749 dns 208.67.222.222,208.67.220.220
750 netmask 255.255.255.0
751 gw
752 ip
753 EOT
754 if [ -n "\$ip" ]; then
755 ifconfig \$eth \$ip netmask \$netmask up
756 route add default gateway \$gw
757 for i in \$(echo \$dns | sed 's/,/ /g'); do
758 echo "nameserver \$i" >> /etc/resolv.conf
759 done
760 else
761 udhcpc -s /lib/udhcpc -i \$eth
762 fi
763 for i in $urliso ; do
764 [ -n "\$URLISO" ] && URLISO="\$URLISO,"
765 URLISO="\${URLISO}http://\$i/iso/\$(cat /etc/slitaz-release)/flavors/slitaz-loram-cdrom.iso"
766 done
767 getarg urliso URLISO
768 DIR=fs
769 if getarg loram DIR; then
770 DEVICE=\${DIR%,*}
771 DIR=/\${DIR#*,}
772 fi
773 mount -t tmpfs \$size tmpfs /mnt
774 path=/mnt/.cdrom/
775 mkdir -p /mnt/.rw \$path
776 while [ ! -d \$path/boot ]; do
777 for i in \$(echo \$URLISO | sed 's/,/ /g'); do
778 httpfs \$i \$path && break
779 done
780 mount -o loop,ro -t iso9660 \$path/*.iso \$path
781 done
782 #copy_rootfs && umount -d \$path && umount -d \$path
784 elif [ -f \$(echo /rootfs*.gz | cut -f1 -d' ') ]; then # loram-ram
786 total=\$(grep MemTotal /proc/meminfo | sed 's/[^0-9]//g')
787 free=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
788 if [ \$(( \$total/\$free )) -gt 1 ] || ! mount -t tmpfs \$size tmpfs /mnt; then
789 echo "No tmpfs for /mnt"
790 mkdir -p /mnt/.rw
791 mount -t tmpfs tmpfs /mnt/.rw
792 mkdir -p /mnt/.rw/mnt/.rw
793 path=/
794 else
795 mkdir -p /mnt/.rw
796 path=/mnt/.
797 for i in rootfs* ; do
798 mv /\$i \$path\$i
799 done
800 fi
801 insmod /lib/squashfs.ko.gz
803 else # loram-cdrom
805 getarg cdrom DRIVE_NAME ||
806 DRIVE_NAME=\$(grep "drive name" < /proc/sys/dev/cdrom/info | cut -f 3)
807 DEVICE=/dev/\$DRIVE_NAME
808 DIR=fs
809 if getarg loram DIR; then
810 DEVICE=\${DIR%,*}
811 DIR=/\${DIR#*,}
812 fi
813 mount -t tmpfs \$size tmpfs /mnt
814 mkdir -p /mnt/.rw /mnt/.cdrom /mnt/mnt/.cdrom
815 i=0
816 while [ \$i -lt 5 ] && ! mount -r \$DEVICE /mnt/.cdrom; do
817 case "\$DEVICE" in
818 /dev/sd*|UUID=*|LABEL=*)
819 mount -t sysfs sysfs /sys
820 USBDELAY=\$(cat /sys/module/usb_storage/parameters/delay_use)
821 umount /sys
822 sleep \$((1+\$USBDELAY)) ;;
823 esac
824 i=\$((i+1))
825 done
826 path=/mnt/.cdrom/
827 copy_rootfs && insmod /lib/squashfs.ko.gz && umount -d /mnt/.cdrom
829 fi
831 memfree=\$(grep MemFree /proc/meminfo | sed 's/[^0-9]//g')
832 umount /proc
833 branch=br=/mnt/.rw:/mnt/.cdrom/\$DIR
834 if [ ! -d /mnt/.cdrom/fs/etc ]; then
835 branch=br=/mnt/.rw
836 for i in \${path}rootfs* ; do
837 fs=\${i#*root}
838 branch=\$branch:/mnt/.\$fs
839 mkdir -p /mnt/.rw/mnt/.\$fs /mnt/.\$fs
840 if [ -f /bin/cromfs-driver ]; then
841 cromfs-driver \${path}root\$fs /mnt/.\$fs -o ro,dev,suid,allow_other
842 else
843 mount -o loop,ro -t squashfs \${path}root\$fs /mnt/.\$fs
844 fi
845 done
846 fi
847 insmod /lib/aufs.ko.gz
848 mount -t aufs -o \$branch none /mnt
849 [ \$memfree -lt 30000 ] && sed -i 's/ slim//' /mnt/etc/rcS.conf
850 [ -x /mnt/sbin/init ] && exec /bin/switch_root mnt /sbin/init || sh
851 EOTEOT
852 chmod +x $TMP_DIR/initfs/init
853 ( cd $TMP_DIR/initfs ; find | busybox cpio -o -H newc 2> /dev/null) | \
854 lzma e $TMP_DIR/initfs.gz -si
855 rm -rf $TMP_DIR/initfs
856 rem=$(( $(stat -c "%s" $TMP_DIR/initfs.gz) % 4 ))
857 [ $rem -ne 0 ] &&
858 dd if=/dev/zero bs=1 count=$(( 4 - $rem )) >> $TMP_DIR/initfs.gz 2> /dev/null
859 return 0
860 }
862 # Move each initramfs to squashfs (or cromfs)
863 build_loram_rootfs()
864 {
865 rootfs_sizes=""
866 for i in $TMP_DIR/iso/boot/rootfs*.gz; do
867 mkdir -p $TMP_DIR/fs
868 cd $TMP_DIR/fs
869 ( zcat $i 2> /dev/null || unlzma -c $i) | cpio -idm
870 cd - > /dev/null
871 rootfs=$TMP_DIR/$(basename $i)
872 if [ -x /usr/bin/mkcromfs ]; then
873 /usr/bin/mkcromfs -qq -f 262144 -b 16384 $TMP_DIR/fs $rootfs
874 else
875 /usr/sbin/mksquashfs $TMP_DIR/fs $rootfs -comp lzma
876 fi
877 cd $TMP_DIR
878 rootfs_sizes="$rootfs_sizes $(( $(du -s $TMP_DIR/fs | cut -f1) - $(du -s $rootfs | cut -f1) ))"
879 if [ "$1" != "cdrom" ]; then
880 ( cd $(dirname $rootfs); echo $(basename $rootfs) | \
881 cpio -o -H newc ) > $rootfs.cpio
882 rm -f $rootfs
883 mv $rootfs.cpio $rootfs
884 fi
885 cd - > /dev/null
886 rm -rf $TMP_DIR/fs
887 done
888 }
890 # Move meta boot configuration files to basic configuration files
891 # because meta loram flavor is useless when rootfs is not loaded in ram
892 unmeta_boot()
893 {
894 if [ -f $TMP_DIR/loramiso/boot/isolinux/noram.cfg ]; then
895 # We keep enough information to do unloram...
896 sed -i 's/label slitaz/label orgslitaz/' \
897 $TMP_DIR/loramiso/boot/isolinux/common.cfg
898 sed -i -e 's|=/boot/rootfs\(.*\).gz |=/boot/rootfs.gz |' \
899 -e 's|label slitaz1|label slitaz|' \
900 -e '/label slitaz[1-9]/{NNNd}' \
901 $TMP_DIR/loramiso/boot/isolinux/*.cfg
902 fi
903 }
905 # Move rootfs to squashfs filesystem(s) to the cdrom writeable with aufs.
906 # These squashfs may be loaded in ram a boot time.
907 # Rootfs are also copied to cdrom for tiny ramsize systems.
908 # Meta flavors are converted to normal flavors.
909 build_loram_cdrom()
910 {
911 build_initfs cdrom || return 1
912 build_loram_rootfs cdrom
913 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
914 mkdir $TMP_DIR/loramiso/fs
915 cd $TMP_DIR/loramiso/fs
916 for i in $( ls ../boot/root* | sort -r ) ; do
917 ( zcat $i 2> /dev/null || unlzma -c $i ) | cpio -idmu
918 rm -f $i
919 done
920 cd - > /dev/null
921 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
922 mv $TMP_DIR/rootfs*.gz $TMP_DIR/loramiso
923 mkdir -p $TMP_DIR/loramiso/fs/mnt/.cdrom
924 unmeta_boot
925 create_iso $OUTPUT $TMP_DIR/loramiso
926 }
928 # Create http bootstrap to load and remove loram_cdrom
929 # Meta flavors are converted to normal flavors.
930 build_loram_http()
931 {
932 build_initfs http || return 1
933 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
934 rm -f $TMP_DIR/loramiso/boot/rootfs*
935 mv $TMP_DIR/initfs.gz $TMP_DIR/loramiso/boot/rootfs.gz
936 unmeta_boot
937 create_iso $OUTPUT $TMP_DIR/loramiso
938 }
940 # Update meta flavor selection sizes.
941 # Reduce sizes with rootfs gains.
942 update_metaiso_sizes()
943 {
944 local append="$(grep append $TMP_DIR/loramiso/boot/isolinux/common.cfg)"
945 local new
946 [ -n "$append" ] || return
947 set -- $append
948 shift
949 new=""
950 while [ -n "$2" ]; do
951 local s
952 case "$1" in
953 *G) s=$(( ${1%G} * 1024 * 1024 ));;
954 *M) s=$(( ${1%M} * 1024 ));;
955 *) s=${1%K};;
956 esac
957 rootfs_sizes=${rootfs_sizes#* }
958 for i in $rootfs_sizes ; do
959 s=$(( $s - $i ))
960 done
961 new="$new $s $2"
962 shift 2
963 done
964 sed -i "s/append .*/append$new $1/" $TMP_DIR/loramiso/boot/isolinux/common.cfg
965 }
967 # Move rootfs to a squashfs filesystem into the initramfs writeable with aufs.
968 # Meta flavor selection sizes are updated.
969 build_loram_ram()
970 {
971 build_initfs ram || return 1
972 build_loram_rootfs
973 cp -a $TMP_DIR/iso $TMP_DIR/loramiso
974 rm -f $TMP_DIR/loramiso/boot/bzImage
975 ln $TMP_DIR/loramiso/boot/vmlinuz* $TMP_DIR/loramiso/boot/bzImage
976 rootfs=$(ls $TMP_DIR/rootfs* | sort | tail -n 1)
977 cat $rootfs >> $TMP_DIR/initfs.gz
978 mv $TMP_DIR/initfs.gz $rootfs
979 cp $TMP_DIR/rootfs* $TMP_DIR/loramiso/boot
980 update_metaiso_sizes
981 create_iso $OUTPUT $TMP_DIR/loramiso
982 }
984 ####################
985 # Tazlito commands #
986 ####################
988 case "$COMMAND" in
989 stats)
990 # Tazlito general statistics from the config file.
991 #
992 echo ""
993 echo -e "\033[1mTazlito statistics\033[0m
994 ===============================================================================
995 Config file : $CONFIG_FILE
996 ISO name : $ISO_NAME.iso
997 Volume name : $VOLUM_NAME
998 Prepared : $PREPARED
999 Packages repository : $PACKAGES_REPOSITORY
1000 Distro directory : $DISTRO"
1001 if [ ! "$ADDFILES" = "" ] ; then
1002 echo -e "Additional files : $ADDFILES"
1003 fi
1004 echo "================================================================================"
1005 echo ""
1006 ;;
1007 list-addfiles)
1008 # Simple list of additional files in the rootfs
1009 echo ""
1010 cd $ADDFILES
1011 find rootfs -type f
1012 echo "" ;;
1013 gen-config)
1014 # Generate a new config file in the current dir or the specified
1015 # directory by $2.
1017 if [ -n "$2" ] ; then
1018 mkdir -p $2 && cd $2
1019 fi
1020 echo -n "Generating empty tazlito.conf..."
1021 empty_config_file
1022 status
1023 echo ""
1024 if [ -f "tazlito.conf" ] ; then
1025 echo "Configuration file is ready to edit."
1026 echo "File location : `pwd`/tazlito.conf"
1027 echo ""
1028 fi
1029 ;;
1030 configure)
1031 # Configure a tazlito.conf config file. Start by getting
1032 # a empty config file and sed it.
1034 if [ -f "tazlito.conf" ] ; then
1035 rm tazlito.conf
1036 else
1037 if test $(id -u) = 0 ; then
1038 cd /etc
1039 else
1040 echo "You must be root to configure the main config file or in"
1041 echo "the same directory of the file you want to configure."
1042 exit 0
1043 fi
1044 fi
1045 empty_config_file
1046 echo""
1047 echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
1048 echo "================================================================================"
1049 # ISO name.
1050 echo -n "ISO name : " ; read answer
1051 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
1052 # Volume name.
1053 echo -n "Volume name : " ; read answer
1054 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
1055 # Packages repository.
1056 echo -n "Packages repository : " ; read answer
1057 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
1058 # Distro path.
1059 echo -n "Distro path : " ; read answer
1060 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
1061 echo "================================================================================"
1062 echo "Config file is ready to use."
1063 echo "You can now extract an ISO or generate a distro."
1064 echo ""
1065 ;;
1066 gen-iso)
1067 # Simply generate a new iso.
1069 check_root
1070 verify_rootcd
1071 gen_livecd_isolinux
1072 distro_stats
1073 ;;
1074 gen-initiso)
1075 # Simply generate a new initramfs with a new iso.
1077 check_root
1078 verify_rootcd
1079 gen_initramfs $ROOTFS
1080 gen_livecd_isolinux
1081 distro_stats
1082 ;;
1083 extract-distro)
1084 # Extract an ISO image to a directory and rebuild the LiveCD tree.
1086 check_root
1087 ISO_IMAGE=$2
1088 if [ -z "$ISO_IMAGE" ] ; then
1089 echo -e "\nPlease specify the path to the ISO image."
1090 echo -e "Example : `basename $0` image.iso /path/target\n"
1091 exit 0
1092 fi
1093 # Set the distro path by checking for $3 on cmdline.
1094 if [ -n "$3" ] ; then
1095 TARGET=$3
1096 else
1097 TARGET=$DISTRO
1098 fi
1099 # Exit if existing distro is found.
1100 if [ -d "$TARGET/rootfs" ] ; then
1101 echo -e "\nA rootfs exists in : $TARGET"
1102 echo -e "Please clean the distro tree or change directory path.\n"
1103 exit 0
1104 fi
1105 echo ""
1106 echo -e "\033[1mTazlito extracting :\033[0m `basename $ISO_IMAGE`"
1107 echo "================================================================================"
1108 # Start to mount the ISO.
1109 echo ""
1110 echo "Mounting ISO image..."
1111 mkdir -p $TMP_DIR
1112 # Get ISO file size.
1113 isosize=`du -sh $ISO_IMAGE | cut -f1`
1114 mount -o loop $ISO_IMAGE $TMP_DIR
1115 sleep 2
1116 # Prepare target dir, copy the kernel and the rootfs.
1117 mkdir -p $TARGET/rootfs
1118 mkdir -p $TARGET/rootcd/boot
1119 echo -n "Copying the Linux kernel..."
1120 if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
1121 ln $TARGET/rootcd/boot/vmlinuz* $TARGET/rootcd/boot/bzImage
1122 else
1123 cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
1124 fi
1125 status
1126 echo -n "Copying isolinux files..."
1127 cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
1128 for i in $(ls $TMP_DIR); do
1129 [ "$i" = "boot" ] && continue
1130 cp -a $TMP_DIR/$i $TARGET/rootcd
1131 done
1132 status
1133 if [ -d $TMP_DIR/boot/syslinux ]; then
1134 echo -n "Copying syslinux files..."
1135 cp -a $TMP_DIR/boot/syslinux $TARGET/rootcd/boot
1136 status
1137 fi
1138 if [ -d $TMP_DIR/boot/extlinux ]; then
1139 echo -n "Copying extlinux files..."
1140 cp -a $TMP_DIR/boot/extlinux $TARGET/rootcd/boot
1141 status
1142 fi
1143 if [ -d $TMP_DIR/boot/grub ]; then
1144 echo -n "Copying GRUB files..."
1145 cp -a $TMP_DIR/boot/grub $TARGET/rootcd/boot
1146 status
1147 fi
1149 echo -n "Copying the rootfs..."
1150 cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
1151 status
1152 # Extract initramfs.
1153 cd $TARGET/rootfs
1154 echo -n "Extracting the rootfs... "
1155 extract_rootfs ../rootcd/boot/rootfs.gz $TARGET/rootfs
1156 # unpack /usr
1157 for i in etc/tazlito/*.extract; do
1158 [ -f "$i" ] && . $i ../rootcd
1159 done
1160 # Umount and remove temp directory and cd to $TARGET to get stats.
1161 umount $TMP_DIR && rm -rf $TMP_DIR
1162 cd ..
1163 echo ""
1164 echo "================================================================================"
1165 echo "Extracted : `basename $ISO_IMAGE` ($isosize)"
1166 echo "Distro tree : `pwd`"
1167 echo "Rootfs size : `du -sh rootfs`"
1168 echo "Rootcd size : `du -sh rootcd`"
1169 echo "================================================================================"
1170 echo ""
1171 ;;
1172 list-flavors)
1173 # Show available flavors.
1174 if [ ! -s /etc/tazlito/flavors.list -o "$2" == "--recharge" ]; then
1175 download flavors.list -O - > /etc/tazlito/flavors.list
1176 fi
1177 echo ""
1178 echo -e "\033[1mList of flavors\033[0m"
1179 echo "================================================================================"
1180 cat /etc/tazlito/flavors.list
1181 echo ""
1182 ;;
1183 show-flavor)
1184 # Show flavor description.
1185 FLAVOR=${2%.flavor}
1186 if [ ! -f "$FLAVOR.flavor" ]; then
1187 echo "File $FLAVOR.flavor not found."
1188 exit 1
1189 fi
1190 mkdir $TMP_DIR
1191 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i > /dev/null)
1192 if [ "$3" = "--brief" ]; then
1193 if [ "$4" != "--noheader" ]; then
1194 echo "Name ISO Rootfs Description"
1195 echo "================================================================================"
1196 fi
1197 printf "%-16.16s %6.6s %6.6s %s\n" "$FLAVOR" \
1198 "$(field ISO $TMP_DIR/$FLAVOR.desc)" \
1199 "$(field 'Rootfs size' $TMP_DIR/$FLAVOR.desc)" \
1200 "$(grep ^Description $TMP_DIR/$FLAVOR.desc | cut -d: -f2)"
1201 else
1202 echo "================================================================================"
1203 cat $TMP_DIR/$FLAVOR.desc
1204 fi
1205 rm -Rf $TMP_DIR
1206 ;;
1207 gen-liveflavor)
1208 # Generate a new flavor from the live system.
1209 FLAVOR=${2%.flavor}
1210 DESC=""
1211 case "$FLAVOR" in
1212 '') echo -n "Flavor name : "
1213 read FLAVOR
1214 [ -z "$FLAVOR" ] && exit 1;;
1215 -?|-h*|--help) echo -e "
1217 SliTaz Live Tool - Version: $VERSION
1218 \033[1mUsage: \033[0m `basename $0` gen-liveflavor flavor-name [flavor-patch-file]
1219 \033[1mflavor-patch-file format: \033[0m
1220 code data
1221 + package to add
1222 - package to remove
1223 ! non-free package to add
1224 ? display message
1225 @ flavor description
1227 \033[1mExample: \033[0m
1228 @ Developer tools for slitaz maintainers
1229 + slitaz-toolchain
1230 + mercurial
1232 exit 1;;
1233 esac
1234 mv /etc/tazlito/distro-packages.list \
1235 /etc/tazlito/distro-packages.list.$$ 2> /dev/null
1236 rm -f distro-packages.list non-free.list 2> /dev/null
1237 tazpkg recharge
1238 [ -n "$3" ] && while read action pkg; do
1239 case "$action" in
1240 +) yes | tazpkg get-install $pkg;;
1241 -) yes | tazpkg remove $pkg;;
1242 !) echo $pkg >> non-free.list;;
1243 @) DESC="$pkg";;
1244 \?) echo -en "$pkg"; read action;;
1245 esac
1246 done < $3
1247 yes '' | tazlito gen-distro
1248 echo "$DESC" | tazlito gen-flavor "$FLAVOR"
1249 mv /etc/tazlito/distro-packages.list.$$ \
1250 /etc/tazlito/distro-packages.list 2> /dev/null
1251 ;;
1252 gen-flavor)
1253 # Generate a new flavor from the last iso image generated.
1254 FLAVOR=${2%.flavor}
1255 echo ""
1256 echo -e "\033[1mFlavor generation\033[0m"
1257 echo "================================================================================"
1258 if [ -z "$FLAVOR" ]; then
1259 echo -n "Flavor name : "
1260 read FLAVOR
1261 [ -z "$FLAVOR" ] && exit 1
1262 fi
1263 check_rootfs
1264 FILES="$FLAVOR.pkglist"
1265 echo -n "Creating file $FLAVOR.flavor..."
1266 for i in rootcd rootfs; do
1267 if [ -d "$ADDFILES/$i" ] ; then
1268 FILES="$FILES\n$FLAVOR.$i"
1269 ( cd "$ADDFILES/$i"; find . | \
1270 cpio -o -H newc 2> /dev/null | gzip -9 ) > $FLAVOR.$i
1271 fi
1272 done
1273 status
1274 answer=`grep -s ^Description $FLAVOR.desc`
1275 answer=${answer#Description : }
1276 if [ -z "$answer" ]; then
1277 echo -n "Description : "
1278 read answer
1279 fi
1280 echo -n "Compressing flavor $FLAVOR..."
1281 echo "Flavor : $FLAVOR" > $FLAVOR.desc
1282 echo "Description : $answer" >> $FLAVOR.desc
1283 ( cd $DISTRO; distro_sizes) >> $FLAVOR.desc
1284 \rm -f $FLAVOR.pkglist $FLAVOR.nonfree 2> /dev/null
1285 for i in $(ls $ROOTFS$INSTALLED); do
1286 eval $(grep ^VERSION= $ROOTFS$INSTALLED/$i/receipt)
1287 EXTRAVERSION=""
1288 eval $(grep ^EXTRAVERSION= $ROOTFS$INSTALLED/$i/receipt)
1289 eval $(grep ^CATEGORY= $ROOTFS$INSTALLED/$i/receipt)
1290 if [ "$CATEGORY" = "non-free" -a "${i%%-*}" != "get" ]
1291 then
1292 echo "$i" >> $FLAVOR.nonfree
1293 else
1294 echo "$i-$VERSION$EXTRAVERSION" >> $FLAVOR.pkglist
1295 fi
1296 done
1297 [ -s $FLAVOR.nonfree ] && $FILES="$FILES\n$FLAVOR.nonfree"
1298 for i in $LOCALSTATE/undigest/*/mirror ; do
1299 [ -s $i ] && cat $i >> $FLAVOR.mirrors
1300 done
1301 [ -s $FLAVOR.mirrors ] && $FILES="$FILES\n$FLAVOR.mirrors"
1302 echo -e "$FLAVOR.desc\n$FILES" | cpio -o -H newc 2>/dev/null | \
1303 gzip -9 > $FLAVOR.flavor
1304 rm `echo -e $FILES`
1305 status
1306 echo "================================================================================"
1307 echo "Flavor size : `du -sh $FLAVOR.flavor`"
1308 echo ""
1309 ;;
1310 upgrade-flavor)
1311 # Update package list to the latest versions available.
1312 FLAVOR=${2%.flavor}
1313 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1314 mkdir $TMP_DIR
1315 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1316 echo -n "Updating $FLAVOR package list..."
1317 [ -s /var/lib/tazpkg/packages.list ] || tazpkg recharge
1318 packed_size=0; unpacked_size=0
1319 while read org; do
1320 i=0
1321 pkg=$org
1322 while ! grep -q ^$pkg$ /var/lib/tazpkg/packages.txt; do
1323 pkg=${pkg%-*}
1324 i=$(($i + 1))
1325 [ $i -gt 5 ] && break;
1326 done
1327 set -- $(get_size $pkg)
1328 packed_size=$(( $packed_size + $1 ))
1329 unpacked_size=$(( $unpacked_size + $2 ))
1330 for i in $(grep ^$pkg /var/lib/tazpkg/packages.list); do
1331 echo $i
1332 break
1333 done
1334 done < $TMP_DIR/$FLAVOR.pkglist \
1335 > $TMP_DIR/$FLAVOR.pkglist.$$
1336 mv -f $TMP_DIR/$FLAVOR.pkglist.$$ $TMP_DIR/$FLAVOR.pkglist
1337 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1338 packed_size=$(($packed_size \
1339 + $(cat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1340 unpacked_size=$(($unpacked_size \
1341 + $(zcat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1342 fi
1343 # Estimate lzma
1344 packed_size=$(($packed_size * 2 / 3))
1345 iso_size=$(( $packed_size + 26000 ))
1346 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1347 iso_size=$(($iso_size \
1348 + $(zcat $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1349 fi
1350 sed -i -e '/Image is ready/d' \
1351 -e "s/Rootfs size\( *:\) \(.*\)/Rootfs size\1 $(cent2human $unpacked_size) (estimated)/" \
1352 -e "s/Initramfs size\( *:\) \(.*\)/Initramfs size\1 $(cent2human $packed_size) (estimated)/" \
1353 -e "s/ISO image size\( *:\) \(.*\)/ISO image size\1 $(cent2human $iso_size) (estimated)/" \
1354 -e "s/date\( *:\) \(.*\)/date\1 $(date +%Y%m%d\ \at\ \%H:%M:%S)/" \
1355 $TMP_DIR/$FLAVOR.desc
1356 ( cd $TMP_DIR ; ls | cpio -o -H newc ) | gzip -9 > \
1357 $FLAVOR.flavor
1358 status
1359 rm -Rf $TMP_DIR
1360 fi
1361 ;;
1362 extract-flavor)
1363 # Extract a flavor into $FLAVORS_REPOSITORY.
1364 FLAVOR=${2%.flavor}
1365 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1366 mkdir $TMP_DIR
1367 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1368 echo -n "Extracting $FLAVOR..."
1369 rm -rf $FLAVORS_REPOSITORY/$FLAVOR 2> /dev/null
1370 mkdir -p $FLAVORS_REPOSITORY/$FLAVOR
1371 echo "FLAVOR=\"$FLAVOR\"" > $FLAVORS_REPOSITORY/$FLAVOR/receipt
1372 grep ^Description $TMP_DIR/$FLAVOR.desc | \
1373 sed 's/.*: \(.*\)$/SHORT_DESC="\1"/' >> \
1374 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1375 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc && \
1376 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1377 sed 's/.*: \(.*\)$/ROOTFS_SELECTION="\1"/' >> \
1378 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1379 grep '^Rootfs size' $TMP_DIR/$FLAVOR.desc | \
1380 sed 's/.*: \(.*\)$/ROOTFS_SIZE="\1"/' >> \
1381 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1382 grep ^Initramfs $TMP_DIR/$FLAVOR.desc | \
1383 sed 's/.*: \(.*\)$/INITRAMFS_SIZE="\1"/' >> \
1384 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1385 grep ^ISO $TMP_DIR/$FLAVOR.desc | \
1386 sed 's/.*: \(.*\)$/ISO_SIZE="\1"/' >> \
1387 $FLAVORS_REPOSITORY/$FLAVOR/receipt
1388 for i in rootcd rootfs; do
1389 [ -f $TMP_DIR/$FLAVOR.$i ] || continue
1390 mkdir $FLAVORS_REPOSITORY/$FLAVOR/$i
1391 zcat $TMP_DIR/$FLAVOR.$i | \
1392 (cd $FLAVORS_REPOSITORY/$FLAVOR/$i; \
1393 cpio -idm > /dev/null)
1394 done
1395 [ -s $TMP_DIR/$FLAVOR.mirrors ] &&
1396 cp $TMP_DIR/$FLAVOR.mirrors \
1397 $FLAVORS_REPOSITORY/$FLAVOR/mirrors
1398 [ -s /var/lib/tazpkg/packages.list ] || tazpkg recharge
1399 while read org; do
1400 i=0
1401 pkg=$org
1402 while ! grep -q ^$pkg$ /var/lib/tazpkg/packages.txt; do
1403 pkg=${pkg%-*}
1404 i=$(($i + 1))
1405 [ $i -gt 5 ] && break;
1406 done
1407 echo $pkg
1408 done < $TMP_DIR/$FLAVOR.pkglist \
1409 > $FLAVORS_REPOSITORY/$FLAVOR/packages.list
1410 status
1411 rm -Rf $TMP_DIR
1412 fi
1413 ;;
1414 pack-flavor)
1415 # Create a flavor from $FLAVORS_REPOSITORY.
1416 FLAVOR=${2%.flavor}
1417 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/receipt ]; then
1418 mkdir $TMP_DIR
1419 echo -n "Creating flavor $FLAVOR..."
1420 [ -s /var/lib/tazpkg/packages.list ] || tazpkg recharge
1421 if [ -s $FLAVORS_REPOSITORY/$FLAVOR/mirrors ]; then
1422 cp $FLAVORS_REPOSITORY/$FLAVOR/mirrors \
1423 $TMP_DIR/$FLAVOR.mirrors
1424 for i in $(cat $TMP_DIR/$FLAVOR.mirrors); do
1425 wget -O - $i/packages.list >> $TMP_DIR/packages.list
1426 done
1427 fi
1428 [ -s $FLAVORS_REPOSITORY/$FLAVOR/packages.list ] &&
1429 get_pkglist $FLAVOR > $TMP_DIR/$FLAVOR.pkglist
1430 if grep -q ^ROOTFS_SELECTION \
1431 $FLAVORS_REPOSITORY/$FLAVOR/receipt; then
1432 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1433 set -- $ROOTFS_SELECTION
1434 [ -n "$FRUGAL_RAM" ] || FRUGAL_RAM=$1
1435 [ -f $FLAVORS_REPOSITORY/$2/packages.list ] ||
1436 tazlito extract-flavor $2
1437 get_pkglist $2 > $TMP_DIR/$FLAVOR.pkglist
1438 for i in rootcd rootfs; do
1439 mkdir $TMP_DIR/$i
1440 # Copy extra files from the first flavor
1441 [ -d $FLAVORS_REPOSITORY/$2/$i ] &&
1442 cp -a $FLAVORS_REPOSITORY/$2/$i $TMP_DIR
1443 # Overload extra files by meta flavor
1444 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] &&
1445 cp -a $FLAVORS_REPOSITORY/$FLAVOR/$i $TMP_DIR
1446 [ -n "$(ls $TMP_DIR/$i)" ] &&
1447 ( cd $TMP_DIR/$i ; find . | cpio -o -H newc 2> /dev/null ) | \
1448 gzip -9 >$TMP_DIR/$FLAVOR.$i
1449 rm -rf $TMP_DIR/$i
1450 done
1451 else
1452 for i in rootcd rootfs; do
1453 [ -d $FLAVORS_REPOSITORY/$FLAVOR/$i ] || \
1454 continue
1455 ( cd $FLAVORS_REPOSITORY/$FLAVOR/$i ; \
1456 find . | cpio -o -H newc 2> /dev/null ) | \
1457 gzip -9 >$TMP_DIR/$FLAVOR.$i
1458 done
1459 fi
1460 if [ -s $TMP_DIR/$FLAVOR.rootfs ]; then
1461 packed_size=$(($packed_size \
1462 + $(cat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1463 unpacked_size=$(($unpacked_size \
1464 + $(zcat $TMP_DIR/$FLAVOR.rootfs | wc -c ) / 100 ))
1465 fi
1466 # Estimate lzma
1467 packed_size=$(($packed_size * 2 / 3))
1468 iso_size=$(( $packed_size + 26000 ))
1469 if [ -s $TMP_DIR/$FLAVOR.rootcd ]; then
1470 iso_size=$(($iso_size \
1471 + $(zcat $TMP_DIR/$FLAVOR.rootcd | wc -c ) / 100 ))
1472 fi
1473 VERSION=""
1474 MAINTAINER=""
1475 ROOTFS_SELECTION=""
1476 ROOTFS_SIZE="$(cent2human $unpacked_size) (estimated)"
1477 INITRAMFS_SIZE="$(cent2human $packed_size) (estimated)"
1478 ISO_SIZE="$(cent2human $iso_size) (estimated)"
1479 . $FLAVORS_REPOSITORY/$FLAVOR/receipt
1480 cat > $TMP_DIR/$FLAVOR.desc <<EOT
1481 Flavor : $FLAVOR
1482 Description : $SHORT_DESC
1483 EOT
1484 [ -n "$VERSION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1485 Version : $VERSION
1486 EOT
1487 [ -n "$MAINTAINER" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1488 Maintainer : $MAINTAINER
1489 EOT
1490 [ -n "$FRUGAL_RAM" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1491 LiveCD RAM size : $FRUGAL_RAM
1492 EOT
1493 [ -n "$ROOTFS_SELECTION" ] && cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1494 Rootfs list : $ROOTFS_SELECTION
1495 EOT
1496 cat >> $TMP_DIR/$FLAVOR.desc <<EOT
1497 Build date : $(date +%Y%m%d\ \at\ \%H:%M:%S)
1498 Packages : $(grep -v ^# $TMP_DIR/$FLAVOR.pkglist | wc -l)
1499 Rootfs size : $ROOTFS_SIZE
1500 Initramfs size : $INITRAMFS_SIZE
1501 ISO image size : $ISO_SIZE
1502 ================================================================================
1504 EOT
1505 rm -f $TMP_DIR/packages.list
1506 ( cd $TMP_DIR ; ls | cpio -o -H newc 2> /dev/null) | \
1507 gzip -9 > $FLAVOR.flavor
1508 status
1509 rm -Rf $TMP_DIR
1510 else
1511 echo "No $FLAVOR flavor in $FLAVORS_REPOSITORY."
1512 fi
1513 ;;
1514 get-flavor)
1515 # Get a flavor's files and prepare for gen-distro.
1516 FLAVOR=${2%.flavor}
1517 echo ""
1518 if [ -f $FLAVOR.flavor ] || download $FLAVOR.flavor; then
1519 echo -n "Cleaning $DISTRO..."
1520 rm -R $DISTRO 2> /dev/null
1521 mkdir -p $DISTRO
1522 status
1523 mkdir $TMP_DIR
1524 echo -n "Extracting flavor $FLAVOR.flavor... "
1525 zcat $FLAVOR.flavor | ( cd $TMP_DIR; cpio -i >/dev/null )
1526 echo -n "Creating distro-packages.list..."
1527 mv $TMP_DIR/$FLAVOR.nonfree non-free.list 2> /dev/null
1528 mv $TMP_DIR/$FLAVOR.pkglist distro-packages.list
1529 status
1530 for i in rootcd rootfs; do
1531 if [ -f $TMP_DIR/$FLAVOR.$i ]; then
1532 echo -n "Adding $i... "
1533 mkdir -p "$ADDFILES/$i"
1534 zcat $TMP_DIR/$FLAVOR.$i | \
1535 ( cd "$ADDFILES/$i"; cpio -id > /dev/null)
1536 fi
1537 done
1538 if [ -s $TMP_DIR/$FLAVOR.mirrors ]; then
1539 n=""
1540 while read line; do
1541 mkdir -p $LOCALSTATE/undigest/$FLAVOR$n
1542 echo "$line" > $LOCALSTATE/undigest/$FLAVOR$n/mirror
1543 n=$(( $n + 1 ))
1544 done < $TMP_DIR/$FLAVOR.mirrors
1545 tazpkg recharge
1546 fi
1547 rm -f /etc/tazlito/rootfs.list
1548 grep -q '^Rootfs list' $TMP_DIR/$FLAVOR.desc &&
1549 grep '^Rootfs list' $TMP_DIR/$FLAVOR.desc | \
1550 sed 's/.*: \(.*\)$/\1/' > /etc/tazlito/rootfs.list
1551 echo -n "Updating tazlito.conf..."
1552 [ -f tazlito.conf ] || cp /etc/tazlito/tazlito.conf .
1553 cat tazlito.conf | grep -v "^#VOLUM_NAME" | \
1554 sed "s/^VOLUM_NA/VOLUM_NAME=\"SliTaz $FLAVOR\"\\n#VOLUM_NA/" \
1555 > tazlito.conf.$$ && mv tazlito.conf.$$ tazlito.conf
1556 sed -i "s/ISO_NAME=.*/ISO_NAME=\"slitaz-$FLAVOR\"/" tazlito.conf
1557 status
1558 rm -Rf $TMP_DIR
1559 fi
1560 echo ""
1561 ;;
1562 check-list)
1563 # Use current packages list in $PWD by default.
1564 DISTRO_PKGS_LIST=distro-packages.list
1565 [ -d "$2" ] && DISTRO_PKGS_LIST=$2/distro-packages.list
1566 [ -f "$2" ] && DISTRO_PKGS_LIST=$2
1567 [ ! -f $DISTRO_PKGS_LIST ] && echo "No packages list found." && exit 0
1568 echo ""
1569 echo -e "\033[1mLiveCD packages list check\033[0m"
1570 echo "================================================================================"
1571 for pkg in `cat $DISTRO_PKGS_LIST`
1572 do
1573 if ! grep -q "$pkg" /var/lib/tazpkg/packages.list; then
1574 echo "Update: $pkg"
1575 up=$(($up + 1))
1576 fi
1577 done
1578 [ -z $up ] && echo -e "List is up-to-date\n" && exit 0
1579 echo "================================================================================"
1580 echo -e "Updates: $up\n" ;;
1581 gen-distro)
1582 # Generate a live distro tree with a set of packages.
1584 check_root
1586 # Check if a package list was specified on cmdline.
1587 LIST_NAME="distro-packages.list"
1588 CDROM=""
1589 while [ -n "$2" ]; do
1590 case "$2" in
1591 --iso=*)
1592 CDROM="-o loop ${2#--iso=}"
1593 ;;
1594 --cdrom)
1595 CDROM="/dev/cdrom"
1596 ;;
1597 --force)
1598 DELETE_ROOTFS="true"
1599 ;;
1600 *) if [ ! -f "$2" ] ; then
1601 echo -e "\nUnable to find the specified packages list."
1602 echo -e "List name : $2\n"
1603 exit 1
1604 fi
1605 LIST_NAME=$2
1606 ;;
1607 esac
1608 shift
1609 done
1611 if [ -d $ROOTFS ] ; then
1612 # Delete $ROOTFS if --force is set on command line
1613 if [ ! -z $DELETE_ROOTFS ]; then
1614 rm -rf $ROOTFS
1615 unset $DELETE_ROOTFS
1616 else
1617 echo -e "\nA rootfs exists in : $DISTRO"
1618 echo -e "Please clean the distro tree or change directory path.\n"
1619 exit 0
1620 fi
1621 fi
1622 if [ ! -f "$LIST_NAME" -a -d $INSTALLED ] ; then
1623 # Build list with installed packages
1624 for i in $(ls $INSTALLED); do
1625 eval $(grep ^VERSION= $INSTALLED/$i/receipt)
1626 EXTRAVERSION=""
1627 eval $(grep ^EXTRAVERSION= $INSTALLED/$i/receipt)
1628 echo "$i-$VERSION$EXTRAVERSION" >> $LIST_NAME
1629 done
1630 fi
1631 # Exit if no list name.
1632 if [ ! -f "$LIST_NAME" ]; then
1633 echo -e "\nNo packages list found or specified. Please read the docs.\n"
1634 exit 0
1635 fi
1636 # Start generation.
1637 echo ""
1638 echo -e "\033[1mTazlito generating a distro\033[0m"
1639 echo "================================================================================"
1640 # Misc checks
1641 [ -n "$PACKAGES_REPOSITORY" ] || PACKAGES_REPOSITORY="."
1642 [ -d $PACKAGES_REPOSITORY ] || mkdir -p $PACKAGES_REPOSITORY
1643 # Get the list of packages using cat for a file list.
1644 LIST=`cat $LIST_NAME`
1645 # Verify if all packages in list are present in $PACKAGES_REPOSITORY.
1646 REPACK=""
1647 DOWNLOAD=""
1648 for pkg in $LIST
1649 do
1650 [ "$pkg" = "" ] && continue
1651 pkg=${pkg%.tazpkg}
1652 [ -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] && continue
1653 PACKAGE=$(installed_package_name $pkg)
1654 [ -n "$PACKAGE" -a "$REPACK" = "y" ] && continue
1655 [ -z "$PACKAGE" -a -n "$DOWNLOAD" ] && continue
1656 echo -e "\nUnable to find $pkg in the repository."
1657 echo -e "Path : $PACKAGES_REPOSITORY\n"
1658 if [ -n "$PACKAGE" -a -z "$REPACK" ]; then
1659 yesorno "Repack packages from rootfs (y/N) ? "
1660 REPACK="$answer"
1661 [ "$answer" = "y" ] || REPACK="n"
1662 [ "$DOWNLOAD" = "y" ] && break
1663 fi
1664 if [ -f $MIRROR -a -z "$DOWNLOAD" ]; then
1665 yesorno "Download packages from mirror (Y/n) ? "
1666 DOWNLOAD="$answer"
1667 if [ "$answer" = "n" ]; then
1668 [ -z "$PACKAGE" ] && exit 1
1669 else
1670 DOWNLOAD="y"
1671 [ -n "$REPACK" ] && break
1672 fi
1673 fi
1674 [ "$REPACK" = "n" -a "$DOWNLOAD" = "n" ] && exit 1
1675 done
1677 # Mount cdrom to be able to repack boot-loader packages
1678 if [ ! -e /boot -a -n "$CDROM" ]; then
1679 mkdir $TMP_MNT
1680 if mount -r $CDROM $TMP_MNT 2> /dev/null; then
1681 ln -s $TMP_MNT/boot /
1682 if [ ! -d "$ADDFILES/rootcd" ] ; then
1683 mkdir -p $ADDFILES/rootcd
1684 for i in $(ls $TMP_MNT); do
1685 [ "$i" = "boot" ] && continue
1686 cp -a $TMP_MNT/$i $ADDFILES/rootcd
1687 done
1688 fi
1689 else
1690 rmdir $TMP_MNT
1691 fi
1692 fi
1694 # Root fs stuff.
1695 echo "Preparing the rootfs directory..."
1696 mkdir -p $ROOTFS
1697 sleep 2
1698 for pkg in $LIST
1699 do
1700 [ "$pkg" = "" ] && continue
1701 # First copy and extract the package in tmp dir.
1702 pkg=${pkg%.tazpkg}
1703 PACKAGE=$(installed_package_name $pkg)
1704 mkdir -p $TMP_DIR
1705 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1706 # Look for package in cache
1707 if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
1708 ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
1709 # Look for package in running distribution
1710 elif [ -n "$PACKAGE" -a "$REPACK" = "y" ]; then
1711 tazpkg repack $PACKAGE && \
1712 mv $pkg.tazpkg $PACKAGES_REPOSITORY
1713 fi
1714 fi
1715 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1716 # Get package from mirror
1717 [ "$DOWNLOAD" = "y" ] && \
1718 download $pkg.tazpkg && \
1719 mv $pkg.tazpkg $PACKAGES_REPOSITORY
1720 fi
1721 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
1722 echo "Missing package $pkg."
1723 cleanup
1724 exit 1
1725 fi
1726 done
1727 if [ -f non-free.list ]; then
1728 echo "Preparing non-free packages..."
1729 cp non-free.list $ROOTFS/etc/tazlito/non-free.list
1730 for pkg in $(cat non-free.list); do
1731 if [ ! -d $INSTALLED/$pkg ]; then
1732 if [ ! -d $INSTALLED/get-$pkg ]; then
1733 tazpkg get-install get-$pkg
1734 fi
1735 get-$pkg
1736 fi
1737 tazpkg repack $pkg
1738 pkg=$(ls $pkg*.tazpkg)
1739 grep -q "^$pkg$" $LIST_NAME || \
1740 echo $pkg >>$LIST_NAME
1741 mv $pkg $PACKAGES_REPOSITORY
1742 done
1743 fi
1744 echo ""
1745 cp $LIST_NAME $DISTRO/distro-packages.list
1746 sed 's/\(.*\)/\1.tazpkg/' < $DISTRO/distro-packages.list > $DISTRO/list-packages
1747 cd $PACKAGES_REPOSITORY
1748 yes y | tazpkg install-list \
1749 $DISTRO/list-packages --root=$ROOTFS
1750 cd $DISTRO
1751 cp distro-packages.list $ROOTFS/etc/tazlito
1752 # Copy all files from $ADDFILES/rootfs to the rootfs.
1753 if [ -d "$ADDFILES/rootfs" ] ; then
1754 echo -n "Copying addfiles content to the rootfs... "
1755 cp -a $ADDFILES/rootfs/* $ROOTFS
1756 status
1757 fi
1758 echo "Root file system is generated..."
1759 # Root CD part.
1760 echo -n "Preparing the rootcd directory..."
1761 mkdir -p $ROOTCD
1762 status
1763 # Move the boot dir with the Linux kernel from rootfs.
1764 # The boot dir goes directly on the CD.
1765 if [ -d "$ROOTFS/boot" ] ; then
1766 echo -n "Moving the boot directory..."
1767 mv $ROOTFS/boot $ROOTCD
1768 cd $ROOTCD/boot
1769 ln vmlinuz-* bzImage
1770 status
1771 fi
1772 cd $DISTRO
1773 # Copy all files from $ADDFILES/rootcd to the rootcd.
1774 if [ -d "$ADDFILES/rootcd" ] ; then
1775 echo -n "Copying addfiles content to the rootcd... "
1776 cp -a $ADDFILES/rootcd/* $ROOTCD
1777 status
1778 fi
1779 # Execute the distro script used to perform tasks in the rootfs
1780 # before compression. Give rootfs path in arg
1781 [ -z $DISTRO_SCRIPT ] && DISTRO_SCRIPT=$TOP_DIR/distro.sh
1782 if [ -x $DISTRO_SCRIPT ]; then
1783 echo "Executing distro script..."
1784 sh $DISTRO_SCRIPT $DISTRO
1785 fi
1786 if [ -s /etc/tazlito/rootfs.list ]; then
1787 [ -f $ROOTCD/boot/isolinux/ifmem.c32 ] ||
1788 cp /boot/isolinux/ifmem.c32 $ROOTCD/boot/isolinux
1789 n=0
1790 last=$ROOTFS
1791 while read flavor; do
1792 n=$(($n+1))
1793 echo "Building $flavor rootfs..."
1794 download $flavor.flavor
1795 zcat $flavor.flavor | cpio -i $flavor.pkglist
1796 sed 's/.*/&.tazpkg/' < $flavor.pkglist \
1797 > $DISTRO/list-packages0$n
1798 mkdir ${ROOTFS}0$n
1799 cd $PACKAGES_REPOSITORY
1800 yes y | tazpkg install-list \
1801 $DISTRO/list-packages0$n --root=${ROOTFS}0$n
1802 rm -rf ${ROOTFS}0$n/boot
1803 status
1804 cd $DISTRO
1805 mv $flavor.pkglist ${ROOTFS}0$n/etc/tazlito/distro-packages.list
1806 rm -f $flavor.flavor install-list
1807 mergefs ${ROOTFS}0$n $last
1808 last=${ROOTFS}0$n
1809 done <<EOT
1810 $(awk '{ for (i = 4; i <= NF; i+=2) print $i; }' < /etc/tazlito/rootfs.list)
1811 EOT
1812 i=$(($n+1))
1813 while [ $n -gt 0 ]; do
1814 mv ${ROOTFS}0$n ${ROOTFS}$i
1815 echo "Compression ${ROOTFS}0$n ($(du -hs ${ROOTFS}$i | awk '{ print $1 }')) ..."
1816 gen_initramfs ${ROOTFS}$i
1817 n=$(($n-1))
1818 i=$(($i-1))
1819 done
1820 mv $ROOTFS ${ROOTFS}$i
1821 gen_initramfs ${ROOTFS}$i
1822 update_bootconfig $ROOTCD/boot/isolinux \
1823 "$(cat /etc/tazlito/rootfs.list)"
1824 else
1825 # Initramfs and ISO image stuff.
1826 gen_initramfs $ROOTFS
1827 fi
1828 gen_livecd_isolinux
1829 distro_stats
1830 cleanup
1831 ;;
1832 clean-distro)
1833 # Remove old distro tree.
1835 check_root
1836 echo ""
1837 echo -e "\033[1mCleaning :\033[0m $DISTRO"
1838 echo "================================================================================"
1839 if [ -d "$DISTRO" ] ; then
1840 if [ -d "$ROOTFS" ] ; then
1841 echo -n "Removing the rootfs..."
1842 rm -f $DISTRO/$INITRAMFS
1843 rm -rf $ROOTFS
1844 status
1845 fi
1846 if [ -d "$ROOTCD" ] ; then
1847 echo -n "Removing the rootcd..."
1848 rm -rf $ROOTCD
1849 status
1850 fi
1851 echo -n "Removing eventual ISO image..."
1852 rm -f $DISTRO/$ISO_NAME.iso
1853 rm -f $DISTRO/$ISO_NAME.md5
1854 status
1855 fi
1856 echo "================================================================================"
1857 echo ""
1858 ;;
1859 check-distro)
1860 # Check for a few LiveCD needed files not installed by packages.
1862 check_rootfs
1863 echo ""
1864 echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
1865 echo "================================================================================"
1866 # SliTaz release info.
1867 if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
1868 echo "Missing release info : /etc/slitaz-release"
1869 else
1870 release=`cat $ROOTFS/etc/slitaz-release`
1871 echo -n "Release : $release"
1872 status
1873 fi
1874 # Tazpkg mirror.
1875 if [ ! -f "$ROOTFS/var/lib/tazpkg/mirror" ]; then
1876 echo -n "Mirror URL : Missing /var/lib/tazpkg/mirror"
1877 todomsg
1878 else
1879 echo -n "Mirror configuration exists..."
1880 status
1881 fi
1882 # Isolinux msg
1883 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.msg; then
1884 echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
1885 todomsg
1886 else
1887 echo -n "Isolinux message seems good..."
1888 status
1889 fi
1890 echo "================================================================================"
1891 echo ""
1892 ;;
1893 writeiso)
1894 # Writefs to ISO image including /home unlike gen-distro we dont use
1895 # packages to generate a rootfs, we build a compressed rootfs with all
1896 # the current filesystem similar to 'tazusb writefs'.
1898 DISTRO="/home/slitaz/distro"
1899 ROOTCD="$DISTRO/rootcd"
1900 if [ -z $2 ]; then
1901 COMPRESSION=none
1902 else
1903 COMPRESSION=$2
1904 fi
1905 if [ -z $3 ]; then
1906 ISO_NAME="slitaz"
1907 else
1908 ISO_NAME="$3"
1909 fi
1910 check_root
1911 # Start info
1912 echo ""
1913 echo -e "\033[1mWrite filesystem to ISO\033[0m
1914 ===============================================================================
1915 The command writeiso will write the current filesystem into a suitable cpio
1916 archive (rootfs.gz) and generate a bootable ISO image (slitaz.iso).
1918 Archive compression: $COMPRESSION"
1919 echo ""
1921 # Save some space
1922 rm /var/cache/tazpkg/* -r -f
1923 rm -rf /home/slitaz/distro
1925 # Optionally remove sound card selection and screen resolution.
1926 echo "Do you wish to remove the sound card and screen configs ? "
1927 echo -n "Press ENTER to keep or answer (No|yes|exit): "
1928 read anser
1929 case $anser in
1930 e|E|"exit"|Exit)
1931 exit 0 ;;
1932 y|Y|yes|Yes)
1933 echo -n "Removing current sound card and screen configurations..."
1934 rm -f /var/lib/sound-card-driver
1935 rm -f /etc/asound.state
1936 rm -f /etc/X11/screen.conf
1937 rm -f /etc/X11/xorg.conf ;;
1938 *)
1939 echo -n "Keeping current sound card and screen configurations..." ;;
1940 esac
1941 status
1943 # Create list of files including default user files since it is defined in /etc/passwd
1944 # and some new users might have been added.
1945 find /bin /etc /init /sbin /var /dev /lib /root /usr /home >/tmp/list
1947 for dir in /proc /sys /tmp /mnt /media /media/cdrom /media/flash /media/usbdisk
1948 do
1949 echo $dir >>/tmp/list
1950 done
1952 # Generate initramfs with specified compression and display rootfs
1953 # size in realtime.
1954 rm -f /tmp/rootfs
1955 write_initramfs &
1956 sleep 2
1957 echo -en "\nFilesystem size:"
1958 while [ ! -f /tmp/rootfs ]
1959 do
1960 sleep 1
1961 echo -en "\\033[18G`du -sh /rootfs.gz | awk '{print $1}'` "
1962 done
1963 echo -e "\n"
1965 # Move freshly generated rootfs to the cdrom.
1966 mkdir -p $ROOTCD/boot
1967 mv -f /rootfs.gz $ROOTCD/boot
1969 # Now we need the kernel and isolinux files.
1970 if mount /dev/cdrom /media/cdrom 2>/dev/null; then
1971 cp /media/cdrom/boot/bzImage $ROOTCD/boot
1972 cp -a /media/cdrom/boot/isolinux $ROOTCD/boot
1973 umount /media/cdrom
1974 else
1975 echo -e "
1976 Unable to mount the cdrom to copy the Kernel and needed files. When SliTaz
1977 is running in RAM the kernel and bootloader files are kept on the cdrom.
1978 Please insert a LiveCD or unmount the current cdrom to let Tazlito handle
1979 the media.\n"
1980 echo -en "----\nENTER to continue..."; read i
1981 exit 1
1982 fi
1984 # Generate the iso image.
1985 cd $DISTRO
1986 echo "Generating ISO image..."
1987 genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
1988 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
1989 -V "SliTaz" -input-charset iso8859-1 -boot-info-table $ROOTCD
1990 if [ -x /usr/bin/isohybrid ]; then
1991 echo -n "Creating hybrid ISO..."
1992 /usr/bin/isohybrid $ISO_NAME.iso 2> /dev/null
1993 status
1994 fi
1995 echo -n "Creating the ISO md5sum..."
1996 md5sum $ISO_NAME.iso > $ISO_NAME.md5
1997 status
1999 echo "==============================================================================="
2000 echo "ISO image: `du -sh /home/slitaz/distro/$ISO_NAME.iso`"
2001 echo ""
2002 echo -n "Exit or burn ISO to cdrom (Exit|burn)? "; read anser
2003 case $anser in
2004 burn)
2005 eject
2006 echo -n "Please insert a blank cdrom and press ENTER..."
2007 read i && sleep 2
2008 tazlito burn-iso /home/slitaz/distro/$ISO_NAME.iso
2009 echo -en "----\nENTER to continue..."; read i ;;
2010 *)
2011 exit 0 ;;
2012 esac ;;
2013 burn-iso)
2014 # Guess cdrom device, ask user and burn the ISO.
2016 check_root
2017 DRIVE_NAME=`cat /proc/sys/dev/cdrom/info | grep "drive name" | cut -f 3`
2018 DRIVE_SPEED=`cat /proc/sys/dev/cdrom/info | grep "drive speed" | cut -f 3`
2019 # We can specify an alternative ISO from the cmdline.
2020 if [ -n "$2" ] ; then
2021 iso=$2
2022 else
2023 iso=$DISTRO/$ISO_NAME.iso
2024 fi
2025 if [ ! -f "$iso" ]; then
2026 echo -e "\nUnable to find ISO : $iso\n"
2027 exit 0
2028 fi
2029 echo ""
2030 echo -e "\033[1mTazlito burn ISO\033[0m "
2031 echo "================================================================================"
2032 echo "Cdrom device : /dev/$DRIVE_NAME"
2033 echo "Drive speed : $DRIVE_SPEED"
2034 echo "ISO image : $iso"
2035 echo "================================================================================"
2036 echo ""
2037 yesorno "Burn ISO image (y/N) ? "
2038 if [ "$answer" == "y" ]; then
2039 echo ""
2040 echo "Starting Wodim to burn the iso..." && sleep 2
2041 echo "================================================================================"
2042 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $iso
2043 echo "================================================================================"
2044 echo "ISO image is burned to cdrom."
2045 else
2046 echo -e "\nExiting. No ISO burned."
2047 fi
2048 echo ""
2049 ;;
2050 merge)
2051 # Merge multiple rootfs into one iso.
2053 if [ -z "$2" ]; then
2054 cat << EOT
2055 Usage: tazlito merge size1 iso size2 rootfs2 [sizeN rootfsN]...
2057 Merge multiple rootfs into one iso. Rootfs are like russian dolls
2058 i.e: rootfsN is a subset of rootfsN-1
2059 rootfs1 is found in iso, sizeN is the RAM size need to launch rootfsN.
2060 The boot loader will select the rootfs according to the RAM size detected.
2062 Example:
2063 $ tazlito merge 160M slitaz-core.iso 96M rootfs-justx.gz 32M rootfs-base.gz
2065 Will start slitaz-core with 160M+ RAM, slitaz-justX with 96M-160M RAM,
2066 slitaz-base with 32M-96M RAM and display an error message if RAM < 32M.
2067 EOT
2068 exit 2
2069 fi
2071 shift # skip merge
2072 append="$1 slitaz1"
2073 shift # skip size1
2074 mkdir -p $TMP_DIR/mnt $TMP_DIR/rootfs1
2076 ISO=$1.merged
2077 # Extract filesystems
2078 echo -n "Mounting $1"
2079 mount -o loop,ro $1 $TMP_DIR/mnt 2> /dev/null
2080 status || cleanup_merge
2081 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2082 rm -f $TMP_DIR/iso/boot/bzImage
2083 ln $TMP_DIR/iso/boot/vmlinuz* $TMP_DIR/iso/boot/bzImage
2084 umount -d $TMP_DIR/mnt
2085 if [ -f $TMP_DIR/iso/boot/rootfs1.gz ]; then
2086 echo "$1 is already a merged iso. Aborting."
2087 cleanup_merge
2088 fi
2089 if [ ! -f $TMP_DIR/iso/boot/isolinux/ifmem.c32 ]; then
2090 if [ ! -f /boot/isolinux/ifmem.c32 ]; then
2091 cat <<EOT
2092 No file /boot/isolinux/ifmem.c32
2093 Please install syslinux package !
2094 EOT
2095 rm -rf $TMP_DIR
2096 exit 1
2097 fi
2098 cp /boot/isolinux/ifmem.c32 $TMP_DIR/iso/boot/isolinux
2099 fi
2101 echo -n "Extracting iso/rootfs.gz"
2102 extract_rootfs $TMP_DIR/iso/boot/rootfs.gz $TMP_DIR/rootfs1 &&
2103 [ -d $TMP_DIR/rootfs1/etc ]
2104 status || cleanup_merge
2105 n=1
2106 while [ -n "$2" ]; do
2107 shift # skip rootfs N-1
2108 p=$n
2109 n=$(($n + 1))
2110 append="$append $1 slitaz$n"
2111 shift # skip size N
2112 mkdir -p $TMP_DIR/rootfs$n
2113 echo -n "Extracting $1"
2114 extract_rootfs $1 $TMP_DIR/rootfs$n &&
2115 [ -d $TMP_DIR/rootfs$n/etc ]
2116 status || cleanup_merge
2117 mergefs $TMP_DIR/rootfs$n $TMP_DIR/rootfs$p
2118 echo "Creating rootfs$p.gz"
2119 pack_rootfs $TMP_DIR/rootfs$p $TMP_DIR/iso/boot/rootfs$p.gz
2120 status
2121 done
2122 echo "Creating rootfs$n.gz"
2123 pack_rootfs $TMP_DIR/rootfs$n $TMP_DIR/iso/boot/rootfs$n.gz
2124 status
2125 rm -f $TMP_DIR/iso/boot/rootfs.gz
2126 update_bootconfig $TMP_DIR/iso/boot/isolinux "$append"
2127 create_iso $ISO $TMP_DIR/iso
2128 rm -rf $TMP_DIR
2129 ;;
2131 repack)
2132 # Repack an iso with maximum lzma compression ratio.
2135 ISO=$2
2137 mkdir -p $TMP_DIR/mnt
2138 # Extract filesystems
2139 echo -n "Mounting $ISO"
2140 mount -o loop,ro $ISO $TMP_DIR/mnt 2> /dev/null
2141 status || cleanup_merge
2142 cp -a $TMP_DIR/mnt $TMP_DIR/iso
2143 umount -d $TMP_DIR/mnt
2145 for i in $TMP_DIR/iso/boot/rootfs* ; do
2146 echo -n "Repacking $(basename $i)"
2147 (zcat $i 2> /dev/null || unlzma -c $i || cat $i) \
2148 2>/dev/null > $TMP_DIR/rootfs
2149 lzma e $TMP_DIR/rootfs $i \
2150 $(lzma_switches $TMP_DIR/rootfs)
2151 status
2152 done
2154 create_iso $ISO $TMP_DIR/iso
2155 rm -rf $TMP_DIR ;;
2157 build-loram)
2158 # Build a Live CD for low ram systems.
2161 ISO=$2
2162 OUTPUT=$3
2163 mkdir -p $TMP_DIR/iso
2164 mount -o loop,ro -t iso9660 $ISO $TMP_DIR/iso
2165 if ! check_iso_for_loram ; then
2166 echo "$2 is not a valid SliTaz live CD. Abort."
2167 umount -d $TMP_DIR/iso
2168 rm -rf $TMP_DIR
2169 exit 1
2170 fi
2172 case "$4" in
2173 cdrom) build_loram_cdrom ;;
2174 http) build_loram_http ;;
2175 *) build_loram_ram ;;
2176 esac
2177 umount -d $TMP_DIR/iso
2178 rm -rf $TMP_DIR ;;
2181 frugal-install|-fi)
2182 ISO_IMAGE="$2"
2183 echo ""
2184 mkdir -p /boot/frugal
2185 if [ -f "$ISO_IMAGE" ]; then
2186 echo -n "Using ISO image: $ISO_IMAGE"
2187 mkdir -p /tmp/iso && mount -o loop $ISO_IMAGE /tmp/iso
2188 status
2189 echo -n "Installing the Kernel and rootfs..."
2190 cp -a /tmp/iso/boot/bzImage /boot/frugal
2191 cp -a /tmp/iso/boot/rootfs.gz /boot/frugal
2192 umount /tmp/iso
2193 status
2194 else
2195 echo -n "Using distro: $DISTRO"
2196 cd $DISTRO && status
2197 echo -n "Installing the Kernel and rootfs..."
2198 cp -a $DISTRO/rootcd/boot/bzImage /boot/frugal
2199 cp -a $DISTRO/rootcd/boot/rootfs.gz /boot/frugal
2200 status
2201 fi
2202 # Grub entry
2203 if ! grep -q "^kernel /boot/frugal/bzImage" /boot/grub/menu.lst; then
2204 echo -n "Configuring GRUB menu list..."
2205 cat >> /boot/grub/menu.lst << EOT
2206 title SliTaz GNU/Linux (frugal)
2207 root (hd0,0)
2208 kernel /boot/frugal/bzImage root=/dev/null
2209 initrd /boot/frugal/rootfs.gz
2210 EOT
2211 else
2212 echo -n "GRUB menu list is up-to-date..."
2213 fi
2214 status
2215 echo "" ;;
2217 emu-iso)
2218 # Emulate an ISO image with Qemu.
2219 if [ -n "$2" ] ; then
2220 iso=$2
2221 else
2222 iso=$DISTRO/$ISO_NAME.iso
2223 fi
2224 if [ ! -f "$iso" ]; then
2225 echo -e "\nUnable to find ISO : $iso\n"
2226 exit 0
2227 fi
2228 if [ ! -x "/usr/bin/qemu" ]; then
2229 echo -e "\nUnable to find Qemu binary. Please install: qemu\n"
2230 exit 0
2231 fi
2232 echo -e "\nStarting Qemu emulator:\n"
2233 echo -e "qemu $QEMU_OPTS $iso\n"
2234 qemu $QEMU_OPTS $iso ;;
2236 usage|*)
2237 # Clear and print usage also for all unknown commands.
2239 clear
2240 usage ;;
2241 esac
2243 exit 0