#!/bin/sh # PROVIDE: hermes_gateway # REQUIRE: LOGIN NETWORKING # KEYWORD: shutdown # # Add the following lines to /etc/rc.conf to enable hermes_gateway: # # hermes_gateway_enable="YES" # hermes_gateway_user="hermes" # REQUIRED: account whose ~/.hermes is used # hermes_gateway_profile="" # OPTIONAL: -p for multi-profile setups # hermes_gateway_args="" # OPTIONAL: extra args for `hermes gateway run` # # e.g. "-v" for INFO logs, "-vv" for DEBUG # # NOTE: do NOT use ${name}_flags for extra args. rc.subr reserves *_flags # for the *command* (i.e. daemon(8)) and will inject them ahead of daemon's # own options, which causes daemon to fail with "invalid option". # Use hermes_gateway_args instead — it is forwarded to `hermes gateway run`. # # Notes: # * Hermes stores all state under $HOME/.hermes (config, sessions, logs, # credentials). This script runs the gateway as ${hermes_gateway_user} # so ~/.hermes resolves to that user's home directory. There is no # sane "root" default — running as root would target /root/.hermes # which is almost never what the operator wants. # * The gateway logs to ${HOME}/.hermes/agent.log via Hermes' own logging. # daemon(8)'s syslog redirection captures any stray stderr to # /var/log/messages with tag "hermes_gateway". # * Crash recovery: daemon(8) -r restarts on non-zero exit. Hermes' own # drain-restart (exit code 75) is handled the same way. . /etc/rc.subr name="hermes_gateway" rcvar="hermes_gateway_enable" load_rc_config $name : ${hermes_gateway_enable:="NO"} : ${hermes_gateway_user:=""} : ${hermes_gateway_profile:=""} : ${hermes_gateway_args:=""} # Back-compat: if someone set the legacy *_flags var, honor it but warn. if [ -n "${hermes_gateway_flags}" ] && [ -z "${hermes_gateway_args}" ]; then warn "hermes_gateway_flags is deprecated (it collides with rc.subr); use hermes_gateway_args" hermes_gateway_args="${hermes_gateway_flags}" fi # Suppress rc.subr's automatic *_flags injection — we route extras via # hermes_gateway_args into the inner command instead. hermes_gateway_flags="" # Resolve home directory of the configured user so ~/.hermes works. if [ -n "${hermes_gateway_user}" ]; then hermes_gateway_home=$(getent passwd "${hermes_gateway_user}" 2>/dev/null | cut -d: -f6) if [ -z "${hermes_gateway_home}" ]; then hermes_gateway_home=$(eval echo "~${hermes_gateway_user}") fi else hermes_gateway_home="" fi piddir="/var/run/${name}" pidfile="${piddir}/${name}.pid" # We launch via daemon(8): # -f fully detach # -r restart on non-zero exit (handles Hermes' SIGUSR1 drain-restart, code 75) # -P pid pidfile owned by daemon(8) for proper PID tracking + signaling # -S send stray stderr to syslog # -T tag syslog tag # HOME=... so Hermes finds ~/.hermes for the right user # # Note: do NOT pass `-u ${hermes_gateway_user}` to daemon. rc.subr already # drops privileges to ${name}_user via su(1) before exec, so adding -u here # would cause daemon to call initgroups() as a non-root user → EPERM and a # tight restart loop with `-r`. command="/usr/sbin/daemon" command_args="-f -r -P ${pidfile} -S -T ${name} \ /usr/bin/env HOME=${hermes_gateway_home} \ %%PREFIX%%/bin/hermes ${hermes_gateway_profile:+-p ${hermes_gateway_profile}} \ gateway run --replace ${hermes_gateway_args}" required_files="%%PREFIX%%/bin/hermes" start_precmd="hermes_gateway_prestart" hermes_gateway_prestart() { if [ -z "${hermes_gateway_user}" ]; then err 1 "hermes_gateway_user is not set in rc.conf — refusing to start" fi if [ -z "${hermes_gateway_home}" ] || [ ! -d "${hermes_gateway_home}" ]; then err 1 "home directory for user '${hermes_gateway_user}' not found" fi # piddir must be writable by the unprivileged user since rc.subr drops # privileges (via ${name}_user) before daemon(8) writes the supervisor # pidfile (-P). Always (re-)assert ownership in case of stale state. install -d -m 0755 -o "${hermes_gateway_user}" "${piddir}" } run_rc_command "$1"