mkudvdプログラムリスト

  • 2009/02/10 Ver 0.06
  • 2009/02/13 Ver 0.07
    • オリジナルCDからのファイルのコピーを最適化し、作業時間を短縮する。
#! /bin/bash

# Custom Ubuntu Live DVD maker
# mkudvd Ver 0.07 (2009/02/13)
# Copyright (C) 2009 Adsaria

# This program is free software; you can redistribute it and/or modify it.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY.

DEBUG=

if [ ${DEBUG} ]; then set -x; fi

################################################################################
# Parameter Settings

WORKING_DIR=/livedvd
ORIGINAL_CD_ISO="${WORKING_DIR}/ubuntu-8.04.2-desktop-i386.iso"
EXTENSION=custom

CUSTOM_DVD_ISO="${WORKING_DIR}/"`basename "${ORIGINAL_CD_ISO}" .iso`-${EXTENSION}.iso
TEMPLATE_ROOT="${WORKING_DIR}/filesystem"
MISC_FILES="${WORKING_DIR}/misc"
DVD_FILES="${WORKING_DIR}/live_dvd_files"
FS_TYPE=squashfs
# FS_TYPE=ext2
REMOVE_999_ACCOUNT=1

################################################################################
# Check base files

if [ ! -e "${TEMPLATE_ROOT}/vmlinuz" ]; then
	echo "Template root file system is not found."
	exit 1
fi

if [ ! -f "${ORIGINAL_CD_ISO}" ]; then
	echo "Ubuntu original CD iso file is not found."
	exit 1
fi

################################################################################
# Check utilities

if [ ! -x /usr/bin/mksquashfs ]; then
	echo "It seems package \"squashfs-tools\" have not been installed."
	exit 1
fi
if [ ! -x /usr/bin/genisoimage ]; then
	echo "It seems package \"genisoimage\" have not been installed."
	exit 1
fi

################################################################################
echo "Copying original CD files"

if [ ! -d "${DVD_FILES}" ]; then
	rm -rf "${DVD_FILES}"
	mkdir -p "${DVD_FILES}"
fi

rm -rf "${WORKING_DIR}/mnt"; mkdir "${WORKING_DIR}/mnt"
mount -t iso9660 -o loop,ro "${ORIGINAL_CD_ISO}" "${WORKING_DIR}/mnt"

rsync -ax --delete --exclude='filesystem.squashfs' \
	"${WORKING_DIR}/mnt/" "${DVD_FILES}/"

umount "${WORKING_DIR}/mnt"; rm -rf "${WORKING_DIR}/mnt"

################################################################################
echo "Modifying boot menu parameter"

sed -i \
	-e 's/^timeout .*$/timeout 50/' \
	"${DVD_FILES}/isolinux/isolinux.cfg"

################################################################################
echo "Triming base filesystem"

### Changing root password character

sed -i -e 's/^root:!:/root:*:/' "${TEMPLATE_ROOT}/etc/shadow"

### Removing trouble-making files

if [ -e "${TEMPLATE_ROOT}/etc/blkid.tab" ]; then
	rm -rf "${TEMPLATE_ROOT}/etc/blkid.tab"*
fi

if [ -e "${TEMPLATE_ROOT}/etc/resolv.conf" ]; then
	rm -rf "${TEMPLATE_ROOT}/etc/resolv.conf"
fi

echo "# UNCONFIGURED FSTAB FOR BASE SYSTEM" \
	> "${TEMPLATE_ROOT}/etc/fstab"

rm -rf "${TEMPLATE_ROOT}/etc/nologin"
ln -s "/var/lib/initscripts/nologin" "${TEMPLATE_ROOT}/etc/nologin"

rm -rf "${TEMPLATE_ROOT}/etc/mtab"

### Removing garbage files

rm -rf "${TEMPLATE_ROOT}/tmp/".[^.]*
rm -rf "${TEMPLATE_ROOT}/tmp/".??*
rm -rf "${TEMPLATE_ROOT}/tmp/"*

rm -rf "${TEMPLATE_ROOT}/var/log/Xorg.0.log"
rm -rf "${TEMPLATE_ROOT}/var/log/gdm/:0.log"
rm -rf "${TEMPLATE_ROOT}/var/log/tomcat6/"*
if [ ${DEBUG} ]; then FIND_OPT="-print" ; fi
find "${TEMPLATE_ROOT}/var/log/" -type f -name \*.gz ${FIND_OPT} -exec rm -f '{}' \;
find "${TEMPLATE_ROOT}/var/log/" -type f -name \*.\[0-9\] ${FIND_OPT} -exec rm -f '{}' \;
find "${TEMPLATE_ROOT}/var/log/" -type f -name \*old ${FIND_OPT} -exec rm -f '{}' \;
find "${TEMPLATE_ROOT}/var/log/" -type f ${FIND_OPT} -exec cp -f /dev/null '{}' \;

REMOVE_LIST=" \
        .bash_history \
        .cache \
        .esd_auth \
        .fontconfig \
        .gtk-bookmarks \
        .gvfs \
        .ICEauthority \
        .local \
        .nautilus \
        .pulse \
        .pulse-cookie \
        .recently-used.xbel \
        .ssh \
        .sudo_as_admin_successful \
        .update-notifier \
        .Xauthority \
        .xsession-errors \
        "

if [ -d "${TEMPLATE_ROOT}/root" ]; then
	echo "Cleaning root directory up...."
	( cd "${TEMPLATE_ROOT}/root"; rm -rf ${REMOVE_LIST} )
fi

if [ -d "${TEMPLATE_ROOT}/home/ubuntu" ]; then
	(
	echo "Cleaning ubuntu directory up...."
	cd "${TEMPLATE_ROOT}/home/ubuntu"
	rm -rf ${REMOVE_LIST}
	if [ ! -f "${MISC_FILES}/ubuntu_home.cpio.gz" ]; then
		echo "Backing ubuntu home up...."
		touch .mark ; chown `stat -c "%u:%g" .` .mark
		find . | cpio -o -H newc --quiet | gzip > "${MISC_FILES}/ubuntu_home.cpio.gz"
	fi
	)

fi

###
# remove pre-configured user account, ubuntu

if [ ${REMOVE_999_ACCOUNT} ]; then
	echo "Removing ubuntu account and home...."
	(chroot "${TEMPLATE_ROOT}" userdel -f -r ubuntu ) &> /dev/null
	rm -rf "${TEMPLATE_ROOT}/home/ubuntu/"
	(chroot "${TEMPLATE_ROOT}" groupdel ubuntu ) &> /dev/null
	if [ -f "${TEMPLATE_ROOT}/etc/gdm/gdm.conf" ]; then
		sed -i \
			-e "s/^AutomaticLoginEnable=.*\$/AutomaticLoginEnable=false/" \
			-e "s/^AutomaticLogin=.*\$/AutomaticLogin=/" \
			-e "s/^TimedLoginEnable=.*\$/TimedLoginEnable=false/" \
			-e "s/^TimedLogin=.*\$/TimedLogin=/" \
			-e "s/^TimedLoginDelay=.*\$/TimedLoginDelay=/" \
			"${TEMPLATE_ROOT}/etc/gdm/gdm.conf"
	fi
fi

################################################################################
# Triming casper for maitainance works

if [ -f "${TEMPLATE_ROOT}/etc/init.d/casper" ]; then
	echo "Modifying /etc/init.d/casper ...."
	sed -i \
		-e 's/TIMEOUT 86400/TIMEOUT 5/' \
		-e '/^[ ]*read x /s/^ /#/' \
		"${TEMPLATE_ROOT}/etc/init.d/casper"
fi

################################################################################
echo "Modifying initrd and copy initrd and kernel"

INITRD_ROOT="${WORKING_DIR}/initrd"

rm -rf "${WORKING_DIR}/initrd.img"
rm -rf "${INITRD_ROOT}"; mkdir "${INITRD_ROOT}"
(
	cd "${INITRD_ROOT}"
	gzip -dc "${TEMPLATE_ROOT}/initrd.img" | cpio -i --quiet

	# Casper can not handle lvm device properly, then modify casper script
	# But modifying just initrd script, not usr/share/initramfs-tools/scripts/casper
	sed -i -e 's/(loop|ram|fd)/(loop|ram|fd|dm-)/' \
		"${INITRD_ROOT}/scripts/casper"

	# Change ubuntu default password to "ubuntu", from "\n"
	sed -i -e 's/U6aMy0wojraho/kBzYzm5JjWKPA/' \
		"${INITRD_ROOT}/scripts/casper-bottom/10adduser"

	# Replace set_hostname script
	if [ -f "${MISC_FILES}/18hostname" ]; then
		cp -f "${MISC_FILES}/18hostname" \
			"${INITRD_ROOT}/scripts/casper-bottom/"
	fi

	# Copy add_ubuntu_home_directory script
	if [ -f "${MISC_FILES}/11adduserhome" ]; then
		cp "${MISC_FILES}/11adduserhome" \
			"${INITRD_ROOT}/scripts/casper-bottom/"
	fi

	# Copy server setup scripts
	cp -f "${MISC_FILES}/"6[0-9]* "${INITRD_ROOT}/scripts/casper-bottom/"

	# Copy ubuntu home directory archive, if exist
	if [ -f "${MISC_FILES}/ubuntu_home.cpio.gz" ]; then
		mkdir -p "${INITRD_ROOT}/var/backups"
		cp -f "${MISC_FILES}/ubuntu_home.cpio.gz" \
			"${INITRD_ROOT}/var/backups/"
	fi

	find . | cpio -o --quiet -H newc | gzip > "${WORKING_DIR}/initrd.img"
)
cp -f "${WORKING_DIR}/initrd.img" "${DVD_FILES}/casper/initrd.gz"

rm -rf "${WORKING_DIR}/initrd.img"
rm -rf "${INITRD_ROOT}"

cp -f "${TEMPLATE_ROOT}/vmlinuz" "${DVD_FILES}/casper/vmlinuz"

################################################################################
echo "Creating filesystem image"

SQUASH_FILE="${DVD_FILES}/casper/filesystem.squashfs"
EXT2_FILE="${DVD_FILES}/casper/filesystem.ext2"
rm -rf "${SQUASH_FILE}" "${EXT2_FILE}"

case "${FS_TYPE}" in
squashfs|squash)
	FS_FILE="${SQUASH_FILE}"
	mksquashfs "${TEMPLATE_ROOT}" "${SQUASH_FILE}"
	;;
ext2|ext)
	FS_FILE="${EXT2_FILE}"
	FS_SIZE=`du -s "${TEMPLATE_ROOT}/" | awk '{print $1}'`
	FS_SIZE=`expr "${FS_SIZE}" + "${FS_SIZE}" / 20`
	dd if=/dev/zero of="${EXT2_FILE}" bs="${FS_SIZE}" count=1024 2>/dev/null
	mkfs -F -q -t ext2 "${EXT2_FILE}"
	rm -rf mnt ; mkdir mnt
	mount -o loop "${EXT2_FILE}" mnt
	rsync -ax "${TEMPLATE_ROOT}/" mnt/
	umount mnt
	rm -rf mnt
	;;
*)
	echo "Filesystem Type is incorrect."
	echo "exit."
	exit 1
	;;
esac
chmod 444 "${FS_FILE}"

MANIFEST_1="${DVD_FILES}/casper/filesystem.manifest"
MANIFEST_2="${DVD_FILES}/casper/filesystem.manifest-desktop"

ORIGINAL_DIFFS=` \
	diff "${MANIFEST_1}" "${MANIFEST_2}" | \
	sed -e '/^[^<]/d' -e 's/^< //' -e 's/ .*//' \
	`
rm -rf "${MANIFEST_1}"
rm -rf "${MANIFEST_2}"

dpkg-query -W --showformat='${Package} ${Version}\n' \
         --admindir="${TEMPLATE_ROOT}/var/lib/dpkg/" \
        > "${MANIFEST_1}"

cp -f "${MANIFEST_1}" "${MANIFEST_2}"
for REMOVE_PKG in ${ORIGINAL_DIFFS}; do
	sed -i -e "/^${REMOVE_PKG} /d" "${MANIFEST_2}"
done

chmod 444 "${MANIFEST_1}"
chmod 444 "${MANIFEST_2}"

################################################################################
echo "Making md5 check file"

touch "${DVD_FILES}/CUSTOM"

(
	cd "${DVD_FILES}"
	rm -f md5sum.txt
	find . -xdev -path ./isolinux -prune -o -type f -print0 \
		| xargs -0 md5sum \
		| sort -k 2 > ../md5sum.txt
	mv ../md5sum.txt .
)

################################################################################
echo "Generating custom DVD iso image"

rm -f "${CUSTOM_DVD_ISO}"
genisoimage -quiet -J -R -D -V "CUSTOM_LIVE_DVD" \
	-o "${CUSTOM_DVD_ISO}" -b isolinux/isolinux.bin -c isolinux/boot.cat \
	-no-emul-boot -boot-load-size 4 -boot-info-table \
	"${DVD_FILES}" 2> /dev/null

################################################################################
echo "Done."

exit 0
#!/bin/sh

PREREQ=""
DESCRIPTION="Adding live session user home directory..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

if [ -f /var/backups/ubuntu_home.cpio.gz ]; then
    if [ -d /root/home/ubuntu ]; then
	(
	    cd /root/home/ubuntu
	    rm -rf .home_template ; mkdir .home_template
	    cd .home_template
	    gzip -dc /var/backups/ubuntu_home.cpio.gz | cpio -i
	    cp -a ..?* .[^.]* * ..
	    cd ..
	    rm -rf .home_template
	)
    fi
fi

log_end_msg

initrd管用のcpioが“-u”オプションを使えないので、少々回りくどい処理をしている。

  • 18hostname:DHCPサーバからホスト名等を取得し設定する。
#! /bin/sh

PREREQ=""
DESCRIPTION="Setting hostname..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

NETCONFIG=/netboot.config
ADDR=127.0.1.1
DOMAIN=

if [ -f $NETCONFIG ]; then

	NET_HOST=$(grep '^ host   :' $NETCONFIG | cut -f6 -d ' ' )
	if [ ! -z "$NET_HOST" ]; then HOST=$NET_HOST; fi
	export HOST

	NET_DOMN=$(grep '^ domain :' $NETCONFIG | cut -f4 -d ' ' )
	if [ ! -z "$NET_DOMN" ]; then DOMAIN=$NET_DOMN; fi

	NET_ADDR=$(grep '^ address:' $NETCONFIG | cut -f3 -d ' ' )
	if [ ! -z "$NET_ADDR" ]; then ADDR=$NET_ADDR; fi
fi

echo "$HOST" > /root/etc/hostname
cat > /root/etc/hosts <<EOF
127.0.0.1 localhost
$ADDR $HOST $HOST.$DOMAIN

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

EOF
hostname "$HOST"

log_end_msg
  • 60setupnfs:/etc/exportsに変更を加え/tmpをネットワークからマウントできるようにしている。
#!/bin/sh

PREREQ=""
DESCRIPTION="Setting up NFS configuration..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

if [ -f /root/etc/exports ]; then
        echo '/tmp      *(rw,all_squash,no_subtree_check,fsid=0)' >> /root/etc/exports
fi

log_end_msg
  • 61setupsmb:/etc/samba/smb.confに変更を加えて/tmpを共有できる様にしている。
#!/bin/sh
PREREQ=""
DESCRIPTION="Setting up Samba configuration..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

if [ -f /root/etc/samba/smb.conf ]; then
        cat >> /root/etc/samba/smb.conf << EOF
[tmp]
        comment = /tmp
        path = /tmp
        browseable = no
        writable = yes
        guest ok = yes
EOF
fi

log_end_msg
  • 62setupntp:/etc/ntp.confを変更する。
#!/bin/sh

PREREQ=""
DESCRIPTION="Setting up NTP configuration..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

if [ -f /root/etc/ntp.conf ]; then
        sed -i -e 's/^server ntp.ubuntu.com/#server ntp.ubuntu.com\
server  255.255.255.255\
server  255.255.255.255/' /root/etc/ntp.conf

fi

log_end_msg

プログラム中の“255.255.255.255”の部分は自分が使っているプロバイダのNTPサーバ、もしくは国内の公共NTPサーバのIPアドレスにする。ただ、このスクリプトは特に必要ないかも。/etc/ntp.confに変更を加えなくても“ntp.ubuntu.com”というNTPサーバを使うような設定になっている。

  • 63setupbind:/etc/bind/named.conf.optionsに変更を加えてBINDをフォワーダーとして起動する。
#!/bin/sh

PREREQ=""
DESCRIPTION="Setting up BIND configuration..."

. /scripts/casper-functions

prereqs()
{
       echo "$PREREQ"
}

case $1 in
# get pre-requisites
prereqs)
       prereqs
       exit 0
       ;;
esac

log_begin_msg "$DESCRIPTION"

if [ -f /root/etc/bind/named.conf.options ]; then
        sed -i \
                -e '/^[\t ]*\/\/[\t ]*0\.0\.0\.0;/,/^[\t ]*\/\/[\t ]*};/d' \
                -e 's/^[\t ]*\/\/ forwarders {/ forwarders { 255.255.255.255; };/' \
                /root/etc/bind/named.conf.options
fi

log_end_msg

プログラム中の“255.255.255.255”の部分は自分が利用しいるプロバイダのDNSサーバのIPアドレスに変更する。詳しくは“最小限の設定でDNSを使う”を参照。