Diskussion:Entwicklerhandbuch/CD remastern

Aus Delixs
Zur Navigation springen Zur Suche springen
#!/bin/bash
#set -e
#set -x
#
# Dieses Script verpackt alle installierten Pakete zurück in debs und erstellt
# auf Basis des debian netinst-ISOs eine InstallationsISO mit eben den Paketen
# dieses Rechners. - mehr kann es derzeit nicht.
# ABER:
# => Nichtmal die Installation läuft durch. Weder etch noch lenny wollen laufen.
# => Ich breche hier ab und nehme simple-cdd.
#
# Was dieses Script aber gut kann, ist die installierten Pakete einzutüten in
# debs und in eine valide Ordnerstruktur zu packen. Als zusätzliche CD für
# apt-cdrom eignet sie sich allemal.
#
###############################################################################
# Copyright (C) 2009 Thorsten Strusch <post@thorstenstrusch.de>
###############################################################################
# GPL2
# This program 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 2 of the License, or (at your option) any later
# version.
#
# 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
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
###############################################################################

# Proxy?
#export http_proxy="http://proxy:8080"

# Verzeichnisse:
# deb_src       hier kannst du Pakete reinlegen, die mit in das ISO sollen  <---
# debsrc        hier legt dpkg-repack die zusammengebauten Debianpakete ab
# netinst-iso   hier liegt das debian iso, welches als Ausgangsimage dient
# netinst-loop  hierher wird das image gemountet
# iso-build     hier wird die CD zusammengebaut
# iso           hier liegt das fertige Image (CD oder DVD)
mkdir -p netinst-{iso,loop} deb{src,_cust} iso{,-build/db}

# Die Farben:
GRUEN="\033[0;42;34m"
ROT="\033[0;0;31m"
EXIT="\033[0;0;39m"
#

if [ $UID -ne 0 ] ; then
  echo -e "${ROT}$0 bitte als root aufrufen${EXIT}"
  exit 1
fi

# XXX
# auf alle benötigte Software testen:
# · wget
# · awk
# · dpkg-repack
# · apt-utils
# . genisoimage
# · rsync
# · loop-support möglich?

export MYOLDPWD=$PWD
export BASEPWD=$(dirname $(readlink -f $0))

# trap setzen
on_exit() {
	set +e
	cd $BASEPWD
	echo -e "${GRUEN}exit: Ich räume nicht vollständig erstellte Paketreste aus dem Weg${EXIT}"
	rm -rf  ${BASEPWD}/debsrc/dpkg-repack-* 2>/dev/null
	rm $TMPFILE 2>/dev/null
	echo -e "${GRUEN}exit: Ich umounte das ISO${EXIT}"
	umount ${BASEPWD}/netinst-loop 2>/dev/null
	echo -e "${GRUEN}exit: Schönen Tag noch =)${EXIT}"
	cd $MYOLDPWD
}

trap on_exit EXIT

export ARCHITECTURE=$(dpkg --print-architecture)
KERNEL=$(uname -r)
export KERNEL=${KERNEL%%-*}

export DEBVERSION=$(cat /etc/debian_version)
# Seit lenny steckt das Release mit drin (z.B. 5.0.1), ich brauche nur die 1. 3 Zeichen:
export DEBVERSION3=${DEBVERSION:0:3}

# Name des netinst.iso bestimmen
case $DEBVERSION3 in
	3.0) # woody
		echo -e "${ROT}sorry unter woody habe ich das Script nicht ausprobiert.\n
		dpkg-repack gibts hier noch nicht und auch der d-i war noch nicht soweit.${EXIT}"
		DEBIANNAME="woddy"
		exit 1
		;;
	3.1) # sarge
		echo -e "${ROT}sorry unter sarge habe ich das Script nicht ausprobiert.\n
		evtl. später mal.${EXIT}"
		DEBIANNAME="sarge"
		exit 1
		;;
	4.0) # ein etch System - derzeit old-stable
		echo -e "${GRUEN}Ich schaue online nach, wie das aktuellste release für etch lautet.\nWenn es hier hängt, trag den Proxy ein!${EXIT}"
		# XXX den tail und tr Aufruf durch awk ersetzen
		export RELEASE=$(wget -O - http://cdimage.debian.org/cdimage/archive/ 2>/dev/null | awk -F \" '/4.0/ {print $6}' | tail -1 | tr -d '4.0_/')
		case $KERNEL in
			2.6.18) # Standard kernel erkannt
				ISOSRC="debian-40${RELEASE}-${ARCHITECTURE}-netinst.iso"
				;;
			2.6.24) # etch n a half kernel erkannt
				ISOSRC="debian-40${RELEASE}-etchnhalf-${ARCHITECTURE}-netinst.iso"
				;;
			*) # muss ein eigener kernel sein, wir nehmen die etchnhalf CD!
				ISOSRC="debian-40${RELEASE}-etchnhalf-${ARCHITECTURE}-netinst.iso"
				;;
		esac
		# Quelle der etch netinst-isos:
		ISOURL="http://cdimage.debian.org/cdimage/archive/4.0_${RELEASE}/${ARCHITECTURE}/iso-cd/"
		DEBIANNAME="etch"
		;;
	5.0) # ein lenny System - derzeit stable
		# Ich schaue nicht online nach, ich nehme den Versionsstand des Systems.
		# aus 5.0.1 mach mir ein 501 :
		RELEASE=${DEBVERSION//.}
		ISOSRC="debian-${RELEASE}-${ARCHITECTURE}-netinst.iso" 
		# XXX Solange lenny=stable ist die URL gültig, danach wirds wohl auf cdimage liegen
		ISOURL="http://ftp5.gwdg.de/pub/linux/debian/debian-cd/current/${ARCHITECTURE}/iso-cd/"
		DEBIANNAME="lenny"
		;;
	*) # jetzt ist der Bock fett
		echo -e "${ROT}Ich erkenne/unterstütze deine debian Version ($DEBVERSION) nicht!\nEine squeezy oder sid Unterstützung ist noch nicht eingebaut.${EXIT}"
		exit 1
		;;
esac

#####################################################
# Das iso wird im Unterordner netinst-iso erwartet.
# Wenn das ISO nicht da ist, zieh es auf Nachfrage:
echo -e "${GRUEN}Ich erwarte das ISO mit dem Namen ${ISOSRC} im Ordner ${BASEPWD}/netinst-iso/${EXIT}"
if [ ! -f "${BASEPWD}/netinst-iso/${ISOSRC}" ] ; then
	echo -e "${ROT}Das netinst-ISO ($ISOSRC) ist nicht im Ordner ${BASEPWD}/netinst-iso/\n${GRUEN}- soll ich es laden von ${ISOURL} (130-160MB)? ${EXIT}"
	echo -n "(y/N)"
	OPTION=""; read OPTION
		case "$OPTION" in
	    y|Y|j|J)  wget -O ${BASEPWD}/netinst-iso/${ISOSRC} ${ISOURL}/${ISOSRC}
				# XXX wie ist der exit Status $? - hat der download funktioniert?
				;;
			*)  echo -e "${ROT}Bitte leg das Image als ${BASEPWD}/netinst-iso/${ISOSRC} ab${EXIT}" 
					exit 1
				;;
		esac
fi
echo -e "${GRUEN}Ok, das ISO ist da${EXIT}"

sleep 1
echo -e "${GRUEN}Ich mounte${EXIT}"
mount -oloop ${BASEPWD}/netinst-iso/${ISOSRC} netinst-loop
echo -e "${GRUEN}Ist gemountet${EXIT}"

cd ${BASEPWD}

echo -e "${GRUEN}Ich kopiere den Installer auf die Platte${EXIT}"
rsync -rav netinst-loop/ iso-build/
find ${BASEPWD}/iso-build/ -type d -exec chmod 775 {} \;
find ${BASEPWD}/iso-build/ -type f -exec chmod 664 {} \;
echo -e "${GRUEN}Das Kopieren hat geklappt.${EXIT}"

cd ${BASEPWD}/iso-build/pool
echo -e "${GRUEN}Ich setze die Rechte neu und verschiebe die Dateien unnötig hin und her...${EXIT}"
mkdir -p udeb deb 
find main -name "*.udeb" -exec mv {} udeb/ \;
find main -type f -exec mv {} deb/ \; 
if [ "$DEBIANNAME" == "etch" ]; then
	find contrib -type f -exec mv {} deb/ \; 
fi

# bisherige Struktur in main löschen und wieder anlegen:
rm -r  main/ 
mkdir -p main main/{custom,{,u}deb}

##########################################################
# Jetzt die lokal installierten Programme wieder einpacken
#
# Damit die Namen komplett erscheinen
export COLUMNS=220
#
# Das Paket dpkg-repack muss vorhanden sein:
#
echo -e "${GRUEN}Prüfe auf das Paket dpkg-repack...${EXIT}"
test -r "$(which dpkg-repack)" || " echo -e "${ROT}Das Packet dpkg-repack ist nicht installiert!\n\(Gibt es erst ab sarge\)${EXIT}" ; exit 0 "

cd ${BASEPWD}/debsrc

TMPFILE=$(mktemp dpkg-l_Liste.XXXXXX) || " echo -e "${ROT}Das Tool mktemp ist nicht installiert${EXIT}" ;exit 0 "
#
##Die installierte Packetliste erzeugen:
##
dpkg -l '*' | awk '/^ii/ { print $2 }' >> $TMPFILE
##
## und nun gehts los:
##
LINES=$(wc -l $TMPFILE | cut -d " " -f1)
echo -e "${GRUEN}\nEs sind $LINES Pakete zu bauen.${EXIT} \n"
sleep 1
## XXX Wenn die Pakete schonmal erstellt wurden bis zum nächsten XXX Marker auskommentieren - ѕpart Zeit.

y=0
while read package ; do
	PaketName="$(apt-cache show $package |  awk -F '/' '/Filename/ { print $5 }')"
	# Architecture kann all oder i386/amd64 sein
	PArchitecture="$(apt-cache show $package | awk  '/^Architecture/ { print $2 }')"
	[ a"$PaketName" == "a" ] && PaketName="$package"
	let y=y+1
	echo -e "Paket ${GRUEN} ${y} ${EXIT} von ${GRUEN}${LINES} ${EXIT}heisst ${ROT} $i (${PaketName}) ${EXIT}"
	if [ ! -e "$PaketName" ] ; then
		echo -e "${GRUEN}Das Paket wird $PaketName gebaut.${EXIT}"
	 dpkg-repack --arch=$PArchitecture $package 
	else
		echo -e "${GRUEN}Das Paket $PaketName ist schon da.${EXIT}"
	fi
done < $TMPFILE
###########################################################
# etch only:
# würgaround, wenn ssmtp installiert ist, fehlt dem d-i
# komischerweise exim4 - also laden wir es herunter
aptitude download exim4 exim4-base exim4-daemon-light exim4-config
###########################################################
# jetzt die Pakete kopieren
#
cd ${BASEPWD}
echo -e "${GRUEN}Ich kopiere die ${LINES} Pakete nun in die CD-Struktur - das dauert!${EXIT}!"
cp ${BASEPWD}/debsrc/*deb ${BASEPWD}/iso-build/pool/main/deb

## XXX <-- nächster Marker ;-)

## XXX nur lokale debs kopieren, wenn welche abgelegt wurden 
echo -e "${GRUEN}Ich kopiere evtl. vorhandene Pakete aus deb_src in die CD-Struktur.${EXIT}!"
# XXX einen check ob überhaupt debs in dem Ordner sind einfügen:
cp ${BASEPWD}/deb_custom/*deb ${BASEPWD}/iso-build/pool/main/custom/ 2>/dev/null


###########################################################
# Jetzt die ursprünglichen Netinst-Pakete rüberkopieren. 
# Hier ist wohl wichtig, dass sie unverändert auf der CD liegen:
# (Ich überschreibe absichtlich ggfls die per dpkg-repack erzeugten Versionen)
cd ${BASEPWD}/iso-build/pool
mv udeb main/
mv deb/* main/deb/
rmdir deb

###########################################################
# die apt-ftparchive configs bauen
#

cd ${BASEPWD}/iso-build
# wir haben nur main - auf etch gibt es noch contrib
#rm -r ./dists/${DEBIANNAME}/contrib/ 2>/dev/null

cat > apt-ftparchive-${ARCHITECTURE}.conf << EOF
Dir {
        ArchiveDir "./";
        CacheDir "./db/";
};

Default {
        Packages::Compress ". gzip bzip2";
        Sources::Compress ". gzip bzip2";
        Contents::Compress ". gzip bzip2";

        Packages {
                Extensions ".deb";
        };
};

TreeDefault
{
        Packages "\$(DIST)/\$(SECTION)/binary-\$(ARCH)/Packages";
        Directory "pool/\$(SECTION)";
        Contents "\$(DIST)/Contents-\$(ARCH)"
};


Tree "dists/${DEBIANNAME}"
{
        Sections "main";
        Architectures "${ARCHITECTURE}";
};


BinDirectory "pool/main" {
}; 
EOF

cat > apt-ftparchive-di.conf << EOF
Dir {
  ArchiveDir "./";
  CacheDir "./db/";
};

Default {
  Packages::Compress ". gzip";

  Packages {
    Extensions ".udeb";
  };
};

TreeDefault
{
  Packages "\$(DIST)/\$(SECTION)/debian-installer/binary-\$(ARCH)/Packages";
  Directory "pool/\$(SECTION)";
   Contents "\$(DIST)/Contents-udeb"
};

Tree "dists/${DEBIANNAME}"
{
  Sections "main";
  Architectures "${ARCHITECTURE}";
};


BinDirectory "pool/main" {
};

EOF

cat > apt-release-${ARCHITECTURE}.conf << EOF
APT::FTPArchive::Release::Origin "Thorsten Strusch";
APT::FTPArchive::Release::Label "custom Debian DVD Repository";
APT::FTPArchive::Release::Suite "stable";
APT::FTPArchive::Release::Codename "${DEBIANNAME}";
APT::FTPArchive::Release::Architectures "${ARCHITECTURE}";
APT::FTPArchive::Release::Components "main";
APT::FTPArchive::Release::Description "custom Debian DVD Repository";
EOF

###########################################################
# apt-ftparchive seine Arbeit verrichten lassen
#
cd ${BASEPWD}/iso-build
echo -e "${GRUEN}apt-ftparchive erzeugt die index-Dateien für die Pakete.${EXIT}"
apt-ftparchive generate apt-ftparchive-${ARCHITECTURE}.conf
sleep 1

echo -e "${GRUEN}apt-ftparchive erzeugt die index-Dateien für den Installer.${EXIT}"
apt-ftparchive generate apt-ftparchive-di.conf
sleep 1

apt-ftparchive -c apt-release-${ARCHITECTURE}.conf release dists/${DEBIANNAME}/ > dists/${DEBIANNAME}/Release
# head weil ich unter etch die md5-Summen nicht abschalten kann :-/
apt-ftparchive -c apt-release-${ARCHITECTURE}.conf release dists/${DEBIANNAME}/main/binary-${ARCHITECTURE}/ | head -8 >\
 dists/${DEBIANNAME}/main/binary-${ARCHITECTURE}/Release
apt-ftparchive -c apt-release-${ARCHITECTURE}.conf release dists/${DEBIANNAME}/main/debian-installer/binary-${ARCHITECTURE}/ | head -8 >\
 dists/${DEBIANNAME}/main/debian-installer/binary-${ARCHITECTURE}/Release
# auch auf der lenny CD gibt es einen contrib-Ordner:
apt-ftparchive -c apt-release-${ARCHITECTURE}.conf release dists/${DEBIANNAME}/contrib/binary-${ARCHITECTURE}/ | head -8 >\
 dists/${DEBIANNAME}/contrib/binary-${ARCHITECTURE}/Release

# Die CD soll später als Unofficial in der sources.list auftauchen:
DISKINFO=$(cat ${BASEPWD}/iso-build/.disk/info)
echo -n "${DISKINFO%%-*} - Unofficial ${ARCHITECTURE} Binary - $(date -I)" > ${BASEPWD}/iso-build/.disk/info

#####################################################################
# Die md5 Summe Erstellen, ansonsten erkennt der d-i die DVD nicht an
#
cd ${BASEPWD}/iso-build
md5sum $(find ! -name "md5sum.txt" ! -path "./isolinux/*" ! -path "./windows/*" -follow -type f) > md5sum.txt

###########################################################
# das Medium mastern
###########################################################
# das Image enthält keine .svn Ordner und nicht den db caching Ordner von apt-ftparchive:
genisoimage -l -r -J -cache-inodes -v -V "custom-debian-$DEBVERSION-$(date -I)" -input-charset utf-8 -no-emul-boot \
-boot-load-size 4 -boot-info-table -b isolinux/isolinux.bin -c isolinux/boot.cat -hide-rr-moved \
-m ".svn" -m "db" -o ${BASEPWD}/iso/custom-debian-$DEBVERSION-$(date -I).iso  ${BASEPWD}/iso-build/

exit 0
Wie gehts weiter?
 · isolinux.cfg anpassen
 · /etc sichern
 · debconf-Einstellungen sichern, später einspielen
 · optional 
     LDAP & mysql & home sichern und mit auf die DVD packen
 · isolinux Screen anpassen (evtl. mit uuencode/uudecode hier im Script arbeiten?)
 · preseed-auto-Datei für root-Passwort zur Verfügung stellen!
 · Script einbinden, welches das System exakt so neu aufzieht
   (beim 1. Booten in inittab/runonce weitere Dinge erfragen)

# vim: set ts=2 background=dark number: