tazlito view tazlito @ rev 17

pave the road to flavors. Use 'tazpkg install --root='
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Dec 14 19:51:19 2007 +0000 (2007-12-14)
parents 9d2a15baf228
children 12ae06f2655a
line source
1 #!/bin/sh
2 # TazLito - SliTaz Live Tool.
3 #
4 # Tazlito is a tool to help generating and configuring SliTaz LiveCD
5 # ISO images. You can creat a custom distro in one command from a list of
6 # packages, extract a existing ISO image to hack it, creat new initramfs
7 # and/or new ISO. Most commands must be run by root, expect the stats
8 # and the configuration file manipulation.
9 #
10 # (C) 2007 SliTaz - GNU General Public License.
11 # Initial author : <pankso@slitaz.org>
12 #
13 VERSION=1.2
15 # Tazlito configuration variables to be shorter
16 # and to use words rater than numbers.
17 COMMAND=$1
18 LIST_NAME=$2
19 TMP_DIR=/tmp/tazlito-$$-$RANDOM
20 TOP_DIR=`pwd`
21 INITRAMFS=rootfs.gz
22 LOCALSTATE=/var/lib/tazpkg
23 INSTALLED=$LOCALSTATE/installed
24 CACHE_DIR=/var/cache/tazpkg
25 MIRROR=$LOCALSTATE/mirror
27 # Try to include config file, continue if command is gen-config or exit.
28 # The main config used by default is in /etc/tazlito.
29 if [ -f "/etc/tazlito/tazlito.conf" ] ; then
30 CONFIG_FILE="/etc/tazlito/tazlito.conf"
31 fi
32 # Specific distro config file can be put in a distro tree.
33 if [ -f "$TOP_DIR/tazlito.conf" ] ; then
34 CONFIG_FILE="$TOP_DIR/tazlito.conf"
35 fi
36 if [ ! "$CONFIG_FILE" = "" ] ; then
37 . $CONFIG_FILE
38 else
39 if [ "$COMMAND" = "gen-config" ] ; then
40 continue
41 else
42 echo "Unable to find any configuration file. Please read the doc"
43 echo "or run '`basename $0` gen-config' to get an empty config file."
44 exit 0
45 fi
46 fi
48 # Set the rootfs and rootcd path with $DISTRO
49 # configuration variable.
50 ROOTFS=$DISTRO/rootfs
51 ROOTCD=$DISTRO/rootcd
53 #####################
54 # Tazlito functions #
55 #####################
57 # Print the usage.
58 usage ()
59 {
60 echo -e "\nSliTaz Live Tool - Version: $VERSION\n
61 \033[1mUsage: \033[0m `basename $0` [command] [list|iso] [dir]
62 \033[1mCommands: \033[0m\n
63 usage Print this short usage.
64 stats View Tazlito and distro configuration statistics.
65 gen-config Generate a new configuration file for a distro.
66 configure Configure the main config file or a specific tazlito.conf.
67 gen-iso Generate a new ISO from a distro tree.
68 gen-initiso Generate a new initramfs and ISO from the distro tree.
69 extract-distro Extract and ISO to a directory and rebuild LiveCD tree.
70 gen-distro Generated a Live distro and ISO from a list of packages.
71 clean-distro Remove all files generated by gen-distro.
72 addhacker Add Linux User Hacker to the current distro.
73 check-distro Help to check if distro is ready to release.
74 burn-iso Burn ISO image to a cdrom using Wodim.\n"
75 }
77 # Status function.
78 status()
79 {
80 local CHECK=$?
81 echo -en "\\033[70G[ "
82 if [ $CHECK = 0 ]; then
83 echo -en "\\033[1;33mOK"
84 else
85 echo -en "\\033[1;31mFailed"
86 fi
87 echo -e "\\033[0;39m ]"
88 }
90 yesorno()
91 {
92 echo -n "$1"
93 case "$DEFAULT_ANSWER" in
94 Y|y) answer="y";;
95 N|n) answer="n";;
96 *) read answer;;
97 esac
98 }
100 todomsg()
101 {
102 echo -e "\\033[70G[ \\033[1;31mTODO\\033[0;39m ]"
103 }
105 # Download a file trying each mirror
106 download()
107 {
108 for i in $(cat $MIRROR); do
109 wget $i$@
110 done
111 }
113 # exec hooks provided by some packages
114 genisohooks()
115 {
116 local here=`pwd`
117 cd $ROOTFS
118 for i in $(ls etc/tazlito/*.$1 2> /dev/null); do
119 . $i $ROOTCD
120 done
121 cd $here
122 }
124 # Check if user is root.
125 check_root()
126 {
127 if test $(id -u) != 0 ; then
128 echo -e "\nYou must be root to run `basename $0` with this option."
129 echo -e "Please type 'su' and root password to become super-user.\n"
130 exit 0
131 fi
132 }
134 # Check for the rootfs tree.
135 check_rootfs()
136 {
137 if [ ! -d "$ROOTFS/etc" ] ; then
138 echo -e "\nUnable to find a distro rootfs...\n"
139 exit 0
140 fi
141 }
143 # Check for the boot dir into the root CD tree.
144 verify_rootcd()
145 {
146 if [ ! -d "$ROOTCD/boot" ] ; then
147 echo -e "\nUnable to find the rootcd boot directory...\n"
148 exit 0
149 fi
150 }
152 # Gen a new ISO image using isolinux.
153 gen_livecd_isolinux()
154 {
155 # Some packages may want to alter iso
156 genisohooks iso
157 if [ ! -f "$ROOTCD/boot/isolinux/isolinux.bin" ] ; then
158 echo -e "\nUnable to find isolinux binary.\n"
159 exit 0
160 fi
161 cd $DISTRO
162 echo ""
163 echo -e "\033[1mGenerating ISO image\033[0m"
164 echo "================================================================================"
165 genisoimage -R -o $ISO_NAME.iso -b boot/isolinux/isolinux.bin \
166 -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
167 -V "$VOLUM_NAME" -p "$PREPARED" -input-charset iso8859-1 \
168 -boot-info-table $ROOTCD
169 echo "================================================================================"
170 }
172 # Gen a new initramfs from the root file system.
173 gen_initramfs()
174 {
175 # Some packages may want to alter rootfs
176 genisohooks rootfs
177 cd $ROOTFS
178 echo ""
179 # Use lzma if installed
180 if [ -x /usr/bin/lzma ]; then
181 echo -n "Generating lzma'ed initramfs... "
182 find . -print | cpio -o -H newc | lzma e -si -so > $DISTRO/$INITRAMFS
183 else
184 echo -n "Generating gziped initramfs... "
185 find . -print | cpio -o -H newc | gzip -9 > $DISTRO/$INITRAMFS
186 fi
187 cd $DISTRO
188 mv $INITRAMFS $ROOTCD/boot
189 }
191 # Print ISO and rootfs size.
192 distro_stats()
193 {
194 echo ""
195 echo -e "\033[1mDistro statistics\033[0m"
196 echo "================================================================================"
197 echo "Build date : `date +%Y%m%d\ \at\ \%H:%M:%S`"
198 echo "Packages : `ls -1 $ROOTFS/var/lib/tazpkg/installed | wc -l`"
199 echo "Rootfs size : `du -sh $ROOTFS`"
200 echo "Initramfs size : `du -sh $ROOTCD/boot/$INITRAMFS`"
201 echo "ISO image size : `du -sh $ISO_NAME.iso`"
202 echo "================================================================================"
203 echo ""
204 }
206 # Creat an empty configuration file.
207 empty_config_file()
208 {
209 cat >> tazlito.conf << "EOF"
210 # tazlito.conf: Tazlito (SliTaz Live Tool)
211 # configuration file.
212 #
214 # Name of the ISO image to generate.
215 ISO_NAME=""
217 # ISO image volum name.
218 VOLUM_NAME="SliTaz"
220 # Name of the preparator.
221 PREPARED="$USER"
223 # Path to the packages repository and the packages.list.
224 PACKAGES_REPOSITORY=""
226 # Path to the distro tree to gen-distro from a
227 # list of packages.
228 DISTRO=""
230 # Path to the directory contening additional files
231 # to copy into the rootfs and rootcd of the LiveCD.
232 ADDFILES="$DISTRO/addfiles"
234 # Default answer for binary question (Y or N)
235 DEFAULT_ANSWER="ASK"
236 EOF
237 }
239 ####################
240 # Tazlito commands #
241 ####################
243 case "$COMMAND" in
244 stats)
245 # Tazlito general statistics from the config file.
246 #
247 echo ""
248 echo -e "\033[1mTazlito statistics\033[0m
249 ===============================================================================
250 Config file : $CONFIG_FILE
251 ISO name : $ISO_NAME.iso
252 Volum name : $VOLUM_NAME
253 Prepared : $PREPARED
254 Packages repository : $PACKAGES_REPOSITORY
255 Distro directory : $DISTRO"
256 if [ ! "$ADDFILES" = "" ] ; then
257 echo -e "Additional files : $ADDFILES"
258 fi
259 echo "================================================================================"
260 echo ""
261 ;;
262 gen-config)
263 # Gen a new config file in the current dir or the specified
264 # directory by $2.
265 #
266 if [ -n "$2" ] ; then
267 mkdir -p $2 && cd $2
268 fi
269 echo -n "Generating empty tazlito.conf..."
270 empty_config_file
271 status
272 echo ""
273 if [ -f "tazlito.conf" ] ; then
274 echo "Configuration file is ready to edit."
275 echo "File location : `pwd`/tazlito.conf"
276 echo ""
277 fi
278 ;;
279 configure)
280 # Configure a tazlito.conf config file. Start by getting
281 # a empty config file and sed it.
282 #
283 if [ -f "tazlito.conf" ] ; then
284 rm tazlito.conf
285 else
286 if test $(id -u) = 0 ; then
287 cd /etc
288 else
289 echo "You must be root to configure the main config file or in"
290 echo "the same directory of the file you want to configure."
291 exit 0
292 fi
293 fi
294 empty_config_file
295 echo""
296 echo -e "\033[1mConfiguring :\033[0m `pwd`/tazlito.conf"
297 echo "================================================================================"
298 # ISO name.
299 echo -n "ISO name : " ; read answer
300 sed -i s#'ISO_NAME=\"\"'#"ISO_NAME=\"$answer\""# tazlito.conf
301 # Volume name.
302 echo -n "Volume name : " ; read answer
303 sed -i s/'VOLUM_NAME=\"SliTaz\"'/"VOLUM_NAME=\"$answer\""/ tazlito.conf
304 # Packages repository.
305 echo -n "Packages repository : " ; read answer
306 sed -i s#'PACKAGES_REPOSITORY=\"\"'#"PACKAGES_REPOSITORY=\"$answer\""# tazlito.conf
307 # Distro path.
308 echo -n "Distro path : " ; read answer
309 sed -i s#'DISTRO=\"\"'#"DISTRO=\"$answer\""# tazlito.conf
310 echo "================================================================================"
311 echo "Config file is ready to use."
312 echo "You can now extract an ISO or generate a distro."
313 echo ""
314 ;;
315 gen-iso)
316 # Simply generated a new iso.
317 #
318 check_root
319 verify_rootcd
320 gen_livecd_isolinux
321 distro_stats
322 ;;
323 gen-initiso)
324 # Simply generated a new initramfs with a new iso.
325 #
326 check_root
327 verify_rootcd
328 gen_initramfs
329 gen_livecd_isolinux
330 distro_stats
331 ;;
332 extract-distro)
333 # Extract a ISO image to a directory and rebuild the LiveCD tree.
334 #
335 check_root
336 ISO_IMAGE=$2
337 if [ -z "$ISO_IMAGE" ] ; then
338 echo -e "\nPlease specify the path to the ISO image."
339 echo -e "Example : `basename $0` image.iso /path/target\n"
340 exit 0
341 fi
342 # Set the distro path by checking for $3 on cmdline.
343 if [ -n "$3" ] ; then
344 TARGET=$3
345 else
346 TARGET=$DISTRO
347 fi
348 # Exit if existing distro is found.
349 if [ -d "$TARGET/rootfs" ] ; then
350 echo -e "\nA rootfs exist in : $TARGET"
351 echo -e "Please clean the distro tree or change directory path.\n"
352 exit 0
353 fi
354 echo ""
355 echo -e "\033[1mTazlito extracting :\033[0m $ISO_IMAGE"
356 echo "================================================================================"
357 # Start to mount the ISO.
358 echo ""
359 echo "Mounting ISO image..."
360 mkdir -p $TMP_DIR
361 # Get ISO file size.
362 isosize=`du -sh $ISO_IMAGE`
363 mount -o loop $ISO_IMAGE $TMP_DIR
364 sleep 2
365 # Prepare target dir, copy the kernel and the rootfs.
366 mkdir -p $TARGET/rootfs
367 mkdir -p $TARGET/rootcd/boot
368 echo -n "Copying the Linux kernel..."
369 if cp $TMP_DIR/boot/vmlinuz* $TARGET/rootcd/boot 2> /dev/null; then
370 ln $TARGET/rootcd/vmlinuz* $TARGET/rootcd/bzImage
371 else
372 cp $TMP_DIR/boot/bzImage $TARGET/rootcd/boot
373 fi
374 status
375 echo -n "Copying isolinux files..."
376 cp -a $TMP_DIR/boot/isolinux $TARGET/rootcd/boot
377 status
378 echo -n "Copying the rootfs..."
379 cp $TMP_DIR/boot/rootfs.?z $TARGET/rootcd/boot
380 status
381 # Exract initramfs.
382 cd $TARGET/rootfs
383 echo -n "Extracting the rootfs... "
384 ( zcat ../rootcd/boot/rootfs.gz 2>/dev/null || \
385 lzma d ../rootcd/boot/rootfs.?z -so ) | cpio -id
386 # Umount and remove temp directory and cd to $TARGET to get stats.
387 umount $TMP_DIR && rm -rf $TMP_DIR
388 cd ..
389 echo ""
390 echo "================================================================================"
391 echo "Extracted : $ISO_IMAGE ($isosize)"
392 echo "Distro tree : `pwd`"
393 echo "Rootfs size : `du -sh rootfs`"
394 echo "Rootcd size : `du -sh rootcd`"
395 echo "================================================================================"
396 echo ""
397 ;;
398 gen-distro)
399 # Generate a live distro tree with a set of packages.
400 #
401 check_root
402 if [ -d $ROOTFS ] ; then
403 echo "A rootfs exist in : $DISTRO"
404 echo -e "Please clean the distro tree or change directory path.\n"
405 exit 0
406 fi
407 # First check for the main packages list then
408 # for a distro-packages.list in the current directory
409 # if none, check if a package list was specified on cmdline.
410 if [ -f "/etc/slitaz-tools/distro-packages.list" ] ; then
411 LIST_NAME="distro-packages.list"
412 fi
413 if [ -f "distro-packages.list" ] ; then
414 LIST_NAME="distro-packages.list"
415 fi
416 if [ -n "$2" ] ; then
417 if [ ! -f "$2" ] ; then
418 echo -e "\nUnable to find the specified packages list."
419 echo -e "List name : $2\n"
420 exit 0
421 else
422 LIST_NAME=$2
423 fi
424 fi
425 # Exit if no list name.
426 if [ "$LIST_NAME" = "" ] ; then
427 echo -e "\nNo packages list found or specified. Please read the doc.\n"
428 exit 0
429 fi
430 # Start generation.
431 echo ""
432 echo -e "\033[1mTazlito generating a distro\033[0m"
433 echo "================================================================================"
434 # Get the list of packages using cat for a file list.
435 LIST=`cat $LIST_NAME`
436 # Verify if all packages in list are presents in $PACKAGES_REPOSITORY.
437 for pkg in $LIST
438 do
439 pkg=${pkg%.tazpkg}
440 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ] ; then
441 echo -e "\nUnable to find $pkg in the repository."
442 echo -e "Path : $PACKAGES_REPOSITORY\n"
443 if [ -f $MIRROR ]; then
444 yesorno "Download packages from mirror (Y/n) ? "
445 [ "$answer" = "n" ] || break
446 fi
447 exit 1
448 fi
449 done
450 # Root fs stuff.
451 echo "Preparing the rootfs directory..."
452 mkdir -p $ROOTFS
453 sleep 2
454 for pkg in $LIST
455 do
456 # First copy and extract the package in tmp dir.
457 pkg=${pkg%.tazpkg}
458 mkdir -p $TMP_DIR
459 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
460 # look for package in cache
461 if [ -f $CACHE_DIR/$pkg.tazpkg ]; then
462 ln -s $CACHE_DIR/$pkg.tazpkg $PACKAGES_REPOSITORY
463 else
464 # get package from mirror
465 download $pkg.tazpkg && mv $pkg.tazpkg $PACKAGE_REPOSITORY
466 fi
467 fi
468 if [ ! -f $PACKAGES_REPOSITORY/$pkg.tazpkg ]; then
469 echo "Missing package $pkg."
470 exit 1
471 fi
472 yes "" | tazpkg install $PACKAGES_REPOSITORY/$pkg.tazpkg --root=$ROOTFS
473 done
474 echo ""
475 cd $DISTRO
476 # Copy all files from $ADDFILES/rootfs to the rootfs.
477 if [ -d "$ADDFILES/rootfs" ] ; then
478 echo -n "Copying addfiles content to the rootfs... "
479 cp -a $ADDFILES/rootfs/* $ROOTFS
480 status
481 fi
482 echo "Root file system is generated..."
483 # Root CD part.
484 echo -n "Preparing the rootcd directory..."
485 mkdir -p $ROOTCD
486 status
487 # Move the boot dir with the Linux kernel from rootfs.
488 # The boot dir goes directly on the CD.
489 if [ -d "$ROOTFS/boot" ] ; then
490 echo -n "Moving the boot directory..."
491 mv $ROOTFS/boot $ROOTCD
492 cd $ROOTCD/boot
493 ln vmlinuz-* bzImage
494 status
495 fi
496 cd $DISTRO
497 # Copy all files from $ADDFILES/rootcd to the rootcd.
498 if [ -d "$ADDFILES/rootcd" ] ; then
499 echo -n "Copying addfiles content to the rootcd... "
500 cp -a $ADDFILES/rootcd/* $ROOTCD
501 status
502 fi
503 # Initramfs and ISO image stuff.
504 gen_initramfs
505 gen_livecd_isolinux
506 distro_stats
507 ;;
508 clean-distro)
509 # Remove old distro tree.
510 #
511 check_root
512 echo ""
513 echo -e "\033[1mCleaning :\033[0m $DISTRO"
514 echo "================================================================================"
515 if [ -d "$DISTRO" ] ; then
516 if [ -d "$ROOTFS" ] ; then
517 echo -n "Removing the rootfs..."
518 rm -f $DISTRO/$INITRAMFS
519 rm -rf $ROOTFS
520 status
521 fi
522 if [ -d "$ROOTCD" ] ; then
523 echo -n "Removing the rootcd..."
524 rm -rf $ROOTCD
525 status
526 fi
527 echo -n "Removing eventual ISO image..."
528 rm -f $DISTRO/$ISO_NAME.iso
529 status
530 fi
531 echo "================================================================================"
532 echo ""
533 ;;
534 addhacker)
535 # Without /etc/passwd...
536 #
537 check_root
538 echo ""
539 echo -e "\033[1mAdduser hacker to :\033[0m $ROOTFS"
540 echo "================================================================================"
541 if [ ! -d "$ROOTFS/etc" ] ; then
542 echo -e "\nUnable to find : $ROOTFS/etc"
543 echo -e "Users and passwords config files will not be found.\n"
544 exit 0
545 fi
546 # Go for echoing on configuration files if any hacker was found.
547 #
548 if [ ! "`cat $ROOTFS/etc/passwd | grep hacker`" ] ; then
549 echo -n "Configuring $ROOTFS/etc..."
550 echo 'hacker:x:500:500:Linux User,,,:/home/hacker:/bin/ash' >> $ROOTFS/etc/passwd
551 echo 'hacker::13646:0:99999:7:::' >> $ROOTFS/etc/shadow
552 echo 'hacker:x:500:' >> $ROOTFS/etc/group
553 echo 'hacker:!::' >> $ROOTFS/etc/gshadow
554 status
555 else
556 echo "Hacker is already in : $ROOTFS/etc/passwd"
557 fi
558 # Hacker can listen to music
559 #
560 if grep -q audio $ROOTFS/etc/group; then
561 sed -i s/'audio:x:20:'/'audio:x:20:hacker'/ $ROOTFS/etc/group
562 fi
563 # /home/hacker files.
564 #
565 echo -n "Creating default directories... "
566 mkdir -p $ROOTFS/home/hacker/Documents \
567 $ROOTFS/home/hacker/Downloads \
568 $ROOTFS/home/hacker/Images \
569 $ROOTFS/home/hacker/Public \
570 $ROOTFS/home/hacker/Templates
571 status
572 # Change permissions.
573 #
574 echo -n "Chmodig all files in /home/hacker..."
575 chown -R 500.500 $ROOTFS/home/hacker
576 status
577 echo "================================================================================"
578 echo "Linux User Hacker have an account in the distro."
579 echo ""
580 ;;
581 check-distro)
582 # Check for a few LiveCD needed files not installed by packages.
583 #
584 check_rootfs
585 echo ""
586 echo -e "\033[1mChecking distro :\033[0m $ROOTFS"
587 echo "================================================================================"
588 # SliTaz release info.
589 if [ ! -f "$ROOTFS/etc/slitaz-release" ]; then
590 echo "Missing release info : /etc/slitaz-release"
591 else
592 release=`cat $ROOTFS/etc/slitaz-release`
593 echo -n "Release : $release"
594 status
595 fi
596 # Tazpkg mirror.
597 if [ ! -f "$ROOTFS/var/lib/tazpkg/mirror" ]; then
598 echo -n "Mirror URL : Missing /var/lib/tazpkg/mirror"
599 todomsg
600 else
601 echo -n "Mirror configuration exist..."
602 status
603 fi
604 # Isolinux msg
605 if grep -q "cooking-XXXXXXXX" /$ROOTCD/boot/isolinux/isolinux.msg; then
606 echo -n "Isolinux msg : Missing cooking date XXXXXXXX (ex `date +%Y%m%d`)"
607 todomsg
608 else
609 echo -n "Isolinux message seems good..."
610 status
611 fi
612 echo "================================================================================"
613 echo ""
614 ;;
615 burn-iso)
616 # Guess cdrom device, ask user and burn the ISO.
617 #
618 check_root
619 DRIVE_NAME=`cat /proc/sys/dev/cdrom/info | grep "drive name" | cut -f 3`
620 DRIVE_SPEED=`cat /proc/sys/dev/cdrom/info | grep "drive speed" | cut -f 3`
621 # We can specify an alternative ISO from the cmdline.
622 if [ -n "$2" ] ; then
623 iso=$2
624 else
625 iso=$DISTRO/$ISO_NAME.iso
626 fi
627 if [ ! -f "$iso" ]; then
628 echo -e "\nUnable to find ISO : $iso\n"
629 exit 0
630 fi
631 echo ""
632 echo -e "\033[1mTazlito burn ISO\033[0m "
633 echo "================================================================================"
634 echo "Cdrom device : /dev/$DRIVE_NAME"
635 echo "Drive speed : $DRIVE_SPEED"
636 echo "ISO image : $iso"
637 echo "================================================================================"
638 echo ""
639 yesorno "Burn ISO image (y/N) ? "
640 if [ "$answer" == "y" ]; then
641 echo ""
642 echo "Starting Wodim to burn the iso..." && sleep 2
643 echo "================================================================================"
644 wodim speed=$DRIVE_SPEED dev=/dev/$DRIVE_NAME $DISTRO/$ISO_NAME.iso
645 echo "================================================================================"
646 echo "ISO image is burned to cdrom."
647 else
648 echo -e "\nExiting. No ISO burned."
649 fi
650 echo ""
651 ;;
652 usage|*)
653 # Clear and print usage also for all unknow commands.
654 #
655 clear
656 usage
657 ;;
659 esac
661 exit 0