Compare commits

...

5 commits

Author SHA1 Message Date
df1edf3dc5 feat(service): merge PID-file based service management (#100)
This merge introduces reliable cross-platform service detection using
PID-files instead of fragile pexp patterns, resolving rcctl check
issues on OpenBSD.

Key improvements:
- PID-file creation in /var/run/furt/ with proper permissions
- Updated start.sh for service vs interactive mode detection
- Fixed OpenBSD rc.d script with PID-file based rc_check()
- Corrected systemd service PIDFile parameter
- Enhanced setup-directories.sh for PID directory creation

Tested successfully on werner (OpenBSD):
- rcctl check furt now shows (ok) instead of (failed)
- Service start/stop/restart works reliably
- PID-file management handles permissions correctly

Closes #100
2025-09-07 17:41:33 +02:00
bbbbeef072 chore: merkwerk auto-update 2025-09-07 16:58:01 +02:00
59f372f2b0 feat(service): implement PID-file based service management
- Add PID directory creation in setup-directories.sh
- Update start.sh to use /var/run/furt/furt.pid for both platforms
- Fix OpenBSD rc.d script pidfile variable path
- Correct systemd service PIDFile parameter path
- Resolve rcctl check detection issues on OpenBSD

Fixes service detection problems where rcctl check would show (failed)
even when service was running. PID-file approach provides reliable
cross-platform service status detection instead of fragile pexp patterns.
Related DAW/furt#100
2025-09-07 16:57:35 +02:00
7ee990b052 chore: merkwerk auto-update 2025-09-05 22:30:13 +02:00
25a709ebbe feat(service): implement PID-file based service management (DAW/furt#100)
- Replace unreliable pexp patterns with PID-file approach
- Add graceful shutdown with timeout handling in rc.d script
- Implement process validation after startup
- Add SIGHUP config reload support for Unix services
- Ensure PID-file cleanup on service exit
- Update systemd service to use PIDFile parameter

Platform improvements:
- OpenBSD: rc_check/rc_stop functions now PID-file based
- Linux: systemd Type=forking with proper PIDFile support
- Cross-platform: /var/run/furt.pid standard location

Resolves service status detection issues where rcctl check showed
(failed) despite running service due to process name variations
across platforms.
2025-09-05 22:30:07 +02:00
5 changed files with 80 additions and 5 deletions

View file

@ -20,3 +20,5 @@
795f8867,78e8ded,fix/json-library-compatibility,2025-09-05T15:44:42Z,michael,git,lua-api
795f8867,d4fa6e3,fix/ssl-dependency-check,2025-09-05T16:20:08Z,michael,git,lua-api
a670de0f,d271b84,refactor/extract-health-routes-and-server-core,2025-09-05T17:25:09Z,michael,git,lua-api
a670de0f,25a709e,feature/pid-file-service-management,2025-09-05T20:30:13Z,michael,git,lua-api
a670de0f,59f372f,feature/pid-file-service-management,2025-09-07T14:58:01Z,michael,git,lua-api

View file

@ -6,7 +6,8 @@ After=network.target
Type=forking
User=furt
Group=furt
ExecStart=/usr/local/share/furt/scripts/start.sh start
ExecStart=/usr/local/share/furt/scripts/start.sh
PIDFile=/var/run/furt/furt.pid
WorkingDirectory=/usr/local/share/furt
Restart=always
RestartSec=5

View file

@ -3,11 +3,52 @@
daemon="/usr/local/share/furt/scripts/start.sh"
daemon_user="_furt"
daemon_cwd="/usr/local/share/furt"
daemon_flags="start"
. /etc/rc.d/rc.subr
pexp="lua.*src/main.lua"
# PID-File location
pidfile="/var/run/furt/furt.pid"
# Custom rc_check function (PID-File based)
rc_check() {
[ -f "$pidfile" ] && kill -0 $(cat "$pidfile") 2>/dev/null
}
# Custom rc_stop function (PID-File based)
rc_stop() {
if [ -f "$pidfile" ]; then
local _pid=$(cat "$pidfile")
echo "Stopping furt (PID: $_pid)"
kill "$_pid" 2>/dev/null
# Wait for process to die
local _timeout=10
while [ $_timeout -gt 0 ] && kill -0 "$_pid" 2>/dev/null; do
sleep 1
_timeout=$((_timeout - 1))
done
# Force kill if still running
if kill -0 "$_pid" 2>/dev/null; then
echo "Force killing furt (PID: $_pid)"
kill -9 "$_pid" 2>/dev/null
fi
rm -f "$pidfile"
echo "furt stopped"
else
echo "furt not running (no PID-File)"
fi
}
# Custom rc_reload function (signal-based)
rc_reload() {
if rc_check; then
local _pid=$(cat "$pidfile")
echo "Reloading furt configuration (PID: $_pid)"
kill -HUP "$_pid"
else
echo "furt not running"
return 1
fi
}
rc_cmd $1

View file

@ -18,12 +18,15 @@ fi
mkdir -p "$CONFIG_DIR"
mkdir -p /usr/local/share/furt
mkdir -p /var/log/furt
mkdir -p /var/run/furt
# Set ownership for log directory (service user needs write access)
chown "$USER:$GROUP" /var/log/furt
chown "$USER:$GROUP" /var/run/furt
echo "Created directories:"
echo " Config: $CONFIG_DIR"
echo " Share: /usr/local/share/furt"
echo " Logs: /var/log/furt (owned by $USER)"
echo " PID: /var/run/furt (owned by $USER)"

View file

@ -19,8 +19,10 @@ LUA_COMMAND=""
# Config check first
if [ "$(uname)" = "OpenBSD" ] || [ "$(uname)" = "FreeBSD" ]; then
CONFIG_FILE="/usr/local/etc/furt/furt.conf"
PID_FILE="/var/run/furt/furt.pid"
else
CONFIG_FILE="/etc/furt/furt.conf"
PID_FILE="/var/run/furt/furt.pid"
fi
if [ ! -f "$CONFIG_FILE" ] && [ ! -f "$PROJECT_DIR/config/furt.conf" ]; then
@ -87,12 +89,38 @@ cd "$PROJECT_DIR"
echo -e "${GREEN}Starting Furt...${NC}"
# PID-File cleanup function
cleanup_pid() {
if [ -f "$PID_FILE" ]; then
rm -f "$PID_FILE"
fi
}
# Service vs Interactive Detection
if [ ! -t 0 ] || [ ! -t 1 ]; then
# Service mode - Background
# Service mode - Background + PID-File
echo -e "${GREEN}Service mode: Background + PID-File${NC}"
# Start process in background
"$LUA_COMMAND" src/main.lua &
PID=$!
# Write PID-File
echo "$PID" > "$PID_FILE"
echo -e "${GREEN}Furt started (PID: $PID, PID-File: $PID_FILE)${NC}"
# Verify process is still running after short delay
sleep 1
if ! kill -0 "$PID" 2>/dev/null; then
echo -e "${RED}Error: Process died immediately${NC}"
cleanup_pid
exit 1
fi
echo -e "${GREEN}Service startup successful${NC}"
else
# Interactive mode - Foreground
# Interactive mode - Foreground (no PID-File)
echo -e "${GREEN}Interactive mode: Foreground${NC}"
exec "$LUA_COMMAND" src/main.lua
fi