File docker-container-generator of Package docker-container-starter

#!/bin/bash

if [[ $# -ne 1 ]]; then
	logger -p error "This script requests exectly one (1) argument, the name of the container to be set-up."
	exit 254
elif [[ -z "$1" ]]; then
	logger -p error "First argument is empty, this is not a valid container name."
	exit 254
fi

# Store the first argument as container name
CONTAINER_NAME="$1"

if [[ -z "${RUNTIME_DIRECTORY}" ]]; then
	logger -p error "Environment variable RUNTIME_DIRECTORY must be set."
	exit 255
fi

if [[ -z "${PROFILE_DIRECTORY}" ]]; then
	logger -p error "Environment variable PROFILE_DIRECTORY must be set."
	exit 255
fi

if [[ ! -d "${PROFILE_DIRECTORY}" ]]; then
	logger -p error "Variable PROFILE_DIRECTORY does not point to and existing or accesable directory, maybe you forgot to create or mount it?"
	exit 255
fi

if [[ ! -f "${PROFILE_DIRECTORY}/${CONTAINER_NAME}" ]]; then
	logger -p error "Configuration file \"${CONTAINER_NAME}\" in Configuration directory \"${PROFILE_DIRECTORY}\" does not exisits."
	exit 255
fi

# Load profile variables
source "${PROFILE_DIRECTORY}/${CONTAINER_NAME}"

# Check if all variable have been set, otherwise exit with an error.
if [[ -z "${CONTAINER_URL}" ]]; then
	logger -p error "Environment variable CONTAINER_URL must be set."
	exit 255
fi
if [[ -z "${CONTAINER_TAG}" ]]; then
	logger -p error "Environment variable CONTAINER_TAG must be set."
	exit 255
fi

# Check these variables and warn if they are not set and provide a default.
if [[ -z "${CONTAINER_HOSTNAME}" ]]; then
	logger -p warning "Environment variable CONTAINER_HOSTNAME is not set, value of \"${CONTAINER_NAME}\" is assumed."
	CONTAINER_HOSTNAME="${CONTAINER_NAME}"
fi
if [[ -z "${CONTAINER_NO_ROOT}" ]]; then
	logger -p warning "Environment variable CONTAINER_NO_ROOT is not set, assume 0."
	CONTAINER_NO_ROOT=0
fi
if [[ -z "${CONTAINER_MOUNTS}" ]]; then
	logger -p warning "Environment variable CONTAINER_MOUNTS is not set, assume no mounts."
	CONTAINER_MOUNTS=""
fi
if [[ -z "${CONTAINER_BRIDGE}" ]]; then
	logger -p warning "Environment variable CONTAINER_BRIDGE is not set, assume no interfaces."
	CONTAINER_BRIDGE=""
fi
if [[ -z "${CONTAINER_VARS}" ]]; then
	logger -p warning "Environment variable RUNTIME_DIRECTORY is not set, assume no container variables."
	CONTAINER_VARS=""
fi
if [[ -z "${CONTAINER_MAC_PREFIX}" ]]; then
	logger -p warning "Environment variable CONTAINER_MAC_PREFIX is not set, assume \"00:00:00:00\"."
	CONTAINER_MAC_PREFIX="00:00:00:00"
fi

uid=0
gid=0

if [ "${CONTAINER_NO_ROOT}" -gt 0 ]; then
	uid=$(id -u)
	gid=$(id -g)
fi

rundir="$(echo "${RUNTIME_DIRECTORY}" | awk -F ':' '{print $1}')"

if [[ ! -d "${rundir}" ]]; then
	logger -p error "First part of RUNTIME_DIRECTORY does not point to a exisitng or accesable directory."
	exit 255
fi

cid="${rundir}/cid"
env_file="${rundir}/vars"
conf_file="${rundir}/config"
ifconf_file="${rundir}/ifconfig"
mountconf_file="${rundir}/mountconfig"

if [[ -n "${CONTAINER_CPUS}" ]]; then
	cpus="${CONTAINER_CPUS}"
else
	n_cpus="$(/usr/bin/lscpu | grep "^CPU(s):" | awk -F ':' '{print $2}' | tr -d ' ')"
	if [ "${n_cpus}" -ge 2 ]; then
		cpus="1-${n_cpus}"
	else
		cpus="1"
	fi
fi
if [[ -n "${CONTAINER_CPU_SHARES}" ]]; then
	cpu_shares="${CONTAINER_CPU_SHARES}"
else
	cpu_shares="1024"
fi
if [[ -n "${CONTAINER_MAX_MEMORY}" ]]; then
	memory="${CONTAINER_MAX_MEMORY}"
else
	memory="$(/usr/bin/lsmem | grep "Total online memory:" | awk -F ':' '{print $2}' | tr -d ' ')"
fi

cat > ${conf_file} << CONFBLOCK1
UID=${uid}
GID=${gid}
NAME="${CONTAINER_NAME}"
HOSTNAME="${CONTAINER_HOSTNAME}"
CID_FILE="${cid}"
URL="${CONTAINER_URL}"
TAG="${CONTAINER_TAG}"
CPUS="${cpus}"
CPU_SHARES="${cpu_shares}"
MAX_MEMORY="${memory}"
ENVIRNMENT_FILE="${env_file}"
IFCONFIG_FILE="${ifconf_file}"
MOUNTCONFIG_FILE="${mountconf_file}"
CONFBLOCK1

cat > ${mountconf_file} << MOUNTCONFBLOCK1
declare -a MOUNTS

MOUNTCONFBLOCK1

i=0
j=1
source_dirs=""
for mount_config in ${CONTAINER_MOUNTS}; do
	source_dir="$(echo "${mount_config}" | awk -F ':' '{print $1}')"
	target_dir="$(echo "${mount_config}" | awk -F ':' '{print $2}')"
	flags="$(echo "${mount_config}" | awk -F ':' '{print $3}')"

	source_dirs+=" ${source_dir}"
	flags_seperator=","
	if [[ -z "${flags}" ]]; then
		flags_seperator=""
	fi

	cat >> ${mountconf_file} << MOUNTCONFBLOCK2
MOUNTS[${i}]="--mount"
MOUNTS[${j}]="type=bind,source=${source_dir},destination=${target_dir}${flags_seperator}${flags}"
MOUNTCONFBLOCK2

	let "i=i+2"
	let "j=j+2"
done

cat >> ${mountconf_file} << MOUNTCONFBLOCK3
MOUNT_SOURCE_DIRS="${source_dirs}"
MOUNTCONFBLOCK3

cat > ${ifconf_file} << IFCONFBLOCK1
declare -a IF_BRIDGE
declare -a IF
declare -a IF_IPADDR
declare -a IF_NETMASK
declare -a IF_MAC
declare -a IF_GW

IFCONFBLOCK1

dns=$(grep "nameserver" /etc/resolv.conf | head -n 1 | awk '{print $2}')
domain=$(grep "search" /etc/resolv.conf | head -n 1 | awk '{print $2}')


declare IP_SEQ_NR
i=0
for bridge_config in ${CONTAINER_BRIDGE}; do
	bridge="$(echo "${bridge_config}" | awk -F ':' '{print $1}')"
	interface="$(echo "${bridge_config}" | awk -F ':' '{print $2}')"
	type="$(echo "${bridge_config}" | awk -F ':' '{print $3}')"
	range="$(echo "${bridge_config}" | awk -F ':' '{print $4}')"
	gw="$(/sbin/ip route list dev "${bridge}" default | grep -Eo "via ([0-9]+[.]){3}[0-9]+" | awk '{print $2}')"

	ip_addr="0.0.0.0"
	if [ "${type}" == "d" ]; then
		ip_addr=$(/usr/bin/dig +short "${CONTAINER_HOSTNAME}.${domain}" @${dns})
		if [ -z "${IP_SEQ_NR}" ]; then
			IP_SEQ_NR=$(echo "${ip_addr}" | awk -F '.' '{print $4}')
		fi
	fi

	netmask=32
	if [ "${range}" == "a" ]; then
		netmask=8
		if [ "${type}" == "s" ]; then
			ip_addr="10.0.${i}.${IP_SEQ_NR}"
		fi
	elif [ "${range}" == "b" ]; then
		netmask=12
		if [ "${type}" == "s" ]; then
			ip_addr="172.16.${i}.${IP_SEQ_NR}"
		fi
	elif [ "${range}" == "c" ]; then
		netmask=16
		if [ "${type}" == "s" ]; then
			ip_addr="192.168.${i}.${IP_SEQ_NR}"
		fi
	fi

	mac_suffix_1=$(printf "%02x\n" "${i}")
	mac_suffix_2_in=$(echo "${ip_addr}" | awk -F '.' '{print $4}')
	mac_suffix_2=$(printf "%02x\n" "${mac_suffix_2_in}")

	cat >> ${ifconf_file} << IFCONFBLOCKIF2
IF_BRIDGE[${i}]="${bridge}"
IF[${i}]="${interface}"
IF_IPADDR[${i}]="${ip_addr}"
IF_NETMASK[${i}]="${netmask}"
IF_MAC[${i}]="${CONTAINER_MAC_PREFIX}:${mac_suffix_1}:${mac_suffix_2}"
IF_GW[${i}]="${gw}"
IFCONFBLOCKIF2
	let "i++"
done

cat >> ${ifconf_file} << IFCONFBLOCKIF3
I_IF=${i}
IFCONFBLOCKIF3



cat > ${env_file} << VARBLOCK1
VARBLOCK1
for var in ${CONTAINER_VARS}; do
cat >> ${env_file} << VARBLOCK2
${var}
VARBLOCK2
done
openSUSE Build Service is sponsored by