-
Notifications
You must be signed in to change notification settings - Fork 2.6k
feat: add support for runit as a process supervisor #13349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -115,7 +115,7 @@ fatal() | |||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # --- fatal if no systemd or openrc --- | ||||||||||||||||||||||||||||||
| # --- fatal if no systemd, openrc, or runit --- | ||||||||||||||||||||||||||||||
| verify_system() { | ||||||||||||||||||||||||||||||
| if [ -x /sbin/openrc-run ]; then | ||||||||||||||||||||||||||||||
| HAS_OPENRC=true | ||||||||||||||||||||||||||||||
|
|
@@ -125,7 +125,11 @@ verify_system() { | |||||||||||||||||||||||||||||
| HAS_SYSTEMD=true | ||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
| fatal 'Can not find systemd or openrc to use as a process supervisor for k3s' | ||||||||||||||||||||||||||||||
| if [ -d /etc/sv ] || [ -d /etc/runit/sv ] || type sv > /dev/null 2>&1; then | ||||||||||||||||||||||||||||||
| HAS_RUNIT=true | ||||||||||||||||||||||||||||||
| return | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
| fatal 'Can not find systemd, openrc, or runit to use as a process supervisor for k3s' | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # --- add quotes to command arguments --- | ||||||||||||||||||||||||||||||
|
|
@@ -250,14 +254,24 @@ setup_env() { | |||||||||||||||||||||||||||||
| UNINSTALL_K3S_SH=${UNINSTALL_K3S_SH:-${BIN_DIR}/${SYSTEM_NAME}-uninstall.sh} | ||||||||||||||||||||||||||||||
| KILLALL_K3S_SH=${KILLALL_K3S_SH:-${BIN_DIR}/k3s-killall.sh} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # --- use service or environment location depending on systemd/openrc --- | ||||||||||||||||||||||||||||||
| # --- use service or environment location depending on systemd/openrc/runit --- | ||||||||||||||||||||||||||||||
| if [ "${HAS_SYSTEMD}" = true ]; then | ||||||||||||||||||||||||||||||
| FILE_K3S_SERVICE=${SYSTEMD_DIR}/${SERVICE_K3S} | ||||||||||||||||||||||||||||||
| FILE_K3S_ENV=${SYSTEMD_DIR}/${SERVICE_K3S}.env | ||||||||||||||||||||||||||||||
| elif [ "${HAS_OPENRC}" = true ]; then | ||||||||||||||||||||||||||||||
| $SUDO mkdir -p /etc/rancher/k3s | ||||||||||||||||||||||||||||||
| FILE_K3S_SERVICE=/etc/init.d/${SYSTEM_NAME} | ||||||||||||||||||||||||||||||
| FILE_K3S_ENV=/etc/rancher/k3s/${SYSTEM_NAME}.env | ||||||||||||||||||||||||||||||
| elif [ "${HAS_RUNIT}" = true ]; then | ||||||||||||||||||||||||||||||
| $SUDO mkdir -p /etc/rancher/k3s | ||||||||||||||||||||||||||||||
| # Determine runit service directory | ||||||||||||||||||||||||||||||
| if [ -d /etc/runit/sv ]; then | ||||||||||||||||||||||||||||||
| RUNIT_SERVICE_DIR=/etc/runit/sv | ||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||
| RUNIT_SERVICE_DIR=/etc/sv | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
| FILE_K3S_SERVICE=${RUNIT_SERVICE_DIR}/${SYSTEM_NAME}/run | ||||||||||||||||||||||||||||||
| FILE_K3S_ENV=/etc/rancher/k3s/${SYSTEM_NAME}.env | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # --- get hash of config & exec for currently installed k3s --- | ||||||||||||||||||||||||||||||
|
|
@@ -794,6 +808,10 @@ for service in /etc/init.d/k3s*; do | |||||||||||||||||||||||||||||
| [ -x $service ] && $service stop | ||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| for service in /etc/sv/k3s* /etc/runit/sv/k3s*; do | ||||||||||||||||||||||||||||||
| [ -d $service ] && sv stop $(basename $service) 2>/dev/null || true | ||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| pschildren() { | ||||||||||||||||||||||||||||||
| ps -e -o ppid= -o pid= | \ | ||||||||||||||||||||||||||||||
| sed -e 's/^\s*//g; s/\s\s*/\t/g;' | \ | ||||||||||||||||||||||||||||||
|
|
@@ -892,6 +910,12 @@ fi | |||||||||||||||||||||||||||||
| if command -v rc-update; then | ||||||||||||||||||||||||||||||
| rc-update delete ${SYSTEM_NAME} default | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
| if command -v sv; then | ||||||||||||||||||||||||||||||
| sv stop ${SYSTEM_NAME} 2>/dev/null || true | ||||||||||||||||||||||||||||||
| rm -rf /var/service/${SYSTEM_NAME} | ||||||||||||||||||||||||||||||
| rm -rf /etc/sv/${SYSTEM_NAME} | ||||||||||||||||||||||||||||||
| rm -rf /etc/runit/sv/${SYSTEM_NAME} | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| rm -f ${FILE_K3S_SERVICE} | ||||||||||||||||||||||||||||||
| rm -f ${FILE_K3S_ENV} | ||||||||||||||||||||||||||||||
|
|
@@ -901,7 +925,7 @@ remove_uninstall() { | |||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| trap remove_uninstall EXIT | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| if (ls ${SYSTEMD_DIR}/k3s*.service || ls /etc/init.d/k3s*) >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||
| if (ls ${SYSTEMD_DIR}/k3s*.service || ls /etc/init.d/k3s* || ls /etc/sv/k3s*/run || ls /etc/runit/sv/k3s*/run) >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||
| set +x; echo 'Additional k3s services installed, skipping uninstall of k3s'; set -x | ||||||||||||||||||||||||||||||
| exit | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
@@ -1014,9 +1038,12 @@ EOF | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # --- write openrc service file --- | ||||||||||||||||||||||||||||||
| create_openrc_service_file() { | ||||||||||||||||||||||||||||||
| LOG_FILE=/var/log/${SYSTEM_NAME}.log | ||||||||||||||||||||||||||||||
| LOG_DIR=/var/log/${SYSTEM_NAME} | ||||||||||||||||||||||||||||||
| LOG_FILE=${LOG_DIR}/${SYSTEM_NAME}.log | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| info "openrc: Creating service file ${FILE_K3S_SERVICE}" | ||||||||||||||||||||||||||||||
| $SUDO mkdir -p ${LOG_DIR} | ||||||||||||||||||||||||||||||
| $SUDO chmod 0755 ${LOG_DIR} | ||||||||||||||||||||||||||||||
| $SUDO tee ${FILE_K3S_SERVICE} >/dev/null << EOF | ||||||||||||||||||||||||||||||
| #!/sbin/openrc-run | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -1049,19 +1076,66 @@ set +o allexport | |||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||
| $SUDO chmod 0755 ${FILE_K3S_SERVICE} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| $SUDO mkdir -p /etc/logrotate.d | ||||||||||||||||||||||||||||||
| $SUDO tee /etc/logrotate.d/${SYSTEM_NAME} >/dev/null << EOF | ||||||||||||||||||||||||||||||
| ${LOG_FILE} { | ||||||||||||||||||||||||||||||
| missingok | ||||||||||||||||||||||||||||||
| notifempty | ||||||||||||||||||||||||||||||
| copytruncate | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # --- write runit service file --- | ||||||||||||||||||||||||||||||
| create_runit_service_file() { | ||||||||||||||||||||||||||||||
| LOG_DIR=/var/log/${SYSTEM_NAME} | ||||||||||||||||||||||||||||||
| LOG_FILE=${LOG_DIR}/${SYSTEM_NAME}.log | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| info "runit: Creating service directory ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME}" | ||||||||||||||||||||||||||||||
| $SUDO mkdir -p ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME}/log | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| info "runit: Creating run script ${FILE_K3S_SERVICE}" | ||||||||||||||||||||||||||||||
| $SUDO tee ${FILE_K3S_SERVICE} >/dev/null << EOF | ||||||||||||||||||||||||||||||
| #!/bin/sh | ||||||||||||||||||||||||||||||
| exec 2>&1 | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| [ -f /etc/environment ] && . /etc/environment | ||||||||||||||||||||||||||||||
| [ -f ${FILE_K3S_ENV} ] && . ${FILE_K3S_ENV} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Load kernel modules | ||||||||||||||||||||||||||||||
| modprobe br_netfilter 2>/dev/null || true | ||||||||||||||||||||||||||||||
| modprobe overlay 2>/dev/null || true | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| exec ${BIN_DIR}/k3s $(escape_dq "${CMD_K3S_EXEC}") | ||||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||
| $SUDO chmod 0755 ${FILE_K3S_SERVICE} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| info "runit: Creating log run script" | ||||||||||||||||||||||||||||||
| $SUDO tee ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME}/log/run >/dev/null << EOF | ||||||||||||||||||||||||||||||
| #!/bin/sh | ||||||||||||||||||||||||||||||
| exec svlogd -tt ${LOG_DIR} | ||||||||||||||||||||||||||||||
| EOF | ||||||||||||||||||||||||||||||
| $SUDO chmod 0755 ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME}/log/run | ||||||||||||||||||||||||||||||
| $SUDO mkdir -p ${LOG_DIR} | ||||||||||||||||||||||||||||||
| $SUDO chmod 0755 ${LOG_DIR} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| $SUDO mkdir -p /etc/logrotate.d | ||||||||||||||||||||||||||||||
| $SUDO tee /etc/logrotate.d/${SYSTEM_NAME} >/dev/null << EOF | ||||||||||||||||||||||||||||||
| ${LOG_DIR}/* { | ||||||||||||||||||||||||||||||
| missingok | ||||||||||||||||||||||||||||||
| notifempty | ||||||||||||||||||||||||||||||
| copytruncate | ||||||||||||||||||||||||||||||
|
Comment on lines
1127
to
1129
|
||||||||||||||||||||||||||||||
| missingok | |
| notifempty | |
| copytruncate | |
| missingok | |
| notifempty | |
| copytruncate |
Copilot
AI
Dec 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The runit_enable function silently does nothing if none of the expected service supervision directories (/var/service, /service, or /etc/runit/runsvdir/default) exist. This could lead to a confusing situation where installation appears to succeed but the service is never enabled. Consider adding an error message or fallback behavior if no valid supervision directory is found, similar to how verify_system() fails when no init system is detected.
| $SUDO ln -sf ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME} /etc/runit/runsvdir/default/${SYSTEM_NAME} | |
| $SUDO ln -sf ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME} /etc/runit/runsvdir/default/${SYSTEM_NAME} | |
| else | |
| echo "[ERROR] runit: No valid supervision directory found to enable ${SYSTEM_NAME} service" >&2 | |
| exit 1 |
Copilot
AI
Dec 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded 2-second sleep is a fragile approach to ensure runsv picks up the service. This could fail on slower systems or succeed unnecessarily on faster systems. Consider using a polling loop with timeout instead, such as checking if the service directory appears in /var/service or checking if sv status succeeds, with retries over a reasonable timeout period. This would make the startup more reliable and potentially faster.
| # Wait for runsv to pick up the service | |
| sleep 2 | |
| # Wait for runsv to pick up the service using polling (max 10s) | |
| TIMEOUT=10 | |
| INTERVAL=0.2 | |
| ELAPSED=0 | |
| while ! $SUDO sv status ${SYSTEM_NAME} >/dev/null 2>&1; do | |
| sleep $INTERVAL | |
| ELAPSED=$(awk "BEGIN {print $ELAPSED+$INTERVAL}") | |
| if [ "$(awk "BEGIN {print ($ELAPSED >= $TIMEOUT)}")" -eq 1 ]; then | |
| warn "runit: Timeout waiting for ${SYSTEM_NAME} to be picked up by runsv" | |
| break | |
| fi | |
| done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The uninstall script removes /var/service/${SYSTEM_NAME} symlink without checking which supervision directory was actually used during installation. The runit_enable function could have created the symlink in /service or /etc/runit/runsvdir/default instead. Consider removing symlinks from all possible supervision directories, or store which directory was used during installation. This could leave orphaned symlinks after uninstall.