feat: add support for runit as a process supervisor#13349
feat: add support for runit as a process supervisor#13349johnitvn wants to merge 2 commits intok3s-io:mainfrom
Conversation
Signed-off-by: John Martin <john.itvn@gmail.com>
There was a problem hiding this comment.
Pull request overview
This pull request adds comprehensive support for runit as an init system alongside the existing systemd and openrc support, enabling k3s to run on distributions that use runit (such as Void Linux). The implementation follows patterns established for systemd and openrc, with appropriate service management, logging, and lifecycle control.
Key changes:
- Added runit detection in system verification and service file creation for the runit supervisor
- Implemented complete service lifecycle management (enable, start, stop, uninstall) for runit services
- Enhanced log management for openrc and runit with dedicated log directories and logrotate configurations
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
install.sh
Outdated
| $SUDO modprobe br_netfilter 2>/dev/null || true | ||
| $SUDO modprobe overlay 2>/dev/null || true |
There was a problem hiding this comment.
The modprobe commands are using $SUDO variable substitution inside a heredoc that will be written to a file and executed later by runit. This will expand $SUDO at file creation time rather than at execution time. The commands should not use $SUDO prefix since runit services typically run as root. Change these lines to simply modprobe br_netfilter 2>/dev/null || true and modprobe overlay 2>/dev/null || true to match the pattern used in the systemd service file (lines 1031-1032).
| $SUDO modprobe br_netfilter 2>/dev/null || true | |
| $SUDO modprobe overlay 2>/dev/null || true | |
| modprobe br_netfilter 2>/dev/null || true | |
| modprobe overlay 2>/dev/null || true |
| missingok | ||
| notifempty | ||
| copytruncate |
There was a problem hiding this comment.
The logrotate configuration uses tabs instead of spaces for indentation, which is inconsistent with the openrc logrotate configuration (lines 1082-1085) that uses spaces. Both service types should use the same indentation style for consistency. Change the tabs on these lines to spaces to match the openrc configuration.
| missingok | |
| notifempty | |
| copytruncate | |
| missingok | |
| notifempty | |
| copytruncate |
| # Wait for runsv to pick up the service | ||
| sleep 2 |
There was a problem hiding this comment.
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 |
| elif [ -d /service ]; then | ||
| $SUDO ln -sf ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME} /service/${SYSTEM_NAME} | ||
| elif [ -d /etc/runit/runsvdir/default ]; then | ||
| $SUDO ln -sf ${RUNIT_SERVICE_DIR}/${SYSTEM_NAME} /etc/runit/runsvdir/default/${SYSTEM_NAME} |
There was a problem hiding this comment.
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 |
| fi | ||
| if command -v sv; then | ||
| sv stop ${SYSTEM_NAME} 2>/dev/null || true | ||
| rm -rf /var/service/${SYSTEM_NAME} |
There was a problem hiding this comment.
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.
| rm -rf /var/service/${SYSTEM_NAME} | |
| rm -rf /var/service/${SYSTEM_NAME} | |
| rm -rf /service/${SYSTEM_NAME} | |
| rm -rf /etc/runit/runsvdir/default/${SYSTEM_NAME} |
Signed-off-by: John Martin <john.itvn@gmail.com>
This pull request updates the
install.shscript to add full support for the runit process supervisor in addition to existing support for systemd and openrc. The changes ensure that k3s can be installed, managed, and uninstalled on systems using runit, with appropriate service files, log handling, and lifecycle management.Key changes include:
runit Supervisor Support:
Service Lifecycle Management:
Service Enablement and Startup:
Log Management Improvements:
These changes make the installer more robust and compatible with a wider range of Linux distributions that use runit as their init system. (I'm already tested on Void Linux )