Remastering script

From MEPIS Documentation Wiki

Jump to: navigation, search

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

  1. creates your remastering environment
  2. mounts the CD/ISO and squashfs
  3. 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.
  4. 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
  5. has a -c or --chroot option (as in: sh remaster.sh -c) to skip creating the remastering environment and log in directly to chroot
  6. has in-built "version" file editing
  7. does basic clean-up: removes chroot .bash_history file
  8. 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

  1. Copy and paste this script in Kwrite or Kate.
  2. Save as "remaster.sh" (don't use "remaster" because that's the default name of the folder that this script creates)
  3. Make script executable. In KDE right-click on it -> Properties -> Permission tab -> check "is executable" (or use chmod +x remaster.sh)
  4. 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
Personal tools