mirror of
https://dev.iopsys.eu/feed/iopsys.git
synced 2025-12-10 07:44:50 +01:00
268 lines
5.2 KiB
Bash
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
|