summaryrefslogblamecommitdiffstats
path: root/core/modules/dnbd3-proxy-mode/data/opt/openslx/scripts/systemd-setup_dnbd3_proxy
blob: 47ad92d8b02a00094c0165cc3e13bae330801f25 (plain) (tree)
1
2
3
4
5
6
7
8



                                                          

                             
                                                                      
 




















                                                                                          



                                                                     


                                                                   

                              




                                               

 
                                              
             








                                              

 
               
                                                             
                                  
                                       
                                                        

  
                                                    
                                                  












                                                                                    
    
                                                                                                           
  
 


                                                        




                                                                   

            
 
                                     
                                                                                             
  


                                                                

                                                          
                                                                



                                                                        
 



























                                                                           
                           

                                                                                                           




                                                                                                                                      
                            
                                     
                               



                                                                                  
                                                                                                                                                                                         



                    
                           
                                    
                         
                               
                            












                                                         
                                                                                        





                                                                                  
                                                           
                                          
                                                
                                                                                                                                                               















                                                                       
                                                








                                                                                                                      
 














                                                                                        
                                                                             




                                                                     
                                                                                       


         
                                    
 
                                     




                                                                               
                                     

               
                                  
                                      
               
                                     
                           
                         
                  
                   
                                     
                                         
 
        
              
                                           
 
         
                                    

   








                                                                             
                                                          
                                                          
                                 
 
                                            
                                 
                                 



                                                                
 
                          


                                                           
                                                                
                                                                                 
  
 
      
 
#!/bin/ash
# This scripts runs as root and prepares the configuration
# for the dnbd3 server (...)

ERRLOG="/run/dnbd3-proxy.err"

[ -s "$ERRLOG" ] && exit 0 # already ran and failed, don't do it again

. /opt/openslx/bin/slx-tools
. /opt/openslx/config

# Normally, exit unclean to signal to systemd
islocal=
mingb=10
if [ "$SLX_RUNMODE_MODULE" != "dnbd3" ]; then
	# But if its local proxy mode, always exit 0 since we don't consider this an error
	islocal=true
	# Not a dnbd3 proxy, see if we have a large partition to try local caching
	if [ "$SLX_DNBD3_SERVERS" = "127.0.0.1" ]; then
		# Already been here, do nothing
		exit 0
	fi
	[ "x$SLX_VM_DNBD3" != "xyes" ] && exit 0 # Do not want
	[ -z "$SLX_DNBD3_SERVERS" ] && exit 0 # No servers!?
	[ -z "$SLX_DNBD3_MIN_GB" ] && exit 0 # Disabled
	[ "$SLX_DNBD3_MIN_GB" -ge "$mingb" ] || exit 0 # Disabled
	mingb="$SLX_DNBD3_MIN_GB"
fi

# This should never exist at bootup, but to be sure, try to remove it
# so we don't assume local caching in the dnbd3-server startup script
rmdir /mnt/dnbd3 2> /dev/null

# Log error to server and local file in /run.
# The main startup script will check whether this file is > 0 bytes
# and start in errormsg-mode.
errormsg () {
	echo "$@" >> "$ERRLOG"
	if [ -z "$islocal" ]; then
		slxlog -s -e "dnbd3-setup" "$@"
		exit 1
	fi
	exit 0
}

# Get size of disk/device at given path, in GB
disksize () {
	local val len
	val="$( fs_path_space "$1" )"
	val="${val#* }"
	len="${#val}"
	if [ "$len" -lt 7 ]; then
		echo 0
	else
		echo "${val:0:$(( len - 6 ))}"
	fi
}

DNBD3_PORT=5003
# Creates the DNBD3 server configuration under DNBD3_CONF_DIR
DNBD3_CONF_DIR="/etc/dnbd3-server"
if ! mkdir -p "${DNBD3_CONF_DIR}"; then
	errormsg "Failed to create '${DNBD3_CONF_DIR}'."
fi

# We prefer ID45 for storage (if >= 10GB), otherwise
# fallback to /tmp if it's not in RAM and >= 10GB.
# For local caching, /tmp is never used.
d="/opt/openslx/persistent"
dsd="$(disksize "$d")"
e="/tmp"
dse="$(disksize "$e")"
if fs_path_ismountpoint "$d" && [ -k "$d/data" ] && [ "$dsd" -ge "$mingb" ]; then
	DNBD3_BASE_DIR="$d/data"
	disksize="$dsd"
elif [ -z "$islocal" ] && ! fs_path_isvolatile "$e" && [ "$dse" -ge "$mingb" ]; then
	DNBD3_BASE_DIR="$e"
	disksize="$dse"
	# We're using /tmp, don't warn about low space
	touch "/run/openslx/no-ram-warning"
else
	errormsg "Neither a persistent part (ID45) nor /tmp (ID44) are available, or they are < ${mingb}GB"
fi

# now try to create the actual folder used by the server
DNBD3_DATA_DIR="${DNBD3_BASE_DIR}/dnbd3"
if ! mkdir -p "${DNBD3_DATA_DIR}"; then
	for i in 0 1 2 3 4 5 $RANDOM $RANDOM; do
		if mkdir -p "${DNBD3_BASE_DIR}/dnbd3.$i"; then
			DNBD3_DATA_DIR="${DNBD3_BASE_DIR}/dnbd3.$i"
			break
		fi
	done
fi

if [ ! -d "${DNBD3_DATA_DIR}" ]; then
	errormsg "Failed to create '${DNBD3_BASE_DIR}/dnbd3' or any of the fallback variants"
fi
if ! chown -R dnbd3:dnbd3 "${DNBD3_DATA_DIR}"; then
	errormsg "Failed to chown '${DNBD3_DATA_DIR}' to dnbd3."
fi
# user rw, group ro, other nothing
if ! chmod -R o-rwx,u+rwX,g+rX-w "${DNBD3_DATA_DIR}"; then
	errormsg "Failed to chmod '${DNBD3_DATA_DIR}' to dnbd3."
fi

# Done with sanity checks, now create configs: server.conf & alt-servers
# Using the information given by the server in /opt/openslx/config

# helper to echo given list of IPs to ${DNBD3_CONF_DIR}/alt-servers
# optionally takes a single char prefix as first param and
# adds it to the IP (for private dnbd3 servers)
# Also sets FOUND_SAT if satellite IP was seen
MY_IPS=$(ip a | grep '^\s*inet\s' | awk '{print $2}')
FOUND_SAT=
add_alt_server() {
	local PRE=
	if [ "${#1}" = "1" ]; then
		PRE="$1"
		shift
	fi
	for ALT in "$@"; do
		for ip in $MY_IPS; do
			[ "x$ALT" = "x${ip%/*}" ] && return 0 # Ignore self
		done
		echo "${PRE}${ALT}" >> "${DNBD3_CONF_DIR}/alt-servers"
		[ "x${ALT}" = "x${SLX_PXE_SERVER_IP}" ] && FOUND_SAT="oui"
	done
	return 0
}

rm -f -- "${DNBD3_CONF_DIR}/alt-servers"

# Local caching mode?
if [ -n "$islocal" ]; then

	# Local caching mode.
	DNBD3_SPARSE="true"
	DNBD3_PRETEND_CLIENT="true"
	DNBD3_AUTOFREE=0 # Immediately start freeing images when running out of space in local caching mode
	if [ -n "$SLX_DNBD3_MIN_GB_HASH" ] && [ "$SLX_DNBD3_MIN_GB_HASH" -gt 0 ] && [ "$disksize" -ge "$SLX_DNBD3_MIN_GB_HASH" ]; then
		DNBD3_BGR="hashblock"
	else
		DNBD3_BGR="false"
	fi
	DNBD3_LOOKUP="false"
	DNBD3_SERVER_PENALTY="500000"
	DNBD3_BGR_MIN_CLIENTS=1
	MAX_REPLICATION_SIZE=500

	# Use DNBD3 servers from openslx config and then patch it to say localhost
	add_alt_server '-' ${SLX_DNBD3_SERVERS}
	sed -i "s/^SLX_DNBD3_SERVERS=.*$/SLX_DNBD3_SERVERS='127.0.0.1'/;s/^SLX_DNBD3_FALLBACK=.*$/SLX_DNBD3_FALLBACK='${SLX_DNBD3_SERVERS} ${SLX_DNBD3_FALLBACK}'/" '/opt/openslx/config'

else

	# Proxy mode
	DNBD3_SPARSE="true"
	DNBD3_PRETEND_CLIENT="false"
	DNBD3_BGR="false"
	DNBD3_BGR_MIN_CLIENTS=0
	DNBD3_LOOKUP="false"
	# Delay deletion only if we're booted early
	hour="$( date +%_H )"
	hour="${hour# }"
	if [ "$hour" -lt 7 ]; then
		DNBD3_AUTOFREE=$(( 7 - hour ))
	else
		DNBD3_AUTOFREE=0
	fi
	# Wait some more on Sunday
	if [ "$( date +%w )" = 0 ]; then
		DNBD3_AUTOFREE=$(( DNBD3_AUTOFREE + 18 ))
	fi

	DNBD3_SERVER_PENALTY=3000 # no BGR = don't like other servers connecting so much
	if [ -n "${SLX_DNBD3_BGR}" ]; then
		DNBD3_BGR="true"
		DNBD3_SERVER_PENALTY=500 # much better
		# Only do chained lookup of image if we're a global proxy with BGR
		[ -z "${SLX_DNBD3_WHITELIST}" ] && DNBD3_LOOKUP="true"
	fi
	# Determine if we need sparse mode, or override BGR
	if ! [ "$disksize" -gt 200 ]; then
		# less than 120GiB or NaN, force
		[ "$DNBD3_BGR" = "true" ] && slxlog -s -e "dnbd3-setup-small" "Cache partition < 200GiB, forcing background replication OFF and sparse mode ON"
		DNBD3_BGR="false"
		DNBD3_SERVER_PENALTY=5000
		DNBD3_LOOKUP="false"
	elif [ "$disksize" -gt 2000 ]; then
		# force non-sparse on > 2TiB
		DNBD3_SPARSE="false"
	fi

	MAX_REPLICATION_SIZE=$(( disksize / 6 ))
	[ "$MAX_REPLICATION_SIZE" -lt 100 ] && MAX_REPLICATION_SIZE=100

	add_alt_server ${SLX_DNBD3_PUBLIC}
	add_alt_server '-' ${SLX_DNBD3_PRIVATE}

	rm -f "/opt/openslx/iptables/rules.d/99-dnbd3"
	# now create iptables helper rules
	if [ -n "${SLX_DNBD3_WHITELIST}" ]; then
		DNBD3_IPTABLES_CONF="$(mktemp)"
		echo '#!/bin/ash' > "${DNBD3_IPTABLES_CONF}"
		for CIDR in ${SLX_DNBD3_WHITELIST} ${SLX_KCL_SERVERS}; do
			echo "iptables -I ipt-helper-INPUT 1 -p tcp -s ${CIDR} --dport ${DNBD3_PORT} -j ACCEPT"
		done >> "${DNBD3_IPTABLES_CONF}"
		echo "iptables -A ipt-helper-INPUT -p tcp --dport ${DNBD3_PORT} -j REJECT" >> "${DNBD3_IPTABLES_CONF}"
		chmod +x "${DNBD3_IPTABLES_CONF}"
		mv -f "$DNBD3_IPTABLES_CONF" "/opt/openslx/iptables/rules.d/99-dnbd3"
	fi

	(
		echo "*******************"
		echo "*** DNBD3 Proxy ***"
		echo "*******************"
	) | tee -a "/etc/issue" -a "/etc/issue.net" >> "/opt/openslx/etc/issue.template"

	# Create a crontab for rebooting - if everything is fine, once a weekend,
	# on failure, reboot every night, hoping things will get better (...)
	M=$(( RANDOM % 60 ))
	H=$(( RANDOM % 5 ))
	if [ -s "$ERRLOG" ]; then
		W="*"
	else
		W="0"
	fi
	# Uptime >10hrs, or we might reboot multiple times if $H is > last $H
	cat > "/etc/cron.d/dnbd3-reboot" <<EOF
# OpenSLX: Reboot proxy at night
SHELL=/bin/ash
PATH=/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin

$M $H	* * $W	root	[ "\$(grep -oEm1 '^[0-9]+' /proc/uptime)" -lt 36000 ] || reboot
EOF
	#

fi # end local caching or proxy mode

rm -f "${DNBD3_CONF_DIR}/server.conf"
# Refer to http://git.openslx.org/dnbd3.git/tree/conf for configuration options
cat << EOF > "${DNBD3_CONF_DIR}/server.conf"
[dnbd3]
listenPort=${DNBD3_PORT}
basePath=${DNBD3_DATA_DIR}
serverPenalty=${DNBD3_SERVER_PENALTY}
clientPenalty=0
isProxy=true
backgroundReplication=${DNBD3_BGR}
bgrMinClients=${DNBD3_BGR_MIN_CLIENTS}
bgrWindowSize=1
lookupMissingForProxy=${DNBD3_LOOKUP}
sparseFiles=${DNBD3_SPARSE}
removeMissingImages=false
uplinkTimeout=5000
clientTimeout=15000
pretendClient=${DNBD3_PRETEND_CLIENT}
autoFreeDiskSpaceDelay=${DNBD3_AUTOFREE}h

[limits]
maxPayload=10M
maxReplicationSize=${MAX_REPLICATION_SIZE}G

[logging]
consoleMask=ERROR WARNING MINOR INFO
EOF

# Extra overrides - make this proerly ini aware some day. For now we don't
# have any name clashes between the ini sections so this works
for item in $SLX_DNBD3_EXTRA; do # space sep
	item="${item#*.}"
	key="${item%%=*}"
	val="${item#*=}"
	sed -i "s/^${key}=.*$/${key}=${val}/" "${DNBD3_CONF_DIR}/server.conf"
done

# To this day, only the sat IP is in SLX_KCL_SERVERS afaik
[ -z "${FOUND_SAT}" ] && add_alt_server ${SLX_KCL_SERVERS}
chmod -R a+Xr "${DNBD3_CONF_DIR}"

# create rpc.acl to allow the satellite only
rm -f "${DNBD3_CONF_DIR}/rpc.acl"
for SRV in ${SLX_KCL_SERVERS}; do
	echo "$SRV ALL"
done >> "${DNBD3_CONF_DIR}/rpc.acl"
# And self
echo "127.0.0.1 STATS IMAGE_LIST" >> "${DNBD3_CONF_DIR}/rpc.acl"

if [ -n "$islocal" ]; then
	# Prepare, so dnbd3-server will be launched with -m
	mkdir -p /mnt/dnbd3
	chown dnbd3:dnbd3 /mnt/dnbd3
	# Start service, is not symlinked when not in proxy mode
	systemctl --no-block start dnbd3-proxy.service dnbd3-local-stage4.service
fi

exit 0