#
# Makefile for DocoMomo - USB boot Linux
#
# Copyright (C) 2006 zunda <zunda at freeshell.org>
# 
# Permission is granted for copying, modification, distribution,
# and distribution of modified versions of this work under the
# terms of GPL version 2 or later.
#
# Read the GPL.txt file or gpl-3.0.txt file for more details.
#

# Target system
system_release = $(shell rpm -q momonga-release)
#system_release = momonga-release-4-1m.mo4
system_release_package = $(system_release).noarch.rpm
system_release_url = http://dist.momonga-linux.org/pub/momonga/4/i686/os/Momonga/$(system_release_package)
keymapdir = /lib/kbd/keymaps/i386/qwerty

# DocoMomo configuration
skelton_dir = skel
default_user = docomomo
default_pass = docomomo

# Directory settings
top_srcdir = .
build_dir = .

system_conf_dir = $(conf_dir)/$(system_release)
list_dir = $(top_srcdir)/lists/$(system_release)
patch_dir = $(top_srcdir)/patches/$(system_release)

# Directory to be used during preparation and installation
absolute_root_dir = `python $(script_dir)/absolute-path.py $(root_dir)`
initrd_dir = $(build_dir)/initrd
usr_dir = $(build_dir)/usr

# Commands
DOWNLOAD = lftpget -v

default: install

include Makefile.install
include Makefile.devel

# Preparation of target tree
PHONY: download-release-package
download-release-package: $(tmp_dir)/$(system_release_pkg)
$(tmp_dir)/$(system_release_package):
	@echo '*** Downloading release package'
	mkdir -p $(tmp_dir)
	chmod a+rwt $(tmp_dir)
	cd $(tmp_dir); $(DOWNLOAD) $(system_release_url)

PHONY: prepare-root
prepare-root: $(root_dir)/var/lib/rpm/Basenames
$(root_dir)/var/lib/rpm/Basenames: $(tmp_dir)/$(system_release_package)
	@echo '*** Preparing root directory'
	mkdir -p $(root_dir)/var/lib/rpm
	mkdir -p $(root_dir)/var/log
	mkdir -p $(root_dir)/dev
	if [ ! -e $(root_dir)/dev/null ]; then mknod $(root_dir)/dev/null c 1 3; fi
	mkdir -p $(root_dir)/etc
	touch $(root_dir)/etc/fstab
	mkdir -p $(root_dir)/proc
	rpm --root=$(absolute_root_dir) --initdb
	rpm --root=$(absolute_root_dir) -ivh --force --replacepkgs --nopost --nodeps $(tmp_dir)/$(system_release_package)
	touch $@

$(root_dir)/etc: prepare-root

$(build_dir)/yum.conf: $(conf_dir)/$(system_release)/yum.conf
	(grep -v reposdir $<; echo reposdir=$(absolute_root_dir)/etc/yum.repos.d) >| $@

PHONY: install-packages
install-packages: $(root_dir)/var/cache/yum/base/repomd.xml
$(root_dir)/var/cache/yum/base/repomd.xml: $(list_dir)/rpms.list $(root_dir)/var/lib/rpm/Basenames $(build_dir)/yum.conf $(wildcard $(patch_dir)/*.patch)
	@echo '*** Installing packages'
	mount -t proc proc $(root_dir)/proc
	(sed 's/#.*//' $(list_dir)/rpms.list | xargs -r yum -e 0 -c $(build_dir)/yum.conf install -y --installroot=$(absolute_root_dir) ) || \
	(sed 's/#.*//' $(list_dir)/rpms.list | xargs -r yum -e 0 -c $(build_dir)/yum.conf install -y --installroot=$(absolute_root_dir) ) || \
	(umount $(root_dir)/proc; exit 1)
	# yum sometimes dies before installing everything
	umount $(root_dir)/proc
	@echo '* Patching files'
	if [ -n "$(wildcard $(patch_dir)/*.patch)" ]; then \
		cat $(wildcard $(patch_dir)/*.patch) |\
		(cd $(root_dir); patch -p1 -N -R 2>&1 |\
		sed -n 's/.*to file \(.*\.rej\)$$/\1/;T;p' | xargs -r rm); \
		cat $(wildcard $(patch_dir)/*.patch) |\
		(cd $(root_dir); patch -p1 -N); \
	fi
	@echo '* copying latest kernel image'
	cp `ls $(root_dir)/boot/vmlinuz-* | python $(script_dir)/latest-version.py` $(root_dir)/boot/vmlinuz
	date "+$(PACKAGE)-$(VERSION)-%Y%m%d" > $(root_dir)/etc/docomomo-release
	touch $@

$(root_dir)/etc/docomomo-release: update-packages

$(root_dir)/boot/vmlinuz: install-packages

PHONY: update-packages
update-packages: $(root_dir)/var/cache/yum/base/repomd.xml
	@echo '*** Updating packages'
	mount -t proc proc $(root_dir)/proc
	yum -c yum.conf update -y --installroot=$(absolute_root_dir)
	umount $(root_dir)/proc
	@echo '* copying latest kernel image'
	cp `ls $(root_dir)/boot/vmlinuz-* | python $(script_dir)/latest-version.py` $(root_dir)/boot/vmlinuz
	date "+$(PACKAGE)-$(VERSION)-%Y%m%d" > $(root_dir)/etc/docomomo-release

$(build_dir)/configure-root-conf-etc.timestamp:
	python $(script_dir)/touch-with-newest.py $(build_dir)/configure-root-conf-etc.timestamp $(system_conf_dir)/etc

PHONY: configure-root
configure-root: $(build_dir)/configure-root.timestamp
$(build_dir)/configure-root.timestamp: $(root_dir)/var/cache/yum/base/repomd.xml /etc/localtime /etc/sysconfig/clock $(build_dir)/configure-root-conf-etc.timestamp $(root_dir)/etc/shadow
	@echo '*** Configuring root'
	# copy configuration from docomomo package
	(cd $(system_conf_dir); tar --exclude .svn --exclude CVS --exclude '*~' -c -f - etc) > $(tmp_dir)/etc.tar
	cat $(tmp_dir)/etc.tar | (cd $(root_dir); tar -x -v -f -)
	tar tf $(tmp_dir)/etc.tar | xargs -i -r chown root:root $(root_dir)/{}
	tar tf $(tmp_dir)/etc.tar | xargs -i -r chmod og-w $(root_dir)/{}
	mkdir -p $(root_dir)/root
	cp $(conf_dir)/root.profile $(root_dir)/root/.profile
	rm $(tmp_dir)/etc.tar
	. $(root_dir)/etc/sysconfig/keyboard; cp /$(keymapdir)/$${KEYTABLE}.map.gz $(root_dir)/$(keymapdir)/
	# correct permissions
	chmod o-r,a-wx $(root_dir)/etc/sudoers
	chmod a+x,og-w $(root_dir)/etc/init.d/*
	chmod og-rwx $(root_dir)/root/.profile
	# configure services
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del docomomo
	/usr/sbin/chroot $(root_dir) /sbin/chkconfig --add docomomo
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del kudzu
	/usr/sbin/chroot $(root_dir) /sbin/chkconfig --add kudzu
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del firstboot
	/usr/sbin/chroot $(root_dir) /sbin/chkconfig --add firstboot
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del ntpd
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del avahi-daemon
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del avahi-dnsconfd
	-/usr/sbin/chroot $(root_dir) /sbin/chkconfig --del haldaemon
	rm -f $(build_dir)/configure-root-conf-etc.timestamp
	touch $@

$(root_dir)/usr: $(build_dir)/configure-root.timestamp
	touch -r $< $@

PHONY: setup-users
setup-users: $(root_dir)/etc/shadow
$(root_dir)/etc/shadow: $(conf_dir)/users.txt $(root_dir)/etc $(root_dir)/var/cache/yum/base/repomd.xml $(root_dir)/var/lib/rpm/Basenames update-packages
	@echo '*** Setting up users'
	/usr/sbin/chroot $(root_dir) /usr/sbin/pwconv
	for line in `grep -v '^#' $(conf_dir)/users.txt`; do \
		username=`echo $$line | cut -d: -f1`; \
		realname=`echo $$line | cut -d: -f2`; \
		if ( ! /usr/sbin/chroot $(root_dir) /usr/bin/id -un "$$username" 2>/dev/null ); then \
			/usr/sbin/chroot $(root_dir) /usr/sbin/useradd -c "$$realname" "$$username"; \
			if [ "$$username" == "$(default_user)" ]; then \
				echo $(default_pass) | /usr/sbin/chroot $(root_dir) /usr/bin/passwd --stdin $(default_user); \
			else \
				/usr/sbin/chroot $(root_dir) /usr/bin/passwd "$$username"; \
			fi; \
		fi; \
	done
	echo $(default_pass) | /usr/sbin/chroot $(root_dir) /usr/bin/passwd --stdin root
	/usr/sbin/chroot $(root_dir) /usr/sbin/pwconv
	# copy skelton files
	for u in skel $(default_user); do \
		if [ ! -e "$(root_dir)/home/$$u" ]; then \
			mkdir -p "$(root_dir)/home/$$u"; \
		fi \
	done
	for s in $(system_conf_dir)/skel/.*; do \
		b=`basename "$$s"`; \
		if [ "$$b" == "." ] || [ "$$b" == ".." ]; then continue; fi; \
		if [ "$$b" == ".svn" ]; then continue; fi; \
		for u in skel $(default_user); do \
			dst="/home/$$u/$$b"; \
			if [ ! -e "$(root_dir)$$dst" ]; then \
				cp -r "$$s" "$(root_dir)$$dst"; \
				chmod -R a+r,og-w "$(root_dir)$$dst"; \
				find "$(root_dir)$$dst" -type d -exec chmod a+x {} \; ;\
				if [ "$$u" == "skel" ]; then \
					chown -R root:root "$(root_dir)$$dst"; \
				else \
					/usr/sbin/chroot $(root_dir) chown -R "$$u":"$$u" "$$dst" ;\
				fi; \
			fi; \
		done; \
	done
	touch $@
	@echo '*** Copy dot files to the home directories if needed'

PHONY: create-initrd
create-initrd: $(initrd_dir)/init
$(initrd_dir)/init: $(list_dir)/initrd-empty-dirs.list $(list_dir)/initrd-copy-files.list $(build_dir)/configure-root.timestamp $(root_dir)/etc/shadow
	@echo '*** Creating initrd'
	rm -rf $(initrd_dir)
	mkdir -p $(initrd_dir)
	# create empty directories
	for d in `sed 's/#.*//' $(list_dir)/initrd-empty-dirs.list`; do \
		mkdir -p $(initrd_dir)/$$d; \
	done
	# copy files from root
	for f in `sed 's/#.*//' $(list_dir)/initrd-copy-files.list`; do \
		for i in "$$f"; do \
			if [ -e $(root_dir)/$$i ]; then \
				mkdir -p $(initrd_dir)/`dirname $$i`; \
				cp -a $(root_dir)/$$i $(initrd_dir)/`dirname $$i`; \
			fi; \
		done; \
	done
	# copy keymap
	rm -rf $(initrd_dir)/kbd
	mkdir -p $(initrd_dir)/$(keymapdir)
	. $(initrd_dir)/etc/sysconfig/keyboard; cp $(root_dir)/$(keymapdir)/$${KEYTABLE}.map.gz $(initrd_dir)/$(keymapdir)/
	# copy kernel modules
	mkdir -p $(initrd_dir)/lib/modules
	cp -a $(root_dir)/lib/modules/`ls $(root_dir)/boot/vmlinuz-* | python $(script_dir)/latest-version.py | sed 's/.*vmlinuz-//'` $(initrd_dir)/lib/modules
	# copy libraries
	for l in `find $(initrd_dir) -type f | xargs -r file |\
	awk -F: '/dynamically linked/{print($$1)}' | xargs -r ldd |\
	sed -n '/^[^\t]/d;s/^[^/]*//;s/ .*//;/^\//p' | sort -u`; do \
		mkdir -p $(initrd_dir)/`dirname $$l`; \
		cp -p -L $(root_dir)$$l $(initrd_dir)$$l; \
	done
	# correct permissions
	chmod a+rwt $(initrd_dir)/tmp
	cd $(initrd_dir); ln -s sbin/init .
	touch $@

PHONY: strip-initrd
strip-initrd: $(build_dir)/strip-initrd.timestamp
$(build_dir)/strip-initrd.timestamp: $(initrd_dir)/init
	@echo '*** Stripping initrd'
	# remove yum configuration
	rm -rf $(etc_dir)/yum.repos.d
	# remove unused locales
	if [ -d $(initrd_dir)/etc/X11/xinit/lang.d ]; then \
		for d in $(initrd_dir)/etc/X11/xinit/lang.d/*; do \
			case `basename $$d` in \
				ja*|en_US|C) continue;; \
				*) rm -f $$d;; \
			esac \
		done; \
	fi
	ls `find $(initrd_dir)/etc -name '*.ja*' -or -name '*-ja*' |\
		grep -v java | sed 's/ja/*/g'` |\
		egrep -v '[.-](ja|c)\b' | xargs rm -f
	# remove unwanted kernel modules
	for d in build extra source; do \
		rm -rf $(initrd_dir)/lib/modules/*/$$d; \
	done
	for n in bluetooth media isdn; do \
		find $(initrd_dir)/lib/modules -name $$n | xargs -r rm -rf; \
	done
	# strip
	find $(initrd_dir)/$$dir -type f | xargs -r file | grep 'not stripped$$' >| $(tmp_dir)/initrd-files.list
	cat $(tmp_dir)/initrd-files.list | grep executable | grep -v 'script text' | cut -f1 -d: | grep -v -x -f $(system_conf_dir)/no-strip.list | xargs -r strip
	cat $(tmp_dir)/initrd-files.list | grep 'shared object' | cut -f1 -d:  | grep -v -x -f $(system_conf_dir)/no-strip.list | xargs -r strip --strip-debug
	rm -f $(tmp_dir)/initrd-files.list
	touch $@

PHONY: create-initrd-image
create-initrd-image: $(tmp_dir)/initrd.img
$(tmp_dir)/initrd.img: $(build_dir)/strip-initrd.timestamp
	@echo '*** Making initrd image'
	# to keep track of modified files in /etc
	touch $(initrd_dir)/etc/.initrd.timestamp
	(cd $(initrd_dir); find . -print0 | sort -z | cpio -o -c -0 | gzip -c -9) >| $@

PHONY: initrd
initrd: create-initrd-image

# Extract /usr for runlevel 3
PHONY: create-usr
create-usr: $(usr_dir)
$(usr_dir): $(root_dir)/usr
	@echo '*** Creating usr'
	rm -rf $(usr_dir)
	cp -a $(root_dir)/usr $(usr_dir)

PHONY: strip-usr
strip-usr: $(build_dir)/strip-usr.timestamp
$(build_dir)/strip-usr.timestamp: $(usr_dir)
	@echo '*** Stripping usr'
	# remove unused locales
	for d in $(usr_dir)/lib/locale/* $(usr_dir)/share/locale/*; do \
		if [ -d $$d ]; then \
			case `basename $$d` in \
				ja*|en_US|C) continue;; \
				*) rm -rf $$d;; \
			esac \
		fi \
	done
	# strip
	find $(usr_dir)/$$dir -type f | xargs -r file | grep 'not stripped$$' >| $(tmp_dir)/usr-files.list
	cat $(tmp_dir)/usr-files.list | grep executable | grep -v 'script text' | cut -f1 -d: | grep -v -x -f $(system_conf_dir)/no-strip.list | xargs -r strip
	cat $(tmp_dir)/usr-files.list | grep 'shared object' | cut -f1 -d:  | grep -v -x -f $(system_conf_dir)/no-strip.list | xargs -r strip --strip-debug
	rm -f $(tmp_dir)/usr-files.list
	touch $@

PHONY: create-usr-image
create-usr-image: $(tmp_dir)/usr.sqs
$(tmp_dir)/usr.sqs: $(build_dir)/strip-usr.timestamp
	@echo '*** Creating /usr image'
	/sbin/mksquashfs $(usr_dir) $@ -all-root -noappend

$(root_dir)/home: setup-users

PHONY: create-images
create-images: create-initrd-image create-usr-image create-home-image

PHONY: clean
clean: umount-usb clean-devel clean-install
	# Backup the yum cached rpm packages
	-mv $(root_dir)/var/cache/yum $(tmp_dir)/
	# Delete the time stamps
	for f in configure-root.timestamp strip-initrd.timestamp strip-usr.timestamp configure-root-conf-etc.timestamp; do \
		rm -f $(build_dir)/$$f; \
	done
	# Delete the conf file
	rm -f $(build_dir)/yum.conf
	# Delete the directories
	for dir in $(root_dir) $(initrd_dir) $(usr_dir); do \
		rm -rf $(build_dir)/$$dir;\
	done
	# Delete the tar ball
	rm -f $(DIST_ARCHIVES)
	# Restore the yum cached rpm packages
	mkdir -p $(root_dir)/var/cache/
	-mv $(tmp_dir)/yum $(root_dir)/var/cache/
	rm -rf $(tmp_dir)
	-for t in headers metadata dbcache; do \
		yum clean $$t --installroot=$(absolute_root_dir); \
	done

PHONY: clean-all
clean-all: clean
	rm -rf $(root_dir)
