summaryrefslogblamecommitdiffstats
path: root/data/openslx-install
blob: 1c943efa421f92523add1ec5ae9259be5201706c (plain) (tree)
1
2
3
4
5
6
7
8
9








                                       
                                       












































                                                                                                                                                                               











                                                                                                                                      







                                                                                                                     

                                                                                                                                                                                                  













                                                                                          



















                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      

                                       
        




































                                                                                                                            


                                        

                                                                                        



                                                                                
              





















                                                                                                                            
                                                                                  








                                                                             
 
                                                                                                      

                        









                                                                                                 
 





                                                                                                                           


































































                                                                                                                        

                                              

                                         







                                                                     
                             
 

                                                          




                                                      
                                             
                        
                                      

                                

       


                             







                                                                                                 
        
                                  
 
#!/bin/bash

function print ()
{
	echo -e "\033[01;29m$@\033[00m"
}

function error ()
{
	echo -e "\033[01;31m$@\033[00m"
	exit 1
}

function getinput ()
{
	[ $# -ne 2 ] && error "getinput called with wrong parameter count ($@)"
	CURRENT_VAR="$2"
	echo -n -e "\033[01;29m$1 [${!CURRENT_VAR}]:\033[00m "
	read RETVAL
	[ -z "$RETVAL" ] && RETVAL="${!CURRENT_VAR}"
}

function accept ()
{
	[ -z "$CURRENT_VAR" ] && error "accept called when CURRENT_VAR is empty"
	eval "$CURRENT_VAR='$RETVAL'"
	CURRENT_VAR=""
	break
}

function deny ()
{
	print "Ungültige Eingabe: '$RETVAL'"
}

function yesno ()
{
	while true; do
		echo -n -e "\033[01;29m$@ [J/n] "
		read KEYPRESS
		[ -z "$KEYPRESS" ] && return 0
		[[ "$KEYPRESS" == J* || "$KEYPRESS" == j* ]] && return 0
		[[ "$KEYPRESS" == N* || "$KEYPRESS" == n* ]] && return 1
		print "Bitte mit J oder N antworten"
	done
}

function save_defaults ()
{
	echo -e "# OpenSLX-NG defaults for this server - saved from a previous run of openslx-install\n# Delete this file if you want to start from scratch" > "$DEFAULTS_FILE"
        for VARNAME in ${!SLX_*}; do
                echo "$VARNAME='${!VARNAME}'" >> "$DEFAULTS_FILE"
        done
}

function check_password ()
{
	[ $# -lt 1 ] && error "No user given to check_password"
	[ $# -lt 2 ] && error "No password given to check_password"
	[ ! -r /etc/shadow ] && return 1
	local correct=$(< /etc/shadow awk -v "user=$1" -F : 'user == $1 {print $2}')
	local prefix=${correct%"${correct#\$*\$*\$}"}
	local supplied="$(perl -e "print crypt('$2', '$prefix')")" # el cheapo: do not pass a password containing a single quote ( ' )
	[ "x$supplied" = "x$correct" ] && return 0
	return 1
}

# Load "Factory defaults" first
FACTORY_DEFAULTS_FILE="/opt/openslx/server-factory-defaults"
if [ -s "$FACTORY_DEFAULTS_FILE" ]; then
	. "$FACTORY_DEFAULTS_FILE" || error "Factory defaults konnten nicht geladen werden. ($FACTORY_DEFAULTS_FILE)"
fi
# Load presets/previously given replies
DEFAULTS_FILE="/opt/openslx/server-defaults"
if [ -s "$DEFAULTS_FILE" ]; then
	. "$DEFAULTS_FILE" || error "Voreinstellungen aus vorherigem Skriptdurchlauf konnten nicht geladen werden. Bitte die Datei $DEFAULTS_FILE überprüfen und reparieren oder ggf. löschen."
	print " *** Voreinstellungen aus vorherigem Skiptaufruf ($SLX_LAST_INVOCATION) gefunden"
	print " *** Diese Einstellungen werden als Standard-Antwort auf alle Fragen"
	print "     angenommen. Um dieses Setup mit den ursprünglichen Standardantworten"
	print "     auszuführen, die Datei $DEFAULTS_FILE löschen."
	print " *** Das Setup kann mit Strg+C abgebrochen werden."
	print ""
fi

print "OpenSLX-NG Server Preview: Setup"
print ""
print "Zum erfolgreichen Aufsetzen eines OpenSLX-NG Servers müssen"
print "einige Fragen beantwortet werden."
print ""

#
# ---- Ask if the private key of Uni Freiburg should be accepted for root logins
#
if [ ! -s "/root/.ssh/authorized_keys" ] || ! grep "openslx-admin@uni-freiburg.de" "/root/.ssh/authorized_keys" > /dev/null; then
	print ""
	print "Soll der Private Key der bwLehrpool-Abteilung in Freiburg für root-Logins auf"
	print "diesem Server zugelassen werden? Dadurch ist es für die Entwickler aus Freiburg"
	print "möglich, sich ohne Kenntnis des Passworts als root auf diesem Server einzuloggen."
	if yesno "Dies vereinfacht die Fernwartung, Fehlerdiagnose und -behebung."; then
		if mkdir -p "/root/.ssh" \
		&& chmod 0700 "/root/.ssh" \
		&& echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC667v6bIksFcwE6DMFs65ySfjySSn9V44GoN7qzIOUok/fgOsiotq2HJby/cgQxGVKogVmGUDRUqK3lKSqYnDmEigP3aQdleP1NFx6ex/zhEUoHp4VfqfQncSZT1zYE5IGQ9YNERrsDEI0YOZ5Cr+/I3p0bJAbXZM9dk/1Y6VOyMt1ZHXam5VvC6EJnJQzW9uAS69JSezprRsDYH+3NGd/XV/INkOsPIvkLc8rp5rtcdHrq/7NPNqtTCUdChv5F5lNMMHyXlhaM9FjG/DOZ0teKzh8MMe3oUXg/VibqEPZK4zVBKypATlWdv6zODiMrbi4n/Vm9IMA5i/71NW2GOdH openslx-admin@uni-freiburg.de" >> "/root/.ssh/authorized_keys" \
		&& chmod 0600 "/root/.ssh/authorized_keys"; then
			print "Key erfolgreich hinzugefügt"
		else
			error "Fehler beim Hinzufügen des Keys!"
		fi
	fi
fi

#
# ---- Haupt-Adresse (zwecks iPXE) ----
#
print ""
print "Zum Einrichten der iPXE-Funktionalität muss die IP-Adresse des Servers"
print "festgelegt werden. Alle Clients werden über diese Adresse bedient."
print "WICHTIG: Sollte sich die Adresse des Servers ändern, muss dieses Setup"
print "erneut ausgeführt werden."
print "Erkannte lokale Adressen:"

LOCAL_ADDRS="$(ip a | grep -E -o '^\s*inet\s+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | grep -E -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')"
echo "$LOCAL_ADDRS"

if [ -z "$SLX_LOCAL_ADDR" ] || [[ $LOCAL_ADDRS != *$SLX_LOCAL_ADDR* ]]; then
	SLX_LOCAL_ADDR=""
	for ADDR in $LOCAL_ADDRS; do
		[[ "$ADDR" == 127.* ]] && continue
		LAN_IP=$ADDR
		[[ "$ADDR" == 192.168.* ]] && continue
		[[ "$ADDR" == 10.* ]] && continue
		[[ "$ADDR" == 172.* ]] && continue
		SLX_LOCAL_ADDR=$ADDR
	done
	[ -z "$SLX_LOCAL_ADDR" ] && SLX_LOCAL_ADDR=$LAN_IP
fi

while true; do
	getinput "Primäre IP-Adresse des Servers" SLX_LOCAL_ADDR
	# syntax check
	echo "$RETVAL" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' > /dev/null || continue
	if ! ip a | grep -E "^\s*inet\s+$RETVAL/" > /dev/null; then
		print "Dieser Server scheint kein Interface zu besitzen, welches auf"
		print "die Adresse $RETVAL konfiguriert ist."
		yesno "Trotzdem diese Adresse verwenden?" || continue
	fi
	accept
done

#
# ---- NFS Share
#
# Is it a local one?
print ""
print "Bereitstellung der VMWare-Images"
print "Die Clients booten die VMWare-Images von einem NFS-Share. Dieses kann"
print "entweder auf diesem Server oder auf einem externen Server mit NFS-Zugang liegen."
print "Sofern die Images von diesem Server ausgeliefert werden sollen, wird ein"
print "zusätzlicher SMB-Server installiert, um das Aufspielen neuer Images"
print "von einem Windows-PC aus zu erleichtern."

while true; do
	getinput "Welches Setup ist erwünscht? L = Lokal, E = Extern" SLX_VM_NFS_TYPE
	# Local Server
	if [[ "$RETVAL" == L* || "$RETVAL" == l* ]]; then
		while true; do
			getinput "Lokaler Speicherort für VM-Images" SLX_VM_PATH
			if [[ "$RETVAL" != /* ]]; then
				print "FEHLER: Der Pfad muss absolut sein (mit einem / beginnen)"
				continue
			fi
			mkdir -p "$RETVAL"
			[ -w "$RETVAL" ] && accept
			print "FEHLER: Verzeichnis '$RETVAL' nicht beschreibbar."
		done
		SLX_VM_NFS="$SLX_LOCAL_ADDR:$SLX_VM_PATH"
		print "Lokaler VM-NFS-Share erreichbar unter $SLX_VM_NFS"
		SLX_VM_NFS_TYPE=L
		break # No accept here as it cannot be nested
	fi
	# External Server
	if [[ "$RETVAL" == E* || "$RETVAL" == e* ]]; then
		while true; do
			getinput "Adresse und Pfad des externen NFS-Shares für VM-Images im Format Adresse:Pfad" SLX_VM_NFS
			echo "$RETVAL" | grep -E '^\S+:\S+$' > /dev/null && accept
			print "FEHLER: Ungültiges NFS-Share-Format: $RETVAL"
		done
		print "Externer VM-NFS-Share erreichbar unter $SLX_VM_NFS"
		SLX_VM_NFS_TYPE=E
		break # No accept
	fi
	print "Ungültige Auswahl '$RETVAL'"
done # Done setting up VM NFS Server type


getinput "Adresse oder IP des NTP-Servers, mit dem die Zeit synchronisiert werden soll" SLX_NTP_SERVER
SLX_NTP_SERVER="$RETVAL"

#
# ---- Safety first: make user change root password if it is still the default ----
#
if [ "x$1" != "x--test" ] && check_password "root" "openslx-ng"; then
	print ""
	print "Aus Sicherheitsgründen sollte das root-Passwort dieses Servers geändert werden."
	while check_password "root" "openslx-ng" && yesno "Passwort jetzt ändern?"; do
		passwd
	done
fi

if yesno "Soll die aktuellste stabile Version des MiniLinux nach der Einrichtung automatisch heruntergeladen werden?"; then
	DOWNLOAD_ML=yes
else
	DOWNLOAD_ML=no
fi

print ""
print "Beginne Installation"

#
# ---- Compile iPXE ----
#
print ""
print "Erstelle iPXE Binary..."
sleep 3
cd /opt/openslx/ipxe || error "cd /opt/openslx/ipxe failed"
cat > ipxelinux.ipxe << HEREEND
#!ipxe
set use-cached 1
dhcp net0
set net0.dhcp/next-server $SLX_LOCAL_ADDR
set net0.dhcp/filename ipxelinux.0
imgload pxelinux.0
boot pxelinux.0
HEREEND
cd src || error "cd src failed"
[ -e "bin/undionly.kkkpxe" ] && unlink "bin/undionly.kkkpxe"
make bin/undionly.kkkpxe EMBED=../ipxelinux.ipxe,../pxelinux.0
[ ! -e "bin/undionly.kkkpxe" -o "$(stat -c %s "bin/undionly.kkkpxe")" -lt 80000 ] && error "Error compiling ipxelinux.0"
cp "bin/undionly.kkkpxe" "/srv/openslx/tftp/ipxelinux.0" || error "Could not write to /srv/openslx/tftp/ipxelinux.0"

#
#
#
if [[ "$SLX_VM_NFS_TYPE" == "L" ]]; then
	# Write SMB Config
cat > "/etc/samba/smb.conf" << HEREEND
[global]

workgroup = WORKGROUP
server string = OpenSLX-NG Test-Server

wins support = no
dns proxy = no
name resolve order = host

log file = /var/log/samba/log.%m
max log size = 100
syslog only = no
syslog = 0

panic action = /usr/share/samba/panic-action %d

security = user
encrypt passwords = true
passdb backend = tdbsam
obey pam restrictions = yes

domain master = no

[images]
   comment = Directory where all the VMWare Images go
   writeable = yes
   locking = no
   path = $SLX_VM_PATH
   guest ok = no
   valid users = vmware
HEREEND
	# End SMB Config
	chown -R vmware "$SLX_VM_PATH"
	# NFS Config
	echo "$SLX_VM_PATH	*(ro,async,insecure,no_root_squash,no_subtree_check)" > "/etc/exports"
	# End NFS Config
	update-rc.d samba defaults
	update-rc.d nfs-kernel-server defaults
	service samba restart
	service nfs-kernel-server restart
else # external NFS Server for VM Images is used. Disable NFS + Samba
	service samba stop
	service nfs-kernel-server stop
	for LEVEL in S 0 1 2 3 4 5; do
		update-rc.d samba disable "$LEVEL"
		update-rc.d nfs-kernel-server disable "$LEVEL"
	done
fi
print "Dienste konfiguriert."

[ ! -e "/srv/openslx/www/config.tgz" ] && openslx-settings

#
# ---- Create boottime system config ----
#
print ""
print "Schreibe Bootzeit-Konfiguration für MiniLinux"
cat > "/opt/openslx/client-config" << HEREEND
SLX_VM_NFS='$SLX_VM_NFS'
SLX_HTTP_ADDR='http://$SLX_LOCAL_ADDR'
SLX_NTP_SERVER='$SLX_NTP_SERVER'
SLX_BIOS_CLOCK='local'
HEREEND

SLX_LAST_INVOCATION="$(date)"
save_defaults

if [[ "$DOWNLOAD_ML" == yes ]]; then
	print ""
	print "Lade aktuellste Version des MiniLinux herunter"
	openslx-update
fi
print ""
print "Das MiniLinux kann jederzeit manuell durch den Befehl openslx-update aktualisiert werden."

print ""
print "Einrichtung abgeschlossen."