From: Thomas Lange Date: Sat, 16 Jan 2016 20:22:11 +0000 (-0800) Subject: upstream 5.1 sample config X-Git-Url: https://iankelling.org/git/?p=automated-distro-installer;a=commitdiff_plain;h=3bd65f0ca635f1349626c2393a4dd8a50df64f54 upstream 5.1 sample config Taken from /usr/share/doc/fai-doc/examples/simple/ per the fai guide. --- 3bd65f0ca635f1349626c2393a4dd8a50df64f54 diff --git a/fai/class/GERMAN.var b/fai/class/GERMAN.var new file mode 100644 index 0000000..8638a75 --- /dev/null +++ b/fai/class/GERMAN.var @@ -0,0 +1,3 @@ +# german environment (for Debian) +KEYMAP=de-latin1-nodeadkeys + diff --git a/fai/config/basefiles/mk-basefile b/fai/config/basefiles/mk-basefile new file mode 100755 index 0000000..6eb29db --- /dev/null +++ b/fai/config/basefiles/mk-basefile @@ -0,0 +1,266 @@ +#! /bin/bash + +# mk-basefile, create basefiles for some distributions +# +# Thomas Lange, Uni Koeln, 2011-2015 +# based on the Makefile implementation of Michael Goetze +# +# Usage example: fai-mk-basefile -J SQUEEZE64 +# This will create a SQUEEZE64.tar.xz basefile. + +# Supported distributions (each i386/amd64): +# Debian GNU/Linux +# Ubuntu 14.04 +# CentOS 5/6/7 +# Scientific Linux Cern 5/6 +# +# Packages you might want to install to use this command: +# debootstrap, rinse, xz-utils + + +# Define your local mirros here +# For the first stage, set the CentOS/SLC mirror in /etc/rinse/rinse.conf +MIRROR_DEBIAN=http://httpredir.debian.org/debian/ +MIRROR_DEBIAN=http://localmirror/debian/ +MIRROR_UBUNTU=http://mirror.netcologne.de/ubuntu/ +MIRROR_CENTOS=http://mirror.netcologne.de/ +#MIRROR_CENTOS=http://localmirror +#MIRROR_SLC=http://localmirror + +EXCLUDE_SQUEEZE=isc-dhcp-client,isc-dhcp-common,info,tasksel,tasksel-data +EXCLUDE_WHEEZY=isc-dhcp-client,isc-dhcp-common,info,tasksel,tasksel-data +EXCLUDE_JESSIE=isc-dhcp-client,isc-dhcp-common,info,tasksel,tasksel-data +EXCLUDE_TRUSTY=dhcp3-client,dhcp3-common,info + +INCLUDE_DEBIAN=aptitude + + +setarch() { + + l32= + if [ X$1 = Xi386 ]; then + l32=linux32 + fi +} + +check() { + + if [ `id -u` != 0 ]; then + echo "You must be root to create chroots." + exit 1 + fi + mknod $xtmp/test-dev-null c 1 3 + if [ $? -eq 1 ]; then + echo "Cannot create device files on $xtmp, aborting." + echo "Perhaps this directory is mounted with option nodev." + rm -rf $xtmp + exit 1 + fi + echo test > $xtmp/test-dev-null + if [ $? -eq 1 ]; then + echo "Cannot create device files on $xtmp, aborting." + echo "Perhaps this directory is mounted with option nodev." + rm -rf $xtmp + exit 1 + fi + rm -f $xtmp/test-dev-null +} + + +mkpost-centos() { + + [ -z "$MIRROR_CENTOS" ] && return + cat < $xtmp/post +#! /bin/sh +mkdir -p $xtmp/etc/yum.repos.d/orig +cp -p $xtmp/etc/yum.repos.d/*.repo $xtmp/etc/yum.repos.d/orig +perl -pi -e 's,mirrorlist=,#mirrorlist=,; s,#baseurl=http://mirror.centos.org,baseurl=$MIRROR_CENTOS,;' $xtmp/etc/yum.repos.d/CentOS-Base.repo +EOM + chmod 555 $xtmp/post +} + + +mkpost-slc() { + + ver=$1 + [ -z "$MIRROR_SLC" ] && return + cat < $xtmp/post +#! /bin/sh +mkdir -p $xtmp/etc/yum.repos.d/orig +cp -p $xtmp/etc/yum.repos.d/*.repo $xtmp/etc/yum.repos.d/orig +perl -pi -e 's,baseurl=http://linuxsoft.cern.ch,baseurl=$MIRROR_SLC,;' $xtmp/etc/yum.repos.d/slc$ver-os.repo +perl -pi -e 's,baseurl=http://linuxsoft.cern.ch,baseurl=$MIRROR_SLC,;' $xtmp/etc/yum.repos.d/slc$ver-updates.repo + +EOM + chmod 555 $xtmp/post +} + + +cleanup-deb() { + + chroot $xtmp aptitude clean + rm -f $xtmp/etc/hostname $xtmp/etc/resolv.conf $xtmp/etc/machine-id + rm $xtmp/var/lib/apt/lists/*_* + rm -f $xtmp/etc/udev/rules.d/70-persistent-net.rules +} + + +cleanup-rinse() { + + # check if chroot works + echo "Installed packages in chroot:" + chroot $xtmp rpm -qa|sort + echo -n "CHROOT rpm -qa: " + chroot $xtmp rpm -qa|wc -l + + rm -f $xtmp/etc/resolv.conf $xtmp/post + if [ -d $xtmp/etc/yum.repos.d/orig ]; then + mv $xtmp/etc/yum.repos.d/orig/* $xtmp/etc/yum.repos.d/ + rm -rf $xtmp/etc/yum.repos.d/orig + fi +} + + +tarit() { + + tar --xattrs --selinux --acl --one-file-system -C $xtmp -cf - . | $zip > $target.$ext +} + + +centos() { + + local arch=$1 + local vers=$2 + local domain=$(domainname) + + check + setarch $arch + mkpost-centos + $l32 rinse --directory $xtmp --distribution centos-$vers --arch $arch --before-post-install $xtmp/post + domainname $domain # workaround for #613377 + cleanup-rinse + tarit +} + + +slc() { + + local arch=$1 + local vers=$2 + + check + setarch $arch + mkpost-slc $vers + $l32 rinse --directory $xtmp --distribution slc-$vers --arch $arch --before-post-install $xtmp/post + cleanup-rinse + tarit +} + + +squeeze() { + + local arch=$1 + + check + debootstrap --arch $arch --exclude=${EXCLUDE_SQUEEZE} squeeze $xtmp ${MIRROR_DEBIAN} + cleanup-deb + tarit +} + +wheezy() { + + local arch=$1 + + check + debootstrap --arch $arch --exclude=${EXCLUDE_WHEEZY} wheezy $xtmp ${MIRROR_DEBIAN} + cleanup-deb + tarit +} + +jessie() { + + local arch=$1 + + check + debootstrap --arch $arch --exclude=${EXCLUDE_JESSIE} --include=${INCLUDE_DEBIAN} jessie $xtmp ${MIRROR_DEBIAN} + cleanup-deb + tarit +} + +trusty() { + + local arch=$1 + + check + debootstrap --arch $arch --exclude=${EXCLUDE_TRUSTY} --include=${INCLUDE_DEBIAN} trusty $xtmp ${MIRROR_UBUNTU} + cleanup-deb + tarit +} + + +unknown() { + + echo "Unknown distribution. Aborting." + echo "Available: + + CENTOS5_32 CENTOS5_64 + CENTOS6_32 CENTOS6_64 + CENTOS7_32 CENTOS7_64 + SLC5_32 SLC5_64 + SLC6_32 SLC6_64 + TRUSTY32 TRUSTY64 + SQUEEZE32 SQUEEZE64 + WHEEZY32 WHEEZY64 + JESSIE32 JESSIE64 +" + exit 99 +} + + +# main routine + +ext=tar +zip=cat +tmpdir=/var/tmp + +while getopts zJd: opt ; do + case "$opt" in + d) tmpdir=$OPTARG ;; + z) zip="gzip -9"; ext=tar.gz ;; + J) zip="xz -8" ext=tar.xz ;; + esac +done +shift $(($OPTIND - 1)) + +xtmp=$(mktemp -d $tmpdir/basefiles.XXXXXXXX) +if [ $? -eq 1 ]; then + echo "mktemp failed. Aborting." + exit 2 +fi + +target=$1 # also the name of the output file + +case "$target" in + CENTOS5_32) centos i386 5 ;; + CENTOS5_64) centos amd64 5 ;; + CENTOS6_32) centos i386 6 ;; + CENTOS6_64) centos amd64 6 ;; + CENTOS7_32) centos i386 7 ;; + CENTOS7_64) centos amd64 7 ;; + SLC5_32) slc i386 5 ;; + SLC5_64) slc amd64 5 ;; + SLC6_32) slc i386 6 ;; + SLC6_64) slc amd64 6 ;; + TRUSTY32) trusty i386 ;; + TRUSTY64) trusty amd64 ;; + SQUEEZE32) squeeze i386 ;; + SQUEEZE64) squeeze amd64 ;; + WHEEZY32) wheezy i386 ;; + WHEEZY64) wheezy amd64 ;; + JESSIE32) jessie i386 ;; + JESSIE64) jessie amd64 ;; + *) unknown ;; +esac + +# cleanup +rm -rf $xtmp diff --git a/fai/config/class/10-base-classes b/fai/config/class/10-base-classes new file mode 100755 index 0000000..eed0846 --- /dev/null +++ b/fai/config/class/10-base-classes @@ -0,0 +1,16 @@ +#! /bin/bash + +# Echo architecture and OS name in uppercase. Do NOT remove these two lines. +uname -s | tr '[:lower:]' '[:upper:]' +[ -x "`which dpkg`" ] && dpkg --print-architecture | tr a-z A-Z + +# determin if we are a DHCP client or not +# count the : chars in the argument of ip= +n="${ip//[^:]}" +if [[ $ip =~ ^(on|any|dhcp)$ ]]; then + echo DHCPC +elif [ ${#n} -lt 6 ]; then + echo DHCPC +fi + +exit 0 diff --git a/fai/config/class/20-hwdetect.sh b/fai/config/class/20-hwdetect.sh new file mode 100755 index 0000000..b42f986 --- /dev/null +++ b/fai/config/class/20-hwdetect.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +# (c) Thomas Lange, 2002-2013, lange@informatik.uni-koeln.de + +# NOTE: Files named *.sh will be evaluated, but their output ignored. + +[ $do_init_tasks -eq 1 ] || return 0 # Do only execute when doing install + +echo 0 > /proc/sys/kernel/printk + +#kernelmodules= +# here, you can load modules depending on the kernel version +case $(uname -r) in + 2.6*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; + 3*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; + 4*) kernelmodules="$kernelmodules mptspi dm-mod md-mod aes dm-crypt" ;; +esac + +for mod in $kernelmodules; do + [ "$verbose" ] && echo Loading kernel module $mod + modprobe -a $mod 1>/dev/null 2>&1 +done + +ip ad show up | egrep -iv 'loopback|127.0.0.1|::1/128|_lft' + +echo $printk > /proc/sys/kernel/printk + +odisklist=$disklist +set_disk_info # recalculate list of available disks +if [ "$disklist" != "$odisklist" ]; then + echo New disklist: $disklist + echo disklist=\"$disklist\" >> $LOGDIR/additional.var +fi + +save_dmesg # save new boot messages (from loading modules) diff --git a/fai/config/class/40-parse-profiles.sh b/fai/config/class/40-parse-profiles.sh new file mode 100755 index 0000000..7ed3055 --- /dev/null +++ b/fai/config/class/40-parse-profiles.sh @@ -0,0 +1,166 @@ + +#! /bin/bash + +# parse *.profile and build a curses menu, so the user can select a profile +# +# (c) 2015 by Thomas Lange, lange@informatik.uni-koeln.de +# Universitaet zu Koeln + +if [ X$FAI_ACTION = Xinstall -o X$FAI_ACTION = Xdirinstall -o X$FAI_ACTION = X ]; then + : +else + return +fi + +[ "$flag_menu" ] || return 0 + +out=$(tty) +tempfile=`(tempfile) 2>/dev/null` +tempfile2=`(tempfile) 2>/dev/null` +trap "rm -f $tempfile $tempfile2" EXIT INT QUIT + +# declare the data structure, use associative arrays +declare -A arshort +declare -A ardesc +declare -A arlong +declare -A arclasses +declare -a list + + +parse_profile() { + + # read a profile and add all info to the data structure + + local short + local long + local desc + local name + local classes + local lflag=0 + + # disable word splitting when reading a line, this helps reading a keyword without a value + local OIF=$IFS + IFS= + + while read -r line || [[ -n $line ]]; do + + if [[ $line =~ "Name: " ]]; then + if [ -n "$long" ]; then + arlong[$name]="$long" + fi + short= + desc= + long= + classes= + lflag=0 + name=${line##Name: } + [ $debug ] && echo "XX NAME $name found" + list+=("$name") # add new item to list + continue + fi + + if [[ $line =~ "Description: " ]]; then + lflag=0 + desc=${line##Description: } + [ $debug ] && echo "XX $desc found" + ardesc[$name]="$desc" + continue + fi + + if [[ $line =~ "Short: " ]]; then + lflag=0 + short=${line##Short: } + [ $debug ] && echo "XX $short found" + arshort[$name]="$short" + continue + fi + + if [[ $line =~ "Classes: " ]]; then + lflag=0 + classes=${line##Classes: } + [ $debug ] && echo "XX classes found" + arclasses[$name]="$classes" + continue + fi + + if [[ $line =~ "Long: " ]]; then + lflag=1 + long=${line##Long: } + [ $debug ] && echo "XX long found" + + # else it's another long line + elif [ $lflag -eq 1 ]; then + long+="\n$line" + fi + + if [[ $line =~ "Default: " ]]; then + lflag=0 + default=${line##Default: } + continue + fi + + done < $1 + + if [ -n "$long" ]; then + arlong[$name]="$long" + fi + IFS=$OIF +} + +prtresult() { + + # set newclasses which is used by fai-class(1) + local res=$(<$tempfile) + echo "$BASH_SOURCE defined new classes: ${arclasses[$res]}" + newclasses="${arclasses[$res]}" +} + + +# read all files with name matching *.profile +_parsed=0 +shopt -s nullglob +for _f in *.profile; do + parse_profile $_f + _parsed=1 +done +unset _f + +# do nothing if no profile was read +if [ $_parsed -eq 0 ]; then + unset _parsed + return 0 +fi + +# create the argument list containing the menu entries +# and the help text file +for i in "${list[@]}"; do + par+=("$i") + par+=("${ardesc[${i}]}") + par+=("${arshort[${i}]}") + echo "Name: ${i}" >> $tempfile2 + echo -e ${arlong[${i}]} >> $tempfile2 + echo -e "Classes: " ${arclasses[${i}]} "\n" >> $tempfile2 +done +unset i + +while true; do + + dialog --clear --item-help --title "FAI - Fully Automatic Installation" --help-button \ + --default-item "$default" \ + --menu "\nSelect your FAI profile\n\nThe profile will define a list of classes,\nwhich are used by FAI.\n\n\n"\ + 15 70 0 "${par[@]}" 2> $tempfile 1> $out + + _retval=$? + case $_retval in + 0) + prtresult + break ;; + 1) + echo "No profile selected." + break ;; + 2) + dialog --title "Description of all profiles" --textbox $tempfile2 0 0 1> $out;; + esac + +done +unset par ardesc arshort arlong arclasses list tempfile tempfile2 _parsed _retval line diff --git a/fai/config/class/50-host-classes b/fai/config/class/50-host-classes new file mode 100755 index 0000000..fc89c1d --- /dev/null +++ b/fai/config/class/50-host-classes @@ -0,0 +1,31 @@ +#! /bin/bash + +# assign classes to hosts based on their hostname + +# do not use this if a menu will be presented +[ "$flag_menu" ] && exit 0 + +# use a list of classes for our demo machine +case $HOSTNAME in + faiserver) + echo "FAIBASE DEBIAN DEMO FAISERVER" ;; + demohost|client*) + echo "FAIBASE DEBIAN DEMO" ;; + xfcehost) + echo "FAIBASE DEBIAN DEMO XORG XFCE LVM";; + gnomehost) + echo "FAIBASE DEBIAN DEMO XORG GNOME";; + centos) + echo "FAIBASE CENTOS" # you may want to add class XORG here + ifclass I386 && echo CENTOS6_32 # AFAIK there's no 32bit C7 + ifclass AMD64 && echo CENTOS7_64 + exit 0 ;; # CentOS does not use the GRUB class + slchost) + # Scientific Linux Cern, is very similar to CentOS. SLC should alsways use the class CENTOS + echo "FAIBASE CENTOS SLC" # you may want to add class XORG here + ifclass I386 && echo SLC7_32 + ifclass AMD64 && echo SLC7_64 + exit 0 ;; # CentOS/SLC does not use the GRUB class + *) + echo "FAIBASE DEBIAN DEMO" ;; +esac diff --git a/fai/config/class/60-misc b/fai/config/class/60-misc new file mode 100755 index 0000000..22a30c0 --- /dev/null +++ b/fai/config/class/60-misc @@ -0,0 +1,4 @@ +#! /bin/bash + +ifclass -o CENTOS SLC && exit 0 +ifclass -o I386 AMD64 && echo GRUB_PC diff --git a/fai/config/class/CENTOS.var b/fai/config/class/CENTOS.var new file mode 100644 index 0000000..1ec7250 --- /dev/null +++ b/fai/config/class/CENTOS.var @@ -0,0 +1,9 @@ +CONSOLEFONT=lat9v-16 +KEYMAP=us +DEFAULTLOCALE=en_US.UTF-8 +SUPPORTEDLOCALE=en_US.UTF-8:en_US:en + +# if you install much software and have only few RAM, use the RAM disk +# not for var/cache/yum +#FAI_RAMDISKS="$target/var/lib/rpm $target/var/cache/yum" +FAI_RAMDISKS="$target/var/lib/rpm" diff --git a/fai/config/class/DEBIAN.var b/fai/config/class/DEBIAN.var new file mode 100644 index 0000000..37cbe7a --- /dev/null +++ b/fai/config/class/DEBIAN.var @@ -0,0 +1,15 @@ +CONSOLEFONT= +KEYMAP=us-latin1 + +# MODULESLIST contains modules that will be loaded by the new system, +# not during installation these modules will be written to /etc/modules +# If you need a module during installation, add it to $kernelmodules +# in 20-hwdetect.sh. +MODULESLIST="usbhid psmouse" + +# if you have enough RAM (>2GB) you may want to enable this line. It +# also puts /var/cache into a ramdisk. +#FAI_RAMDISKS:="$target/var/lib/dpkg $target/var/cache" + +# if you want to use the faiserver as APT proxy +#APTPROXY=http://faiserver:3142 diff --git a/fai/config/class/FAIBASE.var b/fai/config/class/FAIBASE.var new file mode 100644 index 0000000..789cc7f --- /dev/null +++ b/fai/config/class/FAIBASE.var @@ -0,0 +1,18 @@ +# default values for installation. You can override them in your *.var files + +# allow installation of packages from unsigned repositories +FAI_ALLOW_UNSIGNED=1 + +# Set UTC=yes if your system clock is set to UTC (GMT), and UTC=no if not. +UTC=yes +TIMEZONE=Europe/Berlin + +# the hash of the root password for the new installed linux system +# pw is "fai" +ROOTPW='$1$kBnWcO.E$djxB128U7dMkrltJHPf6d1' + +# errors in tasks greater than this value will cause the installation to stop +STOP_ON_ERROR=700 + +# set parameter for install_packges(8) +MAXPACKAGES=800 diff --git a/fai/config/class/INSTALL.var b/fai/config/class/INSTALL.var new file mode 100644 index 0000000..f0c4cbd --- /dev/null +++ b/fai/config/class/INSTALL.var @@ -0,0 +1 @@ +FAI_ACTION=install diff --git a/fai/config/class/INVENTORY.var b/fai/config/class/INVENTORY.var new file mode 100644 index 0000000..6afe995 --- /dev/null +++ b/fai/config/class/INVENTORY.var @@ -0,0 +1 @@ +FAI_ACTION=inventory diff --git a/fai/config/class/SYSINFO.var b/fai/config/class/SYSINFO.var new file mode 100644 index 0000000..617b88d --- /dev/null +++ b/fai/config/class/SYSINFO.var @@ -0,0 +1 @@ +FAI_ACTION=sysinfo diff --git a/fai/config/class/example.profile b/fai/config/class/example.profile new file mode 100644 index 0000000..084824f --- /dev/null +++ b/fai/config/class/example.profile @@ -0,0 +1,65 @@ +Default: Xfce + +Name: Simple +Description: My first FAI installation +Short: just a very simple example, no xorg, an account called demo +Long: This is the demohost example of FAI. +Additional account called demo with password: fai, root password: fai +All needed packages are already on the CD or USB stick. +Classes: INSTALL FAIBASE DEBIAN DEMO + +Name: Xfce +Description: Xfce desktop, LVM partitioning +Short: A fancy Xfce desktop will be installed, the user account is demo +Long: This is the Xfce desktop example. Additional account called +demo with password: fai, root password: fai +All needed packages are already on the CD or USB stick. +Classes: INSTALL FAIBASE DEBIAN DEMO XORG XFCE LVM + +Name: Gnome +Description: Gnome desktop installation +Short: A Gnome desktop, no LVM, You will get an account called demo +Long: This is the Gnome desktop example. Additional account called +demo with password: fai, root password: fai +You should have a fast network connection, because most packages are +downloaded from the internet. +Classes: INSTALL FAIBASE DEBIAN DEMO XORG GNOME + +Name: CentOS 7 +Description: CentOS 7 with Xfce desktop +Short: A normal Xfce desktop, running CentOS 7 +Long: We use the Debian nfsroot for installing the CentOS 7 OS. +You should have a fast network connection, because most packages are +downloaded from the internet. +Classes: INSTALL FAIBASE CENTOS CENTOS7_64 XORG + +Name: Ubuntu +Description: Ubuntu 14.04 desktop installation +Short: Unity desktop +Long: We use the Debian nfsroot for installing the Ubuntu OS. +You should have a fast network connection, because most packages are +downloaded from the internet. +Classes: INSTALL FAIBASE DEMO DEBIAN UBUNTU TRUSTY TRUSTY64 XORG + +Name: Inventory +Description: Show hardware info +Short: Show some basic hardware infos +Long: Execute commands for showing hardware info +Classes: INVENTORY + +Name: Sysinfo +Description: Show defailed system information +Short: Show detailed hardware and system information +Long: Execute a lot of commands for collecting system information +Classes: SYSINFO + +Name: dummy +Description: A dummy profile +Short: This is the short one liner text for the dummy menu, Shown at the bottom of the menu +Long: Here you can add more lines to describe details of you +profile. A profile is only a list of FAI classes. Those classes can +then define the disk partitioning scheme, the list of packages to be +installed, the variables to defined and other things. + +In the end, a profile is just a list of FAI classes combined with some description. +Classes: A B C E diff --git a/fai/config/debconf/DEBIAN b/fai/config/debconf/DEBIAN new file mode 100644 index 0000000..e9dc3c1 --- /dev/null +++ b/fai/config/debconf/DEBIAN @@ -0,0 +1,9 @@ +exim4-config exim4/dc_eximconfig_configtype select local delivery only; not on a network +locales locales/default_environment_locale select en_US.UTF-8 +locales locales/locales_to_be_generated multiselect en_US.UTF-8 UTF-8 +keyboard-configuration keyboard-configuration/modelcode string pc105 +keyboard-configuration keyboard-configuration/xkb-keymap select us +keyboard-configuration keyboard-configuration/variant select USA +keyboard-configuration keyboard-configuration/model select Generic 105-key (Intl) PC +keyboard-configuration keyboard-configuration/layoutcode string us +keyboard-configuration keyboard-configuration/optionscode string ctrl:nocaps,terminate:ctrl_alt_bksp diff --git a/fai/config/files/etc/apt/apt.conf.d/force_confdef/DEBIAN b/fai/config/files/etc/apt/apt.conf.d/force_confdef/DEBIAN new file mode 100644 index 0000000..deb7948 --- /dev/null +++ b/fai/config/files/etc/apt/apt.conf.d/force_confdef/DEBIAN @@ -0,0 +1,5 @@ +DPkg { + Options { + "--force-confdef"; + } +}; diff --git a/fai/config/files/etc/apt/sources.list/GNOME b/fai/config/files/etc/apt/sources.list/GNOME new file mode 100644 index 0000000..84b7172 --- /dev/null +++ b/fai/config/files/etc/apt/sources.list/GNOME @@ -0,0 +1,2 @@ +deb http://httpredir.debian.org/debian jessie main contrib non-free +deb http://httpredir.debian.org/debian-security jessie/updates main contrib non-free diff --git a/fai/config/files/etc/dhcp/dhcpd.conf/FAISERVER b/fai/config/files/etc/dhcp/dhcpd.conf/FAISERVER new file mode 100644 index 0000000..55784e2 --- /dev/null +++ b/fai/config/files/etc/dhcp/dhcpd.conf/FAISERVER @@ -0,0 +1,27 @@ +# dhcpd.conf for a fai installation server +# replace faiserver with the name of your install server + +ignore-client-uids on; +deny unknown-clients; +option dhcp-max-message-size 2048; +use-host-decl-names on; +#always-reply-rfc1048 on; + +subnet 192.168.33.0 netmask 255.255.255.0 { + option routers 192.168.33.1; + option domain-name "fai.example"; + option domain-name-servers 192.168.33.250; + option time-servers faiserver; +# option ntp-servers faiserver; + server-name faiserver; + next-server faiserver; + filename "fai/pxelinux.0"; + allow unknown-clients; + pool { + range 192.168.33.100 192.168.33.150; + } +} + +# generate a lot of entries with: +# perl -e 'for (1..10) {printf "host client%02s {hardware ethernet XXX:$_;fixed-address client%02s;}\n",$_,$_;}' +# then replace XXX with the hardware addresses of your clients diff --git a/fai/config/files/etc/fai/apt/sources.list/FAISERVER b/fai/config/files/etc/fai/apt/sources.list/FAISERVER new file mode 100644 index 0000000..c7b1228 --- /dev/null +++ b/fai/config/files/etc/fai/apt/sources.list/FAISERVER @@ -0,0 +1,5 @@ +deb http://httpredir.debian.org/debian jessie main contrib non-free +deb http://security.debian.org/debian-security jessie/updates main contrib non-free + +# repository that may contain newer fai packages for jessie +deb http://fai-project.org/download jessie koeln diff --git a/fai/config/files/etc/fai/fai.conf/FAISERVER b/fai/config/files/etc/fai/fai.conf/FAISERVER new file mode 100644 index 0000000..4711cd1 --- /dev/null +++ b/fai/config/files/etc/fai/fai.conf/FAISERVER @@ -0,0 +1,8 @@ +# See fai.conf(5) for detailed information. + +# Account for saving log files and calling fai-chboot. +LOGUSER=fai + +# URL to access the fai config space +# If undefined, use default nfs:///$FAI_CONFIGDIR +FAI_CONFIG_SRC=nfs://faiserver/srv/fai/config diff --git a/fai/config/files/etc/fai/nfsroot.conf/FAISERVER b/fai/config/files/etc/fai/nfsroot.conf/FAISERVER new file mode 100644 index 0000000..4cff8cd --- /dev/null +++ b/fai/config/files/etc/fai/nfsroot.conf/FAISERVER @@ -0,0 +1,15 @@ +# For a detailed description see nfsroot.conf(5) + +# " " for debootstrap +FAI_DEBOOTSTRAP="jessie http://httpredir.debian.org/debian" +FAI_ROOTPW='$1$kBnWcO.E$djxB128U7dMkrltJHPf6d1' + +NFSROOT=/srv/fai/nfsroot +TFTPROOT=/srv/tftp/fai +NFSROOT_HOOKS=/etc/fai/nfsroot-hooks/ +FAI_DEBOOTSTRAP_OPTS="--exclude=info --include=aptitude" + +# Configuration space +FAI_CONFIGDIR=/srv/fai/config + +NFSROOT_ETC_HOSTS="192.168.33.250 faiserver" diff --git a/fai/config/files/etc/motd/FAIBASE b/fai/config/files/etc/motd/FAIBASE new file mode 100644 index 0000000..4e5a967 --- /dev/null +++ b/fai/config/files/etc/motd/FAIBASE @@ -0,0 +1,3 @@ + + +Plan your installation, and FAI installs your plan. diff --git a/fai/config/files/etc/rc.local/FAISERVER b/fai/config/files/etc/rc.local/FAISERVER new file mode 100755 index 0000000..764c62a --- /dev/null +++ b/fai/config/files/etc/rc.local/FAISERVER @@ -0,0 +1,90 @@ +#! /bin/bash + +# setup script that is only run once at boot time +# set up an FAI install server + +NORMAL='\E(B\E[m' +RED='\E[31m' +GREEN='\E[32m' + +set -o pipefail + +# setup network +ifup eth0 +sleep 8 +[ -x /etc/init.d/nscd ] && /etc/init.d/nscd restart + +echo "=================================" >/dev/console +echo "Setting up the FAI install server" >/dev/console +echo "This will take a few minutes" >/dev/console +echo "=================================" >/dev/console + +. /etc/fai/fai.conf +. /etc/fai/nfsroot.conf + +# copy the simple examples and pimp my config space +if [ ! -d "$FAI_CONFIGDIR/class" ]; then + mkdir -p $FAI_CONFIGDIR + cp -a /usr/share/doc/fai-doc/examples/simple/* $FAI_CONFIGDIR + ainsl /srv/fai/config/class/FAIBASE.var "LOGUSER=fai" + myip=$(ip addr show up| grep -w inet | cut -d t -f 2 | cut -d ' ' -f 2 | cut -d / -f 1 | grep -v 127.0.0.1) + echo "APTPROXY=http://$myip:3142" >> /srv/fai/config/class/DEBIAN.var + # determine a fast mirror for Ubuntu + list=$(curl -s http://mirrors.ubuntu.com/mirrors.txt) + mirror=$(netselect $list | awk '{print $2}') + sed -i -e "s#MIRRORURL#$mirror#" /srv/fai/config/files/etc/apt/sources.list/UBUNTU +fi +# set the LOGUSER, wo we get all the logs from our install clients +ainsl /etc/fai/fai.conf "LOGUSER=fai" + +# make index, then import the packages from the CD mirror +apt-get update +curl -fs 'http://127.0.0.1:3142/acng-report.html?doImport=Start+Import&calcSize=cs&asNeeded=an#bottom' >/dev/null + +# setup the FAI server, including creating the nfsroot, use my own proxy +export APTPROXY="http://127.0.0.1:3142" +fai-setup -fvB /var/tmp/base.tar.xz 2>&1 +if [ $? -eq 0 ]; then + rm /var/tmp/base.tar.xz + echo "" + echo "================================================" >/dev/console + echo -e "Setting up the FAI server was ${GREEN}successful${NORMAL}" >/dev/console + echo "================================================" >/dev/console + echo "" + sleep 10 +else + echo "" + echo "==================================================" >/dev/console + echo -e "${RED}ERROR${NORMAL}: Setting up the FAI install server ${RED}FAILED${NORMAL}!" >/dev/console + echo "Read /var/log/fai/fai-setup.log for more debugging" >/dev/console + echo "==================================================" >/dev/console + echo "" + sleep 10 + exit 99 +fi + +cat <> /srv/fai/nfsroot/etc/fai/fai.conf +# use short hostname instead of FQDN +export HOSTNAME=\${HOSTNAME%%.*} +echo \$HOSTNAME > /proc/sys/kernel/hostname +EOF + +# create default pxelinux boot configuration +fai-chboot -o default + +# create a template for booting the installation +fai-chboot -Iv -f verbose,sshd,createvt,menu -u nfs://faiserver/srv/fai/config jessie.tmpl + +# Since we do not know the MAC address, our DHCP cannot provide the hostname. +# Therefore we do explicitly set the hostname +fai-chboot -Iv -f verbose,sshd,createvt,menu -u nfs://faiserver/srv/fai/config -k hostname=xfcehost xfcehost +fai-chboot -Iv -f verbose,sshd,createvt,menu -u nfs://faiserver/srv/fai/config -k hostname=demohost demohost +for c in {01..10}; do + fai-chboot -Iv -f verbose,sshd,createvt,menu -u nfs://faiserver/srv/fai/config -k hostname=client$c client$c +done + +fai-monitor > /var/log/fai/fai-monitor.log & + +# move me away +mv $0 /var/tmp +exit 0 diff --git a/fai/config/files/etc/selinux/config/CENTOS b/fai/config/files/etc/selinux/config/CENTOS new file mode 100644 index 0000000..b415aa8 --- /dev/null +++ b/fai/config/files/etc/selinux/config/CENTOS @@ -0,0 +1,12 @@ +# This file controls the state of SELinux on the system. +# SELINUX= can take one of these three values: +# enforcing - SELinux security policy is enforced. +# permissive - SELinux prints warnings instead of enforcing. +# disabled - No SELinux policy is loaded. +SELINUX=enforcing +# SELINUXTYPE= can take one of these two values: +# targeted - Only targeted network daemons are protected. +# strict - Full SELinux protection. +# mls - Multi Level Security protection. +SELINUXTYPE=targeted +# SETLOCALDEFS= Check local definition changes diff --git a/fai/config/hooks/debconf.CENTOS b/fai/config/hooks/debconf.CENTOS new file mode 100755 index 0000000..f98becd --- /dev/null +++ b/fai/config/hooks/debconf.CENTOS @@ -0,0 +1,3 @@ +#! /bin/bash + +skiptask debconf diff --git a/fai/config/hooks/debconf.IMAGE b/fai/config/hooks/debconf.IMAGE new file mode 100755 index 0000000..8c20112 --- /dev/null +++ b/fai/config/hooks/debconf.IMAGE @@ -0,0 +1,45 @@ +#! /bin/bash + +# hook for installing a file system image (tar file) +# this works for Ubuntu 14.04 +# +# Copyright (C) 2015 Thomas Lange, lange@informatik.uni-koeln.de + + +# I use this tar command to create the image of an already running and configured machine +# tar -cf /tmp/IMAGE.tar --exclude /tmp/\* --exclude /run/\* --exclude /proc/\* --exclude /sys/\* --exclude /dev/\* / +# add --xattrs --selinux --acl if needed (for CentOS 7) +# Then copy this image to /srv/fai/config/basefiles/IMAGE.tar and make sure your client belongs to the class IMAGE + +skiptask extrbase debconf repository updatebase instsoft +skiptask configure # do not run the usual configure scripts + +# we assume, that the new host will get its hostname and IP via DHCP +# remove old hostname +fgrep -v 127.0.1.1 $target/etc/hosts >> /tmp/fai/hosts +mv /tmp/fai/hosts $target/etc/hosts +rm $target/etc/hostname + +#install grub +mount -t proc proc $FAI_ROOT/proc +mount -t sysfs sysfs $FAI_ROOT/sys +mount --bind /dev $FAI_ROOT/dev + +if [ -f $target/etc/debian_version ]; then + $ROOTCMD grub-install $BOOT_DEVICE + $ROOTCMD update-grub +fi +if [ -f $target/etc/centos-release ]; then + rm $target/etc/grub2/device.map + $FAI/scripts/CENTOS/40-install-grub + $FAI/scripts/CENTOS/30-mkinitrd + $ROOTCMD fixfiles onboot # this fixes the SELinux security contexts during the first boot +fi + + +# things that may be adjusted: +# +# MAC address ?? (not needed for Ubuntu, it uses iftab(5) +# /etc/hosts may contain the IP and name of the original host +# /etc/hostname (for Ubuntu just remove it) +# /var/lib/NetworkManager/dhclient-eth0.conf? diff --git a/fai/config/hooks/instsoft.DEBIAN b/fai/config/hooks/instsoft.DEBIAN new file mode 100755 index 0000000..f036e2a --- /dev/null +++ b/fai/config/hooks/instsoft.DEBIAN @@ -0,0 +1,16 @@ +#! /bin/bash + +# if package locales will be installed, then install it early, before +# other packages + +if [ $FAI_ACTION != "install" ]; then + exit 0 +fi + +fcopy -Bi /etc/apt/apt.conf.d/force_confdef +ainsl -av /etc/ucf.conf "conf_force_conffold=YES" + +install_packages -l 2>/dev/null | egrep -q ' locales|locales ' +if [ $? -eq 0 ]; then + $ROOTCMD apt-get -y install locales +fi diff --git a/fai/config/hooks/repository.CENTOS b/fai/config/hooks/repository.CENTOS new file mode 100755 index 0000000..e78c0bb --- /dev/null +++ b/fai/config/hooks/repository.CENTOS @@ -0,0 +1,31 @@ +#! /bin/bash + +# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +if [ $FAI_ACTION = "install" ]; then + mount -t proc proc $target/proc + mount -t sysfs sysfs $target/sys + [ -L $target/etc/mtab ] || cp /etc/mtab $target/etc/mtab + + cat > $target/etc/sysconfig/network <<-EOF + NETWORKING=yes + HOSTNAME=$HOSTNAME.$DOMAIN + EOF + echo "127.0.0.1 localhost" > $target/etc/hosts + ifclass DHCPC || ainsl -s /etc/hosts "$IPADDR $HOSTNAME.$DOMAIN $HOSTNAME" + cp /etc/resolv.conf $target/etc +fi + +mkdir $target/dev/pts +mknod -m 000 $target/dev/pts/ptmx c 5 2 + +fcopy -riv /etc/yum.repos.d/ + +# disable the fastestmirror plugin +#sed -i -e 's/enabled=1/enabled=0/' $target/etc/yum/pluginconf.d/fastestmirror.conf + +skiptask repository + +exit $error diff --git a/fai/config/hooks/savelog.LAST.sh b/fai/config/hooks/savelog.LAST.sh new file mode 100755 index 0000000..994a947 --- /dev/null +++ b/fai/config/hooks/savelog.LAST.sh @@ -0,0 +1,187 @@ +#! /bin/bash + +# parse all log files for error messages +# print errors and warnings found to error.log +# WARNING: This will only work with english error messages! + +errfile=$LOGDIR/error.log + +# Define grep patterns. Do not start or end with an empty line! +globalerrorpatterns="error +fail +warn +bad +no space +syntax +Couldn't stat +Cannot access + conflict +is bigger than the limit +did not exist +non existent +not found +couldn't +can't +E: Sorry, broken packages +operator expected +ambiguous redirect +No previous regular expression +No such +Device or resource busy +unknown option +[a-z]\+\.log:E: +No candidate version found +segfault +Couldn't find any package whose name or description matched +cannot create +The following packages have unmet dependencies" + +globalignorepatterns="[a-z]\+\.log:# +Error: Driver 'pcspkr' is already registered, aborting +: bytes packets errors dropped +:+ error=0 +:+ trap error= +task_error_func= +STOP_ON_ERROR= +courier-webadmin +plugins-bad +Enabling conf localized-error-pages +ibwebadmin +kernel-patch-badram +kolab-webadmin +kolabadmin +gstreamer0.10-plugins-really-bad +liberrors.so +gsambad +libad +libtest-nowarnings-perl +libtest-warn-perl +libclass-errorhandler-perl +zope-ploneerrorreporting +libroxen-errormessage +liberror-perl +libgpg-error-dev +libgpg-error0 +^fstab.\+errors=remount +Opts: errors=remount-ro +[RT]X packets: +WARNING: unexpected IO-APIC +warned about = ( ) +daemon.warn +kern.warn +rw,errors= +Expect some cache +no error +failmsg +RPC call returned error 101 +deverror.out +(floppy), sector 0 +mount version older than kernel +Can't locate module +Warning only 896MB will be used. +hostname: Host name lookup failure +I can't tell the difference. +warning, not much extra random data, consider using the -rand option +confC._FILE +Warning: 3 database(s) sources +were not found, (but were created) +removing exim +The home dir you specified already exists. +No Rule for /usr/lib/ispell/default.hash. +/usr/sbin/update-fonts-.\+: warning: absolute path +hostname: Unknown server error +EXT2-fs warning: checktime reached +RPC: sendmsg returned error 101 +can't print them to stdout. Define these classes +warning: downgrading +suppress emacs errors +echo Error: +Can't open dependencies file +documents in /usr/doc are no longer supported +if you have both a SCSI and an IDE CD-ROM +Warning: /proc/ide/hd?/settings interface is obsolete, and will be removed soon +Monitoring disabled +Error: only one processor found. +Error Recovery Strategy: +sector 0 does not have an +syslogin_perform_logout: logout() returned an error +grub is not in an XFS filesystem. +grub-install: line 374: +grub-probe: error: Cannot open \`/boot/grub/device.map' +is harmless +not updating .\+ font directory data. +register_serial(): autoconfig failed +Fontconfig error: Cannot load default config file +asking for cache data failed +However, I can not read the target: +Warning: The partition table looks like it was made +task_error=0 +^info: Trying to set +warning: /usr/lib/X11/fonts +can't read /etc/udev/rules.d/z25_persistent-net.rules +/cow': No such file or directory +Dummy start-stop-daemon called +X: bytes packets errors +ACPI Error +ACPI Warning +AE_NOT_FOUND +conflicts with ACPI region +cannot stat \`/etc/modprobe.d/\*.conf' +cdrom: open failed. +libgpg-error +process \`kudzu' used the deprecated sysctl system call +PM: Resume from disk failed +JBD: barrier-based sync failed +aufs: module is from the staging directory, the quality is unknown +warning: linuxlogo stop runlevel arguments (none) do not match +insserv: warning: script .\+ missing LSB tags and overrides +live-premount.\+ If this fails +cannot read table of mounted file systems +error: no alternatives for +ERST: Error Record Serialization Table (ERST) support is initialized +ERST: Table is not found +HEST: Table not found +failed to stat /dev/pts +Failed to connect to socket /var/run/dbus/system_bus_socket +fail to add MMCONFIG information +can't initialize iptables table +can't initialize ip6tables table +Authentication warning overridden +update-alternatives: warning: skip creation of +update-rc.d: warning: start and stop actions are no longer supported" + +# add pattern on some conditions +if [ -n $FAI_ALLOW_UNSIGNED ] ; then + globalignorepatterns="$globalignorepatterns +WARNING: untrusted versions +Ignoring these trust violations" +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Here you can define your own patterns. Put one pattern in a line, +# do not create empty lines. +myerrorpatterns="X_X-X_XX" +myignorepatterns="X_X-X_XX" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# The main routine +errorpatterns="$globalerrorpatterns +$myerrorpatterns" +ignorepatterns="$globalignorepatterns +$myignorepatterns" + +cd $LOGDIR || exit 3 +if [ -s $errfile ]; then + echo "Errorfile already exists. Aborting." >&2 + exit +fi + +grep -i "$errorpatterns" *.log | grep -vi "$ignorepatterns" > $errfile +if [ "$verbose" ]; then + egrep -v '^software.log:' $errfile > $LOGDIR/tempfile + mv $LOGDIR/tempfile $errfile +fi + +if [ -s $errfile ]; then + echo "ERRORS found in log files. See $errfile" >&2 +else + echo "Congratulations! No errors found in log files." +fi diff --git a/fai/config/hooks/setup.DEFAULT.sh b/fai/config/hooks/setup.DEFAULT.sh new file mode 100755 index 0000000..711fa7f --- /dev/null +++ b/fai/config/hooks/setup.DEFAULT.sh @@ -0,0 +1,5 @@ +#! /bin/bash + +# use short hostname instead of FQDN +export HOSTNAME=${HOSTNAME%%.*} +echo $HOSTNAME > /proc/sys/kernel/hostname diff --git a/fai/config/hooks/updatebase.CENTOS b/fai/config/hooks/updatebase.CENTOS new file mode 100755 index 0000000..6f5813a --- /dev/null +++ b/fai/config/hooks/updatebase.CENTOS @@ -0,0 +1,14 @@ +#! /bin/bash + +if [ ! -f $target/etc/resolv.conf ]; then + cp /etc/resolv.conf $target/etc +fi + +if [ "$verbose" ]; then + echo "Updating base" + $ROOTCMD yum -y update 2>&1 | tee -a $LOGDIR/software.log +else + $ROOTCMD yum -y update >> $LOGDIR/software.log +fi + +skiptask updatebase diff --git a/fai/config/hooks/updatebase.DEBIAN b/fai/config/hooks/updatebase.DEBIAN new file mode 100755 index 0000000..e828eef --- /dev/null +++ b/fai/config/hooks/updatebase.DEBIAN @@ -0,0 +1,14 @@ +#! /bin/bash + +if [ -n "$APTPROXY" ]; then + echo "Acquire::http::Proxy \"$APTPROXY\";" > $target/etc/apt/apt.conf.d/02proxy +else + rm -f $target/etc/apt/apt.conf.d/02proxy +fi + +echo force-unsafe-io > $target/etc/dpkg/dpkg.cfg.d/unsafe-io + +# you may want to add i386 arch to amd64 hosts +# if ifclass AMD64; then +# $ROOTCMD dpkg --add-architecture i386 +# fi diff --git a/fai/config/hooks/updatebase.UBUNTU b/fai/config/hooks/updatebase.UBUNTU new file mode 100755 index 0000000..226fb75 --- /dev/null +++ b/fai/config/hooks/updatebase.UBUNTU @@ -0,0 +1,17 @@ +#! /bin/bash + +# use external mirror, remove this script when using a mirror from CD + +dist=trusty + +cat < $target/etc/apt/sources.list +# external mirror +deb MIRRORURL $dist main restricted universe multiverse +deb MIRRORURL $dist-updates main restricted universe multiverse +deb MIRRORURL $dist-security main restricted universe multiverse +EOM + +# determine a fast mirror for Ubuntu +list=$(curl -s http://mirrors.ubuntu.com/mirrors.txt) +mirror=$(netselect $list | awk '{print $2}') +sed -i -e "s#MIRRORURL#$mirror#" $target/etc/apt/sources.list diff --git a/fai/config/package_config/CENTOS b/fai/config/package_config/CENTOS new file mode 100644 index 0000000..96f8719 --- /dev/null +++ b/fai/config/package_config/CENTOS @@ -0,0 +1,28 @@ +PACKAGES yumgroup +core + +PACKAGES yumgroup XORG +#gnome-desktop base-x # slc5/CentOS 5 +#basic-desktop x11 fonts #slc6/CentOS 6 +gnome-desktop # CentOS 7 + +PACKAGES yumi +authconfig +kernel +# grub # CentOS 5 and 6 +grub2 # CentOS 7 +less +openssh +openssh-clients +openssh-server +vim-enhanced +man +curl +screen +unzip +which +nfs-utils +pakchois +ncurses-base # currently missing in the base file + +#sendmail # only for C5 and C6 diff --git a/fai/config/package_config/DEBIAN b/fai/config/package_config/DEBIAN new file mode 100644 index 0000000..253e89c --- /dev/null +++ b/fai/config/package_config/DEBIAN @@ -0,0 +1,20 @@ +PACKAGES install I386 +linux-image-686-pae initramfs-tools +memtest86+ + +PACKAGES install CHROOT +linux-image-686-pae- +linux-image-amd64- + +PACKAGES install AMD64 +linux-image-amd64 initramfs-tools +memtest86+ + +PACKAGES install DHCPC +isc-dhcp-client + +PACKAGES install GRUB_PC +grub-pc grub-legacy- lilo- + +PACKAGES install LVM +lvm2 diff --git a/fai/config/package_config/DEBIAN.asc b/fai/config/package_config/DEBIAN.asc new file mode 100644 index 0000000..72c34ca --- /dev/null +++ b/fai/config/package_config/DEBIAN.asc @@ -0,0 +1,687 @@ +# gpg key of fai-project.org repository: 4096R/074BCDE4 + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.12 (GNU/Linux) + +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 +Bjx0CB7rV1AiU3+Nw/9SRlg2peJGhoi9yIhaLcnmNzLP24E48hhZBx3zf050gmcY +Dwsy+mKQI0iE9VMlLYFbng8KzEKOCX+G7Tzs48ItQ6dn9y3SkV5YIaJEAIpYNa+/ +xry1ARSXviZxJCfsx5YH108/DI9aPLThX34n4fUBGpPDR90wxokC8AQTAQoA2gUC +UgoEBsASGmh0dHA6Ly9tYXJ0aW4ta3JhZmZ0Lm5ldC9ncGcvY2VydC1wb2xpY3kv +NTVjOTg4MmQ5OTliYmNjNC8yMDA5MDcxMjE4MzM/c2hhNTEyc3VtPWYzM2IxN2M5 +YWY1MTViZDk4YjI5MjdjYjQ1M2E5OTJkM2Q3NTAwZTlmNjcxOTY2NjE2ZTkwNTEw +Yjk5NDA4OTUxMDhkMjQxNjQ4ZDFhMGViNDZiMzJiY2JmMzI1MWExMzZhNmVlMWUy +Mjc1NzQ1ZTExYmIzMjhjMTRlN2U3MjYzAAoJEFXJiC2Zm7zEE1EP/1QC4Meh6+1N +xVnnr3/DTbEg0kzYCV/BkYr9F7ELyb3j8djzjujKPQDVmrQhqMIVjkJnkpUOnr1A +QHweMDdWwN0XSPyFiiOqVKvzTHg5+DxVUWr8mVqr83nuNcgkSjrYgs7WAAQutpFw +5KOhxMhZocLIXq5wckW3FcrkVCA67hnG8JFovgD2GSCEGbpVM8yDzo4TGIcZt8Vt +SxbEnfjGMZoQZ5IxowPMAWc52sz9VNFK1xU3cO30pcTr15LogZbZLnUb88nfHr88 +fvEAeIFGVMchaP2IWo0LShVSfThf1YhNC35E+RQjfzK1gaLiUkgVaj5+cEfnvcjp +dhFrZNMTCdo8bAllxMxldZkZlaLJPXFxx8LlsDzZPClHSTqfDUA9IUj+q4bsGdq9 +n6dYUGJcTZ83ohhZqE1wHyuSzhCgBClPvpe9Hpvpfxnpm+wDC6xJkdn9rA2CjDmB +3vUH5vKuZQ9jLj7Dp7K/4BTUPcRMn5Gg/eyHR9dNKAF31lydo/nZIGOaqUIXdXkC +ktKlAkPgrW4vUcF3Nxx4kDDNoaw/RK1hekEPVMKMwRiMQ/xw6ltfiAeqRIaYZXod +rVJZLznov22d7Wvv0tSaV6ACc0dKq7xf5qNOakiz5q9JrQUdAV6XctQCfOcup0/+ +gBfGF/4WChaHYzH+7bevnxk7ZkoozhSRiQIcBBABCAAGBQJSChWAAAoJEK7IKHSd +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 +mrrwI2VHtBVOyb18Nb8+o1xOy/4nk5q5JxznNA6e/X5QkUklz9To2gQ1HvbUU24q +hUE5h0JniyTay6zl7CP4I5TT/MMDkZ9jBLuoUT7NL8BHmR9n3hNQyTh401nInVsE +DbHi3DWbiOEBmnFdKA1MkSRu/vFL90trpA7rt8UmXbXbd3ijWKCc1cREX3DmWP13 +xDTL0xVfdtiNINY8f4QuG5JDF61nTaLF4wyPz/no96zFzrjper5zMJ3clcCWiQIc +BBABAgAGBQJSCVHtAAoJEIMBYBQlHR2wd9gP/j3abEoMu1PYsFehQYnwdZcRmY7P +dZYCB7SagmoE4SG3avsIps8eRBfqApP7LwHaT6V+ZtF3u/FCVfFwmGyJaKmH2ZuR +z4sZPnKvhAzzGgL4NTVUnfOFw+fodQyTNeG11xFOFo3XOQz8nKNXh4M404jPde1F +E+4jerOqjM4bDOpZNoywYiJF11cx6/pQPEETUHe5h4TxqRRKrHPuk2OK2znaNzB5 +N/sDG1smkxAUdccRkvbetEOjCeBPKmcpDM2oXZ3lysOILEnNqW1it6Zsudju0rRL +SATFY8nGkG15e+FDUkv+Uw39mkp1aXfbfqfX3Q26DeG0GotF5uFhKYm1pMQws+t3 +UkvfmCVihvxiV6gqwaR8Expc40Oa+7n51DmoKzcq/UHPUEuvtwny+GSVJE9KMl3w +hKtqHGs6bqWdE3Kmr+KnkIrBvBDibk6T8VsBPlVxUwvvNMC8J9uGi1wsRaD6KPkl ++LPcW9U1TM80s7BNzctIO39bSNx6MZBCm0lmNQ4Q0qG9ePca5o/20wJR6y3Vu6/4 +EThESDoyBgEyAKMAxWyomBmxoSS2EuikeE7/tFXoY+CDvqTgZSqYK8W1wrF7sk7L +gecpulvWtadioPoD3ZMo3mdFYwRsdpxdzOx70NzbWtiJ4bx9dnWPG9OBOlpNuFSA +fHd4SnQKR++woHNEiQIcBBABCAAGBQJSCWkzAAoJED9qGiAYq/jD31wQAIub6DCa +pCtHWLru7ytWTmVQ04yBalq10TEs3FwTcjgFVDEC1SO8H8woryPhXPhHB4r8xush +aHLgGjJ2kUqoI/1WTiMzi5L6xQIJQ/hreFNl2LU2bs02Ysncf660S8uYQIxBbcpx +jrFpouNhOM2tLdBenNdzuv5QnSnbiBTOzOXctf2ILWQa4r47KdUXdBpK2U2/pwoq ++GCTPJLymUs2zLlMWXCZhDQUaHQ9/7QVwFpjdi/gcIvJJ2DSEyIB5zjpZ3SQSz6s +GjBLdKJFWw6qHCf//ithAOSZH3YY4To4jGYMVkXD4GgoeZEmHQNYtdv2p5mnmw1T +ORApJRh0iA+vAGg7EMDKFAsqtxRNxPmjGeLRAxc3jqFFPw4rUdpBhaYvcXJE/7Ad +U+O8nzZMXqkbCX+14ICC2JDxR7n+HnP6/KZ7E0aB/xRpYUL2yBUvCqk8aOTiXxGX +Mf85e2GvDk1UdfiAe27qN9eCxpMX/nSfvyH+6M0CQLVeoJjZsqshHMLk4f+lsINw +HKstBM4tMOOEKtYKsCZ4Tnk3+b4xYsF4HftDLEsEYJQaJg3s3Ajfn2p61KDtxTkd +6njl8v+mJldqTvTrzqNIf/VFKgRavLcVOcsMc69TFZeVevwPsJWS/oZuHFPFkx5H +TeLF7fJmOf/ki+uboFYscCK261sb9pJoV2UTiEYEEBEIAAYFAlIJaUUACgkQGc/R +GrFqUYNMlQCffJpk47YGn4L1/U73qi4e6cu0IosAnROJEn49yaRNXejzOsYCgUQf +nAZmiEYEEBEIAAYFAlIJbKQACgkQJwRJTy3zZoEHCgCeMtpU3NJBNg9z3Tq6sz1L +3P8UzIgAn3xkMycT/vhAdQrYwRiodLUalPoSiQIcBBABCAAGBQJSCWypAAoJELog +ZmLR+sd/SiYP/0xmYtSOYSN00cKsyiHSAqvx+n/iGjsi7gvdI0NS3HI/3OWvw1UX +ZfuTerOvzsqo0N8WLWzlGFpuIt+fLoBNcxHwD156CUgC36X5Gex0l5v8qQQuNYsI +qxvrI2gLWPip8bKfeE6jpNxLWeEzhwzTk8Lhs6KWMjjfyw979r/0Vkvob/oqjnYC +xO1oydVwJ7SlXmU1PCC659ogwXzh9DNf60h0AFotgOiURqdswy8ImpOkIEfxJAUb +TBRTXOgELjjar5b9UGRCXJ4gI4UihTpSyPICJEMUxZLwjn6c3F9pWq5T+QGE+8Zf +PCM4ahaMKiwR79bP1O7C4rY1Lhjm0Ydev3NIyA3qWZ+Z+fALWgMEViJl3YnbKG8p +OSlhb7ihPf4KbGHAvCwnd8azJJB3/HeGwfejmaMtS1+W5u4A0Z2TTc7bmjpETATF +92qgdqbW3rMEVO49FwyV1gLtZdxJ1s3j6XUBcSsH9D+pMV0+D0iVmkXMcBerT+Xg +AAGEOJKOZU0TzOn4S/B4IhTXNxZbfXJnEVNp79ezfDqDSgPYnPuG4sctTAfGXHRe +FjPR5fQCAOVkkgQrezpOUwpXP44ozyKlEQs6d698uhJUCKcmnEviY11O8ZMQYpYr +ReWt7orepOhUtJ2WNpDgTjg4bwEjC3jFsTML7H9i5+LzzJ0YD34R7tsRiQLwBBMB +CgDaBQJSCgQGwBIaaHR0cDovL21hcnRpbi1rcmFmZnQubmV0L2dwZy9jZXJ0LXBv +bGljeS81NWM5ODgyZDk5OWJiY2M0LzIwMDkwNzEyMTgzMz9zaGE1MTJzdW09ZjMz +YjE3YzlhZjUxNWJkOThiMjkyN2NiNDUzYTk5MmQzZDc1MDBlOWY2NzE5NjY2MTZl +OTA1MTBiOTk0MDg5NTEwOGQyNDE2NDhkMWEwZWI0NmIzMmJjYmYzMjUxYTEzNmE2 +ZWUxZTIyNzU3NDVlMTFiYjMyOGMxNGU3ZTcyNjMACgkQVcmILZmbvMTaXQ/+JVjn +1Wlt8sm7wTkiKIFVxYwqDa4xTfQKFMAMO+n/LJnvAEcK77X5F121sdXKcNtBSfMQ +QrplNClqVbd9wd1ix4D0auggnGaMUtgfwP5SBOf/zrYB6w5Ej1uhdLZl5YRmqOEt +7yY61TK8fGB6i5osgJE47P6OYep28Q2qK1jOtIt6HaNkKOtmfsq0wWTg7Iq/DXHS +twozq3Wi4QTLl2QAtLhKoNrmzDg4jsPQhbXARJtTnL9eHCZTML+OtJb7aca60thZ +VxEkzSElQNikJCNtlCF5PCWCvZCwGDyAMo8UGlTgjVnIunVeAWBEva4GcJJduC1M +bFpzoQyWJXtwIwD+QC71Dhl+vlmwN3wb7qnwZ5vEb5un/010v+AdMvRXpuDJs6oc +WXOrw00Fmg0AjaD9ly0dTPTYtH8olvpUO9shDd0EXr3uNFtBgJLu+X/QGhNOEzZC +YHZL8/osVgnXNfktczEI+pcnkXa06YhA6CvFgGG7s3BDMUafNsobw2hXCj2zNGbv +8Vve4po6en+pzafTFVUnsGYREv9v3eSc6R6zb4YSYSxMXCAIS4Osq5ZnMwjTHRx3 +32AYDeGlNp3tx6dzPSBCFksCdpVQzwQYh74Z+bVx9wK/10meQYEZwgXxlngy9bb8 +b6yD5pff8hHneLkaiLwwEjQuovuO0nhJGj4PTa2JAhwEEAEIAAYFAlIKFYAACgkQ +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 +=a+eH +-----END PGP PUBLIC KEY BLOCK----- diff --git a/fai/config/package_config/DEMO b/fai/config/package_config/DEMO new file mode 100644 index 0000000..ace8bad --- /dev/null +++ b/fai/config/package_config/DEMO @@ -0,0 +1,10 @@ +# some packages we need on a demo machine + +PACKAGES aptitude +fortune-mod fortunes +rstat-client #rstatd + +# only when also class XORG is defined +PACKAGES aptitude XORG +bb xpenguins +#frozen-bubble diff --git a/fai/config/package_config/FAIBASE b/fai/config/package_config/FAIBASE new file mode 100644 index 0000000..591327b --- /dev/null +++ b/fai/config/package_config/FAIBASE @@ -0,0 +1,18 @@ +PACKAGES aptitude DEBIAN +fai-client +cron +debconf-utils +file +less +linuxlogo +rdate +rsync +openssh-client openssh-server +strace +time +procinfo +nullmailer +eject +locales +console-setup kbd +pciutils usbutils diff --git a/fai/config/package_config/FAISERVER b/fai/config/package_config/FAISERVER new file mode 100644 index 0000000..ddcf458 --- /dev/null +++ b/fai/config/package_config/FAISERVER @@ -0,0 +1,14 @@ +PACKAGES aptitude +fai-quickstart + +isc-dhcp-client +debmirror tcpdump +xorriso grub-pc +lftp curl +netselect +syslinux-common pxelinux +apt-cacher-ng +nscd psmisc +bind9 dnsutils +iptables-persistent +emacs24-nox diff --git a/fai/config/package_config/GNOME b/fai/config/package_config/GNOME new file mode 100644 index 0000000..429586e --- /dev/null +++ b/fai/config/package_config/GNOME @@ -0,0 +1,10 @@ +PACKAGES aptitude + +iceweasel +#icedove +menu gdm3 +gnome-core +gconf-editor +gnome-screensaver gnome-system-monitor gnome-system-tools +gnome-network-admin +libgnomevfs2-bin diff --git a/fai/config/package_config/UBUNTU b/fai/config/package_config/UBUNTU new file mode 100644 index 0000000..6028909 --- /dev/null +++ b/fai/config/package_config/UBUNTU @@ -0,0 +1,21 @@ +PACKAGES install I386 +linux-image-generic initramfs-tools +memtest86+ + +PACKAGES install CHROOT +linux-image-generic- + +PACKAGES install AMD64 +linux-image-generic initramfs-tools +memtest86+ + +PACKAGES install DHCPC +isc-dhcp-client + +PACKAGES install GRUB_PC +grub-pc + +PACKAGES aptitude-r XORG +ubuntu-desktop +ubuntu-standard +ubuntu-minimal diff --git a/fai/config/package_config/XFCE b/fai/config/package_config/XFCE new file mode 100644 index 0000000..a248674 --- /dev/null +++ b/fai/config/package_config/XFCE @@ -0,0 +1,5 @@ +PACKAGES aptitude +xfce4 # base system +xfce4-goodies # additional tools +xdm +iceweasel diff --git a/fai/config/package_config/XORG b/fai/config/package_config/XORG new file mode 100644 index 0000000..084ef84 --- /dev/null +++ b/fai/config/package_config/XORG @@ -0,0 +1,7 @@ +PACKAGES aptitude DEBIAN +xorg xserver-xorg-video-all xserver-xorg-input-all +ttf-freefont +xscreensaver +xscreensaver-gl +xterm +desktop-base diff --git a/fai/config/scripts/CENTOS/10-security b/fai/config/scripts/CENTOS/10-security new file mode 100755 index 0000000..ecf1c23 --- /dev/null +++ b/fai/config/scripts/CENTOS/10-security @@ -0,0 +1,16 @@ +#! /bin/bash + +# (c) Michael Goetze, 2010-11, mgoetze@mgoetze.net +# Thomas Lange, 2015 + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +$ROOTCMD authconfig --enableshadow --enablemd5 \ + --enablelocauthorize --updateall +$ROOTCMD usermod -p $ROOTPW root + +fcopy -v /etc/selinux/config +$ROOTCMD fixfiles onboot # this fixes the SELinux security contexts during the first boot +chmod a+rx $target + +exit $error diff --git a/fai/config/scripts/CENTOS/30-mkinitrd b/fai/config/scripts/CENTOS/30-mkinitrd new file mode 100755 index 0000000..89357b9 --- /dev/null +++ b/fai/config/scripts/CENTOS/30-mkinitrd @@ -0,0 +1,54 @@ +#! /bin/bash + +# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net +# (c) Thomas Lange, 2011, Uni Koeln + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +ainsl -v /etc/fstab "proc /proc proc defaults 0 0" +ainsl -v /etc/fstab "sysfs /sys sysfs auto 0 0" + +version=`$ROOTCMD rpm -qv kernel | cut -d- -f2-` + +use_mkinitrd() { + + # CentOS 5 uses mkinitrd + $ROOTCMD kudzu -q -k $version + # Unfortunately mkinitrd is horrible at guessing which modules to include, + # especially when the running kernel is different than the kernel for which + # we are creating an initrd... + + drivers="" + for bus in pci virtio; do + for dr in `$ROOTCMD kudzu -p -k $version -b $bus|grep driver:|cut -d' ' -f2|sort -u`; do + found=`find $target/lib/modules/$version/ -name $dr.ko 2>/dev/null` + if [ -n "$found" ]; then + # add driver only if it's available as .ko module in the destination kernel + drivers+=" --with=$dr" + fi + done + done + + $ROOTCMD mkinitrd -f -v $drivers /boot/initrd-$version.img $version + + if [ $? -eq 1 ]; then + echo "WARNING: generating initrd with list of drivers failed. Trying without." + $ROOTCMD mkinitrd -f -v /boot/initrd-$version.img $version + fi +} + +# CentOS 5 uses mkinitrd +if [ -f $target/sbin/mkinitrd ]; then + use_mkinitrd +fi + +# call dracut for CentOS 7 +if [ -f $target/usr/sbin/dracut ]; then + # add filesystem driver into initrd + ainsl -av /etc/dracut.conf.d/fai.conf 'filesystems+="ext4"' + $ROOTCMD dracut -v --kver $version --force +fi + +# for CentOS 6 we do not need to call dracut + +exit $error diff --git a/fai/config/scripts/CENTOS/40-install-grub b/fai/config/scripts/CENTOS/40-install-grub new file mode 100755 index 0000000..6af18f2 --- /dev/null +++ b/fai/config/scripts/CENTOS/40-install-grub @@ -0,0 +1,96 @@ +#! /bin/bash + +# (c) Michael Goetze, 2011, mgoetze@mgoetze.net +# (c) Thomas Lange 2014 + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +if [ -r $LOGDIR/disk_var.sh ] ; then + . $LOGDIR/disk_var.sh +else + echo "disk_var.sh not found!" + exit 1 +fi + + +# CentOS 7 does not have a device.map file, so generate one +if [ -d $target/boot/grub2 -a ! -f $target/boot/grub2/device.map ]; then + echo "# Generated by FAI" >> $target/boot/grub2/device.map + centosdisks=$(awk '/[sv]d.$/ {print $4}' /proc/partitions | sort) + dcount=0 + for d in $centosdisks; do + echo "(hd$dcount) /dev/$d" >> $target/boot/grub2/device.map + dcount=$((dcount + 1)) + done +fi + +bootdev=`device2grub $BOOT_DEVICE` +bootpart=`device2grub $BOOT_PARTITION` +version=`$ROOTCMD rpm -qv kernel | cut -d- -f2-` + +if grep '[[:space:]]/boot[[:space:]]' $LOGDIR/fstab; then + bootdir='' +else + bootdir='/boot' +fi + +mount -o bind /dev $target/dev + + + +if [ -f $target/usr/sbin/grub2-install ]; then + + # CentOS 7 + $ROOTCMD grub2-install --no-floppy "$BOOT_DEVICE" + $ROOTCMD grub2-mkconfig --output=/boot/grub2/grub.cfg +else + +$ROOTCMD grub-install --just-copy + +$ROOTCMD grub --device-map=/dev/null --no-floppy --batch <<-EOF + device $bootdev $BOOT_DEVICE + root $bootpart + setup $bootdev + quit + EOF + +ln -s ./menu.lst $target/boot/grub/grub.conf + +if [ -f $target/boot/grub/splash.xpm.gz ]; then + pretty="splashimage=$bootpart$bootdir/grub/splash.xpm.gz" +else + pretty="color cyan/blue white/blue" +fi + +if [ -f $target/sbin/dracut -o -f $target/usr/sbin/dracut ]; then + # CentOS 6 + iname=initramfs +else + # CentOS 5 + iname=initrd +fi +title=`head -1 $target/etc/redhat-release` + +cat > $target/boot/grub/grub.conf <<-EOF + timeout 5 + default 0 + $pretty + hiddenmenu + + title $title + root $bootpart + kernel $bootdir/vmlinuz-$version root=$ROOT_PARTITION ro + initrd $bootdir/$iname-$version.img + EOF + +fi + +umount $target/dev + +echo "" +echo "Grub installed on $BOOT_DEVICE = $bootdev" +echo "Grub boot partition is $BOOT_PARTITION = $bootpart" +echo "Root partition is $ROOT_PARTITION" +echo "Boot kernel: $version" + +exit $error diff --git a/fai/config/scripts/CENTOS/50-sysconfig b/fai/config/scripts/CENTOS/50-sysconfig new file mode 100755 index 0000000..1792071 --- /dev/null +++ b/fai/config/scripts/CENTOS/50-sysconfig @@ -0,0 +1,28 @@ +#! /bin/bash + +# (c) Michael Goetze, 2011, mgoetze@mgoetze.net + +error=0 ; trap "error=$((error|1))" ERR + +cat > $target/etc/sysconfig/clock <<-EOF + UTC=$UTC + ZONE=$TIMEZONE + EOF +cat > $target/etc/sysconfig/i18n <<-EOF + LANG="$DEFAULTLOCALE" + SUPPORTED="$SUPPORTEDLOCALE" + SYSFONT="$CONSOLEFONT" + EOF +cat > $target/etc/sysconfig/keyboard <<-EOF + KEYBOARDTYPE="pc" + KEYTABLE="$KEYMAP" + EOF + +if [ -f $target/usr/lib/locale/locale-archive.tmpl \ + -a ! -s $target/usr/lib/locale/locale-archive ]; then + mv $target/usr/lib/locale/locale-archive.tmpl $target/usr/lib/locale/locale-archive +fi + +fcopy -iv /etc/sysconfig/i18n /etc/sysconfig/keyboard + +exit $error diff --git a/fai/config/scripts/CENTOS/60-network-scripts b/fai/config/scripts/CENTOS/60-network-scripts new file mode 100755 index 0000000..a9f6d91 --- /dev/null +++ b/fai/config/scripts/CENTOS/60-network-scripts @@ -0,0 +1,32 @@ +#! /bin/bash + +# (c) Michael Goetze, 2011, mgoetze@mgoetze.net + +error=0 ; trap "error=$((error|1))" ERR + +# Note: Kudzu will automatically configure eth0 for DHCP +if [ $FAI_ACTION != "softupdate" ] && ! ifclass DHCPC +then + ainsl -v /etc/sysconfig/network "^GATEWAY=$GATEWAYS_1\$" + [ -n "$IPADDR" ] && cat > $target/etc/sysconfig/network-scripts/ifcfg-eth0 <<-EOF + # generated by FAI + DEVICE=eth0 + BOOTPROTO=static + ONBOOT=yes + HWADDR=`ip l sh dev eth0 | tail -1 | cut -d" " -f6` + IPADDR=$IPADDR + NETMASK=$NETMASK + EOF + # Kudzu for some reason won't write eth0 into /etc/sysconfig/hwconf + # from within the chroot. The following hack puts it in there + # so that Kudzu doesn't overwrite our config on first boot. + if [ -f $target/sbin/kudzu ]; then + grep eth0 $target/etc/sysconfig/hwconf || $ROOTCMD kudzu -c NETWORK -p \ + >> $target/etc/sysconfig/hwconf + fi +fi + +fcopy -iv /etc/sysconfig/network /etc/resolv.conf /etc/networks +fcopy -ivr /etc/sysconfig/network-scripts + +exit $error diff --git a/fai/config/scripts/CENTOS/80-misc b/fai/config/scripts/CENTOS/80-misc new file mode 100755 index 0000000..f4ab9ac --- /dev/null +++ b/fai/config/scripts/CENTOS/80-misc @@ -0,0 +1,18 @@ +#! /bin/bash + +error=0 ; trap "error=$((error|1))" ERR + +# add a demo user account +if ! $ROOTCMD getent passwd demo ; then + $ROOTCMD adduser -c "fai demo user" demo + $ROOTCMD usermod -p "$ROOTPW" demo +fi + +# enable graphical login screen, make run level 5 as default +if [ -f $target/usr/sbin/gdm ]; then + sed -i -e 's/id:3:initdefault:/id:5:initdefault:/' $target/etc/inittab + # do not run this tool + echo "RUN_FIRSTBOOT=NO" > $target/etc/sysconfig/firstboot +fi + +exit $error diff --git a/fai/config/scripts/CENTOS/90-cleanup b/fai/config/scripts/CENTOS/90-cleanup new file mode 100755 index 0000000..2eadacd --- /dev/null +++ b/fai/config/scripts/CENTOS/90-cleanup @@ -0,0 +1,3 @@ +#! /bin/bash + +$ROOTCMD yum clean all diff --git a/fai/config/scripts/DEBIAN/10-rootpw b/fai/config/scripts/DEBIAN/10-rootpw new file mode 100755 index 0000000..fe08f9d --- /dev/null +++ b/fai/config/scripts/DEBIAN/10-rootpw @@ -0,0 +1,8 @@ +#! /bin/bash + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +# set root password +$ROOTCMD usermod -p $ROOTPW root + +exit $error diff --git a/fai/config/scripts/DEBIAN/20-capabilities b/fai/config/scripts/DEBIAN/20-capabilities new file mode 100755 index 0000000..6e63c92 --- /dev/null +++ b/fai/config/scripts/DEBIAN/20-capabilities @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Capabilities get lost when creating the fai base.tar.xz image. +# Restore them here. +# + +set -e + +if [ ! -x $target/sbin/setcap ] ; then + exit 0 +fi + +for FILE in /bin/ping /bin/ping6 /usr/bin/fping /usr/bin/fping6; do + if [ -x $target/$FILE ] ; then + if $ROOTCMD /sbin/setcap cap_net_raw+ep $FILE; then + echo "Setcap worked! $FILE is not suid!" + fi + fi +done +if [ -x $target/usr/bin/systemd-detect-virt ] ; then + $ROOTCMD /sbin/setcap cap_dac_override,cap_sys_ptrace+ep /usr/bin/systemd-detect-virt +fi diff --git a/fai/config/scripts/DEBIAN/30-interface b/fai/config/scripts/DEBIAN/30-interface new file mode 100755 index 0000000..c3fbeaa --- /dev/null +++ b/fai/config/scripts/DEBIAN/30-interface @@ -0,0 +1,36 @@ +#! /bin/bash + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +if ifclass DHCPC && [ $FAI_ACTION = "install" ] +then + cat > $target/etc/network/interfaces <<-EOF + # generated by FAI + auto lo $NIC1 + iface lo inet loopback + iface $NIC1 inet dhcp +EOF +elif [ $FAI_ACTION = "install" ] +then + [ -n "$IPADDR" ] && cat > $target/etc/network/interfaces <<-EOF + # generated by FAI + auto lo $NIC1 + iface lo inet loopback + iface $NIC1 inet static + address $IPADDR + netmask $NETMASK + broadcast $BROADCAST + gateway $GATEWAYS +EOF + [ -n "$NETWORK" ] && echo "localnet $NETWORK" > $target/etc/networks + if [ ! -L $target/etc/resolv.conf -a -e /etc/resolv.conf ]; then + cp -p /etc/resolv.conf $target/etc + fi +fi + +# here fcopy is mostly used, when installing a client for running in a +# different subnet than during the installation +fcopy -iM /etc/resolv.conf +fcopy -iM /etc/network/interfaces /etc/networks + +exit $error diff --git a/fai/config/scripts/DEBIAN/40-misc b/fai/config/scripts/DEBIAN/40-misc new file mode 100755 index 0000000..f2a6578 --- /dev/null +++ b/fai/config/scripts/DEBIAN/40-misc @@ -0,0 +1,44 @@ +#! /bin/bash + +# (c) Thomas Lange, 2001-2015, lange@debian.org +# (c) Michael Goetze, 2010-2011, mgoetze@mgoetze.net + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +# a list of modules which are loaded at boot time +for module in $MODULESLIST; do + ainsl -a /etc/modules "^$module$" +done + +fcopy -Mv /etc/hostname || echo $HOSTNAME > $target/etc/hostname +ainsl -av /etc/mailname ${HOSTNAME} +if [ ! -e $target/etc/adjtime ]; then + printf "0.0 0 0.0\n0\nUTC" > $target/etc/adjtime +fi +if [ "$UTC" = "yes" ]; then + sed -i -e 's:^LOCAL$:UTC:' $target/etc/adjtime +else + sed -i -e 's:^UTC$:LOCAL:' $target/etc/adjtime +fi + +# enable linuxlogo +if [ -f $target/etc/inittab ]; then + sed -i -e 's#/sbin/getty 38400#/sbin/getty -f /etc/issue.linuxlogo 38400#' ${target}/etc/inittab +elif [ -f $target/lib/systemd/system/getty@.service ]; then + sed -i -e 's#sbin/agetty --noclear#sbin/agetty -f /etc/issue.linuxlogo --noclear#' $target/lib/systemd/system/getty@.service +fi + +if [ ! -f $target/etc/machine-id -a -f $target/bin/systemd-machine-id-setup ]; then + $ROOTCMD systemd-machine-id-setup +fi + +ln -fs /proc/mounts $target/etc/mtab + +rm -f $target/etc/dpkg/dpkg.cfg.d/fai + +[ $FAI_ACTION = "install" -a -f /etc/fai/fai.conf ] && cp /etc/fai/fai.conf $target/etc/fai/fai.conf +ainsl -av /etc/fai/fai.conf "FAI_CONFIG_SRC=$FAI_CONFIG_SRC" + +fcopy -Miv /etc/fai/fai.conf + +exit $error diff --git a/fai/config/scripts/DEMO/10-misc b/fai/config/scripts/DEMO/10-misc new file mode 100755 index 0000000..45f0573 --- /dev/null +++ b/fai/config/scripts/DEMO/10-misc @@ -0,0 +1,24 @@ +#! /bin/bash + +# (c) Thomas Lange, 2001-2013, lange@debian.org + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +ifclass XORG && { + fcopy -M /etc/X11/xorg.conf +} + +if ifclass UBUNTU; then + groups="adm cdrom sudo dip plugdev lpadmin sambashare" + $ROOTCMD addgroup --system lpadmin || true + $ROOTCMD addgroup --system sambashare || true +fi + +# add a demo user account +if ! $ROOTCMD getent passwd demo ; then + $ROOTCMD adduser --disabled-login --gecos "fai demo user" demo + $ROOTCMD usermod -p "$ROOTPW" demo + for g in $groups; do + $ROOTCMD adduser demo $g + done +fi diff --git a/fai/config/scripts/FAIBASE/10-misc b/fai/config/scripts/FAIBASE/10-misc new file mode 100755 index 0000000..6394ad2 --- /dev/null +++ b/fai/config/scripts/FAIBASE/10-misc @@ -0,0 +1,27 @@ +#! /bin/bash + +# (c) Thomas Lange, 2001-2012, lange@debian.org + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +echo $TIMEZONE > $target/etc/timezone +cp -f /usr/share/zoneinfo/${TIMEZONE} $target/etc/localtime + +if [ -n "$IPADDR" ]; then + ifclass DHCPC || ainsl -s /etc/hosts "$IPADDR $HOSTNAME.$DOMAIN $HOSTNAME" +else + ifclass DHCPC && ainsl -s /etc/hosts "127.0.0.1 $HOSTNAME" +fi + +fcopy -iM /etc/hosts /etc/motd + +# make /root accessible only by root +chmod -c 0700 $target/root +chown -c root:root $target/root +# copy default dotfiles for root account +fcopy -ir /root + +chmod -c 1777 ${target}/tmp +chown -c 0:0 ${target}/tmp + +exit $error diff --git a/fai/config/scripts/FAIBASE/20-removable_media b/fai/config/scripts/FAIBASE/20-removable_media new file mode 100755 index 0000000..4ba258f --- /dev/null +++ b/fai/config/scripts/FAIBASE/20-removable_media @@ -0,0 +1,27 @@ +#! /bin/bash + +# (c) Thomas Lange, 2006,2009, lange@debian.org +# create entries for removable media in fstab and directories in /media + +[ -b $target/dev/fd0 ] && ainsl /etc/fstab "/dev/fd0 /media/floppy auto users,noauto 0 0" + +cdromlist() { + [ -f /proc/sys/dev/cdrom/info ] || return + devs=$(grep 'drive name:' /proc/sys/dev/cdrom/info | cut -d ":" -f 2) + for d in $devs; do + echo $d + done +} + +fstabline () { + line=$(printf "%-15s %-15s %-7s %-15s %-7s %s\n" "$1" "$2" "$3" "$4" "$5" "$6") + ainsl /etc/fstab "$line" +} + +i=0 +for cdrom in $(cdromlist | tac); do + [ $i -eq 0 ] && ln -sfn cdrom0 $target/media/cdrom + mkdir -p $target/media/cdrom$i + fstabline /dev/$cdrom /media/cdrom$i udf,iso9660 ro,user,noauto 0 0 + i=$(($i + 1)) +done diff --git a/fai/config/scripts/FAISERVER/10-conffiles b/fai/config/scripts/FAISERVER/10-conffiles new file mode 100755 index 0000000..4bf2ed2 --- /dev/null +++ b/fai/config/scripts/FAISERVER/10-conffiles @@ -0,0 +1,46 @@ +#! /bin/bash + +fcopy -Bvr /etc/fai +fcopy -Bv /etc/fai/apt/sources.list /etc/dhcp/dhcpd.conf +fcopy -v /etc/rc.local + +if [ $FAI_ACTION = "install" ]; then + + # use the same sources.list for the server itself and the clients + cp -a $target/etc/fai/apt $target/etc/ + + if ifclass DHCPC; then + rm -f $target/etc/resolv.conf + else + echo 127.0.0.1 > $target/etc/resolv.conf + fi + + # faiserver uses its own apt cache + ainsl -av /etc/apt/apt.conf.d/02proxy 'Acquire::http::Proxy "http://127.0.0.1:3142";' + + # create some host entries + myip=$(ip addr show up| grep -w inet | cut -d t -f 2 | cut -d ' ' -f 2 | cut -d / -f 1 | grep -v 127.0.0.1) + ainsl /etc/hosts "$myip faiserver" # that's me + ainsl /etc/hosts "192.168.33.100 demohost" + ainsl /etc/hosts "192.168.33.101 xfcehost" + # add entries for 10 hosts called client 01 .. 10 + perl -e 'for (1..10) {printf "192.168.33.%s client%02s\n",101+$_,$_;}' >> $target/etc/hosts + + sed -i -e '/# ReuseConnections: 1/d' $target/etc/apt-cacher-ng/acng.conf + ainsl -v /etc/apt-cacher-ng/acng.conf "ReuseConnections: 0" + + # copy base file for faster building of nfsroot + cp -p /var/tmp/base.tar.xz $target/var/tmp + + if [ -d /media/mirror/pool ]; then + mkdir $target/var/cache/apt-cacher-ng/_import + cp -p /media/mirror/pool/*/*/*/*.deb $target/var/cache/apt-cacher-ng/_import + $ROOTCMD chown -R apt-cacher-ng.apt-cacher-ng /var/cache/apt-cacher-ng/_import + fi + + # copy basefiles from CD to config space + if [ -d $FAI/basefiles ]; then + mkdir -p $target/srv/fai/config/basefiles + cp -vp $FAI/basefiles/*.tar.* $target/srv/fai/config/basefiles 2>/dev/null + fi +fi diff --git a/fai/config/scripts/GRUB_PC/10-setup b/fai/config/scripts/GRUB_PC/10-setup new file mode 100755 index 0000000..c945daf --- /dev/null +++ b/fai/config/scripts/GRUB_PC/10-setup @@ -0,0 +1,42 @@ +#! /bin/bash +# support for GRUB version 2 + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +set -a +# during softupdate use this file +[ -r $LOGDIR/disk_var.sh ] && . $LOGDIR/disk_var.sh + +if [ -z "$BOOT_DEVICE" ]; then + exit 189 +fi + +# disable os-prober because of #788062 +ainsl /etc/default/grub 'GRUB_DISABLE_OS_PROBER=true' + +# skip the rest, if not an initial installation +if [ $FAI_ACTION != "install" ]; then + $ROOTCMD update-grub + exit $error +fi + +$ROOTCMD grub-mkdevicemap --no-floppy +GROOT=$($ROOTCMD grub-probe -tdrive -d $BOOT_DEVICE) + +# Check if RAID is used for the boot device +if [[ $BOOT_DEVICE =~ '/dev/md' ]]; then + raiddev=${BOOT_DEVICE#/dev/} + # install grub on all members of RAID + for device in `LC_ALL=C perl -ne 'if(/^'$raiddev'\s.+raid\d+\s(.+)/){ $_=$1; s/\d+\[\d+\]//g; print }' /proc/mdstat`; do + echo Install grub on /dev/$device + $ROOTCMD grub-install --no-floppy "/dev/$device" + done +else + $ROOTCMD grub-install --no-floppy "$GROOT" + if [ $? -eq 0 ]; then + echo "Grub installed on $BOOT_DEVICE = $GROOT" + fi +fi +$ROOTCMD update-grub + +exit $error diff --git a/fai/config/scripts/LAST/50-misc b/fai/config/scripts/LAST/50-misc new file mode 100755 index 0000000..62c31db --- /dev/null +++ b/fai/config/scripts/LAST/50-misc @@ -0,0 +1,57 @@ +#! /bin/bash + +# copyright Thomas Lange 2001-2015, lange@debian.org + +error=0; trap 'error=$(($?>$error?$?:$error))' ERR # save maximum error code + +# check if mdadm has been forgotten +if grep -q active /proc/mdstat 2>/dev/null; then + if [ ! -d $target/etc/mdadm ]; then + echo ERROR: Found Software RAID, but the mdadm package was not installed + error=1 + fi +fi + +usedm=$(dmsetup ls | egrep -v '^live-rw|^live-base|^No devices found' | wc -l) +if [ $usedm -ne 0 ]; then + if [ ! -d $target/etc/lvm ]; then + echo ERROR: Found lvm devices, but the lvm2 package was not installed + error=1 + fi +fi + +# remove backup files from cfengine, but only if cfengine is installed +if [ -x /usr/sbin/cfagent ] || [ -x $target/usr/sbin/cfagent ] ; then + dirs="root etc var" + for path in $dirs; do + find $target/$path -maxdepth 20 -name \*.cfedited -o -name \*.cfsaved | xargs -r rm + done +fi + +[ "$FAI_DEBMIRROR" ] && + ainsl /etc/fstab "#$FAI_DEBMIRROR $MNTPOINT nfs ro 0 0" + +# set bios clock +if [ $do_init_tasks -eq 1 ] ; then + case "$UTC" in + no|"") hwopt="--localtime" ;; + yes) hwopt="--utc" ;; + esac + hwclock $hwopt --systohc || true +fi + +# Make sure everything is configured properly +if ifclass DEBIAN ; then + echo "Running \"apt-get -f install\" for the last time." + $ROOTCMD apt-get -f install +fi + +if [ $FAI_ACTION = "install" ]; then + lskernels=$(echo $target/boot/vmlinu*) + [ -f ${lskernels%% *} ] || echo "ERROR: No kernel was installed. Have a look at shell.log" >&2 +fi + +# copy sources.list +fcopy -iM /etc/apt/sources.list + +exit $error diff --git a/fai/config/scripts/UBUNTU/90-apt b/fai/config/scripts/UBUNTU/90-apt new file mode 100755 index 0000000..072e560 --- /dev/null +++ b/fai/config/scripts/UBUNTU/90-apt @@ -0,0 +1,18 @@ +#! /bin/bash + +# check if we already use an external mirror +grep -q "external mirror" $target/etc/apt/sources.list && exit 0 + +dist=trusty + +cat < $target/etc/apt/sources.list +# external mirror +deb MIRRORURL $dist main restricted universe multiverse +deb MIRRORURL $dist-updates main restricted universe multiverse +deb MIRRORURL $dist-security main restricted universe multiverse +EOM + +# determine a fast mirror for Ubuntu +list=$(curl -s http://mirrors.ubuntu.com/mirrors.txt) +mirror=$(netselect $list | awk '{print $2}') +sed -i -e "s#MIRRORURL#$mirror#" $target/etc/apt/sources.list diff --git a/fai/config/tests/FAIBASE_TEST b/fai/config/tests/FAIBASE_TEST new file mode 100755 index 0000000..79bfab2 --- /dev/null +++ b/fai/config/tests/FAIBASE_TEST @@ -0,0 +1,44 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use Faitest; +package FAITEST; + +setup_test(); +# - - - - - - - - - - - - - - - - - - - - - - - - - - +# now comes the test itself + +my $dev = &getDevByMount("/target/home"); +&checkE2fsAttribute($dev,"Filesystem volume name","home"); +&checkE2fsAttribute($dev,"Maximum mount count","-1"); +&checkE2fsAttribute($dev,"Check interval","0 ()"); + +exit printresult(); +# - - - - - - - - - - - - - - - - - - - - - - - - - - +__END__ + +=head1 NAME + +FAIBASE_TEST - regression test for setup-storage disk layout FAIBASE + +=head1 SYNOPSIS + +FAIBASE_TEST checks some important aspects of setup-storage. The +disk_config/FAIBASE tunes some filesystem parameters upon creation. We +check only the last partition since we expect prior errors to make +creation of the last partition fail. + + Options: + -help simple help + -verbose=n increase verbosity of test script + +=head1 OPTIONS + +=over 8 + +=item B<-help> +simple help + +=item B<-verbose> +increase verbosity of test script diff --git a/fai/config/tests/Faitest.pm b/fai/config/tests/Faitest.pm new file mode 100644 index 0000000..022b407 --- /dev/null +++ b/fai/config/tests/Faitest.pm @@ -0,0 +1,96 @@ +#! /usr/bin/perl + +# Subroutines for automatic tests +# +# Copyright (C) 2009 Thomas Lange, lange@informatik.uni-koeln.de +# Based on the first version by Sebastian Hetze, 08/2008 + +package FAITEST; + +my $errors = 0; + +use strict; +use Getopt::Long; +use Pod::Usage; +# - - - - - - - - - - - - - - - - - - - - - - - - - - +sub setup_test { + + my $verbose = 0; + my $help = 0; + my $man = 0; + $verbose = $ENV{'debug'} if $ENV{'debug'}; + + my $result = GetOptions ( + "verbose=i" => \$verbose, + "help" => \$help, + "man" => \$man, + + ); + + pod2usage(1) if $help; + pod2usage(-exitstatus => 0, -verbose => 2) if $man; + + open(LOGFILE,">> $ENV{LOGDIR}/test.log") || die "Can't open test.log. $!"; + print LOGFILE "------------ Test $0 starting ------------\n"; +} + +sub printresult { + + # write test result and set next test + my ($nexttest) = @_; + + if ($errors > 0) { + print STDERR "\n===> $0 FAILED with $errors errors\n"; + print LOGFILE "\n===> $0 FAILED with $errors errors\n"; + } else { + print STDERR "\n===> $0 PASSED successfully\n"; + print LOGFILE "\n===> $0 PASSED successfully\n"; + print LOGFILE "NEXTTEST=$nexttest\n" if $nexttest; + } + close (LOGFILE); + return $errors; +} + +sub getDevByMount { + + my $mount = shift; + my $dev = qx#mount|grep $mount|cut -d' ' -f1#; + chomp $dev; + return $dev +} + +sub checkMdStat { + + my ($device, $expected) = @_; + my ($value) = qx#grep -i "^$device\\b" /proc/mdstat# =~ m/$device\s*:\s*(.*)/i; + + if ($value eq $expected) { + print LOGFILE "Check raid $device success\n"; + return 0; + } else { + print LOGFILE "Check raid $device FAILED.\n Expect <$expected>\n Found <$value>\n"; + $errors++; + return 1; + } +} + +sub checkE2fsAttribute { + + my ($device, $attribute, $expected) = @_; + + # since attribute is a space separated list of attributes, IMO we must loop over + # the list. Ask Sebastian again + my ($value) = qx#tune2fs -l $device |grep -i "$attribute"# =~ m/$attribute:\s+(.*)/i; + + if ($value eq $expected) { + print LOGFILE "Check $attribute for $device success\n"; + return 0; + } else { + print LOGFILE "Check $attribute for $device FAILED.\n Expect <$expected>\n Found <$value>\n"; + + $errors++; + return 1; + } +} + +1; diff --git a/fai/debconf/GERMAN b/fai/debconf/GERMAN new file mode 100644 index 0000000..a1fbc27 --- /dev/null +++ b/fai/debconf/GERMAN @@ -0,0 +1,8 @@ +locales locales/default_environment_locale select de_DE.UTF-8 +locales locales/locales_to_be_generated multiselect de_DE.UTF-8 UTF-8 +keyboard-configuration keyboard-configuration/modelcode string pc105 +keyboard-configuration keyboard-configuration/xkb-keymap select de +keyboard-configuration keyboard-configuration/variant select Germany +keyboard-configuration keyboard-configuration/model select Generic 105-key (Intl) PC +keyboard-configuration keyboard-configuration/layoutcode string de +keyboard-configuration keyboard-configuration/optionscode string ctrl:nocaps,terminate:ctrl_alt_bksp diff --git a/fai/disk_config/CENTOS b/fai/disk_config/CENTOS new file mode 100644 index 0000000..99bf0b5 --- /dev/null +++ b/fai/disk_config/CENTOS @@ -0,0 +1,17 @@ +# example of new config file for setup-storage +# +# + +disk_config disk1 disklabel:msdos bootable:1 fstabkey:label + +# Note that the CentOS 5 version of GRUB cannot read from ext3 filesystems with inode_size > 128 +# CentOS 5.6 needs /boot as ext3, so we use ext3 for / + +#primary / 350 ext3 rw,noatime,errors=remount-ro createopts="-L ROOT -I 128" + +# use following line for CentOS 7 +primary / 4G-10G ext4 rw,noatime,errors=remount-ro createopts="-L ROOT" + +logical swap 200-1000 swap sw createopts="-L SWAP" +logical /tmp 100-1G ext4 rw,noatime,nosuid,nodev createopts="-L TMP -m 0" tuneopts="-c 0 -i 0" +logical /home 100-50% ext4 rw,noatime,nosuid,nodev createopts="-L HOME -m 1" tuneopts="-c 0 -i 0" diff --git a/fai/disk_config/FAIBASE b/fai/disk_config/FAIBASE new file mode 100644 index 0000000..c6d2d3e --- /dev/null +++ b/fai/disk_config/FAIBASE @@ -0,0 +1,10 @@ +# example of new config file for setup-storage +# +# + +disk_config disk1 disklabel:msdos bootable:1 fstabkey:uuid + +primary / 2G-15G ext4 rw,noatime,errors=remount-ro +logical swap 200-1G swap sw +logical /tmp 100-1G ext4 rw,noatime,nosuid,nodev createopts="-L tmp -m 0" tuneopts="-c 0 -i 0" +logical /home 100-50% ext4 rw,noatime,nosuid,nodev createopts="-L home -m 1" tuneopts="-c 0 -i 0" diff --git a/fai/disk_config/FAISERVER b/fai/disk_config/FAISERVER new file mode 100644 index 0000000..29bf219 --- /dev/null +++ b/fai/disk_config/FAISERVER @@ -0,0 +1,11 @@ +# config file for an FAI install server +# +# + +disk_config disk1 disklabel:msdos fstabkey:uuid + +primary / 2G-15G ext4 rw,noatime,errors=remount-ro +logical swap 200-1000 swap sw +logical /tmp 100-1000 ext4 rw,noatime,nosuid,nodev createopts="-m 0" tuneopts="-c 0 -i 0" +logical /home 100-40% ext4 rw,noatime,nosuid,nodev createopts="-m 1" tuneopts="-c 0 -i 0" +logical /srv 1G-50% ext4 rw,noatime createopts="-m 1" tuneopts="-c 0 -i 0" diff --git a/fai/disk_config/LVM b/fai/disk_config/LVM new file mode 100644 index 0000000..f1b43fc --- /dev/null +++ b/fai/disk_config/LVM @@ -0,0 +1,15 @@ +# + +# entire disk with LVM, separate /home + +disk_config disk1 fstabkey:uuid align-at:1M + +primary /boot 200 ext2 rw,noatime +primary - 4G- - - + +disk_config lvm + +vg vg1 disk1.2 +vg1-root / 3G-15G ext4 noatime,rw +vg1-swap swap 200-4G swap sw +vg1-home /home 600- ext4 noatime,nosuid,nodev,rw diff --git a/fai/package_config/GERMAN b/fai/package_config/GERMAN new file mode 100644 index 0000000..6ef01fa --- /dev/null +++ b/fai/package_config/GERMAN @@ -0,0 +1,5 @@ +PACKAGES aptitude +task-german + +PACKAGES aptitude GNOME +iceweasel-l10n-de icedove-l10n-de