iopsys-feed/swmodd/files/etc/init.d/crun
2025-09-06 15:14:24 +05:30

290 lines
7.9 KiB
Bash
Executable file

#!/bin/sh /etc/rc.common
START=99
STOP=01
USE_PROCD=1
log() {
echo "${@}"|logger -t crun.init -p info
}
is_container_running() {
crun list |tail -n +2|grep -wq "^${1}"
return $?
}
configure_lxc_container() {
local requested_state name ctype du_status BUNDLE section
ctype="${1}"
name="${2}"
requested_state="${3}"
du_status="${4}"
BUNDLE="${5}"
section="${6}"
if [ "${ctype}" != "lxc" ]; then
return 0;
fi
if [ "${du_status}" = "Uninstalling" ]; then
lxc-stop -q -k "${name}"
if [ -d "${BUNDLE:?}/${name:?}" ]; then
rm -rf "${BUNDLE:?}/${name:?}"
fi
# If directory still exists then uninstall failed
if [ -d "${BUNDLE}/${name}" ]; then
uci_set ocicontainer "${section}" du_status Uninstalling_failed
uci_set ocicontainer "${section}" fault_string "Failed to remove ${BUNDLE}/${name}"
log "LXC container ${name} remove failed"
else
uci_set ocicontainer "${section}" du_status Uninstalling_success
log "LXC container ${name} removed"
fi
return 0;
fi
if [ "${requested_state}" = "Idle" ]; then
lxc-stop -q -k "${name}"
elif [ "${requested_state}" = "Active" ]; then
lxc-start -q "${name}" >/dev/null 2>&1
fi
}
configure_crun_container() {
local name type autostart du_status requested_state url username password capability envlist
local BRIDGE BUNDLE BOOT PERM
local RUNNER="/etc/swmodd/run.sh"
BUNDLE="${2}"
BRIDGE="${3}"
BOOT="${4}"
TIMEOUT="${5}"
config_get name "${1}" name ""
config_get type "${1}" type ""
config_get_bool autostart "${1}" autostart 1
config_get du_status "${1}" du_status ""
config_get requested_state "${1}" requested_state ""
config_get url "${1}" url ""
config_get username "${1}" username ""
config_get password "${1}" password ""
config_get capability "${1}" capability ""
config_get envlist "${1}" env_var ""
if [ -n "${envlist}" ]; then
envlist="${envlist// /;}"
fi
if [ -n "${capability}" ]; then
PERM="-p ${capability// /,}"
fi
if [ -z "${name}" ] || [ -z "${type}" ] || [ -z "${du_status}" ]; then
return 0;
fi
if [ "${type}" != "crun" ]; then
configure_lxc_container "${type}" "${name}" "${requested_state}" "${du_status}" "${BUNDLE}" "${1}"
return 0;
fi
if [ "${du_status}" = "Installing" ]; then
local result
log "Pull image from registry"
uci_set ocicontainer "${1}" du_status Installing_start
uci_set ocicontainer "${1}" username ""
uci_set ocicontainer "${1}" password ""
result=$(${RUNNER} -b "${BUNDLE}" -n "${name}" -r "${url}" -l "${username}:${password}" -t "${TIMEOUT}")
if [ "$?" -eq 0 ]; then
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_description")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" description "${result}"
fi
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_vendor")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" vendor "${result}"
fi
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_version")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" version "${result}"
fi
uci_set ocicontainer "${1}" du_status Installing_success
du_status="Installed"
else
uci_set ocicontainer "${1}" du_status Installing_failed
uci_set ocicontainer "${1}" fault_string "${result}"
return 0;
fi
fi
if [ "${du_status}" = "Uninstalling" ]; then
ubus call service delete "{\"name\":\"crun\",\"instance\":\"${name}\"}"
if is_container_running "${name}"; then
crun kill --all "${name}" 9
fi
${RUNNER} -c -n "${name}"
if [ -d "${BUNDLE:?}/${name:?}" ]; then
rm -rf "${BUNDLE:?}/${name:?}"
fi
# If directory still exists then uninstall failed
if [ -d "${BUNDLE}/${name}" ]; then
uci_set ocicontainer "${1}" du_status Uninstalling_failed
uci_set ocicontainer "${1}" fault_string "Failed to remove ${BUNDLE}/${name}"
else
uci_set ocicontainer "${1}" du_status Uninstalling_success
fi
# Delete the uci config section after uninstall
log "CRUN container ${name} removed"
return 0;
fi
if [ ! -d "${BUNDLE:?}/${name:?}" ]; then
log "Crun container {${BUNDLE:?}/${name:?}} not available"
return 0;
fi
if [ "${du_status}" != "Installed" ]; then
return 0;
fi
if [ "${BOOT}" -eq "1" ]; then
if [ "${autostart}" -eq 1 ]; then
${RUNNER} -U -b "${BUNDLE}" -n "${name}" -e "${envlist}" ${PERM}
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_description")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" description "${result}"
fi
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_vendor")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" vendor "${result}"
fi
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_version")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" version "${result}"
fi
uci_set ocicontainer "${1}" requested_state "Active"
else
uci_set ocicontainer "${1}" requested_state "Idle"
return 0;
fi
else
log "Container [$name] req_status [${requested_state}]"
if [ "${requested_state}" = "Idle" ]; then
if is_container_running "${name}"; then
crun pause "${name}"
else
return 0;
fi
elif [ "${requested_state}" = "Active" ]; then
if is_container_running "${name}"; then
${RUNNER} -u -n "${name}" -i "${BRIDGE}" ${PERM}
crun resume "${name}"
else
${RUNNER} -U -b "${BUNDLE}" -n "${name}" -e "${envlist}" ${PERM}
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_description")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" description "${result}"
fi
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter "@.annotations.org_opencontainers_image_vendor")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" vendor "${result}"
fi
result="$(cat ${BUNDLE}/${name}/config.json |jsonfilter -e "@.annotations.org_opencontainers_image_version")"
if [ "${result}" != "null" ]; then
uci_set ocicontainer "${1}" version "${result}"
fi
fi
else
return 0;
fi
fi
procd_open_instance "${name}"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param command "${RUNNER}"
procd_append_param command -b "${BUNDLE}" -n "${name}" -i "${BRIDGE}"
#procd_set_param respawn
procd_close_instance "${name}"
}
boot() {
start "bootstrap"
}
start_service() {
local bundle root env bridge boot
# Check if crun present
if ! command -v crun >/dev/null 2>&1; then
log "CRUN binary not found"
return 0;
fi
if [ "${1}" = "bootstrap" ]; then
boot=1
else
boot=0
fi
# crun default runtime directory /run, if not present then create
if [ ! -d "/run" ]; then
if [ ! -L "/run" ]; then
ln -fs /var/run /run
fi
fi
config_load swmodd
config_get root globals root ""
config_get bridge globals lan_bridge "br-lan"
config_get timeout globals oci_pull_timeout "10"
env=$(uci -q get swmodd.@execenv[0].name)
if [ -z "${root}" ] || [ -z "${bridge}" ]; then
log "# Base bundle root[$root] or bridge[$bridge] not defined"
return 0;
fi
bundle="${root}/${env}"
if [ -f "${bundle}/ocicontainer" ]; then
UCI_CONFIG_DIR="${bundle}"
config_load ocicontainer
config_foreach configure_crun_container du_eu_assoc "${bundle}" "${bridge}" "${boot}" "${timeout}"
uci_commit ocicontainer
# Add a timer for DuStateChange!
(sleep 5 && ubus -t 5 call swmodules reload) &
else
log "${bundle}/ocicontainer not present"
fi
}
stop_service() {
local cid
cid="$(crun list|tail -n +2 |awk '{printf $1 " "}')"
for f in $cid; do
crun kill --all "${f}" 9
done
}
reload_service() {
start
}
service_triggers() {
procd_add_reload_trigger "crun" "network"
}