# HG changeset patch # User Christophe Lincoln # Date 1488814929 -3600 # Node ID 3085a3c9e29220e6bd5245483eb11979bae4e130 # Parent 85937e3de0b06e1b3b0ebf43a44c8a479b717b41 Add seb builder utility diff -r 85937e3de0b0 -r 3085a3c9e292 seb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/seb Mon Mar 06 16:42:09 2017 +0100 @@ -0,0 +1,465 @@ +#!/bin/sh +# +# SEB - SliTaz Embedded Builder - Back to the roots with SliTaz in +# only a few MB. Please read the README file for more information. +# +# Copyright (C) 2017 SliTaz GNU/Linux - BSD License +# Author: Christophe Lincoln +# +. /lib/libtaz.sh +unset status get_cols separator colorize boldify + +# --iso --work --linux can be set in config file or from cmdline +[ -f "build.conf" ] && . build.conf + +[ "$work" ] || work="$(pwd)" +[ "$iso" ] || iso="seb-os-$(date '+%Y%m%d').iso" +[ "$linux" ] || linux="/boot/vmlinuz-$(uname -r)" + +rootfs="$work/rootfs" +rootiso="$work/rootiso" +sebfs="$work/sebfs" +sebpkgs="$work/sebpkgs" +cache="$work/cache" +vdisk="$work/sebhome.img" +qemu_opts="-m 512" + +tools="/usr/share/seb/tools" +initfs="/usr/share/seb/initfs" +packages="/usr/share/seb/packages" + +# Working from source tree +[ -d "tools" ] && tools="$(pwd)/tools" +[ -d "initfs" ] && initfs="$(pwd)/initfs" +[ -d "packages" ] && packages="$(pwd)/packages" + +# Source libseb.sh (overwrite libtaz.sh function) +if [ -f "$PWD/libseb.sh" ]; then + libseb="$PWD/libseb.sh" + . ${libseb} +else + if ! . /lib/libseb.sh; then + echo "Can't source any: libseb.sh"; exit 1 + fi + libseb="/lib/libseb.sh" +fi +debug "work=$work" + +# +# Functions +# + +help() { + cat << EOT + +$(colorize 35 "SliTaz Embedded Builder") + +$(boldify "Usage:") $(basename $0) [command] [--opts] + +$(boldify "Commands:") + -h help Display this short built-in help + -i init Creat base files to customize + -b build Generate a distribution (initramfs & iso) + -p packages Handle packages: --list --add + -g geniso Re-generate the ISO image + -c clean Remove all SEB generated files + -l lsfs List all files in rootfs (-type f) + -v vdisk Create, mount or unmount a virtual disk + -e emu Emulate ISO image with Qemu + env Print current seb environment + +$(boldify "Options:") + --work= Path to build directory + --iso= Specify SliTaz Embedded ISO image name + --linux= Path to a custom Linux kernel + --all Clean all files including sebfs + --emu Emulate ISO image after build + --check Check a virtual disk image + +EOT +} + +# Initial files who can be modified via sebfs/ +init() { + mkdir -p ${sebfs} ${sebpkgs} + cp -rf ${initfs}/* ${sebfs} +} + +geniso() { + echo -n "Generating ISO image: ${iso}" + cd ${work} + genisoimage -R -o ${iso} \ + -b boot/isolinux/isolinux.bin \ + -c boot/isolinux/boot.cat -no-emul-boot -boot-load-size 4 \ + -V "SliTaz Embedded" -input-charset iso8859-1 \ + -boot-info-table rootiso 2> /dev/null; check + echo -n "Checking ISO image size..." + info 035 $(du -mhs $iso | awk '{print $1}') +} + +emulate() { + if [ -x "/usr/bin/qemu" ]; then + echo "qemu $qemu_opts -cdrom $1" + if [ -f "$vdisk" ]; then + hda="-hda $vdisk" + umount ${vdisk} 2>/dev/null + fi + qemu ${qemu_opts} ${hda} -cdrom ${1} + else + echo $(echo "Please install:") $(boldify qemu); exit 0 + fi +} + +# Install files in the rootfs with same path than on the build host +# Usage: install_files "/file/1" "/lib/lib.so*" "/file/N" +install_files() { + for file in ${@} ; do + path=$(dirname $file) + echo -n "Installing: $file" + cp -a ${file} ${rootfs}${path} && check + done +} + +# Populate /dev + 'mdev -s' on boot +create_dev_files() { + echo -n "Populating: /dev" + mkdir -p ${rootfs}/dev/pts ${rootfs}/dev/shm + cd ${rootfs}/dev + mknod -m 0666 null c 1 3 + mknod -m 0622 console c 5 1 + mknod -m 0666 tty c 5 0 + for i in 0 1 2; do + mknod -m 0666 tty$i c 4 $i + done; check +} + +# Configuration files for /etc not generate by init to keep initfs/sebfs +# filesytems minimals +create_etc_files() { + echo -n "Creating config files in: /etc" + (echo "127.0.0.1 localhost seb" > ${rootfs}/etc/hosts + echo "localnet 127.0.0.1" > ${rootfs}/etc/networks + echo "order hosts,bind" > ${rootfs}/etc/host.conf + echo "multi on" >> ${rootfs}/etc/host.conf + # Users & passwd + echo "root:x:0:0:root:/root:/bin/sh" > ${rootfs}/etc/passwd + echo "root::13525:0:99999:7:::" > ${rootfs}/etc/shadow + cat > ${rootfs}/etc/group << EOT +root:x:0: +www:x:80: +EOT + cat > ${rootfs}/etc/gshadow << EOT +root:*:: +www:!:: +EOT + chmod 640 ${rootfs}/etc/*shadow) + cat > ${rootfs}/etc/nsswitch.conf << EOT +# /etc/nsswitch.conf: GNU Name Service Switch config. +# + +passwd: files +group: files +shadow: files + +hosts: files dns +networks: files +EOT + check +} + +build() { + title "Starting SliTaz Embedded builder" + + # Build environment + rm -rf ${rootfs} ${rootiso} + mkdir -p ${rootfs} ${rootiso}/boot/isolinux + + # FSH Tree + echo -n "Populating: filesystem" + for d in bin dev etc lib root run home proc media sbin sys \ + usr/bin usr/sbin usr/share var/log var/cache var/lib + do + mkdir -p ${rootfs}/${d} + done + install -d -m 1777 ${rootfs}/tmp; check + + # /etc + /dev + create_etc_files + create_dev_files + + # Initial sebfs from initfs: files can be modified + [ ! -d "$sebfs" ] && init + + # GNU libc before chroot /bin/busybox --install + name resolution + for lib in /lib/libm[-.]* /lib/libc[-.]* /lib/ld-* /lib/libpthread*; do + echo -n "Installing: $lib" + cp -a ${lib} ${rootfs}/lib && check + done + install_files "/lib/libnss_dns*" "/lib/libnss_file*" "/lib/libresolv*" + + # Busybox applets + action "Installing: busybox" + cp -a /bin/busybox ${rootfs}/bin + chroot ${rootfs} /bin/busybox --install -s; check + + # Busybox configs + echo -n "Installing: busybox configs" + cp -r /usr/share/udhcpc ${rootfs}/usr/share + cp -f /etc/udhcpd.conf ${rootfs}/etc + cp -f /etc/httpd.conf ${rootfs}/etc + check + + # Busybox keymap + echo -n "Dumping : keymap" + mkdir -p ${rootfs}/usr/share/kmap + dumpkmap > ${rootfs}/usr/share/kmap/default; check + + # Kilo editor (20K) with syntax highlight and search (Thanks Paul :-) + action "Installing: kilo text editor" + cp -a ${tools}/kilo ${rootfs}/usr/bin; check + + # Ncursesw && dialog for sebos and additional tools + install_files "/lib/libncursesw.so*" "/usr/bin/dialog" + mkdir -p ${rootfs}/usr/share/terminfo/l + cp /usr/share/terminfo/l/linux ${rootfs}/usr/share/terminfo/l + cp /etc/dialogrc ${rootfs}/etc + + # /lib/libseb.sh & sebos config tool + echo -n "Installing: /lib/libseb.sh" + cp ${libseb} ${rootfs}/lib; check + action "Installing: sebos config tool" + cp ${tools}/sebos ${rootfs}/usr/bin; check + + # httphelper.sh for amazing CGI/Shell functions + mkdir -p ${rootfs}/usr/lib/slitaz + cp /usr/lib/slitaz/httphelper.sh ${rootfs}/usr/lib/slitaz + + # Packages TODO: handle deps + touch ${rootfs}/var/lib/packages + for pkg in $(ls $sebpkgs); do + echo -n $(colorize 035 "Installing package:"); info 036 "$pkg" + . ${packages}/${pkg} + seb_install; echo "$pkg|$desc" >> ${rootfs}/var/lib/packages + done + + # Custom files NOW + if [ -d "$sebfs" ]; then + echo -n "Copying custom files from sebfs..." + cp -rf ${sebfs}/* ${rootfs}; check + fi + + # COPYING + mkdir -p ${rootfs}/usr/share/licenses + cat > ${rootfs}/usr/share/licenses/COPYING << EOT +Copyright (c) 2007-$(date '+%Y') SliTaz GNU/Linux + +SliTaz is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3 of the License, or (at your option) +any later version. + +SliTaz is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + +EOT + + # Build date + cat >> ${rootfs}/etc/seb.conf << EOT + +# Seb-OS Build date +build_date="$(date '+%Y%m%d')" + +# Seb-OS/SliTaz release string +seb_os_release="$(cat /etc/slitaz-release)" + +EOT + + # Security check + chmod 0600 ${rootfs}/etc/busybox.conf + + # Rootfs archive + action "Creating the initramfs..." + cd ${rootfs} + find . -print | cpio -o -H newc | lzma e -si -so \ + > ${rootiso}/boot/rootfs.gz 2>/dev/null + check + + # Linux Kernel + echo -n "Copying the Linux kernel..." + cp ${linux} ${rootiso}/boot/bzImage; check + + # Bootloader + echo -n "Copying the bootloader (isolinux)..." + cp ${tools}/isolinux.bin ${rootiso}/boot/isolinux; check + + echo -n "Creating bootloader configs..." + cat > ${rootiso}/boot/isolinux/isolinux.cfg << EOF +display display.txt +default seb +label seb + kernel /boot/bzImage + append initrd=/boot/rootfs.gz rw root=/dev/null rdinit=/sbin/init +implicit 0 +prompt 1 +timeout 40 +EOF + cat > ${rootiso}/boot/isolinux/display.txt << EOF + + ____ _ _ _ _ ___ _ + / ___| \ | | | | | / / | (_)_ __ _ ___ __ + | | _| \| | | | |/ /| | | | '_ \| | | \ \/ / + | |_| | |\ | |_| / / | |___| | | | | |_| |> < + \____|_| \_|\___/_/ |_____|_|_| |_|\__,_/_/\_\ + + SliTaz Embedded OS - Press to boot + www.slitaz.org + + +EOF + check + + echo -n "Checking rootfs size..." + info 035 $(du -mhs $rootfs | awk '{print $1}') + echo -n "Installed files in rootfs..." + info 036 $(find ${rootfs} -type f | wc -l) + + # ISO image + geniso; footer +} + +# Handle seb packages +packages_handler() { + + # List avalaible packages + if [ ! "$1" ]; then + title "Seb packages" + for pkg in $(ls ${packages}); do + . ${packages}/${pkg} + echo -n "$(colorize 036 $pkg)"; indent 20 "$desc" + unset desc deps + done + footer && exit 0 + fi + + # Add package(s) + if [ "$add" ]; then + for pkg in ${@}; do + case "$pkg" in + --*) continue ;; + *) + if [ -f "$packages/$pkg" ]; then + echo -n "Addind package: $pkg" + mkdir -p ${sebpkgs} + cp -f ${packages}/${pkg} ${sebpkgs}; check + else + echo "Can't find package: $package/$pkg" + fi ;; + esac + done + fi +} + +# Handle vdisk: create, check, mount, umount +vdisk_hanler() { + title "SEB Virtual disk" + vsize=40960 + root=${vdisk%.img} + + # Info or create + if [ -f "$vdisk" ]; then + echo -n "Virtual disk: $vdisk" + info 035 "$(du -mhs $vdisk | awk '{print $1}')" + else + echo "Creating virtual disk image..." + dd if=/dev/zero of=${vdisk} bs=1k count=${vsize} + action "Creating ext3 filesystem..."; echo + mkfs.ext3 -L "SebOShome" ${vdisk} + fi + + # Check + if [ "$check" ]; then + echo "Umounting vdisk before: e2fsck -p" + umount ${vdisk} >/dev/null + e2fsck -p ${vdisk} + fi + + # Action: mount/unmount + if ! mount | grep -q "^$vdisk"; then + echo -n "Mounting virtual disk..."; mkdir -p ${root} + mount -o loop -t ext3 ${vdisk} ${root}; status + else + echo -n "Unmounting virtual disk..." + umount ${vdisk}; status; sleep 1 + fi; footer +} + +# +# Commands +# + +case "$1" in + + -i|init) + rootfs="$sebfs" + echo -n "Creating files in: ${rootfs}" + init; check ;; + + -b|build) + check_root + build + [ "$emu" ] && emulate ${work}/${iso} ;; + + -g|geniso) + check_root + geniso ;; + + -c|clean) + check_root + echo -n "Cleaning: ${work}" + [ "$all" ] && rm -rf ${sebfs} ${cache} + rm -rf ${rootfs}* ${rootiso} ${work}/*.iso + check ;; + + -p|package*) + shift + packages_handler "$@" ;; + + -v|vdisk) + vdisk_hanler ;; + + -l|lsfs) + title "Listing: $rootfs" + cd ${rootfs}; find . -type f | sed s'/^.//'g + footer "Rootfs files: $(find . -type f | wc -l)" ;; + + emu) + title "Emulating: $iso" + emulate ${work}/${iso} + footer ;; + + env) + title "SEB environment" + cat << EOT +work=$work +rootfs=$rootfs +rootiso=$rootiso +sebfs=$sebfs +sebpkgs=$sebpkgs +cache=$cache +vdisk=$vdisk +tools=$tools +initfs=$initfs +packages=$packages +iso=$iso +linux=$linux +EOT + footer ;; + + -t|testsuite) + # Development purpose + ${tools}/libseb.sh ;; + + *) help ;; + +esac && exit 0