#!/bin/sh /etc/rc.common START=99 STOP=01 USE_PROCD=1 log() { echo "${@}"|logger -t crun.init -p info } validate_container_section() { uci_validate_section swmodd du_eu_assoc "${1}" \ 'name:string' \ 'type:string' \ 'autostart:bool:1' \ 'du_status:string' \ 'requested_state:string' \ 'url:string' \ 'username:string' \ 'password:string' } is_container_running() { crun list |tail -n +2|grep -wq "^${1}" return $? } configure_crun_container() { local name type autostart du_status requested_state url username password local BRIDGE BUNDLE local RUNNER="/etc/swmodd/run.sh" validate_container_section "${1}" || { log "Validation of container section failed" return 0; } BUNDLE="${2}" BRIDGE="${3}" if [ -z "${name}" ] || [ -z "${type}" ] || [ -z "${du_status}" ]; then return 0; fi if [ "${type}" != "crun" ]; then return 0; fi if [ "${du_status}" == "Installing" ]; then local result log "Pull image from registry" uci_set swmodd ${1} du_status Installing_start uci_set swmodd ${1} username "" uci_set swmodd ${1} password "" result=$(${RUNNER} -b "${BUNDLE}" -n "${name}" -r "${url}" -l "${username}:${password}") if [ "$?" -eq 0 ]; then result=$(cat ${BUNDLE}/${name}/config.json |jq '.annotations.org_opencontainers_image_description') if [ "${result}" != "null" ]; then uci_set swmodd ${1} description ${result} fi result=$(cat ${BUNDLE}/${name}/config.json |jq '.annotations.org_opencontainers_image_vendor') if [ "${result}" != "null" ]; then uci_set swmodd ${1} vendor ${result} fi result=$(cat ${BUNDLE}/${name}/config.json |jq '.annotations.org_opencontainers_image_version') if [ "${result}" != "null" ]; then uci_set swmodd ${1} version ${result} fi uci_set swmodd ${1} du_status Installing_success du_status="Installed" else uci_set swmodd ${1} du_status Installing_failed uci_set swmodd ${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 swmodd ${1} du_status Uninstalling_failed uci_set swmodd ${1} fault_string "Failed to remove ${BUNDLE}/${name}" else uci_set swmodd ${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 [ "${autostart}" -eq 0 ]; then ubus call service delete "{\"name\":\"crun\",\"instance\":\"${name}\"}" # stop the container if not enabled crun kill --all "${name}" 9 return 0; fi if is_container_running "${name}"; then log "Container [$name] req_status [${requested_state}]" if [ "${requested_state}" == "Idle" ]; then crun pause "${name}" elif [ "${requested_state}" == "Active" ]; then ${RUNNER} -u -n "${name}" -i "${BRIDGE}" crun resume "${name}" fi else ${RUNNER} -U -b "${BUNDLE}" -n "${name}" 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}" } start_service() { local bundle bridge # Check if crun present if ! command -v crun >/dev/null 2>&1; then log "CRUN binary not found" return 0; fi config_load swmodd config_get bundle globals bundle_root "" config_get bridge globals lan_bridge "br-lan" if [ -z "${bundle}" ] || [ -z "${bridge}" ]; then log "Empty bundle path or bridge" return 0; fi mkdir -p "${bundle}" config_foreach configure_crun_container du_eu_assoc "${bundle}" "${bridge}" uci_commit # Add a timer for DuStateChange! (sleep 5 && ubus -t 5 call swmodules reload) & } 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" }