swmodd: Handle OCI containers

This commit is contained in:
vdutta 2022-08-08 14:05:41 +05:30
parent d96d43b1a4
commit b86771d08f
8 changed files with 314 additions and 32 deletions

View file

@ -1,9 +0,0 @@
if PACKAGE_swmodd
menu "Configuration"
config SWMOD_HOST_IS_EXECENV
bool "Enable host system as execution environment"
default n
endmenu
endif

View file

@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=swmodd
PKG_VERSION:=2.1.5
PKG_VERSION:=2.1.6
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=2f953ea76b5779a73a540777dfb450982802e4f8
PKG_SOURCE_VERSION:=cc5e8c52db0fbded33523dfec9742cc0260d41a6
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/swmodd.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
@ -30,33 +30,29 @@ define Package/swmodd
SUBMENU:=TRx69
TITLE:= Software Modules Daemon
DEPENDS:=+libuci +libubox +ubus +libuuid +opkg +libcurl \
+PACKAGE_liblxc:liblxc +PACKAGE_liblxc:cgroupfs-mount \
+@BUSYBOX_CONFIG_BUSYBOX +@BUSYBOX_CONFIG_FEATURE_SHOW_SCRIPT
+PACKAGE_liblxc:liblxc +cgroupfs-mount \
+@BUSYBOX_CONFIG_BUSYBOX +@BUSYBOX_CONFIG_FEATURE_SHOW_SCRIPT \
+@BUSYBOX_CONFIG_SCRIPT
endef
define Package/swmodd/description
Software module daemon to manage software/deployment units using TR181 datamodel.
endef
define Package/swmodd/config
source "$(SOURCE)/Config.in"
endef
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-D_GNU_SOURCE \
-Wall -Werror
ifeq ($(CONFIG_PACKAGE_crun),y)
MAKE_FLAGS += \
SWMOD_CRUN="yes"
endif
ifeq ($(CONFIG_PACKAGE_liblxc),y)
MAKE_FLAGS += \
SWMOD_LXC="yes"
endif
ifeq ($(CONFIG_SWMOD_HOST_IS_EXECENV),y)
MAKE_FLAGS += \
SWMOD_HOST_IS_EXECENV="yes"
endif
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/swmodd/* $(PKG_BUILD_DIR)/
@ -67,7 +63,6 @@ define Package/swmodd/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/usr/lib/bbfdm
$(INSTALL_DIR) $(1)/etc/swmod
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/etc/init.d/swmodd $(1)/etc/init.d/swmodd
$(INSTALL_BIN) ./files/etc/config/swmodd $(1)/etc/config/swmodd
@ -79,6 +74,15 @@ ifeq ($(CONFIG_PACKAGE_liblxc),y)
$(INSTALL_BIN) $(PKG_BUILD_DIR)/templates/lxc-iopsys $(1)/usr/share/lxc/templates/lxc-iopsys
$(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/opkg_offline.sh $(1)/usr/share/swmodd/opkg_offline
endif
ifeq ($(CONFIG_PACKAGE_crun),y)
$(INSTALL_DIR) $(1)/etc/swmodd
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/swmodd/run.sh $(1)/etc/swmodd/run.sh
$(INSTALL_BIN) ./files/etc/init.d/crun $(1)/etc/init.d/crun
$(INSTALL_BIN) ./files/etc/config/crun $(1)/etc/config/crun
$(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/crun_create $(1)/usr/sbin/crun_create
$(INSTALL_BIN) ./files/etc/uci-defaults/01-fix-bundle-path $(1)/etc/uci-defaults/01-fix-bundle-path
endif
endef
$(eval $(call BuildPackage,swmodd))

View file

@ -0,0 +1,2 @@
config global global
option enable '1'

View file

@ -1,4 +1,5 @@
config globals 'globals'
option enabled '1'
option debug '1'
option log_level '3'
option enabled '1'
option debug '1'
option log_level '3'
option lan_bridge 'br-lan'

View file

@ -0,0 +1,133 @@
#!/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'
}
is_container_running() {
crun list |tail -n +2|grep -wq "^${1}"
return $?
}
configure_crun_container() {
local name type autostart du_status requested_state
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 [ ! -d "${BUNDLE:?}/${name:?}" ]; then
log "Crun container {${BUNDLE:?}/${name:?}} not available"
return 0;
fi
if [ "${du_status}" == "Uninstalling" ] || [ "${du_status}" == "Uninstalled" ]; then
ubus call service delete "{\"name\":\"crun\",\"instance\":\"${name}\"}"
crun kill --all "${name}" 9
${RUNNER} -c -n "${name}"
if [ -d "${BUNDLE:?}/${name:?}" ]; then
rm -rf "${BUNDLE:?}/${name:?}"
fi
# Delete the uci config section after uninstall
uci_remove swmodd "${1}"
log "CRUN container ${name} removed"
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}" -b "${BRIDGE}"
crun resume "${name}"
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}"
}
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
}
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"
}

View file

@ -12,11 +12,12 @@ validate_globals_section()
'enabled:bool:1' \
'debug:bool:false' \
'log_level:uinteger:1' \
'bundle_root:string' \
'sock:string'
}
start_service() {
local enabled debug log_level sock
local enabled debug log_level sock bundle_root
# creating fallback shared mount-point
mkdir -p /tmp/swmodd_dw
@ -30,17 +31,20 @@ start_service() {
[ "${enabled}" -eq 0 ] && return 0
[ -z "${bundle_root}" ] && return 0
mkdir -p "${bundle_root}"
procd_open_instance swmodd
procd_set_param command ${PROG}
if [ "${debug}" -eq 1 ]; then
procd_set_param stdout 1
procd_set_param stderr 1
procd_append_param command -l ${log_level}
procd_append_param command -l "${log_level}"
fi
if [ -f "${sock}" ]; then
procd_append_param command -s ${sock}
procd_append_param command -s "${sock}"
fi
procd_set_param respawn
@ -52,6 +56,14 @@ stop_service() {
}
reload_service() {
stop
start
if ubus list swmodules >/dev/null 2>&1; then
ubus -t 20 call swmodules reload
else
stop
start
fi
}
service_triggers() {
procd_add_reload_trigger "swmodd"
}

View file

@ -0,0 +1,118 @@
#!/bin/sh
VETHNAME=""
log() {
echo "${@}"|logger -t crun.runner -p info
}
if ! command -v crun >/dev/null 2>&1;then
log "CRUN binary not present"
return 1
fi
if ! command -v script >/dev/null 2>&1;then
log "script not present"
return 1
fi
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}"
}
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
}
clean=0
net_update=0
while getopts b:n:i:cu options
do
case "${options}" in
b) BUNDLE=${OPTARG};;
n) NAME=${OPTARG};;
i) BRIDGE=${OPTARG};;
c) clean=1;;
u) net_update=1;;
*) log "Invalid options";;
esac
done
if [ -z "${NAME}" ]; then
log "Emtpy container name"
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

View file

@ -0,0 +1,21 @@
#!/bin/sh
. /lib/functions.sh
# if bundle_root not define in swmodd, update it with lxc path
lxc=""
bundle=""
if [ -f "/etc/lxc/lxc.conf" ]; then
lxc=$(cat /etc/lxc/lxc.conf |grep "lxc.lxcpath"| cut -d "=" -f 2)
fi
config_load swmodd
config_get bundle globals bundle_root ""
if [ -z "${bundle}" ] && [ -n "${lxc}" ]; then
uci_set swmodd globals bundle_root ${lxc}
uci_commit
elif [ -z "${bundle}" ]; then
uci_set swmodd globals bundle_root "/tmp/"
uci_commit
fi