Remastering script
From MEPIS Documentation Wiki
This script has been written by MEPIS users to make it easier to remaster the CD, please see remastering article for more details, please improve the script and add suggestion in the discussion page.
Contents |
Features
- creates your remastering environment
- mounts the CD/ISO and squashfs
- logs in to chroot, the remastering environment, where you can customize the image, run updates, remove programs that you don't need, add new programs, etc.
- has a -b or --build-iso option (as in: sh remaster.sh -b) to skip creating the remastering environment and go straight into rebuilding the iso
- has a -c or --chroot option (as in: sh remaster.sh -c) to skip creating the remastering environment and log in directly to chroot
- has in-built "version" file editing
- does basic clean-up: removes chroot .bash_history file
- creates the ISO file after you exit from chroot
Requirements
The script depends on squashfs-tools
apt-get install squashfs-tools
You need enough space on hard disk to duplicate the content of ISO and unpack it, if you remaster it you need space for the resulting ISO. Therefore you probably need to have free space on your hard disk about three times the size of the original ISO.
Unpacking, copying and remastering are resource intensive operations, you need to take into consideration that these operations will tie down your computer for some time, don't run the script if you have other things going at the same time (especially if you burn CDs or DVDs.)
How to run it
- Copy and paste this script in Kwrite or Kate.
- Save as "remaster.sh" (don't use "remaster" because that's the default name of the folder that this script creates)
- Make script executable. In KDE right-click on it -> Properties -> Permission tab -> check "is executable" (or use chmod +x remaster.sh)
- Run script with ./remaster.sh filename.iso (where filename.iso is the name of the ISO you want to remaster, use TAB for autocompletion)
Run X-based (GUI) programs in chroot
Once you are in the chroot environment you can run different commands in the console. However there's a little trick you need to start GUI programs:
- install xnest
apt-get install xnest
- outside of chroot run this command in console (this should open a window)
Xnest -ac :1
- within chroot run this command:
export DISPLAY=localhost:1
Then, when you start a command in chroot, for example "synaptic", the GUI should appear in the window opened before.
Script
#!/bin/bash
# -------------------------------------------------------------------------------------- #
# Script: remaster.sh #
# Details: remasters ISOs or CDs created with SquashFS #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
# -------------------------------------------------------------------------------------- #
# Provides a synopsis:
function usage () {
echo "$0 [-b|--build-iso] [-c|--chroot] [old-iso]"
echo "$0 {-h|--help}"
}
# Offers help:
function help () {
usage
echo " old-iso the path to the original ISO image"
echo
echo " -b|--build-iso skip creating the chroot environment"
echo " -c|--chroot logs into already created chroot environment"
echo " -h|--help display this help"
echo
exit
}
# Checks whether a given filesystem is configured.
function fs_configured () {
grep -q $1 /proc/filesystems
}
# Asks yes/no question and return true for "y" and false for "n"; default is "yes"
function Y_or_n () {
echo -en " (Y/n)? "
read answer
echo
case $answer in
no|n) return 1;;
*) return 0;;
esac
}
# Asks yes/no question and return true for "y" and false for "n"; default is "no"
function y_or_N () {
echo -en " (y/N)? "
read answer
echo
case $answer in
yes|y) return 0;;
*) return 1;;
esac
}
# Sets the current directory as path, if path/remaster exists it prompts for another path
function get_host_path () {
export STARTPATH=$PWD
if [[ -e $STARTPATH/remaster ]]; then
while true; do
echo -e "Enter the host path (i.e. /home/username) in which you want to remaster your project: \n"
read HOSTPATH
echo
if [[ -e $HOSTPATH ]]; then
export HOSTPATH
echo -e "The project will be created in \"$HOSTPATH/remaster\" directory \n"
break
else
echo -n "\"$HOSTPATH\" doesn't exist, create"
Y_or_n && {
mkdir -p $HOSTPATH
if [[ $? -ne 0 ]]; then
echo -e "Error: the folder was not created, please try again \n"
else
echo -e "The project will be created in \"$HOSTPATH/remaster\" directory \n"
break
fi
}
fi
done
else
HOSTPATH=$STARTPATH
echo -e "The project will be created in \"$HOSTPATH/remaster\" directory \n"
fi
}
# Sets the path to iso or cdrom
function get_iso_path () {
if [[ -e $1 ]]; then
CD=$1
echo -e "This script will remaster \"$CD\" \n"
else
while true; do
echo -e "Please enter the path of your optical drive with the MEPIS CD (i.e. /dev/hdc)"
echo -e "or enter the complete path to a MEPIS iso on your hard disk (i.e. /path_to_iso/mepis.iso): \n"
read CD
echo
if [[ -e $CD ]]; then
break
else
echo -e "Path or file doesn't exist, please try again \n"
fi
done
fi
export CD
}
function create_remastering_env () {
export REM=$HOSTPATH/remaster
mkdir $REM
cd $REM
echo -e "Okay, we have added a \"remaster\" subdirectory to your host path. From now on we are working in this \"$REM\" environment and its subdirectories only. \n"
echo "creating directory structure for this operation"
mkdir iso squashfs new-iso new-squashfs
echo "($REM/iso) directory to mount CD on"
echo "($REM/squashfs) directory for old squashfs"
echo "($REM/new-squashfs) directory for new squashfs"
echo -e "($REM/new-iso) directory for new iso \n"
echo -e "mounting original cd to $REM/iso directory"
cd $STARTPATH
mount -o loop $CD $REM/iso
if [[ $? -ne 0 ]]; then
rm -r remaster
echo -n "Could not mount the CD image, do you want to try again"
Y_or_n || exit 3
$0
exit
fi
cd $REM
# Finds the biggest file in ISO, which is most likely the squash file
SQUASH=$(find $REM/iso -type f -printf "%s %p\n" | sort -rn | head -n1 | cut -d " " -f 2)
echo "mounting original squashfs to $REM/squashfs"
mount -t squashfs -o loop $SQUASH squashfs
if [[ $? -ne 0 ]]; then
cd $STARTPATH
umount $REM/iso
rm -r remaster
echo -n "Error mounting squashfs file. \"$SQUASH\" is probable not a squashfs file. Removing \"remaster\" folder and exiting..."
exit 4
fi
echo "copying mounted iso to $REM/new-iso (takes some time)"
SQUASH_REL=${SQUASH#$REM/iso/}
rsync -a iso/ new-iso --exclude=$SQUASH_REL
echo -e "copying mounted squashfs to $REM/new-squashfs (takes some time) \n"
cp -a squashfs/* new-squashfs/
umount $REM/squashfs
umount $REM/iso
rm -r $REM/squashfs
rm -r $REM/iso
}
function get_remaster_dir () {
HOSTPATH=$PWD
if [[ ! -d $HOSTPATH/remaster ]]; then
echo -e "Enter the path to the remaster directory (e.g., /home/username):\n"
while true; do
read HOSTPATH
echo
[[ -d $HOSTPATH/remaster ]] && break
echo -e "\"remaster\" directory not found in that path, please try again:\n"
done
fi
export REM=$HOSTPATH/remaster
cd $REM
}
# Mounts all needed directories for chroot evironment
function mount_all () {
# Mount /proc and /sys and set up networking (I prefer to mount temporarily resolv.conf instead of copying it)
mount --bind /proc new-squashfs/proc
mount --bind /sys new-squashfs/sys
mount --bind /dev new-squashfs/dev
mount --bind /tmp new-squashfs/tmp
touch new-squashfs/etc/resolv.conf
mount --bind /etc/resolv.conf new-squashfs/etc/resolv.conf
}
# Unmounts all mounted directories
function umount_all () {
umount new-squashfs/tmp
umount new-squashfs/dev
umount new-squashfs/sys
umount new-squashfs/proc
umount new-squashfs/etc/resolv.conf
}
# Commands that clean up the chroot enveronment at log out
function cleanup () {
# Remove bash history
rm -f $REM/new-squashfs/root/.bash_history
}
# Asks if ready; exits if "no", starts building ISO if "yes"
function start_build? () {
echo
echo -n "Are you ready to start buiding the ISO"
Y_or_n || {
echo -e "OK, to remaster later on, run this script with \"build-iso\" argument, like this \"$0 --build-iso\" or \"$0 -b\" "
echo
exit
}
}
# Mounts filesystems and chroots to remastering environment, at exit unmounts all filesystems and perform cleanup for remastering environment
function chroot_env () {
mount_all
# Assume root in our new squashfs
echo -e "Chrooting into your / "
echo -e "You should now be in the environment you want to remaster. To check please type \"ls\" - you should see a root directory tree."
echo -e "When done please type \"exit\" or press CTRL-D \n"
# If you need to set environment variable and/or execute commands in the
# chrooted environment but before the shell gets started, you can do it this way:
# VAR=value ... chroot new-squashfs "$SHELL -c \"commands; ... ; $SHELL -il\""
# where 'VAR', 'value' and 'command' are what you want to set/execute and
# '...' means "as many as you wish".
chroot new-squashfs
umount_all
cleanup
}
function edit_version_file () {
echo -e "This is your current version file: \n"
echo "----------------------------------------------------"
cat $REM/new-iso/version
echo
echo -e "----------------------------------------------------\n"
echo -n "Would you like to amend your version file"
y_or_N && {
chmod +w $REM/new-iso/version
${EDITOR:-nano} $REM/new-iso/version
chmod -w $REM/new-iso/version
}
}
# Set ISO path
function set_iso_path () {
echo -e "The ISO file will be placed by default in \"$REM\" directory. \n"
echo -n "Is that OK"
Y_or_n && ISOPATH=$REM || {
while true; do
echo -e "Enter the path (i.e. /home/username) in which you want to place your ISO file: \n"
read ISOPATH
echo
if [[ -d $ISOPATH ]]; then
break
else
echo -n "\"$ISOPATH\" doesn't exist, create"
Y_or_n && {
mkdir -p $ISOPATH
if [[ $? -ne 0 ]]; then
echo -e "Error: the folder was not created, please try again \n"
else
echo -e "The path will be \"$ISOPATH\" \n"
break
fi
}
fi
done
}
export ISOPATH
}
function set_iso_name () {
set_iso_path
echo -e "Please enter the name of the ISO file (default: remastered.iso) \n"
read ISONAME
if [[ $ISONAME = "" ]]; then
ISONAME="remastered.iso"
fi
ISONAME=$ISOPATH/$ISONAME
echo
if [[ -e $ISONAME ]]; then
while true; do
echo -n "File exists, overwrite"
Y_or_n && break
echo -e "Please enter another name for the ISO file (i.e. file_name.iso) \n"
read ISONAME
ISONAME=$ISOPATH/$ISONAME
echo
if [[ ! -e $ISONAME ]]; then
break
fi
done
fi
export ISONAME
}
# Create new squashfs in the new-iso
function make_squashfs () {
echo -e "Good. We are now creating your iso. Sit back and relax, this takes some time (some 20 minutes on an AMD +2500 for a 680MB iso). \n"
mksquashfs new-squashfs new-iso/mepis/mepis -noappend
if [[ $? -ne 0 ]]; then
echo "Error making squashfs file. Exiting..."
exit 5
fi
}
function make_iso () {
cd $REM/new-iso
mkisofs -l -r -R -v -V "Mepis" -no-emul-boot -boot-load-size 5 -boot-info-table -b boot/grub/stage2_eltorito -c boot.catalog -hide-rr-moved -o $1 .
if [[ $? -eq 0 ]]; then
echo
echo -e "Done. You will find your very own remastered home-made Linux here: $1\n"
else
echo
echo -e "ISO building failed\n"
fi
}
# Root check
if [[ $UID != "0" ]]; then
echo -e "You need to be root to execute this script.\n"
exit 1
fi
# Check that we have a squashfs filesystem configured.
fs_configured squashfs || {
echo
echo "This remastering process uses the \"squashfs\" filesystem which doesn't seem to be installed on your system. Without it we cannot proceed. Run \"apt-get install squashfs-modules-\$(uname -r)\" "
echo "If you do have the package installed you might need to run this command \"modprobe squashfs\" before running this script"
echo
echo "Script aborted."
echo
exit 2
}
# Capture command line options:
ERROR=false
BUILD=false
CHROOT=false
for args
do
case "$1" in
-b|--build-iso) BUILD=true;;
-c|--chroot) CHROOT=true;;
-h|--help) help;;
--) shift; break;;
-*) echo "Unrecognised option: $1"; ERROR=true;;
*) break;;
esac
shift
done
# Exit to help if not understood:
$ERROR && help
# Create environment only if script is NOT called with --build-iso OR --chroot arguments
$BUILD || $CHROOT || {
get_host_path
get_iso_path $1
create_remastering_env
}
# Get the remaster directory if script called with --build-iso OR --chroot arguments.
$BUILD || $CHROOT && get_remaster_dir
# Execute chroot_env if script is NOT called with --boot-iso argument.
$BUILD || {
chroot_env
start_build?
}
edit_version_file
set_iso_name
make_squashfs
make_iso $ISONAME

