#!/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: