#!/bin/sh

# This small shell script sets various iDRAC configuration
# so that the serial console can work by default.

set -e

PRODUCT_NAME=$(dmidecode -s system-product-name)

if [ "${PRODUCT_NAME}" = "PowerEdge R410" ] || [ "${PRODUCT_NAME}" = "PowerEdge R610" ] ; then
	# This fixes a security problem on this type of hardware, where it's possible
	# otherwise to create an IPMI user without being authenticated.
	ipmitool lan set 1 cipher_privs Xaaaaaaaaaaaaaa
	IPMI_TYPE=iDRAC6
else
	IPMI_TYPE=$(ipmitool sdr elist mcloc | awk '{print $1}')
fi

if ! [ -x /usr/bin/racadm ] ; then
	exit 0
fi

JOB=no

if [ "${IPMI_TYPE}" = "iDRAC6" ] || [ "${IPMI_TYPE}" = "iDRAC7" ] || [ "${IPMI_TYPE}" = "iDRAC8" ] || [ "${IPMI_TYPE}" = "iDRAC9" ] ; then
	RACADM=racadm

	if [ "${IPMI_TYPE}" = "iDRAC6" ] || [ "${IPMI_TYPE}" = "iDRAC7" ] ; then
		${RACADM} config -g cfgLanNetworking -o cfgDNSDomainNameFromDHCP 0
		${RACADM} config -g cfgIpmiLan -o cfgIpmiLanEnable 1

		${RACADM} config -g cfgNetTuning -o cfgNetTuningNicAutoneg 1
		${RACADM} config -g cfgNetTuning -o cfgNetTuningNicFullDuplex 1
		${RACADM} config -g cfgNetTuning -o cfgNetTuningNicMtu 1500

		# Serial over LAN config setup
		${RACADM} config -g cfgUserAdmin -o cfgUserAdminSolEnable 1 -i 2
		${RACADM} config -g cfgSerial -o cfgSerialBaudRate 115200
		${RACADM} config -g cfgSerial -o cfgSerialConsoleEnable 1
		${RACADM} config -g cfgSerial -o cfgSerialConsoleIdleTimeout 0
		${RACADM} config -g cfgSerial -o cfgSerialConsoleNoAuth 1
		${RACADM} config -g cfgSerial -o cfgSerialSshEnable 1
		${RACADM} config -g cfgSerial -o cfgSerialCom2RedirEnable 1
		${RACADM} config -g cfgIpmiSol -o cfgIpmiSolEnable 1
		${RACADM} config -g cfgIpmiSol -o cfgIpmiSolBaudRate 115200
		${RACADM} config -g cfgIpmiSerial -o cfgIpmiSerialBaudRate 115200
		${RACADM} config -g cfgIpmiSerial -o cfgIpmiSerialConnectionMode 1
		${RACADM} config -g cfgIpmiSerial -o cfgIpmiSerialHandshakeControl 1

		# Activate the web interface:
		${RACADM} config -g cfgRacTuning -o cfgRacTuneWebserverEnable 1
		${RACADM} config -g cfgRacTuning -o cfgRacTuneRemoteRacadmEnable 1
		${RACADM} config -g cfgRacTuning -o cfgRacTuneVirtualConsoleAuthorizeMultipleSessions 1

		# First boot device
		#${RACADM} config -g cfgServerInfo -o cfgServerFirstBootDevice PXE
	else
		# Make sure the user 2 is activated
		${RACADM} set iDRAC.Users.2.Enable Enabled

		# Various general BIOS settings
		${RACADM} set BIOS.SysSecurity.AcPwrRcvry On

		# IPMI ip configuration
		${RACADM} set iDRAC.IPv4.DHCPEnable Disabled
		${RACADM} set iDRAC.IPv4.DNSFromDHCP Disabled
		${RACADM} set iDRAC.IPv4.Enable Enabled
		${RACADM} set iDRAC.IPv4Static.DNSFromDHCP Disabled

		# IPMI NIC configuration
		${RACADM} set iDRAC.NIC.Failover All
		${RACADM} set iDRAC.NIC.Enable Enabled
		${RACADM} set iDRAC.IPMILan.Enable Enabled

		# Default is GMT+5 (ie: us east coast), let's fix this
		${RACADM} set iDRAC.Time.Timezone UTC

		# IPMI serial config
		${RACADM} set BIOS.SerialCommSettings.RedirAfterBoot Enabled

		${RACADM} set BIOS.SerialCommSettings.ConTermType Vt100Vt220
		if [ "${PRODUCT_NAME}" = "PowerEdge R6525" ] ; then
			SERIAL_PORT_ADDR=$(${RACADM} get BIOS.SerialCommSettings.SerialPortAddress | grep SerialPortAddress | cut -d= -f2)
			if ! [ "${SERIAL_PORT_ADDR}" != "Com2" ] ; then
				${RACADM} set BIOS.SerialCommSettings.SerialPortAddress Com2
				JOB=yes
			fi
		else
			${RACADM} set BIOS.SerialCommSettings.ExtSerialConnector Serial1
			SERIAL_COM=$(${RACADM} get BIOS.SerialCommSettings.SerialComm | grep SerialComm= | cut -d= -f2)
			if ! [ "${SERIAL_COM}" = "OnConRedirCom2" ] ; then
				${RACADM} set BIOS.SerialCommSettings.SerialComm OnConRedirCom2
				JOB=yes
			fi
			SERIAL_PORT_ADDR=$(${RACADM} get BIOS.SerialCommSettings.SerialPortAddress | grep SerialPortAddress | cut -d= -f2)
			if ! [ "${SERIAL_PORT_ADDR}" = "Serial1Com1Serial2Com2" ] ; then
				${RACADM} set BIOS.SerialCommSettings.SerialPortAddress Serial1Com1Serial2Com2
				JOB=yes
			fi
		fi

		# Disable embedded network cards in these machines,
		# as it gets on the way for proper boot on additional PCI
		# cards (like Mellanox Connect-X 5)
		if [ "${PRODUCT_NAME}" = "PowerEdge R6525" ] ; then
			EMBEDDED_NICS_DISABLED=$(${RACADM} get BIOS.IntegratedDevices.EmbNic1Nic2 | grep EmbNic1Nic2 | cut -d= -f2)
			if [ "${EMBEDDED_NICS_DISABLED}" != "DisabledOs" ] ; then
				racadm set BIOS.IntegratedDevices.EmbNic1Nic2 DisabledOs
				JOB=yes
			fi
		fi

		${RACADM} set iDRAC.IPMISerial.BaudRate 115200
		${RACADM} set iDRAC.IPMISerial.FlowControl RTS/CTS
		${RACADM} set iDRAC.IPMISerial.HandshakeControl Enabled
		${RACADM} set iDRAC.IPMISOL.BaudRate 115200
		${RACADM} set iDRAC.IPMISOL.Enable Enabled
		${RACADM} set iDRAC.Serial.BaudRate 115200
		${RACADM} set iDRAC.Serial.Enable Enabled
		${RACADM} set iDRAC.SerialRedirection.Enable Enabled
		if [ "${PRODUCT_NAME}" = "PowerEdge R6525" ] ; then
			COM_PORT=$(${RACADM} get BIOS.SerialCommSettings.SerialPortAddress | grep SerialPortAddress | cut -d= -f2)
			if [ "${COM_PORT}" != "Com2" ] ; then
				${RACADM} set BIOS.SerialCommSettings.SerialPortAddress Com2
				JOB=yes
			fi
		fi

		# Enable the WEB interface
		${RACADM} set iDRAC.WebServer.Enable Enabled

		# SATA settings
		${RACADM} set BIOS.SataSettings.EmbSata AhciMode

		# NUMA Node Per Socket (NPS):
		if [ "${PRODUCT_NAME}" = "PowerEdge R6525" ] ; then
			CPU_MODEL=$(lscpu | grep "Model name:" | sed -e 's/Model name://')
			if echo "${CPU_MODEL}" | grep -q "AMD EPYC" ; then
				AMD_CPU_NAME=$(echo "${CPU_MODEL}" | sed -e 's/AMD EPYC //' | awk '{print $1}')
				case "${AMD_CPU_NAME}" in
				7H12|7F32|7F52|7262|7302|7352|7402|7452|7502|7532|7542|7642|7662|7702|7742)
					NUMA_NPS=4
				;;
				7F72|7552)
					NUMA_NPS=2
				;;
				7252|7272|7282)
					NUMA_NPS=1
				;;
				*)
				;;
				esac
				CUR_VALUE=$(racadm get BIOS.ProcSettings.NumaNodesPerSocket | grep NumaNodesPerSocket | cut -d= -f2 | awk '{print $1}')
				if [ "${CUR_VALUE}" != "${NUMA_NPS}" ] ; then
					racadm set BIOS.ProcSettings.NumaNodesPerSocket "${NUMA_NPS}"
					JOB=yes
				fi
			fi
		fi

		# Some CPU settings
		VIRTU_ON=$(${RACADM} get BIOS.ProcSettings.ProcVirtualization | grep ProcVirtualization | cut -d= -f2)
		if ! [ "${VIRTU_ON}" = "Enabled" ] ; then
			${RACADM} set BIOS.ProcSettings.ProcVirtualization Enabled
			JOB=yes
		fi
		if [ "${PRODUCT_NAME}" = "PowerEdge R6525" ] ; then
			echo "No BIOS.ProcSettings.ProcAdjCacheLine in PowerEdge R6525"
		else
			ADJ_CACHE_LINE=$(${RACADM} get BIOS.ProcSettings.ProcAdjCacheLine | grep ProcAdjCacheLine | cut -d= -f2)
			if ! [ "${ADJ_CACHE_LINE}" = "Enabled" ] ; then
				${RACADM} set BIOS.ProcSettings.ProcAdjCacheLine Enabled
				JOB=yes
			fi
		fi
		if [ "${JOB}" = "yes" ] ; then
			# This creates a job on next reboot, as some settings needs this.
			${RACADM} jobqueue create BIOS.Setup.1-1
		fi
	fi
fi

exit 0
