iopsys-feed/swmodd/files/etc/swmodd/run.sh
2022-09-16 17:00:00 +05:30

268 lines
5.2 KiB
Bash

#!/bin/sh
VETHNAME=""
log() {
echo "${@}"|logger -t crun.runner -p info
echo "${@}"
}
check_binary() {
if [ -z "${1}" ]; then
return 0;
fi
if ! command -v "${1}" >/dev/null 2>&1;then
log "${1} not present in system"
exit 1
fi
return 0;
}
check_binary crun
check_binary script
get_veth_name() {
local name
name="cr$1"
VETHNAME="${name:0:15}"
}
clean_container_network() {
local name
name="${1}"
# clean up
if ip netns list|grep -qw "${name}"; then
get_veth_name "${name}"
ip netns del "${name}"
ip link delete "${VETHNAME}" type veth peer name eth0
fi
}
setup_container_network() {
local name bridge_name
if [ "$#" -lt 2 ]; then
return 0
fi
name="${1}"
bridge_name="${2}"
clean_container_network "${name}"
get_veth_name "${name}"
# Add a namespace
ip netns add "${name}"
# Add a veth pair
ip link add "${VETHNAME}" type veth peer name eth0 netns "$name"
# Make veth on network side up
ip netns exec "$name" ip link set dev eth0 up
# Create loopback interface
ip netns exec "$name" ip link set lo up
# Make veth on host side up
ip link set dev "${VETHNAME}" up
# Link with host bridge
brctl addif "${bridge_name}" "${VETHNAME}"
# Get Ip from bridge and make the link ready
ip netns exec "$name" udhcpc -i eth0 -x hostname:"CRUN-${name}"
if [ "${du_status}" != "Installed" ]; then
return 0;
fi
}
run_container() {
local bundle name bridge
bundle="${1}"
name="${2}"
bridge="${3}"
if [ ! -d "${bundle:?}/${name:?}" ]; then
log "Bundle does not exists"
return 1
fi
setup_container_network "${name}" "${bridge}"
script -q -c "crun run -b ${bundle}/${name} ${name}" /dev/null
}
update_network_ns() {
local type
json_select $2
json_get_var type type
if [ "${type}" == "network" ]; then
json_add_string path "/var/run/netns/${NAME}"
break;
fi
json_select ..
}
update_config_json() {
if [ ! -f "${BUNDLE:?}/${NAME:?}/config.json" ]; then
log "config.json not found or bundle missing"
exit 0;
fi
if [ -f "/usr/share/libubox/jshn.sh" ]; then
. /usr/share/libubox/jshn.sh
else
log "jshn.sh missing in the system"
exit 1;
fi
cd "${BUNDLE}/${NAME}"
if cat config.json |jq '.linux.namespaces[] |select (.type == "network") |.path' |grep -q ${NAME}; then
exit 0;
fi
mv config.json config_orig.json
json_init
json_load_file "config_orig.json"
json_select linux
json_for_each_item update_network_ns namespaces
json_dump >config.json
}
pull_image_from_registry() {
local temp raw blobsize disksize exsize
if [ -z "${BUNDLE}" -o -z "${NAME}" -o -z "${REGURL}" ]; then
log "Information missing for installation"
exit 1
fi
if [ -d "${BUNDLE}/${NAME}" ]; then
log "Container with same name already present"
exit 1
fi
check_binary skopeo
check_binary umoci
temp="$(mktemp -d)"
if [ ! -d "${temp}" ]; then
log "Failed to create temp directory"
exit 1
fi
cd "${temp}"
OPTS=""
INSPECT_OPT=""
if [ "${#LOGIN}" -gt 3 ]; then
OPTS="--src-creds ${LOGIN}"
INSPECT_OPT="--creds ${LOGIN}"
fi
# inspect and get size check system
raw=$(skopeo --command-timeout 30s inspect ${INSPECT_OPT} --raw ${REGURL})
blobsize=$(echo $raw|jq '[ .layers[].size ] | add' 2>/dev/null)
if [ -z "${blobsize}" ]; then
blobsize=0
fi
exsize=$(( blobsize * 2 ))
# Get the available disk space
disksize=$(df -P -k ${temp} |tail -n +2 |awk '{print $4}')
if [ "${disksize}" -lt "${exsize}" ]; then
log "Not enough memory ${blobsize} available ${disksize}, download aborted"
exit 1
fi
if ! skopeo --command-timeout 4m copy ${OPTS} ${REGURL} oci:${NAME}_tmp:latest >/dev/null 2>&1; then
log "Failed to download image"
cd -
rm -rf "${temp}"
exit 1
fi
if ! umoci unpack --image ${NAME}_tmp:latest ${NAME} >/dev/null 2>&1; then
log "Failed to unpack image"
cd -
rm -rf "${temp}"
exit 1
fi
rm -rf "${NAME}_tmp"
if [ ! -f "${NAME}/config.json" ]; then
log "Failed to pull the image config missing"
cd -
rm -rf "${temp}"
exit 1
fi
# Check disk available space before copy
disksize=$(df -P -k ${BUNDLE} |tail -n +2 |awk '{print $4}')
exsize=$(du -s ${temp} |awk '{print $1}')
if [ "${disksize}" -lt "${exsize}" ]; then
log "Disk space ${disksize} less that required ${exists}"
cd -
rm -rf "${temp}"
exit 1
fi
mv ${NAME} ${BUNDLE}/
if [ "$?" -ne 0 ]; then
log "Failed ${name} move in ${BUNDLE}"
cd -
rm -rf "${temp}"
rm -rf ${BUNDLE}/${NAME}
exit 1
fi
cd -
rm -rf "${temp}"
update_config_json
}
clean=0
net_update=0
update_json=0
while getopts b:n:i:r:l:cuU options
do
case "${options}" in
b) BUNDLE=${OPTARG};;
n) NAME=${OPTARG};;
i) BRIDGE=${OPTARG};;
r) REGURL=${OPTARG};;
l) LOGIN=${OPTARG};;
c) clean=1;;
u) net_update=1;;
U) update_json=1;;
*) log "Invalid options";;
esac
done
if [ -z "${NAME}" ]; then
log "Emtpy container name"
return 0;
fi
if [ "${update_json}" -eq 1 ]; then
update_config_json
return 0;
fi
if [ -n "${REGURL}" ]; then
pull_image_from_registry
return 0;
fi
if [ "$clean" -eq 1 ]; then
clean_container_network "${NAME}"
return 0;
fi
if [ -z "${BRIDGE}" ]; then
log "Empty bridge name"
return 0;
fi
if [ "${net_update}" -eq 1 ]; then
get_veth_name "${NAME}"
brctl addif "${BRIDGE}" "${VETHNAME}"
return 0;
fi
if [ -n "${BUNDLE}" ] ; then
run_container "${BUNDLE}" "${NAME}" "${BRIDGE}"
fi