#!/bin/bash PROGNAME=$(basename $0) set -e loading() { echo "loading \"$1\" ..."; } ############################################################################## # # Hosts (in order) # ############################################################################## HOSTNAMES= # The container HOSTNAMES="$HOSTNAMES chifferi" # Non-NIS-client core systems fitst #HOSTNAMES="$HOSTNAMES lumaconi" #HOSTNAMES="$HOSTNAMES ditalini" #HOSTNAMES="$HOSTNAMES spirali" #HOSTNAMES="$HOSTNAMES nidi" # Prerequisites for totally order-independent systems #HOSTNAMES="$HOSTNAMES bavette" #HOSTNAMES="$HOSTNAMES mista" #HOSTNAMES="$HOSTNAMES anelli" # Order-independent systems #HOSTNAMES="$HOSTNAMES lasagne" #HOSTNAMES="$HOSTNAMES linguine" #HOSTNAMES="$HOSTNAMES strigoli" #HOSTNAMES="$HOSTNAMES fusilli" #HOSTNAMES="$HOSTNAMES tortellino" # DNS entries only HOSTNAMES="$HOSTNAMES rotini" ############################################################################## # # Hosts' properties # ############################################################################## rotini_IPADDR=192.168.1.1 rotini_ROLES= rotini_ROLES="$rotini_ROLES dnsentry" # Container and X/sound chifferi_IPADDR=192.168.1.40 chifferi_ROLES= #chifferi_ROLES="$chifferi_ROLES vzserver" chifferi_ROLES="$chifferi_ROLES standalonepc" chifferi_ROLES="$chifferi_ROLES trustserver" chifferi_ROLES="$chifferi_ROLES trustclient" # chifferi must provide and use file level access so that it can *install* the FTP server chifferi_ROLES="$chifferi_ROLES aptfileclient" chifferi_ROLES="$chifferi_ROLES apthttpserver" chifferi_ROLES="$chifferi_ROLES apthttpclient" chifferi_ROLES="$chifferi_ROLES aptfileserver" # Then it can provide FTP services, also to itself. #chifferi_ROLES="$chifferi_ROLES aptftpserver" #chifferi_ROLES="$chifferi_ROLES aptftpclient" chifferi_ROLES="$chifferi_ROLES displayserver" chifferi_ROLES="$chifferi_ROLES audioserver" # Is NIS client so that it can also be a login server chifferi_ROLES="$chifferi_ROLES nisserver" chifferi_ROLES="$chifferi_ROLES nntpserver" chifferi_ROLES="$chifferi_ROLES btserver" chifferi_ROLES="$chifferi_ROLES nisclient" chifferi_ROLES="$chifferi_ROLES wikiserver" chifferi_ROLES="$chifferi_ROLES svnserver" # Is login server specifically to allow access to USB devices (for which OpenVZ has # no nice solution yet) chifferi_ROLES="$chifferi_ROLES loginserver" chifferi_ROLES="$chifferi_ROLES dnsserver" chifferi_ROLES="$chifferi_ROLES dnsclient" chifferi_ROLES="$chifferi_ROLES ahbackupserver" chifferi_ROLES="$chifferi_ROLES ahbackupclient" chifferi_ROLES="$chifferi_ROLES mailserver" #chifferi_ROLES="$chifferi_ROLES mailclient" chifferi_ROLES="$chifferi_ROLES storageserver" #chifferi_ROLES="$chifferi_ROLES syslogclient" chifferi_ROLES="$chifferi_ROLES ntpserver" chifferi_ROLES="$chifferi_ROLES webserver" chifferi_ROLES="$chifferi_ROLES popserver" chifferi_ROLES="$chifferi_ROLES noipclient" chifferi_ROLES="$chifferi_ROLES btclient" # Chifferi sometimes is and sometimes isn't a automounter client, but for backups we'll assume it # is (otherwise we get a second backup of a load of stuff we don't want). chifferi_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging /vzos /vzdata" # Syslog server (logger) lumaconi_IPADDR=192.168.1.47 lumaconi_VZSERVER_HOSTNAME=chifferi lumaconi_ROLES= lumaconi_ROLES="$lumaconi_ROLES vzclient" lumaconi_ROLES="$lumaconi_ROLES trustclient" lumaconi_ROLES="$lumaconi_ROLES aptftpclient" lumaconi_ROLES="$lumaconi_ROLES apthttpclient" lumaconi_ROLES="$lumaconi_ROLES dnsclient" lumaconi_ROLES="$lumaconi_ROLES mailclient" lumaconi_ROLES="$lumaconi_ROLES ahbackupclient" lumaconi_ROLES="$lumaconi_ROLES syslogserver" lumaconi_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts" # DNS ditalini_IPADDR=192.168.1.41 ditalini_VZSERVER_HOSTNAME=chifferi ditalini_ROLES= ditalini_ROLES="$ditalini_ROLES vzclient" ditalini_ROLES="$ditalini_ROLES trustclient" ditalini_ROLES="$ditalini_ROLES aptftpclient" ditalini_ROLES="$ditalini_ROLES apthttpclient" ditalini_ROLES="$ditalini_ROLES dnsserver" ditalini_ROLES="$ditalini_ROLES dnsclient" ditalini_ROLES="$ditalini_ROLES ahbackupclient" ditalini_ROLES="$ditalini_ROLES mailclient" ditalini_ROLES="$ditalini_ROLES syslogclient" ditalini_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts" # Storage spirali_IPADDR=192.168.1.42 spirali_VZSERVER_HOSTNAME=chifferi spirali_ROLES= spirali_ROLES="$spirali_ROLES vzclient" spirali_ROLES="$spirali_ROLES trustclient" spirali_ROLES="$spirali_ROLES aptftpclient" spirali_ROLES="$spirali_ROLES apthttpclient" spirali_ROLES="$spirali_ROLES dnsclient" spirali_ROLES="$spirali_ROLES storageserver" spirali_ROLES="$spirali_ROLES ahbackupclient" spirali_ROLES="$spirali_ROLES mailclient" spirali_ROLES="$spirali_ROLES syslogclient" # /var/lib/nfs has some NFS Unix sockets that cause problems. spirali_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging /vol1 /vol2 /var/lib/nfs" # NIS nidi_IPADDR=192.168.1.44 nidi_VZSERVER_HOSTNAME=chifferi nidi_ROLES= nidi_ROLES="$nidi_ROLES vzclient" nidi_ROLES="$nidi_ROLES trustclient" nidi_ROLES="$nidi_ROLES aptftpclient" nidi_ROLES="$nidi_ROLES apthttpclient" nidi_ROLES="$nidi_ROLES dnsclient" nidi_ROLES="$nidi_ROLES nisserver" nidi_ROLES="$nidi_ROLES ahbackupclient" nidi_ROLES="$nidi_ROLES mailclient" nidi_ROLES="$nidi_ROLES syslogclient" # nidi is not a NIS/automounter client nidi_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts" # Backup (is NIS client so uses automounter so to workaround race condition at # server/client boot-time) bavette_IPADDR=192.168.1.43 bavette_VZSERVER_HOSTNAME=chifferi bavette_ROLES= bavette_ROLES="$bavette_ROLES vzclient" bavette_ROLES="$bavette_ROLES trustclient" bavette_ROLES="$bavette_ROLES aptftpclient" bavette_ROLES="$bavette_ROLES apthttpclient" bavette_ROLES="$bavette_ROLES dnsclient" bavette_ROLES="$bavette_ROLES mailclient" bavette_ROLES="$bavette_ROLES syslogclient" bavette_ROLES="$bavette_ROLES nisclient" bavette_ROLES="$bavette_ROLES ahbackupserver" bavette_ROLES="$bavette_ROLES ahbackupclient" bavette_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # Mailserver mista_IPADDR=192.168.1.46 mista_VZSERVER_HOSTNAME=chifferi mista_ROLES= mista_ROLES="$mista_ROLES vzclient" mista_ROLES="$mista_ROLES trustclient" mista_ROLES="$mista_ROLES aptftpclient" mista_ROLES="$mista_ROLES apthttpclient" mista_ROLES="$mista_ROLES dnsclient" mista_ROLES="$mista_ROLES nisclient" mista_ROLES="$mista_ROLES ahbackupclient" mista_ROLES="$mista_ROLES syslogclient" mista_ROLES="$mista_ROLES mailserver" mista_ROLES="$mista_ROLES popserver" mista_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # Production and development webserver anelli_IPADDR=192.168.1.45 anelli_VZSERVER_HOSTNAME=chifferi anelli_ROLES= anelli_ROLES="$anelli_ROLES vzclient" anelli_ROLES="$anelli_ROLES trustclient" anelli_ROLES="$anelli_ROLES aptftpclient" anelli_ROLES="$anelli_ROLES apthttpclient" anelli_ROLES="$anelli_ROLES dnsclient" anelli_ROLES="$anelli_ROLES nisclient" anelli_ROLES="$anelli_ROLES ahbackupclient" anelli_ROLES="$anelli_ROLES mailclient" anelli_ROLES="$anelli_ROLES syslogclient" anelli_ROLES="$anelli_ROLES webserver" anelli_ROLES="$anelli_ROLES wikiserver" anelli_ROLES="$anelli_ROLES apthttpserver" anelli_ROLES="$anelli_ROLES btclient" anelli_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # Login server (lasagne) lasagne_IPADDR=192.168.1.48 lasagne_VZSERVER_HOSTNAME=chifferi lasagne_ROLES= lasagne_ROLES="$lasagne_ROLES vzclient" lasagne_ROLES="$lasagne_ROLES trustclient" lasagne_ROLES="$lasagne_ROLES aptftpclient" lasagne_ROLES="$lasagne_ROLES apthttpclient" lasagne_ROLES="$lasagne_ROLES dnsclient" lasagne_ROLES="$lasagne_ROLES ahbackupclient" lasagne_ROLES="$lasagne_ROLES mailclient" lasagne_ROLES="$lasagne_ROLES nisclient" lasagne_ROLES="$lasagne_ROLES syslogclient" lasagne_ROLES="$lasagne_ROLES loginserver" lasagne_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # Login server (linguine) linguine_IPADDR=192.168.1.51 linguine_VZSERVER_HOSTNAME=chifferi linguine_ROLES= linguine_ROLES="$linguine_ROLES vzclient" linguine_ROLES="$linguine_ROLES trustclient" linguine_ROLES="$linguine_ROLES aptftpclient" linguine_ROLES="$linguine_ROLES apthttpclient" linguine_ROLES="$linguine_ROLES dnsclient" linguine_ROLES="$linguine_ROLES ahbackupclient" linguine_ROLES="$linguine_ROLES mailclient" linguine_ROLES="$linguine_ROLES nisclient" linguine_ROLES="$linguine_ROLES syslogclient" linguine_ROLES="$linguine_ROLES loginserver" linguine_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # Subversion server (strigoli) strigoli_IPADDR=192.168.1.49 strigoli_VZSERVER_HOSTNAME=chifferi strigoli_ROLES= strigoli_ROLES="$strigoli_ROLES vzclient" strigoli_ROLES="$strigoli_ROLES trustclient" strigoli_ROLES="$strigoli_ROLES aptftpclient" strigoli_ROLES="$strigoli_ROLES apthttpclient" strigoli_ROLES="$strigoli_ROLES dnsclient" strigoli_ROLES="$strigoli_ROLES ahbackupclient" strigoli_ROLES="$strigoli_ROLES mailclient" strigoli_ROLES="$strigoli_ROLES nisclient" strigoli_ROLES="$strigoli_ROLES syslogclient" strigoli_ROLES="$strigoli_ROLES svnserver" strigoli_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # News server (fusilli) fusilli_IPADDR=192.168.1.50 fusilli_VZSERVER_HOSTNAME=chifferi fusilli_ROLES= fusilli_ROLES="$fusilli_ROLES vzclient" fusilli_ROLES="$fusilli_ROLES trustclient" fusilli_ROLES="$fusilli_ROLES aptftpclient" fusilli_ROLES="$fusilli_ROLES apthttpclient" fusilli_ROLES="$fusilli_ROLES dnsclient" fusilli_ROLES="$fusilli_ROLES ahbackupclient" fusilli_ROLES="$fusilli_ROLES mailclient" fusilli_ROLES="$fusilli_ROLES syslogclient" fusilli_ROLES="$fusilli_ROLES nntpserver" fusilli_BACKUPEXCLUSIONS="/tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" # News server (tortellino) tortellino_IPADDR=192.168.1.52 tortellino_VZSERVER_HOSTNAME=chifferi tortellino_ROLES= tortellino_ROLES="$tortellino_ROLES vzclient" tortellino_ROLES="$tortellino_ROLES trustclient" tortellino_ROLES="$tortellino_ROLES aptftpclient" tortellino_ROLES="$tortellino_ROLES apthttpclient" tortellino_ROLES="$tortellino_ROLES dnsclient" # Is a NIS client 'cos will need to access storage on storage server tortellino_ROLES="$tortellino_ROLES nisclient" tortellino_ROLES="$tortellino_ROLES ahbackupclient" tortellino_ROLES="$tortellino_ROLES mailclient" tortellino_ROLES="$tortellino_ROLES syslogclient" tortellino_ROLES="$tortellino_ROLES btserver" tortellino_ROLES="$tortellino_ROLES mirrorsserver" tortellino_BACKUPEXCLUSIONS="/var/run/dbus/system_bus_socket /tmp /var/tmp /proc /sys /dev/shm /dev/pts /home /staging" ############################################################################## # # Steps (ordered) # ############################################################################## STEPS= STEPS="$STEPS install_os" STEPS="$STEPS create_key_pair" STEPS="$STEPS configure_trustserver" STEPS="$STEPS configure_trustclient" STEPS="$STEPS configure_aptfileserver" STEPS="$STEPS configure_aptfileclient" STEPS="$STEPS configure_vzserver" STEPS="$STEPS configure_standalonepc" STEPS="$STEPS configure_aptftpserver" STEPS="$STEPS configure_aptftpclient" STEPS="$STEPS perform_standard_postinstall" STEPS="$STEPS configure_dnsentry" STEPS="$STEPS configure_dnsserver" STEPS="$STEPS configure_dnsclient" STEPS="$STEPS configure_syslogserver" STEPS="$STEPS configure_syslogclient" STEPS="$STEPS configure_nisserver" STEPS="$STEPS configure_nisclient" STEPS="$STEPS configure_storageserver" STEPS="$STEPS configure_ahbackupserver" STEPS="$STEPS configure_ahbackupclient" STEPS="$STEPS configure_displayserver" STEPS="$STEPS configure_audioserver" STEPS="$STEPS configure_ntpserver" STEPS="$STEPS configure_mailserver" STEPS="$STEPS configure_mailclient" STEPS="$STEPS configure_popserver" STEPS="$STEPS configure_loginserver" STEPS="$STEPS configure_webserver" STEPS="$STEPS configure_apthttpserver" STEPS="$STEPS configure_apthttpclient" STEPS="$STEPS configure_wikiserver" STEPS="$STEPS configure_svnserver" STEPS="$STEPS configure_nntpserver" STEPS="$STEPS configure_noipclient" STEPS="$STEPS configure_btserver" STEPS="$STEPS configure_btclient" STEPS="$STEPS configure_mirrorsserver" ############################################################################## # # Role tests # ############################################################################## install_os_APPTEST='has_roles --any $HOSTNAME vzserver vzclient' create_key_pair_APPTEST='! has_roles --any $HOSTNAME dnsentry' perform_standard_postinstall_APPTEST='true' configure_displayserver_APPTEST='has_roles --any $HOSTNAME displayserver' configure_trustserver_APPTEST='has_roles --any $HOSTNAME trustserver' configure_trustclient_APPTEST='has_roles --any $HOSTNAME trustclient' configure_audioserver_APPTEST='has_roles --any $HOSTNAME audioserver' configure_ntpserver_APPTEST='has_roles --any $HOSTNAME ntpserver' configure_nisserver_APPTEST='has_roles --any $HOSTNAME nisserver' configure_nisclient_APPTEST='has_roles --any $HOSTNAME nisclient' configure_vzserver_APPTEST='has_roles --any $HOSTNAME vzserver' configure_standalonepc_APPTEST='has_roles --any $HOSTNAME standalonepc' configure_storageserver_APPTEST='has_roles --any $HOSTNAME storageserver' configure_ahbackupserver_APPTEST='has_roles --any $HOSTNAME ahbackupserver' configure_ahbackupclient_APPTEST='has_roles --any $HOSTNAME ahbackupclient' configure_mailserver_APPTEST='has_roles --any $HOSTNAME mailserver' configure_popserver_APPTEST='has_roles --any $HOSTNAME popserver' configure_mailclient_APPTEST='has_roles --any $HOSTNAME mailclient' configure_syslogserver_APPTEST='has_roles --any $HOSTNAME syslogserver' configure_syslogclient_APPTEST='has_roles --any $HOSTNAME syslogclient' configure_dnsserver_APPTEST='has_roles --any $HOSTNAME dnsserver' configure_dnsclient_APPTEST='has_roles --any $HOSTNAME dnsclient' configure_dnsentry_APPTEST='has_roles --any $HOSTNAME dnsentry' configure_loginserver_APPTEST='has_roles --any $HOSTNAME loginserver' configure_webserver_APPTEST='has_roles --any $HOSTNAME webserver' configure_svnserver_APPTEST='has_roles --any $HOSTNAME svnserver' configure_nntpserver_APPTEST='has_roles --any $HOSTNAME nntpserver' # These two procedures were called directly by the VZ server, but since # they are *only* in order to facilitate installing ftpd as part # of configure_aptftpserver(), they have been moved to there. configure_aptfileclient_APPTEST='has_roles --any $HOSTNAME aptfileclient' configure_aptfileserver_APPTEST='has_roles --any $HOSTNAME aptfileserver' configure_aptftpclient_APPTEST='has_roles --any $HOSTNAME aptftpclient' configure_aptftpserver_APPTEST='has_roles --any $HOSTNAME aptftpserver' configure_apthttpclient_APPTEST='has_roles --any $HOSTNAME apthttpclient' configure_apthttpserver_APPTEST='has_roles --any $HOSTNAME apthttpserver' configure_btserver_APPTEST='has_roles --any $HOSTNAME btserver' # It is totally irrelevent where we run the NO-IP updated; it does *not* # have to the the OpenVZ server, we just choose this 'cos we have to # choose something. configure_noipclient_APPTEST='has_roles --any $HOSTNAME noipclient' configure_btclient_APPTEST='has_roles --any $HOSTNAME btclient' configure_mirrorsserver_APPTEST='has_roles --any $HOSTNAME mirrorsserver' configure_wikiserver_APPTEST='has_roles --any $HOSTNAME wikiserver' ############################################################################## # # Other globals # ############################################################################## GENERAL_PASSWD=patch22 USE_VETH=true USE_PRECOMPILED_OPENVZ_KERNEL=true TMP_DIR=${TMP_DIR:-/var/tmp} AHDG_PACKAGE_ARCHIVE_ADMIN_CMD=$(dirname $0)/ahdg-package-archive-admin AH_PACKAGE_SYMLINK_CMD=/root/bin/ah-package-symlink AH_INSTALL_INITD_CMD=/root/bin/ah-install-initd # If you will assign roles 'ahbackupserver' and 'ahbackupclient' then # you will need these. AH_BACKUP_CMD=/root/bin/ah-backup AH_CRONJOBWRAPPER_CMD=/root/bin/ah-cronjob-wrapper DNS_DOMAIN=pasta.net NIS_DOMAIN=pasta.net #MIRRORS_ROOTDIR=/vzdata/spirali/vol1/pub/mirrors MIRRORS_ROOTDIR=/vol1/pub/mirrors ARCHIVES="mplayer debian" ARCHIVE_STAMP="lenny-20071125" ############################################################################## # # Main # ############################################################################## loading main main() { # Default values for options ADE_MSG_VERBOSELEVEL=3 # Process options while [ "X$1" != X ]; do case $1 in -d) ADE_MSG_VERBOSELEVEL=$2; shift ;; -v) ADE_MSG_VERBOSELEVEL=3 ;; --debug=*) ADE_MSG_VERBOSELEVEL=${1#*=} ;; --) shift; break ;; -*) usage ;; *) break ;; esac shift done # Guts process_all_hosts } usage() { { echo "$PROGNAME [ -d | --debug= | -v ]" } >&2 exit 1 } ############################################################################## # # Menu handlers # ############################################################################## loading process_all_hosts process_all_hosts() { local DFLT_RESPONSE I HOSTNAME RESPONSE ROLES DFLT_RESPONSE=1 while :; do # Display menu I=1 for HOSTNAME in $HOSTNAMES quit; do eval "ROLES=\$${HOSTNAME}_ROLES" #printf "%-2d %-11s (%s)\n" $I $HOSTNAME "$ROLES" printf "%-2d %-11s\n" $I $HOSTNAME I=$(expr $I + 1) done # Get selection echo -n "hostname [$DFLT_RESPONSE]: " read RESPONSE || { echo; break; } [ "X$RESPONSE" = X ] && RESPONSE=$DFLT_RESPONSE [ $RESPONSE != q -a $RESPONSE != $I ] || break # Translate number to step name I=1 for HOSTNAME in $HOSTNAMES; do [ $I != $RESPONSE ] || break I=$(expr $I + 1) done # Call process_all_steps $HOSTNAME # Decide next step DFLT_RESPONSE=$(expr $I + 1) done } loading process_all_steps process_all_steps() { local HOSTNAME ROLE DFLT_RESPONSE RESPONSE SUBSETSTEPS I HOSTNAME=$1 # Work out the limited menu to show for this host SUBSETSTEPS= for STEP in $STEPS; do debug 10 "process_all_steps: considering adding step $STEP to possible steps for host $HOSTNAME ..." eval "APPTEST=\"\$${STEP}_APPTEST\"" debug 10 "process_all_steps: step $STEP has apptest \"$APPTEST\"" if [ "X$APPTEST" = X ]; then debug 10 "process_all_steps: step $STEP has no apptest; not adding to steps for host $HOSTNAME" continue fi if eval "$APPTEST"; then debug 10 "process_all_steps: step $STEP's apptest returned zero; adding to steps for host $HOSTNAME ..." SUBSETSTEPS="$SUBSETSTEPS $STEP" else debug 10 "process_all_steps: step $STEP's apptest returned non-zero; not adding to steps for host $HOSTNAME" continue fi done DFLT_RESPONSE=1 while :; do # Display menu I=1 for STEP in $SUBSETSTEPS quit; do printf "%-2d %s\n" $I $STEP I=$(expr $I + 1) done # Get selection echo -n "step [$DFLT_RESPONSE]: " read RESPONSE || { echo; break; } [ "X$RESPONSE" = X ] && RESPONSE=$DFLT_RESPONSE [ $RESPONSE != q -a $RESPONSE != $I ] || break # Translate number to step name I=1 for STEP in $SUBSETSTEPS; do [ $I != $RESPONSE ] || break I=$(expr $I + 1) done # Invoke step $STEP $HOSTNAME # Decide next step DFLT_RESPONSE=$(expr $I + 1) done } ############################################################################## # # Step handlers # ############################################################################## install_os() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzserver; then explain_debian_installation "$@" switch_to_bridged_networking "$@" write_commented_fstab_entries "$@" ${PAGER:-less} <> /etc/X11/xorg.conf" < /etc/modprobe.d/alexis info "activating changes ..." host_exec -n $HOSTNAME "/etc/init.d/gdm start" } grant_unprompted_ssh_access_from_to() { local SRC_USERHOST DST_USERHOST SRC_USERHOST=$1 DST_USERHOST=$2 debug 10 "grant_unprompted_ssh_access_from_to: SRC_USERHOST=$SRC_USERHOST, DST_USERHOST=$DST_USERHOST" host_exec --work-around-locale -n $SRC_USERHOST "cat .ssh/id_dsa.pub" > /tmp/$PROGNAME.$$ # Actually the target host may not yet be in DNS, so this should fail. # We should not reorder the steps since putting the host in DNS - as # part of configure_trustclient() involves a *lot* of ssh'ing which # can only really comfortably be done if *this* step is done first. # The right fix would be to make this function support some sort of # --do-it-using-vzctl-exec option. host_exec --work-around-locale $DST_USERHOST "mkdir -p .ssh; cat >> .ssh/authorized_keys" < /tmp/$PROGNAME.$$ # I did put something in here to familiarise the source host with the # destination host's host key, where the destination host was referenced # by hostname, not IP address (as it would be referenced in this way # by the user. Unfortunately DNS is still not configured when this # function runs so then there is a problem. Especially because there # really is a mista.pasta.net on the internet! } loading configure_trustserver configure_trustserver() { local HOSTNAME HOSTNAME=$1 } loading configure_trustclient configure_trustclient() { local HOSTNAME TRUSTSERVER_HOSTNAME HOSTNAME=$1 # # Configure unprompted SSH access # TRUSTSERVER_HOSTNAME=`role2host trustserver` || return $? info "configuring unprompted SSH access to $HOSTNAME for $TRUSTSERVER_HOSTNAME ..." grant_unprompted_ssh_access_from_to root@$TRUSTSERVER_HOSTNAME root@$HOSTNAME } configure_aptfileserver() { local HOSTNAME HOSTNAME=$1 info "verifying archive accessibility ..." for ARCHIVE in $ARCHIVES; do host_exec -n --work-around-locale $HOSTNAME "[ -d $MIRRORS_ROOTDIR/$ARCHIVE.$ARCHIVE_STAMP ]" || error "$MIRRORS_ROOTDIR/$ARCHIVE.$ARCHIVE_STAMP: does not exist" done } configure_apthttpserver() { : } configure_aptfileclient() { local HOSTNAME HOSTNAME=$1 configure_aptclient $HOSTNAME file } configure_aptftpclient() { local HOSTNAME HOSTNAME=$1 configure_aptclient $HOSTNAME ftp } configure_apthttpclient() { local HOSTNAME HOSTNAME=$1 configure_aptclient $HOSTNAME http } configure_aptclient() { local HOSTNAME APTFILESERVER_HOSTNAME APTFTPSERVER_HOSTNAME APTHTTPSERVER_HOSTNAME HOSTNAME=$1 METHOD=$2 # Derivations APTFILESERVER_HOSTNAME=$(role2host aptfileserver) || return $? if [ $METHOD = ftp ]; then APTFTPSERVER_HOSTNAME=$(role2host aptftpserver) || return $? elif [ $METHOD = http ]; then APTHTTPSERVER_HOSTNAME=$(role2host apthttpserver) || return $? fi # Create links on the file server info "creating symlinks for per-host archive access on $APTFILESERVER_HOSTNAME ..." for ARCHIVE in $ARCHIVES; do host_exec -n --work-around-locale $APTFILESERVER_HOSTNAME "rm -f $MIRRORS_ROOTDIR/$ARCHIVE.$HOSTNAME; ln -s $ARCHIVE.$ARCHIVE_STAMP $MIRRORS_ROOTDIR/$ARCHIVE.$HOSTNAME" done if [ $METHOD = http ]; then info "creating apache config file to allow $HOSTNAME access to archive ..." { for ARCHIVE in $ARCHIVES; do echo "Alias /$ARCHIVE.$HOSTNAME/ \"/pub/mirrors/$ARCHIVE.$HOSTNAME/\"" echo "" echo " Options Indexes FollowSymLinks MultiViews" echo " AllowOverride None" echo " Order allow,deny" echo " Allow from 192.168.0.0/255.255.0.0" echo "" done } | host_exec --work-around-locale $APTHTTPSERVER_HOSTNAME "cat > /etc/apache2/conf.d/$HOSTNAME" debug 10 "configure_apthttpclient: restarting apache on $APTHTTPSERVER_HOSTNAME ..." host_exec -n --work-around-locale $APTHTTPSERVER_HOSTNAME "/etc/init.d/apache2 restart" fi # Write sources.list on the client info "writing sources.list on client ..." { for ARCHIVE in $ARCHIVES; do case $ARCHIVE in mplayer) SECTIONS="main" ;; debian) SECTIONS="main contrib non-free" ;; esac case $METHOD in file) echo "deb file:$MIRRORS_ROOTDIR/$ARCHIVE.$HOSTNAME/ lenny $SECTIONS" ;; ftp) # when the APT file:// server is installed then the APT file:// server knows the APT file:// server's IP, but when # lumaconi is installed then lumaconi does not know the APT file:// server's IP (because # the installation of the DNS server comes *after* the installation of # lumaconi). Hence the IP address. echo "deb ftp://$(host2ipaddr $APTFTPSERVER_HOSTNAME)/mirrors/$ARCHIVE.$HOSTNAME/ lenny $SECTIONS" ;; http) echo "deb http://$APTHTTPSERVER_HOSTNAME/$ARCHIVE.$HOSTNAME/ lenny $SECTIONS" ;; esac done } | host_exec --work-around-locale $HOSTNAME "cat > /etc/apt/sources.list" # Update package list on client (if we don't do this then there # will be problems when the next package comes to be installed.) info "updating package list on client $HOSTNAME ..." host_exec --work-around-locale -n $HOSTNAME "apt-get update" } configure_aptftpserver() { local HOSTNAME HOSTNAME=$1 info "configuring FTP server ..." install_deb --work-around-locale $HOSTNAME vsftpd # /home will be used as an automounter mount point so ftp's home needs to # be moved elsewhere. host_exec -n --work-around-locale $HOSTNAME "perl -pi -e 's@:/home/ftp:@:/var/local/ftp:@' /etc/passwd" host_exec -n --work-around-locale $HOSTNAME "mv /home/ftp /var/local/ftp" echo "anon_root=$MIRRORS_ROOTDIR" >> /etc/vsftpd.conf host_exec -n --work-around-locale $HOSTNAME "/etc/init.d/vsftpd restart" } configure_btserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? # Already checked: host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --privvmpages 1024000 --save" # These were copied from the loginserver, and were found to be enough, but should # be pared down (and then this comment updated) host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numfile 8192:8192 --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --othersockbuf 1024K:3072K --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --kmemsize 10240K:12288K --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numproc 128 --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numpty 32 --save" # It seems this is not enough, as it usually is; the VZ actually # needs to be restarted. restart_vz $HOSTNAME fi info "installing BitTorrent packages ..." # We need to acknowledge a license for sun-java5-jre and # sun-java5-bin; the only way I could find to do this was to # preseed debconf. But then later also this didn't work. host_exec -n $HOSTNAME "debconf-set-selections" < /var/local/azureus/azureusheadless" <<'EOF' #!/bin/sh set -e JAVA=java LAUNCHDIR=$HOME/.azureus JAR=$HOME/.azureus/Azureus2.jar JAVALIBRARYPATH=$HOME/.azureus:/usr/share/java:/usr/lib AZUREUSOPTS="--ui=console" LOGFILE=/var/log/azureus/azureus.log cd $LAUNCHDIR exec $JAVA \ -Djava.library.path=$JAVALIBRARYPATH \ -jar $JAR $AZUREUSOPTS \ < /dev/null >$LOGFILE 2>&1 EOF host_exec -n $HOSTNAME "chmod 755 /var/local/azureus/azureusheadless; chown azureus:azureus /var/local/azureus/azureusheadless" scp $AH_INSTALL_INITD_CMD $HOSTNAME:/tmp host_exec -n $HOSTNAME "/tmp/$(basename $AH_INSTALL_INITD_CMD) --service-cmd=azureus --daemon-forks=false --daemon-locks=false --chuid=azureus --pid-file=/var/run/azureus/azureus.pid ~azureus/azureusheadless \"Azureus\"" host_exec -n $HOSTNAME "/etc/init.d/azureus start > /dev/null 2>&1 < /dev/null" EOF } configure_btclient() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME webserver; then info "proxying web access to Azureus ..." host_exec -n $HOSTNAME "a2enmod proxy" host_exec -n $HOSTNAME "a2enmod proxy_http" BTSERVER_HOSTNAME=`role2host btserver` || return $? host_exec $HOSTNAME "cat > /etc/apache2/conf.d/azureus" < Order deny,allow ProxyPass http://$BTSERVER_HOSTNAME:6886/index.tmpl AuthType Basic AuthName "Dione General Services" AuthUserFile /home/alexis/doc/html/alexis-hp/.htpasswd Require valid-user Order deny,allow ProxyPass http://$BTSERVER_HOSTNAME:6886/styles/theme.css EOF host_exec -n $HOSTNAME "/etc/init.d/apache2 restart" fi if has_roles --any $HOSTNAME loginserver; then : not sure what goes here yet fi } loading explain_azureus_installation explain_azureus_installation() { export LESS=${LESS:--SX} ${PAGER:-less} <<'EOF' If you have a .azureus directory for copy from another machine do it. If not then: Run: xhost + echo $DISPLAY ssh root@ su - azureus export DISPLAY= azureus Switch from the new view to the old with: View -> Advanced View -> Search Bar View -> Tab Bar Install the following plugins: Azureus HTML WebUI DHT Scraper SafePeer Telnet Access (accepting that these be installed for the local user only) Make all the necessary configuration you need. E.g. Connect -> Incoming -> TCP listen port: 6885 Connection -> Incoming -> UDP listen port: 6885 Transfer -> 25 KB/s global max upload speed: 25 Files -> Default directory: /var/spool/azureus/incomplete Files -> Automatically download to default directory: yes Files -> Completion moving -> Directory: /var/spool/azureus Files -> Torrents -> Save .torrent files -> Directory: /var/spool/azureus/incomplete Interface -> Display -> Add passed URLs silently: yes Interface -> Display -> Add torrents silently: yes Plugins -> UPnP -> Enable UPnP: no Queue -> Max simultaneous downloads: 0 Plugins->DHT Scraper -> Enable: yes Plugins->DHT Scraper -> Port: 29000 Plugins -> HTML Web UI -> Port: 6886 Plugins -> HTML Web UI ->Access: local Plugins -> HTML Web UI ->User name: azureus Plugins -> HTML Web UI ->Password: Plugins -> HTML Web UI ->Access: 192.168.1.1-192.168.1.255 Exit out of azureus. If you have files to copy from another machine do it. On the firewall open the above specified ports. Check: /var/spool/azureus accessible from BitTorrent server ownership is correctly seen from BitTorrent server Run azureus again, as desribed above. EOF } loading perform_standard_postinstall perform_standard_postinstall() { local HOSTNAME VZSERVER_HOSTNAME HOSTNAME=$1 pgp_mit_edu_IPADDR=18.92.0.144 # apt-get update will complain without the following installed in advance. info "installing critical PGP keys ..." gpg --keyserver $(host2ipaddr pgp.mit.edu) --recv-keys 07DC563D1F41B907 gpg --armor --export 07DC563D1F41B907 | apt-key add - # This update will complain about key 07DC563D1F41B907 not being known, # despite above attempt to import keys. # http://www.debian-multimedia.org/faq.php says install # debian-multimedia-keyring, but this is a chicken and egg situation. # So we do the update twice. info "retrieving package list ..." host_exec --work-around-locale -n $HOSTNAME "apt-get update" install_deb --work-around-locale $HOSTNAME --allow-unauthenticated debian-multimedia-keyring host_exec --work-around-locale -n $HOSTNAME "apt-get update" # Somehow that leaves a couple of essential packages being marked for # removal and that will make apt-get fail to install anything else. So # fix that. (Until we reconfigure debconf to use the noninteractive front # end, we will see some debconf fallback warnings.) info "preventing removal of some essential packages which got marked for removal ..." install_deb --work-around-locale $HOSTNAME util-linux tzdata # Ensure packages installations will not go interactive info "stopping package installation from prompting ..." # debconf-utils is needed to set answers in debconf db. install_deb --work-around-locale $HOSTNAME debconf-utils echo "debconf debconf/frontend select noninteractive" | host_exec --work-around-locale $HOSTNAME "debconf-set-selections" # Badly configures locales is *very* noisy, so fix ASAP. info "fixing locales ..." # VZs don't get locales installed, physical machines do. We install it in both cases. install_deb --work-around-locale $HOSTNAME locales host_exec -n --work-around-locale $HOSTNAME "rm -f /etc/locale.gen.off; [ -f /etc/locale.gen ] && mv /etc/locale.gen /etc/locale.gen.off; ln -s ../usr/share/i18n/SUPPORTED /etc/locale.gen; locale-gen" info "fixing timezone ..." host_exec -n $HOSTNAME "echo \"Europe/Berlin\" > /etc/timezone; cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime" # Purge dselect; it is dangerous: it automatically marks all Standard # packages for installation even though we don't want them yet. info "removing dangerous packages ..." remove_deb $HOSTNAME dselect info "consistentifying installed/available packages ..." # Unfortunately simultaneously install 'at' and 'masqmail' triggers a # problem: at needs mail-transport-agent and masqmail provides this, but # this provision is not detected and so at pulls in courier mail. # Installing masqmail in advance of the other packages fixes this problem. debug 10 "perform_standard_postinstall: installing MTA ..." install_deb $HOSTNAME masqmail # Here's the subset of 'Standard' packages we install. debug 10 "perform_standard_postinstall: installing some standard packages ..." install_deb $HOSTNAME at file gettext-base less mailx pciutils perl reportbug inetutils-inetd # Here's some small extra packages we install; psmisc contains fuser and # killall. patch will be needed by this script later. debconf-utils is to # have debconf-get-selections which in turn we will use to fix locales. debug 10 "perform_standard_postinstall: installing useful/imporant packages ..." install_deb $HOSTNAME rsync host bzip2 psmisc patch debconf-utils strace time vim pdksh nfs-common subversion whois nmap telnet nullidentd eject perl-doc unzip # inetd is not restarted after nullidentd is installed host_exec -n $HOSTNAME "/etc/init.d/inetutils-inetd restart" # Here's some packages we can remove (note ssh is not # openssh-{client,server}, which are in any case installed). debug 10 "perform_standard_postinstall: removing unwanted standard packages ..." remove_deb $HOSTNAME quota ssh time traceroute tcpd nano info aptitude debug 10 "perform_standard_postinstall: stripping superfluous libraries ..." reap_orphaned_debs $HOSTNAME # # Configure basic login environment for root # info "configuring basic login environment for root ..." debug 10 "perform_standard_postinstall: fixing motd ..." host_exec -n $HOSTNAME "rm -f /etc/motd.old; mv /etc/motd /etc/motd.old; true > /etc/motd" debug 10 "perform_standard_postinstall: fixing root's .profile ..." host_exec $HOSTNAME "cat > /root/.profile" <<'EOF' [ ! -f ~/.bashrc ] || . ~/.bashrc export PAGER=less export EDITOR=vi export LESS=-X EOF debug 10 "perform_standard_postinstall: fixing root's .bashrc ..." host_exec $HOSTNAME "cat > /root/.bashrc" <<'EOF' export LS_OPTIONS='--color=auto' alias ls='ls $LS_OPTIONS' export PS1='\h\$ ' lx() { echo -e -n "\e]0;$1\a"; } [ ! -t 0 ] || [ "X$TERM" = Xlinux ] || lx $LOGNAME@`uname -n` EOF debug 10 "perform_standard_postinstall: fixing root's .vimrc ..." host_exec $HOSTNAME "cat > /root/.vimrc" <<'EOF' :syntax on :set bg=dark :set paste EOF host_exec -n $HOSTNAME "touch /root/.hushlogin" # Configure SSH to accept only public keys (minimise number of # SSh calls since DNS not set up yet and this means server is # slow to give up trying to log hostname or something like that.) host_exec -n $HOSTNAME "perl -pi -e \"s/^#?\\\s*(PermitRootLogin).*/\\\$1 yes/; s/^#?\\\s*(StrictModes).*/\\\$1 yes/; s/^#?\\\s*(RSAAuthentication).*/\\\$1 no/; s/^#?\\\s*(PubkeyAuthentication).*/\\\$1 yes/; s/^#?\\\s*(IgnoreRhosts).*/\\\$1 yes/; s/^#?\\\s*(RhostsRSAAuthentication).*/\\\$1 no/; s/^#?\\\s*(HostbasedAuthentication).*/\\\$1 no/; s/^#?\\\s*(ChallengeResponseAuthentication).*/\\\$1 no/; s/^#?\\\s*(PasswordAuthentication).*/\\\$1 no/; s/^#?\\\s*(X11Forwarding).*/\\\$1 yes/;\" /etc/ssh/sshd_config; perl -pi -e \"s/^#?\\\s*(HashKnownHosts).*/\\\$1 no/;\" /etc/ssh/ssh_config; /etc/init.d/ssh restart" } create_key_pair() { local HOSTNAME PW_OPTS [ "X$1" != X--no-password ] || { shift; PW_OPTS="-N \"\""; } HOSTNAME=$1 # FIX: openssh is not installed yet but already needed! warning "somehow openssh-server needs to be installed now (sleeping 60)" info "generating a keypair for root@$HOSTNAME ..." # Remove the existing backup server key if exists, 'cos ssh-keygen # will go interative (prompting for its removal) otherwise. rm -f $TMP_DIR/id_dsa* # Generate the keypair. This will prompt to set a password. eval "ssh-keygen -q -t dsa -f $TMP_DIR/id_dsa -C root@$HOSTNAME $PW_OPTS" info "copying locally generated keypair for root@$HOSTNAME to $HOSTNAME ..." # If the host where we are running this script already has an entry for # $HOSTNAME's IP then the ssh and scp in a moment will fail. So delete # such entries. (The sed is to prevent the '.' in IP addresses being # interpreted by perl as 'any character'. And the '.' after the '$' is to # eat the newline.) [ ! -f ~/.ssh/known_hosts ] || perl -0777 -pi -e "s/^$(host2ipaddr $HOSTNAME | sed 's/\./\\./g') .*?\$.//ms" ~/.ssh/known_hosts # Here we use ssh 'cos we want to provide an option host_exec doesn't # provide. ssh -n -o 'StrictHostKeyChecking no' $(host2ipaddr $HOSTNAME) "mkdir -p /root/.ssh" scp $TMP_DIR/id_dsa* $(host2ipaddr $HOSTNAME):.ssh/ rm -f $TMP_DIR/id_dsa* warning "probably you want to abort now, run 'eval \`ssh-agent\`; ssh-add' and then continue" } reap_orphaned_debs() { local HOSTNAME REMOVABLE_DEBS HOSTNAME=$1 info "removing superfluous libraries ..." install_deb $HOSTNAME deborphan while :; do REMOVABLE_DEBS="$(host_exec -n $HOSTNAME deborphan | paste -s -d' ')" [ "X$REMOVABLE_DEBS" != X ] || break debug 10 "perform_standard_postinstall: removing $REMOVABLE_DEBS ..." remove_deb $HOSTNAME $REMOVABLE_DEBS done } loading explain_debian_installation explain_debian_installation() { export LESS=${LESS:--SX} ${PAGER:-less} <<'EOF' Boot the 'Debian 4.0r0 (etch)' DVD. At boot prompt, select 'expert' At the 'Debian installer main menu' window, select 'Choose language' (default) At the 'Choose language' window, when prompted 'Choose a language', select 'English' (default) At the 'Choose language' window, when prompted 'Choose country, territory or area', select the appropriate location At the 'Choose language' window, when prompted 'Choose locale', select 'en_US.UTF-8' (default) At the 'Choose language' window, when prompted 'Choose other locates to be supported', select none (default) At the 'Debian installer main menu' window, select 'Select a keyboard layout' (default) At the 'Select a keyboard layout' window, when prompted 'Type of keyboard', select 'PC-style' (default) At the 'Select a keyboard layout' window, when prompted 'keymap to use', select appropriate At the 'Debian installer main menu' window, select 'Detect and mount CD-ROM' (default) At the 'Detect and mount CD-ROM' window, when prompted 'Modules to load', accept the defaults and comtinue. At the 'Detect and mount CD-ROM' window, when prompted 'Start PC card services', select 'No' (not the default) At the 'Detect and mount CD-ROM' window, when prompted 'CD-ROM detected', continue At the 'Debian installer main menu' window, select 'Load installer components from CD' (default) At the 'Load installer components from CD' window, when prompted 'Installer components to load', select 'network-console' At the 'Debian installer main menu' window, select 'Detect network hardware' (default) At the 'Detect network hardware' window, when prompted 'Modules to load', accept defaults At the 'Debian installer main menu' window, select 'Configure the network' (default) At the 'Configure the network' window, when prompted 'Auto-configure network with DHCP', select 'No' (not the default) At the 'Configure the network' window, when prompted 'IP address', enter system's IP address At the 'Configure the network' window, when prompted 'Netmask', enter system's netmask At the 'Configure the network' window, when prompted 'Gateway', enter system's gateway's IP address At the 'Configure the network' window, when prompted 'Name server addresses', enter system's nameservers' IP addresses At the 'Configure the network' window, when prompted 'Is this information correct', check it and then select 'Yes' (not the default) At the 'Configure the network' window, when prompted 'Hostname', enter system's hostname At the 'Configure the network' window, when prompted 'Domain', enter system's domain At the 'Debian installer main menu' window, select 'Configure installation remotely using SSH' (default) At the 'Configure installation remotely using SSH' window, when prompted 'Remote installation password', set a password At the 'Configure installation remotely using SSH' window, when prompted 'Re-enter to verify', set the same password again At the 'Configure installation remotely using SSH' window, when prompted 'To continue the installation ...' press ENTER From a remote location run 'ssh installer@' At the 'Configuring network-console-menu' window, when prompted Network console option', select 'Start menu' (default) At the 'Debian installer main menu' window, select 'Detect disks' At the 'Detect disks' window, when prompted 'Modules to load', accept the defaults At the 'Debian installer main menu' window, select 'Partition disks' (default) Be very careful *NOT* to format/mount those partitions which will be managed by the storage server. At the 'Partition disks' window, when prompted 'Partitioning method', select 'Manual' (not the default) *make changes as per requirements* At the 'Partition disks' window, when prompted 'Write the changes to disks', select 'Yes' (not the default) a At the 'Debian installer main menu' window, select 'Configure time zone' (default) At 'Based on your country, your time zone is ...' continue At the 'Debian installer main menu' window, select 'Configure the clock' (default) At the 'Configure the clock' window, when prompted 'Is the system clock set to UTC', select 'Yes' (default) At the 'Debian installer main menu' window, select 'Set up users and passwords' (default) At the 'Set up users and passwords' window, when prompted 'Enable shadow passwords' select 'Yes' (default) At the 'Set up users and passwords' window, when prompted 'Allow login as root' select 'Yes' (default) At the 'Set up users and passwords' window, when prompted 'Root password' set root password At the 'Set up users and passwords' window, when prompted 'Re-enter password to verify' set root password At the 'Set up users and passwords' window, when prompted 'Create a normal user account now' select 'No' (not the default) At the 'Debian installer main menu' window, select 'Install the base system' (default) At the 'Install the base system' window, when prompted 'Kernel to install', select 'linux-image-2.6.18-4-686' (not the default) At the 'Install the base system' window, when prompted 'Tool to use to generate boot initrd', select 'initramfs-tools' (default) At the 'Debian installer main menu' window, select 'Install the GRUB boot loader on a hard disk' (not the default) At the 'Install the GRUB boot loader on a hard disk' window, when prompted 'Install the GRUB boot loader to the master boot record', select 'Yes' (default) At the 'Install the GRUB boot loader on a hard disk' window, when prompted 'GRUB password' enter no password (default) At the 'Debian installer main menu' window, select 'Finish the installation' (default) remove the DVD from the drive At 'Finish the installation', continue. EOF } configure_vzserver() { local HOSTNAME HOSTNAME=$1 acquire_new_kernel $HOSTNAME vzserver install_new_kernel $HOSTNAME vzserver remove_old_kernel $HOSTNAME vzserver install_openvz $HOSTNAME vzserver install_deb $HOSTNAME gpm } configure_standalonepc() { local HOSTNAME HOSTNAME=$1 install_new_kernel $HOSTNAME standalonepc remove_old_kernel $HOSTNAME standalonepc install_deb $HOSTNAME gpm } switch_to_bridged_networking() { local HOSTNAME HOSTNAME=$1 install_deb $HOSTNAME netbase bridge-utils host_exec $HOSTNAME "cat > /etc/network/interfaces" <> /etc/sysctl.conf" <<'EOF' # START OF ADDITIONS FOR OPENVZ # On Hardware Node we generally need # packet forwarding enabled and proxy arp disabled net.ipv4.ip_forward = 1 net.ipv4.conf.default.proxy_arp = 0 # Enables source route verification net.ipv4.conf.all.rp_filter = 1 # Enables the magic-sysrq key kernel.sysrq = 1 # TCP Explict Congestion Notification #net.ipv4.tcp_ecn = 0 # we do not want all our interfaces to send redirects net.ipv4.conf.default.send_redirects = 1 net.ipv4.conf.all.send_redirects = 0 # END OF ADDITIONS FOR OPENVZ EOF # The above will not take affect until the file is reloaded. host_exec -n $HOSTNAME "sysctl -p" host_exec $HOSTNAME "cat >> /etc/modules" <<'EOF' nfs autofs4 EOF # The above will not take affect until the modules is reloaded. host_exec -n $HOSTNAME "/etc/init.d/module-init-tools start" # Start VZ host_exec -n $HOSTNAME "/etc/init.d/vz start" } loading configure_mailclient configure_mailclient() { local HOSTNAME HOSTNAME=$1 configure_mail $HOSTNAME client } loading configure_svnserver configure_svnserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi info "installing svn packages ..." install_deb $HOSTNAME subversion # This is taken from AHDG info "configuring svn ..." REPOSROOT=/staging/svn-repos SVNGROUP=svn SVNUSER=svn host_exec -n $HOSTNAME "addgroup --system $SVNUSER" host_exec -n $HOSTNAME "adduser --system --ingroup $SVNGROUP --home $REPOSROOT --shell /bin/bash --gecos \"SVN Repository Accessor\" $SVNUSER" host_exec $HOSTNAME "cat > $REPOSROOT/conf/svnserve.conf" <<'EOF' [general] password-db = passwd EOF host_exec $HOSTNAME "cat > $REPOSROOT/conf/passwd" <<'EOF' [users] EOF host_exec -n $HOSTNAME "chown -R $SVNUSER:$SVNGROUP $REPOSROOT" host_exec -n $HOSTNAME "chmod -R g+w $REPOSROOT" host_exec -n $HOSTNAME "chmod go-rwx $REPOSROOT/conf/passwd" host_exec $HOSTNAME "cat > /usr/local/bin/svncoop" <<'EOF' #!/bin/sh umask 002 exec /usr/bin/`/usr/bin/basename $0`.distrib "$@" EOF host_exec -n $HOSTNAME "chmod 755 /usr/local/bin/svncoop" host_exec -n $HOSTNAME "dpkg-divert --add --rename /usr/bin/svnserve " host_exec -n $HOSTNAME "rm -f /usr/bin/svnserve; ln -s /usr/local/bin/svncoop /usr/bin/svnserve" host_exec -n $HOSTNAME "chmod g+s $REPOSROOT/db" scp $AH_INSTALL_INITD_CMD $HOSTNAME:/tmp host_exec -n $HOSTNAME "/tmp/$(basename $AH_INSTALL_INITD_CMD) --daemon-forks=false --daemon-locks=false --chuid=$SVNUSER --daemon-args=\"-d --foreground -r $REPOSROOT\" /usr/bin/svnserve \"Subversion server\"" # For some reason the init.d script does not let SSH return. Pressing # CTRL-C is fine; svn remains running. I suspect that the init.d script # needs to either redirect its own stdin/out/err or that of su or that # of svnserve itself. host_exec -n $HOSTNAME "/etc/init.d/svnserve start < /dev/null > /dev/null 2>&1" } loading configure_nntpserver configure_nntpserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --shmpages 16384 --save" fi info "installing nntpcache packages ..." install_deb $HOSTNAME gcc-4.2 libc6-dev make scp $(dirname $0)/../lib/nntpcache* $HOSTNAME:/tmp NNTPCACHEGROUP=nntpcache NNTPCACHEUSER=nntpcache host_exec -n $HOSTNAME "addgroup --system $NNTPCACHEGROUP" host_exec -n $HOSTNAME "adduser --system --ingroup $NNTPCACHEGROUP --home /var/local/nntpcache --shell /bin/bash --gecos \"NNTP Cache Server\" $NNTPCACHEUSER" host_exec -n $HOSTNAME "rm -fr /var/local/nntpcache /usr/local/opt/nntpcache-3.0.2 /var/run/nntpcache /tmp/nntpcache-3.0.2 /etc/*.d/*nntpcache*; cd /tmp; tar xzf nntpcache-3.0.2.tar.gz; cd nntpcache*; export CC=gcc-4.2; make distclean; ./configure --prefix=/usr/local/opt/nntpcache-3.0.2 --localstatedir=/var/local; make; make install; mkdir -p /var/run/nntpcache" scp $AH_INSTALL_INITD_CMD $HOSTNAME:/tmp host_exec -n $HOSTNAME "/tmp/$(basename $AH_INSTALL_INITD_CMD) --daemon-forks=true --daemon-locks=true --pid-file=/var/run/nntpcache/nntpcache.pid.DEFAULT:119 /usr/local/opt/nntpcache-3.0.2/sbin/nntpcached \"NNTPCache\"" host_exec -n $HOSTNAME "chown -R $NNTPCACHEUSER:$NNTPCACHEGROUP /var/local/nntpcache /usr/local/opt/nntpcache-3.0.2 /var/run/nntpcache" info "configuring nntpcache ..." host_exec $HOSTNAME "perl -pi -e 's/^(Organization) .*/\$1 None/; s@^(pidFile) .*@\$1 /var/run/nntpcache/nntpcache.pid@;' /usr/local/opt/nntpcache-3.0.2/etc/nntpcache/nntpcache.config" host_exec $HOSTNAME "cat > /usr/local/opt/nntpcache-3.0.2/etc/nntpcache/nntpcache.servers" <<'EOF' news.alice-dsl.de. DEFAULT 4h 24h 2d 30m 60d 60d news.gmane.org. DEFAULT 24h 4d 4d 30m 60d 60d puce.octanews.net. DEFAULT 24h 4d 4d 30m 60d 60d %BeginGroups * news.alice-dsl.de. gmane.* news.gmane.org. oesterreich.* puce.octanews.net. EOF host_exec $HOSTNAME "cat > /usr/local/opt/nntpcache-3.0.2/etc/nntpcache/nntpcache.access" < * read,quick localhost.localdomain * read,post,filter spam.filter *.$DNS_DOMAIN * read,post * *.-.*, deny,strip * *._.* deny,strip EOF # nntpcache tries to send mails to the authors on crashing; redirect these. host_exec -n $HOSTNAME "perl -pi -e 's/^to=.*/to=root/' /usr/local/opt/nntpcache-3.0.2/libexec/nntpcache-gdb.sh" host_exec -n $HOSTNAME "/etc/init.d/nntpcached restart" } loading configure_mailserver configure_mailserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi configure_mail $HOSTNAME server } loading configure_popserver configure_popserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi info "installing POP packages ..." # This isn't well behaved; the ssh session hangs. install_deb $HOSTNAME popa3d info "configuring POP ...." } loading configure_mail configure_mail() { local HOSTNAME MODE VEID MAILSERVER_HOSTNAME HOSTNAME=$1 MODE=$2 MAILSERVER_HOSTNAME=`role2host mailserver` || return $? # masqmail should have been installed, but I saw a couple of times # that it wasn't. debug 10 "configure_mail: installing masqmail ..." install_deb $HOSTNAME masqmail procmail debug 10 "configure_mail: configuring masqmail ..." host_exec -n $HOSTNAME "hostname -f > /etc/mailname" { echo "postmaster: root" if [ $MODE = server ]; then echo "root: alexis" fi } | host_exec $HOSTNAME "cat > /etc/aliases" { echo "host_name=\"/etc/mailname\"" if [ $MODE = client ]; then echo "local_hosts=\"\"" echo "local_nets=\"\"" echo "listen_addresses=\"localhost:25\"" else echo "local_hosts=\"localhost;$MAILSERVER_HOSTNAME;*.$DNS_DOMAIN\"" echo "local_nets=\"\"" echo "listen_addresses=\"localhost:25;$MAILSERVER_HOSTNAME:25\"" fi echo "spool_dir=\"/var/spool/masqmail\"" echo "mail_dir=\"/var/mail\"" echo "log_dir=\"/var/log/masqmail\"" echo "do_queue=false" echo "use_syslog=true" echo "online_detect=file" echo "online_file=\"/var/run/masqmail-route\"" echo "mbox_default=mbox" echo "mda=\"/usr/bin/procmail -Y -d \${rcpt_local}\"" echo "alias_file=/etc/aliases" echo "alias_local_caseless=\"false\"" if [ $MODE = client ]; then echo "online_routes.nullclient = \"/etc/masqmail/nullclient.route\"" else echo "online_routes.server = \"/etc/masqmail/alexis-gmx.route\"" fi } | host_exec $HOSTNAME "cat > /etc/masqmail/masqmail.conf" { echo "mail_host = \"$MAILSERVER_HOSTNAME.$DNS_DOMAIN\"" echo "set_h_from_domain = \"$DNS_DOMAIN\"" } | host_exec $HOSTNAME "cat > /etc/masqmail/nullclient.route" host_exec -n $HOSTNAME "perl -0777 -pi -e 's/(PPP_IPPARAM|PPP_IFACE)=.*?\\n//g' /etc/default/masqmail" { echo "PPP_IFACE=xxx" if [ $MODE = client ]; then echo "PPP_IPPARAM=nullclient" else echo "PPP_IPPARAM=server" fi # This is my trick to get a route file written. } | host_exec $HOSTNAME "cat >> /etc/default/masqmail" { if [ $MODE = client ]; then echo "nullclient" else echo "server" fi } | host_exec $HOSTNAME "cat > /var/run/masqmail-route" if [ $MODE = server ]; then { echo "# conditions under which this is used" echo "allowed_mail_locals = \"alexis\"" echo "not_allowed_rcpt_domains = \"mail.i2p\"" echo "# server" echo "mail_host = \"mail.gmx.net\"" echo "do_correct_helo = true" echo "# authentication" echo "auth_name=\"cram-md5\"" echo "auth_login=\"13979910\"" echo "auth_secret=\"russia7\"" echo "# header rewriting (\"ahuxley: ...\" is for the case where I already" echo "# put ahuxley@gmx.net as the From: address and masqmail rewrites it" echo "# as ahuxley@pasta.net for some reason)." echo "map_h_from_addresses = \"alexis: Alexis Huxley ; ahuxley: Alexis Huxley \"" echo "map_return_path_addresses = \"alexis: ahuxley@gmx.net; ahuxley: ahuxley@gmx.net\"" } | host_exec $HOSTNAME "cat > /etc/masqmail/alexis-gmx.route" fi # Get route seen host_exec -n $HOSTNAME "/etc/init.d/masqmail restart" } restart_vz() { local HOSTNAME VZSERVER_HOSTNAME VEID HOSTNAME=$1 VZSERVER_HOSTNAME=`role2host vzserver` || return $? VEID=$(host2veid $HOSTNAME) || return $? host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet stop $VEID; vzctl --quiet start $VEID" # This sleep is the reason this function exists at all. sleep 10 } configure_dnsentry() { local HOSTNAME DNSSERVER_HOSTNAME IPADDR HOSTNAME=$1 DNSSERVER_HOSTNAME=$(role2host dnsserver) || return $? IPADDR=$(host2ipaddr $HOSTNAME) info "updating DNS on server ..." debug 10 "configure_dnsentry: adding A record ..." host_exec -n $DNSSERVER_HOSTNAME "perl -0777 -pi -e \"s/$HOSTNAME +A +[\\d\\.]*\\n//msg\" /etc/bind/db.$DNS_DOMAIN" printf "%-8s %-6s %s\n" $HOSTNAME A $IPADDR | host_exec $DNSSERVER_HOSTNAME "cat >> /etc/bind/db.$DNS_DOMAIN" debug 10 "configure_dnsentry: adding PTR record ..." host_exec -n $DNSSERVER_HOSTNAME "perl -0777 -pi -e \"s/\\d+ +PTR +$HOSTNAME\\.$DNS_DOMAIN\\.\\n//msg\" /etc/bind/db.192.168.1" printf "%-8s %-6s %s\n" ${IPADDR##*.} PTR $HOSTNAME.$DNS_DOMAIN. | host_exec $DNSSERVER_HOSTNAME "cat >> /etc/bind/db.192.168.1" debug 10 "configure_dnsentry: adding special records ..." info "activating updates on DNS server ..." host_exec -n $DNSSERVER_HOSTNAME "/etc/init.d/bind9 restart" } loading configure_dnsclient configure_dnsclient() { local HOSTNAME DNSSERVER_HOSTNAME HOSTNAME=$1 DNSSERVER_HOSTNAME=$(role2host dnsserver) || return $? # Add an entry in the DNS for this machine configure_dnsentry $HOSTNAME # # Fix name resolution (any proper resolv.conf at this stage is # pointless because there is still no entry in the DNS for this # machine, therefore all we do now is de-DNS it). # info "fixing name resolution ..." remove_deb $HOSTNAME resolvconf host_exec -n $HOSTNAME "rm -f /etc/resolv.conf" host_exec -n $HOSTNAME "rm -f /etc/host.conf" debug 10 "configure_dnsclient: fixing hosts ..." { echo "# The localhost entry uses domainless as default id; Alexis's preference only." echo "127.0.0.1 localhost localhost.localdomain" echo "$(host2ipaddr $HOSTNAME) $HOSTNAME.$DNS_DOMAIN $HOSTNAME" } | host_exec $HOSTNAME "cat > /etc/hosts" debug 10 "configure_dnsclient: configuring DNS on client ..." { echo "domain $DNS_DOMAIN" echo "nameserver $(host2ipaddr $DNSSERVER_HOSTNAME)" echo "search $DNS_DOMAIN" } | host_exec $HOSTNAME "cat > /etc/resolv.conf" debug 10 "configure_dnsclient: activating DNS on client ..." host_exec -n $HOSTNAME "perl -pi -e 's/^hosts:.*/hosts: files dns/' /etc/nsswitch.conf" # We can also take this chance to acquaint the host where this is # running with the DNS client's SSH host key - using the *hostname* # as the lookup key. ssh -n -o 'StrictHostKeyChecking no' $HOSTNAME "true" } loading configure_dnsserver configure_dnsserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi info "installing DNS server software ..." # dnsutils includes dig install_deb $HOSTNAME bind9 dnsutils info "configuring DNS server (without adding any hosts yet) ..." host_exec -n $HOSTNAME 'perl -pi -e "s@^(\s*)//\s*(query-source address \* port 53;)@\$1// Next line uncommented by script\n\$1\$2@" /etc/bind/named.conf.options' host_exec $HOSTNAME "cat > /etc/bind/named.conf.local" < /etc/bind/db.$DNS_DOMAIN" < /etc/bind/db.192.168.1" < /etc/exports" < $TMP_DIR/$PROGNAME.$$.crontab || true debug 10 "configure_ahbackupserver: appending entry to temporary copy of crontab ..." # Note that the crontab entry uses my wrapper to ensure correct delivery # of output when it would otherwise take so long to close the input # stream that masqmail will timeout waiting for it. echo "0 * * * * bin/ah-cronjob-wrapper \"bin/ah-backup -v --backup-all-applicable-savesets\"" >> $TMP_DIR/$PROGNAME.$$.crontab debug 10 "configure_ahbackupserver: activating temporary copy of crontab ..." host_exec $HOSTNAME "crontab -" < $TMP_DIR/$PROGNAME.$$.crontab debug 10 "configure_ahbackupserver: cleaning up ..." rm -f $TMP_DIR/$PROGNAME.$$.crontab warning "you might want to now replace $HOSTNAME:bin/ah-backup with a svnwcs and symlink, etc" } configure_ahbackupclient() { local HOSTNAME BACKUPSERVER_HOSTNAME HOSTNAME=$1 BACKUPSERVER_HOSTNAME=$(role2host ahbackupserver) || return $? # # Install client software (actually it is a server, since # the backup server is the client!) # install_deb $HOSTNAME rdiff-backup flexbackup afio # # Grant backup server unprompted access to backup client. # grant_unprompted_ssh_access_from_to root@$BACKUPSERVER_HOSTNAME root@$HOSTNAME # # Create config file for backing up this system's OS # { echo "REMOTEROOT=/" echo "REMOTEHOST=$HOSTNAME" echo "LOCALROOT=${HOSTNAME}_root" eval "echo \"EXCLUSIONS=\\\"\$${HOSTNAME}_BACKUPEXCLUSIONS\\\"\"" echo "RETENTIONPERIOD=60" echo "BACKUPTIME='0 3 * * *'" } | host_exec $BACKUPSERVER_HOSTNAME "bin/ah-backup --create-saveset ${HOSTNAME}_root" # # Some other clients have *additional* savesets. # case $HOSTNAME in spirali) { echo "REMOTEROOT=/vol1/home" echo "REMOTEHOST=$HOSTNAME" echo "LOCALROOT=${HOSTNAME}_vol1-home" echo "RETENTIONPERIOD=60" echo "BACKUPTIME='0 * * * *'" } | host_exec $BACKUPSERVER_HOSTNAME "bin/ah-backup --create-saveset ${HOSTNAME}_vol1-home" { echo "REMOTEROOT=/vol1/pub" echo "REMOTEHOST=$HOSTNAME" echo "LOCALROOT=${HOSTNAME}_vol1-pub" echo "RETENTIONPERIOD=60" echo "BACKUPTIME='0 0 * * */2'" } | host_exec $BACKUPSERVER_HOSTNAME "bin/ah-backup --create-saveset ${HOSTNAME}_vol1-pub" { echo "REMOTEROOT=/vol1/wikis" echo "REMOTEHOST=$HOSTNAME" echo "LOCALROOT=${HOSTNAME}_vol1-wikis" echo "RETENTIONPERIOD=60" echo "BACKUPTIME='0 * * * *'" } | host_exec $BACKUPSERVER_HOSTNAME "bin/ah-backup --create-saveset ${HOSTNAME}_vol1-wikis" { echo "REMOTEROOT=/vol1/svn-repos" echo "REMOTEHOST=$HOSTNAME" echo "LOCALROOT=${HOSTNAME}_vol1-svn-repos" echo "RETENTIONPERIOD=60" echo "BACKUPTIME='0 * * * *'" } | host_exec $BACKUPSERVER_HOSTNAME "bin/ah-backup --create-saveset ${HOSTNAME}_vol1-svn-repos" { echo "REMOTEROOT=/vol1/var-log-apache2" echo "REMOTEHOST=$HOSTNAME" echo "LOCALROOT=${HOSTNAME}_vol1-var-log-apache2" echo "RETENTIONPERIOD=60" echo "BACKUPTIME='0 * * * *'" } | host_exec $BACKUPSERVER_HOSTNAME "bin/ah-backup --create-saveset ${HOSTNAME}_vol1-var-log-apache2" ;; esac info "acquainting backup server with backup client's host key ..." # without this the backups will fail simply because the backup server will not know the # host key, even though it has SSH access. host_exec -n $BACKUPSERVER_HOSTNAME "ssh -n -o 'StrictHostKeyChecking no' $HOSTNAME \"true\"" } configure_ntpserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi info "installing NTP server ..." install_deb $HOSTNAME ntp info "configuring NTP ..." } configure_webserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi # # Apache # info "installing web server ..." install_deb $HOSTNAME apache2-mpm-prefork php5 php5-gd info "configuring web server ..." debug 10 "configure_webserver: stopping apache ..." host_exec -n $HOSTNAME "/etc/init.d/apache2 stop" debug 10 "configure_webserver: disabling default site ..." host_exec -n $HOSTNAME "perl -pi -e 's/allow from all/deny from all/i' /etc/apache2/sites-available/default" debug 10 "configure_webserver: configuring homes access ..." host_exec -n $HOSTNAME "perl -pi -e 's/([^\.])public_html/\$1.public_html/g' /etc/apache2/mods-available/userdir.conf" host_exec -n $HOSTNAME "perl -pi -e 's/^(\s*AllowOverride.*)/\$1 Options Indexes/g; s/^(\s*Options.*)/\$1 FollowSymLinks/g;' /etc/apache2/mods-available/userdir.conf" host_exec -n $HOSTNAME "a2enmod userdir" debug 10 "configure_webserver: configuring rewrite engine ..." host_exec -n $HOSTNAME "a2enmod rewrite" debug 10 "configure_webserver: fixing hostname lookups ..." host_exec -n $HOSTNAME "perl -pi -e 's/^(HostnameLookups).*/\$1 on/g;' /etc/apache2/apache2.conf" debug 10 "configure_webserver: becoming windows friendly ..." host_exec -n $HOSTNAME "perl -pi -e 's/^(AccessFileName).*/\$1 .htaccess htaccess.txt/g;' /etc/apache2/apache2.conf" host_exec -n $HOSTNAME "perl -pi -e 's/^()/\$1 ~ \"^(\\\\.|)ht(access|passwd)\\\$\">/g;' /etc/apache2/apache2.conf" debug 10 "configure_webserver: simplifying indexes ..." host_exec $HOSTNAME "cat > /etc/apache2/conf.d/empty" <<'EOF' Order deny,allow Allow from all EOF host_exec -n $HOSTNAME "touch /var/www/empty.txt; chmod 644 /var/www/empty.txt" debug 10 "configure_webserver: configuring PHP ..." host_exec -n $HOSTNAME "perl -pi -e 's/^;(browscap)/\$1/' /etc/php5/apache2/php.ini" debug 10 "configure_webserver: extending logfile retention ..." host_exec -n $HOSTNAME "perl -pi -e 's/(rotate)\\s+\\d+/\$1 1000/' /etc/logrotate.d/apache2" host_exec -n $HOSTNAME "rm -fr /var/log/apache2.old; mv /var/log/apache2 /var/log/apache2.old; ln -s /staging/var-log-apache2 /var/log/apache2" debug 10 "configure_webserver: starting apache ..." host_exec -n $HOSTNAME "/etc/init.d/apache2 start" } configure_wikiserver() { local HOSTNAME HOSTNAME=$1 # python-imaging needed by Gallery2 plugin install_deb $HOSTNAME python-moinmoin python-imaging MOINSWROOT=/usr MOININSTANCESROOT=/var/local/moin FARMCONFIG=/etc/moin/farmconfig.py # Taken from AHDG info "performing generic configuration for moinmoin ..." host_exec -n $HOSTNAME "perl -pi -e 's/^(\\s*)(data_dir|data_underlay_dir)/\$1#\$2/; s@(\\s*)(\\(\"mywiki.*)@\$1#\$2@;' $FARMCONFIG" host_exec -n $HOSTNAME "perl -pi -e \"s@(sitename = u')(Untitled Wiki)(')@\\\$1MOININSTANCENAME\\\$3@; s@(data_dir = ')(.*)(')@\\\$1MOININSTANCESROOT/MOININSTANCENAME/data/\\\$3@; s@(data_underlay_dir = ')(.*)(')@\\\$1MOININSTANCESROOT/MOININSTANCENAME/underlay/\\\$3@; s@(.*)(#)(page_front_page = u\\\"MyStartingPage\\\")@\\\$1\\\$3@;\" /usr/share/moin/config/wikiconfig.py" host_exec -n $HOSTNAME "echo $MOINSWROOT/share/moin/underlay/pages/*Template | xargs -n 1 echo | egrep -v 'HomepageTem|Category' | while read X; do mv \$X /var/tmp/\$(basename \$X).old; done" host_exec -n $HOSTNAME "echo \"Alias /wiki/ \\\"MOINSWROOT/share/moin/htdocs/\\\"\" > /etc/apache2/conf.d/moin" host_exec -n $HOSTNAME "perl -pi -e \"s@MOINSWROOT@$MOINSWROOT@g; s@MOININSTANCESROOT@$MOININSTANCESROOT@\" /etc/apache2/conf.d/moin" host_exec -n $HOSTNAME "/etc/init.d/apache2 reload" host_exec -n $HOSTNAME "mkdir -p $MOININSTANCESROOT/" # Instance-specific MOININSTANCENAME=AlexisWiki host_exec -n $HOSTNAME "mkdir -p $MOININSTANCESROOT/$MOININSTANCENAME/" # This is commented out because it risks overwriting my wiki. if false; then host_exec -n $HOSTNAME "cp -r $MOINSWROOT/share/moin/data $MOINSWROOT/share/moin/underlay $MOINSWROOT/share/moin/server/moin.cgi $MOININSTANCESROOT/$MOININSTANCENAME/" host_exec -n $HOSTNAME "perl -pi -e \"s@MOININSTANCENAME@$MOININSTANCENAME@g\" $MOININSTANCESROOT/$MOININSTANCENAME/moin.cgi" host_exec -n $HOSTNAME "cp $MOINSWROOT/share/moin/config/wikiconfig.py $MOININSTANCESROOT/$MOININSTANCENAME/$MOININSTANCENAME.py" host_exec -n $HOSTNAME "perl -pi -e \"s@MOINSWROOT@$MOINSWROOT@g; s@MOININSTANCESROOT@$MOININSTANCESROOT@; s@MOININSTANCENAME@$MOININSTANCENAME@g\" $MOININSTANCESROOT/$MOININSTANCENAME/$MOININSTANCENAME.py" fi host_exec -n $HOSTNAME "perl -pi -e \"s@(.*\\\"mywiki.*)@\\\$1\\n(\\\"MOININSTANCENAME\\\", r\\\".*MOININSTANCENAME.*\\\"),@\" $FARMCONFIG" host_exec -n $HOSTNAME "perl -pi -e \"s@MOINSWROOT@$MOINSWROOT@g; s@MOININSTANCESROOT@$MOININSTANCESROOT@; s@MOININSTANCENAME@$MOININSTANCENAME@g\" $FARMCONFIG" host_exec -n $HOSTNAME "chown -R www-data $MOININSTANCESROOT/$MOININSTANCENAME/" host_exec -n $HOSTNAME "echo \"ScriptAlias /MOININSTANCENAME \\\"MOININSTANCESROOT/MOININSTANCENAME/moin.cgi\\\"\" > /etc/apache2/conf.d/$MOININSTANCENAME" host_exec -n $HOSTNAME "perl -pi -e \"s@MOINSWROOT@$MOINSWROOT@g; s@MOININSTANCESROOT@$MOININSTANCESROOT@; s@MOININSTANCENAME@$MOININSTANCENAME@g\" /etc/apache2/conf.d/$MOININSTANCENAME" host_exec -n $HOSTNAME "/etc/init.d/apache2 reload" # When installing themes, don't bother installing the theme's .py file # where README.Debian says; install it in ...AlexisWiki/data/plugin/theme. } ############################################################################## # # Role-specific steps: NIS server # ############################################################################## loading configure_nisserver configure_nisserver() { local HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? fi # If we're running VZ at all then we need '-nolock' # because we're using nfs-user-server, and that doesn't # support locking. if has_roles --any $HOSTNAME vzserver vzclient; then NOLOCK="-nolock" fi STORAGESERVER_HOSTNAME=`role2host storageserver` || return $? configure_nis $HOSTNAME master info "configuring NIS server ..." # Alexis host_exec -n $HOSTNAME "addgroup --gid 1000 alexis" || true host_exec -n $HOSTNAME "adduser --no-create-home --uid 1000 --gid 1000 --gecos \"Alexis Huxley\" --disabled-password alexis" || true echo "alexis $NOLOCK $STORAGESERVER_HOSTNAME:/vol1/home/alexis" | host_exec $HOSTNAME "cat >> /etc/auto.home" host_exec -n $HOSTNAME "make -C /var/yp" # Judith host_exec -n $HOSTNAME "addgroup --gid 1001 judith" || true host_exec -n $HOSTNAME "adduser --no-create-home --uid 1001 --gid 1001 --gecos \"Judith Habgood-Everett,,,\" --disabled-password judith" || true echo "judith $NOLOCK $STORAGESERVER_HOSTNAME:/vol1/home/judith" | host_exec $HOSTNAME "cat >> /etc/auto.home" host_exec -n $HOSTNAME "make -C /var/yp" host_exec $HOSTNAME "cat >> /etc/auto.staging" <> /etc/nsswitch.conf" host_exec -n $HOSTNAME "/etc/init.d/autofs restart" # This makes life much easier for LINK in pub; do host_exec -n $HOSTNAME "rm -f /$LINK; ln -s /staging/$LINK /$LINK" done if has_roles --any $HOSTNAME vzclient; then # Hack for the automounter not invoking mount/umount with '-n' # option, and since VZs can't actually update /etc/mtab (since it # is a symlink to /proc/mounts) this is needed. info "hacking mount/umount/automount to use '-n' option ..." host_exec -n $HOSTNAME "dpkg-divert --add --rename /bin/mount" host_exec -n $HOSTNAME "dpkg-divert --add --rename /bin/umount" host_exec $HOSTNAME "cat > /bin/mount" <<'EOF' #!/bin/sh if [ "X$MOUNT_MTAB" = Xfalse -a $(/usr/bin/basename $0) = mount ]; then exec $0.distrib -n "$@" elif [ "X$MOUNT_MTAB" = Xfalse -a $(/usr/bin/basename $0) = umount ]; then exec $0.distrib -in "$@" else exec $0.distrib "$@" fi EOF host_exec -n $HOSTNAME "chmod 755 /bin/mount" host_exec -n $HOSTNAME "ln -f /bin/mount /bin/umount" host_exec -n $HOSTNAME "echo \"export MOUNT_MTAB=false\" >> /etc/default/autofs" fi host_exec -n $HOSTNAME "/etc/init.d/autofs stop" host_exec -n $HOSTNAME "/etc/init.d/autofs start" if has_roles --any $HOSTNAME vzclient; then # The NFS server has entries in its /etc/exports which # it could not resolve when the NFS server started. This # means it did not export them. Therefore when we add an # entry to DNS then we need to restart the NFS server - # if it was exporting something to this DNS client. But # at DNS-client configuration time, the dependencies # are too complicated (the NFS server hasn't even been # installed when the DNS client records are added). So # safer is that, since all NFS clients are also NIS # clients on pasta.net, we restart NFS when we configure # NIS. I.e. now. Note that this is really only a problem # that affects VZs; hence conditional. info "restarting NFS so it sees newly resolvable hostnames ..." STORAGESERVER_HOSTNAME=`role2host storageserver` || return $? host_exec -n $STORAGESERVER_HOSTNAME "/etc/init.d/nfs-user-server restart" fi # Due to the NIS server running in a VZ, we do not want to start # autofs automatically on a VZ server if has_roles --any $HOSTNAME vzserver; then info "disabling automatic startup of autofs on VZ server (depends on a as-yet-unstarted VZ client) ..." host_exec -n $HOSTNAME "update-rc.d -f autofs remove" fi } loading configure_nis configure_nis() { local HOSTNAME NISSERVER_TYPE NISMASTER_HOSTNAME HOSTNAME=$1 NISSERVER_TYPE=$2 # # Install NIS # info "installing NIS ..." # This will make the system hang as the assumption is you want to # configure a client that can broadcast. warning "expect next step to take a long time to timeout ..." NISSERVER_HOSTNAME=`role2host nisserver` # These two lines are also done after nis package is installed, but # I want to see if its preexistence speeds up the bind. They cause # a problem: 'apt-get install nis' will say 'Do you want to keep # your current version. For this reason we can't use the standard # install_deb call to install nis. echo "$NIS_DOMAIN" | host_exec $HOSTNAME "cat > /etc/defaultdomain" echo "ypserver $NISSERVER_HOSTNAME" | host_exec $HOSTNAME "cat > /etc/yp.conf" host_exec -n $WORKAROUNDLOCALE_OPTTEXT $HOSTNAME "yes n | apt-get -qq -y install nis" # # On master servers to master-specific actions. # if [ $NISSERVER_TYPE = master ]; then info "configuring as NIS master server ..." host_exec -n $HOSTNAME "perl -pi -e 's/^NISSERVER=.*/NISSERVER=master/' /etc/default/nis" # This asks some questions but seems to get it all right without help host_exec -n $HOSTNAME "/usr/lib/yp/ypinit -m" info "telling NIS to manage autofs maps ..." host_exec -n $HOSTNAME "perl -0777 -pi -e 'BEGIN{sub sf{ my(\$string,%ch)=@_; foreach (keys %ch) {\$string=~s/\$_/\$ch{\$_}/g} return(\$string);}} s/^(AUTO_LOCAL.*?\\n)/\$1.&sf(\$1,\"LOCAL\",\"STAGING\",\"local\",\"staging\")/mes' /var/yp/Makefile" host_exec -n $HOSTNAME "perl -pi -e 's@^(ALL\\s*=.*)@\$1\\nALL += auto.home auto.staging auto.master@' /var/yp/Makefile" host_exec -n $HOSTNAME "perl -0777 -pi -e 'BEGIN{sub sf{ my(\$string,%ch)=@_; foreach (keys %ch) {\$string=~s/\$_/\$ch{\$_}/g} return(\$string);}} s/^(auto\.local.*?\\n\\n)/\$1.&sf(\$1,\"LOCAL\",\"STAGING\",\"local\",\"staging\")/mes' /var/yp/Makefile" # Create basic maps host_exec $HOSTNAME "touch /etc/auto.home /etc/auto.master /etc/auto.staging" echo -e "/home auto.home\n/staging auto.staging" | host_exec $HOSTNAME "cat > /etc/auto.master" host_exec -n $HOSTNAME "make -C /var/yp" # Portmapper is needed but doesn't seem to start. host_exec -n $HOSTNAME "/etc/init.d/portmap restart" host_exec -n $HOSTNAME "/etc/init.d/nis restart" # # On clients to client-specific actions # elif [ $NISSERVER_TYPE = client ]; then # The fact that the client does not rewrite /etc/default/nis or any other # of the server specific settings, means that this function can be used to # configure a server or a server which is also a client. host_exec -n $HOSTNAME "perl -pi -e 's/^(passwd|shadow|group):.*/\$1: files nis/' /etc/nsswitch.conf" # Portmapper is needed but doesn't seem to start. The init.d script for the portmapper # uses pidof and this does not work well in OpenVZ environment (because it reports the # pids of the portmappers running also in the VZs). So instead I use my own init.d # script which is a bit more intelligent. if ! has_roles --any $HOSTNAME vzserver; then host_exec -n $HOSTNAME "/etc/init.d/portmap restart" else info "working around VZ-intolerant init.d script for portmapper ..." host_exec -n $HOSTNAME "update-rc.d -f portmap remove" scp $AH_INSTALL_INITD_CMD $HOSTNAME:/tmp host_exec -n $HOSTNAME "/tmp/$(basename $AH_INSTALL_INITD_CMD) --daemon-forks=true --daemon-locks=false --service-cmd=portmapper2 /sbin/portmap \"Portmapper (OpenVZ-tolerant)\"" host_exec -n $HOSTNAME "/etc/init.d/portmapper2 start" # But we still have the problem that actually the NIS client cannot be started # automatically on the VZ server because it depends on a NIS server which is # running in a VZ which has not been started yet! info "disabling automatic startup of portmapper2 on VZ server (depends on a as-yet-unstarted VZ client) ..." host_exec -n $HOSTNAME "update-rc.d -f portmapper2 remove" # And if portmap doesn't start automatically then there is no point in nfs-common # attempting to start (it would fail). host_exec -n $HOSTNAME "update-rc.d -f nfs-common remove" # And same with nis host_exec -n $HOSTNAME "update-rc.d -f nfs-common nis" fi sleep 2 host_exec -n $HOSTNAME "/etc/init.d/nfs-common restart" sleep 2 host_exec -n $HOSTNAME "/etc/init.d/nis restart" sleep 2 # # On slaves to slaves-specific actions (not implemented). # elif [ $NISSERVER_TYPE = slave ]; then internal "currently no support for slave NIS servers" else internal "$NISSERVER_TYPE: invalid NIS server type" fi } loading configure_syslogclient configure_syslogclient() { local HOSTNAME HOSTNAME=$1 SYSLOGSERVER_HOSTNAME=`role2host syslogserver` # Prevent boot-time hang on VZ server if has_roles --any $HOSTNAME vzserver; then SYSLOGSERVER_IPADDR=`host2ipaddr $SYSLOGSERVER_HOSTNAME` info "adding syslog server to /etc/hosts to prevent boot-time hang ..." echo "$SYSLOGSERVER_IPADDR $SYSLOGSERVER_HOSTNAME.$DNS_DOMAIN SYSLOGSERVER_HOSTNAME" | host_exec $HOSTNAME "cat >> /etc/hosts" fi # syslog server is *not* a syslog client. If it was then we would get loops! ! has_roles --any $HOSTNAME syslogserver || error "the syslog server cannot also be a syslog client" # Configure syslog client host_exec -n $HOSTNAME "echo -e \"*.*\\t@$SYSLOGSERVER_HOSTNAME\" > /etc/syslog.conf; /etc/init.d/sysklogd restart" } loading configure_syslogserver configure_syslogserver() { local HOSTNAME VZSERVER_HOSTNAME HOSTNAME=$1 if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --dgramrcvbuf 512K --save" fi # # Configure syslog server # # log server overflows sometimes. VZSERVER_HOSTNAME=`role2host vzserver` || return $? VEID=`host2veid $HOSTNAME` || return $? host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --dgramrcvbuf 256K --save" install_deb $HOSTNAME sysklogd host_exec -n $HOSTNAME "perl -pi -e \"s/SYSLOGD=\\\"\\\"/SYSLOGD=\\\"-r\\\"/\" /etc/default/syslogd" host_exec -n $HOSTNAME "/etc/init.d/sysklogd restart" } loading configure_noipclient configure_noipclient() { local HOSTNAME HOSTNAME=$1 # *someone* has to tell no-ip.com what my IP address is. # It could be anybody. We choose to use the OpenVZ server. # Unfortunately no-ip is not in lenny yet. #install_deb $HOSTNAME no-ip scp $(dirname $0)/../lib/no-ip* $HOSTNAME:/tmp host_exec -n $HOSTNAME "dpkg -i /tmp/no-ip*" warning "run '/etc/init.d/no-ip stop; no-ip -C; /etc/init.d/no-ip start' on $HOSTNAME manually now!" } install_gcc() { local HOSTNAME HOSTNAME=$1 # gcc needed to make google # (Previously we had installed 4.2, but the kernel itself is compiled # with 4.1 and therefore at least 4.1 *must* be installed; it then seems # kind of superfluous to install 4.2 as well.) install_deb $HOSTNAME gcc-4.1 g++-4.1 # This does not install a 'gcc' command, and while for most programs this # can be overruled with 'CC=gcc-4.1', this isn't always the case (e.g. # linux-uvc driver). host_exec -n $HOSTNAME "rm -f /usr/local/bin/gcc; ln -s \`which gcc-4.1\` /usr/local/bin/gcc" host_exec -n $HOSTNAME "rm -f /usr/local/bin/g++; ln -s \`which g++-4.1\` /usr/local/bin/g++" } loading configure_loginserver configure_loginserver() { local HOSTNAME VZSERVER_HOSTNAME HOSTNAME=$1 # # More disk space will be needed # if has_roles --any $HOSTNAME vzclient; then info "tuning VZ parameters ..." VEID=$(host2veid $HOSTNAME) || return $? VZSERVER_HOSTNAME=`role2host vzserver` || return $? host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --diskspace 3g --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numfile 8192:8192 --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --othersockbuf 1024K:3072K --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numtcpsock 160 --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --kmemsize 10240K:12288K --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --privvmpages 512000 --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numproc 128 --save" host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --numpty 32 --save" # Grip needs this and permanent chmod on /dev/hda to work host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --devnodes hda:rw --save" fi # Install packages info "installing packages ..." # Basic X/XFCE stuff install_deb $HOSTNAME gdm xfce4 xorg xscreensaver xterm xvfb xfce4-terminal xnest # Install all the stuff we actually want. Some packages are not signed. install_deb $HOSTNAME ascii bc evince ibritish id3v2 less lyx mgdiff ncftp nmap openoffice.org screen tightvncserver unrar vsound zip mpg321 # Graphics install_deb $HOSTNAME gphoto2 gqview gimp gnuplot jpeginfo libjpeg-progs # Firefox install_deb $HOSTNAME iceweasel flashplugin-nonfree # News, mail and other miscelleneous network clients install_deb $HOSTNAME mutt slrn mail-notification safecat fetchmail w3m wget podracer # CD-ROM/DVD stuff install_deb $HOSTNAME k3b dvdrip grip cdda2wav lame # devede wants mkisofs install_deb $HOSTNAME devede mkisofs # k2b wants dvd+rw-tools # Media players install_deb $HOSTNAME mplayer rhythmbox aumix xmms xmms-shell kmix install_deb $HOSTNAME w32codecs # mesa-utils is just to test that the displayserver has been correctly # configured. install_deb $HOSTNAME stellarium mesa-utils install_gcc $HOSTNAME # text install_deb $HOSTNAME vim-gnome acroread mozilla-acroread acroread-plugin-speech # ttf-bitstream-vera is needed for googleearth. install_deb $HOSTNAME googleearth-package ttf-bitstream-vera host_exec -n $HOSTNAME "dpkg -l googleearth > /dev/null || { CC=gcc-4.1 make-googleearth-package; dpkg -i googleearth_*.deb; rm -f GoogleEarthLinux.bin googleearth_*.deb; }" # audiooss will allow realplayer and rhythmbox to use NAS. install_deb $HOSTNAME realplayer install_deb $HOSTNAME audiooss # games install_deb $HOSTNAME gnome-games gnome-hearts # encryption install_deb $HOSTNAME bcrypt ccrypt # instant messaging install_deb $HOSTNAME pidgin pidgin-extprefs pidgin-libnotify pidgin-plugin-pack # other video apps install_deb $HOSTNAME gtk-recordmydesktop # webcam stuff install_deb $HOSTNAME ekiga libpt-plugins-v4l2 # Only VZ server and standalone machines gets webcam driver installed if has_roles --any $HOSTNAME vzserver standalonepc; then scp $(dirname $0)/../lib/linux-uvc* $HOSTNAME:/tmp host_exec -n $HOSTNAME "cd /tmp && tar xzf linux-uvc-svn151.tar.gz && cd /tmp/linux-uvc-svn151 && make clean all install" install_deb $HOSTNAME libsdl1.2-dev libjpeg62-dev scp $(dirname $0)/../lib/luvcview-20070512.tar.gz $HOSTNAME:/tmp scp $AH_PACKAGE_SYMLINK_CMD $HOSTNAME:/tmp host_exec -n $HOSTNAME "PREFIX=/usr/local && cd /tmp && tar xzf luvcview-20070512.tar.gz && cd /tmp/luvcview-20070512 && make && mkdir -p \$PREFIX/opt/\$(basename \$(pwd))/bin && make install BIN=\$PREFIX/opt/\$(basename \$(pwd))/bin && /tmp/$(basename $AH_PACKAGE_SYMLINK_CMD) \$PREFIX/opt/\$(basename \$(pwd)) \$PREFIX/bin" scp $(dirname $0)/../lib/uvccapture-0.4.tar.bz2 $HOSTNAME:/tmp scp $AH_PACKAGE_SYMLINK_CMD $HOSTNAME:/tmp host_exec -n $HOSTNAME "PREFIX=/usr/local && cd /tmp && tar xjf uvccapture-0.4.tar.bz2 && cd /tmp/uvccapture-0.4 && make && mkdir -p \$PREFIX/opt/\$(basename \$(pwd))/bin && make install PREFIX=\$PREFIX/opt/\$(basename \$(pwd))/bin && /tmp/$(basename $AH_PACKAGE_SYMLINK_CMD) \$PREFIX/opt/\$(basename \$(pwd)) \$PREFIX/bin" fi # MIDI keyboard stuff (rosegarden complains if flac and lilypond not found); for the rest # they can only be used on a machine capable of playing accessing USB hardware, but we install # even on VZs simply for uniformity. install_deb $HOSTNAME timidity freepats playmidi pmidi fluidsynth rosegarden unrar flac lilypond if has_roles --any $HOSTNAME vzserver standalonepc; then # Timidity will not start unless snd_seq_midi is # loaded. This module is loaded automatically if the # MIDI keyboard is attached, but if it is not, then # timidity on its own won't load it and will fail # to start. We can force loading the module though. host_exec $HOSTNAME "echo \"snd_seq_midi\" >> /etc/modules" # The 'rtc' module causes some problems with timidity. Specifically the following message # a million times: # # rtc: lost some interrupts at 1024Hz. # rtc: lost some interrupts at 1024Hz. # rtc: lost some interrupts at 1024Hz. # rtc: lost some interrupts at 1024Hz. # Forcing loading of the genrtc module instead of the rtc module seems to fix # this although - according to my AHDG document - genrtc gives problems with chronyd. host_exec $HOSTNAME "echo \"install rtc /sbin/modprobe genrtc\" > /etc/modprobe.d/timidity" # Timidity does not release the audio device and so it causes problems with nas. So # better do not start it by default. #host_exec -n $HOSTNAME "perl -pi -e 's/^#?(TIM_ALSASEQ)=.*/\$1=true/' /etc/default/timidity" #host_exec -n $HOSTNAME "/etc/init.d/timidity restart" fi # Synaptic and other package management tools install_deb $HOSTNAME synaptic apt-file alien # LaTeX install_deb $HOSTNAME texlive texlive-latex-extra # For reasons unknown the last installs leave a lot of orphaned libs. reap_orphaned_debs $HOSTNAME # Tell GDM to listen for remote connections. - FIX: this is not reentrant! host_exec -n $HOSTNAME "perl -pi -e \"s/(\\[daemon\\])/\\\$1\\nRemoteGreeter=\\/usr\\/lib\\/gdm\\/gdmgreeter/; s/(\\[xdmcp\\])/\\\$1\\nEnable=true/; s/(\\[security\\])/\\\$1\\nDisallowTCP=false/;\" /etc/gdm/gdm.conf" # GDM needs to be restarted but if the machine on which it needs to be # restarted is providing the X session then this would kill that session # at the 'stop' part of restarting, this script would immediately exit # and the 'start' would not be called. So you have to do it yourself! warning "gdm must NOW be restarted manually on $HOSTNAME!" # Login servers are places where we can run web browsers and web browsers will # want to go to the internal web server, not the true dione.no-ip.org, which is # my DSL router. host_exec -n $HOSTNAME "perl -0777 -pi -e 's/[^\n]*dione\.no-ip\.org.*?\n//msg' /etc/hosts" WEBSERVER_HOSTNAME=`role2host webserver` || return $? WEBSERVER_IPADDR=`host2ipaddr $WEBSERVERHOSTNAME` || return $? host_exec -n $HOSTNAME "echo \"$WEBSERVER_IPADDR dione.no-ip.org\" >> /etc/hosts" } ############################################################################## # # Support functions # ############################################################################## loading role2host role2host() { local ROLE HOSTNAME HOSTNAME_ROLE HOSTNAME_ROLES FOUND ROLE=$1 debug 4 "role2host: ROLE=$ROLE, HOSTNAMES=\"$HOSTNAMES\"" FOUND=false for HOSTNAME in $HOSTNAMES; do debug 200 "role2host: checking if $HOSTNAME's role is $ROLE ..." eval "HOSTNAME_ROLES=\"\$${HOSTNAME}_ROLES\"" for HOSTNAME_ROLE in $HOSTNAME_ROLES; do debug 200 "role2host: checking if $HOSTNAME's role $HOSTNAME_ROLE is $ROLE ..." [ "X$ROLE" != "X$HOSTNAME_ROLE" ] || { echo $HOSTNAME; FOUND=true; } done done $FOUND } loading host2veid host2veid() { local VZSERVER_HOSTNAME LAST_VEID HOST HOST=$1 debug 4 "host2veid: sof (HOST=$1)" VZSERVER_HOSTNAME=`role2host vzserver` || return $? debug 4 "host2veid: VZSERVER_HOSTNAME=$VZSERVER_HOSTNAME" # From vzlist output strip header line and take last line's first field VEID=`host_exec -n $VZSERVER_HOSTNAME "vzlist -a" | sed -n "s/^ *\([0-9][0-9]*\) .* $HOST/\1/p"` debug 4 "host2veid: VEID=$VEID" [ "X$VEID" != X ] || internal "host2veid: could not determine VEID for host $HOST" echo $VEID } get_next_free_veid() { local VZSERVER_HOSTNAME LAST_VEID debug 4 "get_next_free_veid: sof" VZSERVER_HOSTNAME=`role2host vzserver` || return $? debug 4 "get_next_free_veid: VZSERVER_HOSTNAME=$VZSERVER_HOSTNAME" # From vzlist output strip header line and take last line's first field LAST_VEID=`host_exec -n $VZSERVER_HOSTNAME "vzlist -a" | sed -n -e 1d -e '$s/^ *\([0-9][0-9]*\).*/\1/p'` [ X$LAST_VEID != X ] || LAST_VEID=100 debug 4 "get_next_free_veid: LAST_VEID=$LAST_VEID" [ "X$LAST_VEID" != X ] || internal "get_next_free_veid: could not determine last used VEID" expr $LAST_VEID + 1 } loading host2ipaddr host2ipaddr() { local HOST HOST=$1 # The ${HOST//./_} is because 'pgp.mit.edu_IPADDR' is not a valid variable, so the IP address # is stored in 'pgp_mit_edu_IPADDR' instead. eval "echo \"\$${HOST//./_}_IPADDR\"" } easymac() { dd if=/dev/urandom bs=1 count=3 2>/dev/null | od -tx1 | head -1 | cut -d' ' -f2- | awk '{ print "00:0c:29:"$1":"$2":"$3 }' | tr '[a-z]' '[A-Z]' } loading create_vz create_vz() { local HOSTNAME VEID VZSERVER_HOSTNAME I HOSTNAME=$1 eval "VZSERVER_HOSTNAME=\$${HOSTNAME}_VZSERVER_HOSTNAME" debug 4 "create_vz: VZSERVER_HOSTNAME=$VZSERVER_HOSTNAME" VEID=`get_next_free_veid` || return $? debug 4 "create_vz: VEID=$VEID" debug 4 "create_vz: VZSERVER_HOSTNAME=$VZSERVER_HOSTNAME, VEID=$VEID" info "creating VZ $HOSTNAME on $VZSERVER_HOSTNAME ..." host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet create $VEID --ostemplate debian-4.0-i386-minimal --hostname $HOSTNAME" if ! $USE_VETH; then host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --ipadd $(host2ipaddr $HOSTNAME) --save" else # These instructions taken from http://wiki.openvz.org/Virtual_Ethernet_device VE_MAC=$(easymac) HN_MAC=$(easymac) host_exec -n $VZSERVER_HOSTNAME "vzctl --quiet set $VEID --netif_add eth0,$VE_MAC,veth$VEID.0,$HN_MAC --save" host_exec -n $VZSERVER_HOSTNAME "echo \"CONFIG_CUSTOMIZED=\\\"yes\\\"\" >> /etc/vz/conf/$VEID.conf" host_exec -n $VZSERVER_HOSTNAME "echo \"VETH_IP_ADDRESS=\\\"$(host2ipaddr $HOSTNAME)\\\"\" >> /etc/vz/conf/$VEID.conf" host_exec $VZSERVER_HOSTNAME "cat > /usr/sbin/vznetaddroute" <<'EOF' #!/bin/bash PROGNAME=$(basename $0) # a script to bring up virtual network interfaces (veth's) in a VE debug() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt $1 ] || echo "$PROGNAME: DEBUG[$1]: $2" >&2; } info() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt 3 ] || echo "$PROGNAME: INFO: $1" >&2; } warning() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt 2 ] || echo "$PROGNAME: WARNING: $1" >&2; } error() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt 1 ] || echo "$PROGNAME: ERROR: $1" >&2; exit 1; } internal() { echo "$PROGNAME: INTERNAL ERROR: $1" >&2; exit 2; } ADE_MSG_VERBOSELEVEL=3 CONFIGFILE=/etc/vz/conf/$VEID.conf . $CONFIGFILE VZHOSTIF=`echo $NETIF |sed 's/^.*host_ifname=\(.*\),.*$/\1/g'` if [ ! -n "$VETH_IP_ADDRESS" ]; then error "according to $CONFIGFILE VE$VEID has no veth IPs configured" fi if [ ! -n "$VZHOSTIF" ]; then error "according to $CONFIGFILE VE$VEID has no veth interface configured" fi for IP in $VETH_IP_ADDRESS; do info "connecting $VZHOSTIF to bridge ..." /sbin/ifconfig $VZHOSTIF 0 /usr/sbin/brctl addif br0 $VZHOSTIF done exit 0 EOF host_exec -n $VZSERVER_HOSTNAME "chmod 500 /usr/sbin/vznetaddroute" host_exec $VZSERVER_HOSTNAME "cat > /etc/vz/vznet.conf" <<'EOF' #!/bin/bash EXTERNAL_SCRIPT="/usr/sbin/vznetaddroute" EOF host_exec $VZSERVER_HOSTNAME "cat > /vzos/$VEID/private/etc/network/interfaces" < /etc/vz/conf/$VEID.mount" <<'EOF' #!/bin/bash . $VE_CONFFILE [ ! -d /vzdata/$HOSTNAME ] || { for ENCODED_MOUNT_POINT in $(cd /vzdata/$HOSTNAME && ls ); do DECODED_MOUNT_POINT=${ENCODED_MOUNT_POINT//_//} mkdir -p $VE_ROOT/$DECODED_MOUNT_POINT mount -n --bind /vzdata/$HOSTNAME/$ENCODED_MOUNT_POINT $VE_ROOT/$DECODED_MOUNT_POINT done } EOF host_exec -n $VZSERVER_HOSTNAME "chmod 755 /etc/vz/conf/$VEID.mount" # Actually it's already stopped and we just want to start it. restart_vz $HOSTNAME } write_commented_fstab_entries() { local ALL_DISK_DEVS MOUNTED_DISK_DEVS VZSERVER_UNCLAIMED_PARTITIONS VZSERVER_HOSTNAME VZSERVER_HOSTNAME=$1 ALL_DISK_DEVS=`host_exec -n $VZSERVER_HOSTNAME "fdisk -l" | sed -n 's@^\(/dev/.d..\).*@\1@p' | sort` MOUNTED_DISK_DEVS=`host_exec -n $VZSERVER_HOSTNAME "df; swapon -s" | sed -n 's@^\(/dev/.d..\).*@\1@p' | sort` VZSERVER_UNCLAIMED_PARTITIONS=`comm -2 -3 <(echo "$ALL_DISK_DEVS") <(echo "$MOUNTED_DISK_DEVS")` for VZSERVER_UNCLAIMED_PARTITION in $VZSERVER_UNCLAIMED_PARTITIONS; do printf "# %-15s %-20s %-5s %-5s %1d %1d\n" $VZSERVER_UNCLAIMED_PARTITION "/vzdata//vol" ext3 defaults 0 0 done | host_exec $VZSERVER_HOSTNAME "cat >> /etc/fstab" } loading install_deb install_deb() { local HOSTNAME ENV WORKAROUNDLOCALE_OPTTEXT WORKAROUNDLOCALE_OPTTEXT= while [ "X$1" != X ]; do case $1 in --work-around-locale) WORKAROUNDLOCALE_OPTTEXT=$1 ;; --) shift; break ;; -*) internal "install_deb: $1: unknown option" ;; *) break ;; esac shift done [ "X$2" != X ] || internal "install_deb: bad argument count" HOSTNAME=$1 # shift in order to make passing remaining args easier shift host_exec -n $WORKAROUNDLOCALE_OPTTEXT $HOSTNAME "apt-get -qq -y install $*" } host_exec() { local IPADDR ENV SSHOPTS REMOTECMD ENV= SSHOPTS= debug 101 "host_exec: sof" while [ "X$1" != X ]; do case $1 in --work-around-locale) ENV="$ENV LC_ALL=C" ;; -n) SSHOPTS="$SSHOPTS -n" ;; --) shift; break ;; -*) internal "host_exec: $1: unknown option" ;; *) break ;; esac shift done [ "X$2" != X -a "X$3" = X ] || internal "host_exec: bad argument count" IPADDR=${1#*@} REMOTECMD="$2" debug 20 "host_exec: IPADDR=$IPADDR, REMOTECMD=\"$REMOTECMD\"" # Convert things that don't look like IP addresses to IP addresses if expr $IPADDR : '[a-z]' > /dev/null; then debug 20 "host_exec: converting $IPADDR to IP address ..." IPADDR=$(host2ipaddr $IPADDR) || return $? fi # The string needs some extra escaping REMOTECMD="$(echo "$REMOTECMD" | sed -e 's/\\/\\\\/g' -e 's/\$/\\\$/g' -e 's/"/\\"/g')" CMD="ssh $SSHOPTS $IPADDR \"$ENV $REMOTECMD\"" debug 20 "host_exec: calling $CMD ..." eval "$CMD" } loading remove_deb remove_deb() { local HOSTNAME HOSTNAME=$1 shift host_exec -n $HOSTNAME "apt-get -qq -y --purge remove $*" } loading has_role has_roles() { local PASSES TEST_ROLES TEST_ROLE MODE HOSTNAME ACTUAL_ROLES ACTUAL_ROLE # Defaults for options MODE=all # Process options while [ "X$1" != X ]; do case $1 in --any) MODE=any ;; --all) MODE=all ;; --) shift; break ;; -*) internal "has_roles: $1: illegal option" ;; *) break ;; esac shift done # Process args HOSTNAME=$1; shift TEST_ROLES="$@" # Guts eval "ACTUAL_ROLES=\"\$${HOSTNAME}_ROLES\"" if [ $MODE = all ]; then for TEST_ROLE in $TEST_ROLES; do PASSES=false for ACTUAL_ROLE in $ACTUAL_ROLES; do [ $ACTUAL_ROLE != $TEST_ROLE ] || { PASSES=true; break; } done $PASSES || { debug 10 "has_roles: decided host $HOSTNAME does *not* have *all* of following roles: $TEST_ROLES"; return 1; } done debug 10 "has_roles: decided host $HOSTNAME *does* have *all* of following roles: $TEST_ROLES" return 0 elif [ $MODE = any ]; then PASSES=false for TEST_ROLE in $TEST_ROLES; do for ACTUAL_ROLE in $ACTUAL_ROLES; do [ $ACTUAL_ROLE != $TEST_ROLE ] || { PASSES=true; break; } done ! $PASSES || { debug 10 "has_roles: decided host $HOSTNAME *does* have *any* of following roles: $TEST_ROLES"; return 0; } done debug 10 "has_roles: decided host $HOSTNAME does *not* have *any* of following roles: $TEST_ROLES" return 1 else internal "has_roles: $MODE: illegal mode" fi } invert_rc() { local CMD RC CMD="$1" eval "$CMD" RC=$? [ $RC != 0 ] } ############################################################################## # # Messaging functions # ############################################################################## debug() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt $1 ] || echo "$PROGNAME: DEBUG[$1]: $2" >&2; } info() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt 3 ] || echo "$PROGNAME: INFO: $1" >&2; } warning() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt 2 ] || echo "$PROGNAME: WARNING: $1" >&2; } error() { [ ${ADE_MSG_VERBOSELEVEL:-2} -lt 1 ] || echo "$PROGNAME: ERROR: $1" >&2; exit 1; } internal() { echo "$PROGNAME: INTERNAL ERROR: $1" >&2; exit 2; } ############################################################################## # # Entry point # ############################################################################## main "$@"