diff --git a/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre b/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre
index a19b863..36e6097 100755
--- a/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre
+++ b/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre
@@ -21,6 +21,13 @@ fi
# therefore refresh configd before the MVC service controller can call them.
/usr/sbin/service configd restart >/dev/null 2>&1 || true
/usr/local/sbin/pluginctl -cq cache_flush >/dev/null 2>&1 || true
+
+# Apply model migrations before rendering the service template. In particular
+# 1.4.0 copies the old combined listener values into the split address/port
+# fields so upgrades keep their existing ports instead of falling back.
+if [ -x /usr/local/opnsense/mvc/script/run_migrations.php ]; then
+ /usr/local/opnsense/mvc/script/run_migrations.php >/dev/null 2>&1 || true
+fi
/usr/local/sbin/configctl template reload OPNsense/RustProxy >/dev/null 2>&1 || true
exit 0
diff --git a/opnsense-plugin/www/rustproxy/Makefile b/opnsense-plugin/www/rustproxy/Makefile
index 546dce8..abd1039 100644
--- a/opnsense-plugin/www/rustproxy/Makefile
+++ b/opnsense-plugin/www/rustproxy/Makefile
@@ -1,6 +1,6 @@
PLUGIN_NAME= rustproxy
PLUGIN_VERSION?= 0.23.3
-PLUGIN_REVISION?= 0
+PLUGIN_REVISION?= 1
PLUGIN_COMMENT= RustProxy reverse proxy service
PLUGIN_MAINTAINER?= local@localhost
PLUGIN_WWW?= https://git.linuxiarz.pl/gru/RustProxy
diff --git a/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy b/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy
index 6907b0c..0f651b4 100755
--- a/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy
+++ b/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy
@@ -160,7 +160,9 @@ fi
command_args="-r -R ${rustproxy_restart_delay} -P ${pidfile} -p ${child_pidfile} ${rustproxy_daemon_user_arg} -o ${rustproxy_log_file} ${rustproxy_command} ${rustproxy_runtime_args}"
required_files="${rustproxy_command}"
start_precmd="rustproxy_prestart"
+start_postcmd="rustproxy_poststart"
stop_postcmd="rustproxy_poststop"
+status_cmd="rustproxy_status"
rustproxy_prestart()
{
@@ -179,6 +181,72 @@ rustproxy_prestart()
/bin/chmod 0640 "${rustproxy_log_file}"
echo "RustProxy listeners: HTTP=${rustproxy_proxy_listen_resolved} TLS=${rustproxy_tls_listen_resolved} ADMIN=${rustproxy_admin_listen_resolved}"
+ echo "RustProxy exec: ${rustproxy_command} ${rustproxy_runtime_args}"
+ printf '%s\n' "${rustproxy_command} ${rustproxy_runtime_args}" > "${rustproxy_run_dir}/command.txt"
+ /bin/chmod 0640 "${rustproxy_run_dir}/command.txt"
+}
+
+rustproxy_child_pid()
+{
+ [ -r "${child_pidfile}" ] || return 1
+ _rp_pid="$(/bin/cat "${child_pidfile}" 2>/dev/null)"
+ case "${_rp_pid}" in
+ ''|*[!0-9]*) return 1 ;;
+ esac
+ /bin/kill -0 "${_rp_pid}" 2>/dev/null || return 1
+ printf '%s\n' "${_rp_pid}"
+}
+
+rustproxy_poststart()
+{
+ # daemon(8) may stay alive with -r even when rust-proxy exits immediately.
+ # Verify the supervised child so service/configd cannot report a false OK.
+ /bin/sleep 1
+ if _rp_pid="$(rustproxy_child_pid)"; then
+ echo "RustProxy child started as PID ${_rp_pid}"
+ return 0
+ fi
+
+ echo "RustProxy failed to stay running; stopping the restart supervisor." >&2
+ if [ -s "${rustproxy_log_file}" ]; then
+ echo "Last RustProxy log lines:" >&2
+ /usr/bin/tail -n 40 "${rustproxy_log_file}" >&2
+ fi
+ if [ -r "${pidfile}" ]; then
+ _rp_supervisor_pid="$(/bin/cat "${pidfile}" 2>/dev/null)"
+ case "${_rp_supervisor_pid}" in
+ ''|*[!0-9]*) ;;
+ *) /bin/kill -TERM "${_rp_supervisor_pid}" 2>/dev/null || true ;;
+ esac
+ fi
+ /bin/sleep 1
+ /bin/rm -f "${child_pidfile}" "${pidfile}"
+ return 1
+}
+
+rustproxy_status()
+{
+ if _rp_pid="$(rustproxy_child_pid)"; then
+ echo "rustproxy is running as pid ${_rp_pid}"
+ return 0
+ fi
+
+ _rp_supervisor_pid=""
+ if [ -r "${pidfile}" ]; then
+ _rp_supervisor_pid="$(/bin/cat "${pidfile}" 2>/dev/null)"
+ fi
+ case "${_rp_supervisor_pid}" in
+ ''|*[!0-9]*) ;;
+ *)
+ if /bin/kill -0 "${_rp_supervisor_pid}" 2>/dev/null; then
+ echo "rustproxy is not running (daemon supervisor ${_rp_supervisor_pid} is waiting/restarting)"
+ return 1
+ fi
+ ;;
+ esac
+
+ echo "rustproxy is not running"
+ return 1
}
rustproxy_poststop()
diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/ServiceController.php b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/ServiceController.php
index f96d74b..9f25c66 100644
--- a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/ServiceController.php
+++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/ServiceController.php
@@ -13,6 +13,8 @@ class ServiceController extends ApiMutableServiceControllerBase
protected function reconfigureForceRestart()
{
- return 0;
+ // Listener addresses are process startup arguments, so Apply must
+ // always stop and start the service after regenerating the template.
+ return 1;
}
}
diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml
index 7d599f6..f7e8bdb 100644
--- a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml
+++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml
@@ -20,13 +20,13 @@
rustproxy.general.proxyAddress
text
- HTTP bind address. Leave empty for 0.0.0.0 or to keep the legacy combined listener after an upgrade.
+ HTTP bind address. Default: 0.0.0.0. Existing installations are migrated from the legacy combined listener automatically.
rustproxy.general.proxyPort
text
- HTTP port passed as --proxy-listen. Leave empty for 8080 or to keep the legacy combined listener after an upgrade.
+ HTTP port passed as --proxy-listen. Default: 8080.
@@ -44,13 +44,13 @@
rustproxy.general.tlsAddress
text
- HTTPS/TLS bind address. Leave empty for 0.0.0.0 or to keep the legacy combined listener after an upgrade.
+ HTTPS/TLS bind address. Default: 0.0.0.0. Existing installations are migrated automatically.
rustproxy.general.tlsPort
text
- HTTPS/TLS port passed as --tls-listen. Leave empty for 8181 or to keep the legacy combined listener after an upgrade.
+ HTTPS/TLS port passed as --tls-listen. Default: 8181.
@@ -62,13 +62,13 @@
rustproxy.general.adminAddress
text
- Administration bind address. Leave empty for 0.0.0.0 or to keep the legacy combined listener after an upgrade.
+ Administration bind address. Default: 0.0.0.0. Existing installations are migrated automatically.
rustproxy.general.adminPort
text
- Administration port passed as --admin-listen. Leave empty for 9090 or to keep the legacy combined listener after an upgrade.
+ Administration port passed as --admin-listen. Default: 9090.
rustproxy.general.allowRemoteAdmin
diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_4_0.php b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_4_0.php
new file mode 100644
index 0000000..202805c
--- /dev/null
+++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_4_0.php
@@ -0,0 +1,68 @@
+ 65535) {
+ return null;
+ }
+
+ return [$address, (string)$number];
+ }
+
+ private function migrateListener($general, $legacyField, $addressField, $portField)
+ {
+ $parts = $this->splitListener((string)$general->$legacyField);
+ if ($parts === null) {
+ return;
+ }
+ $general->$addressField = $parts[0];
+ $general->$portField = $parts[1];
+ }
+
+ public function run($model)
+ {
+ parent::run($model);
+
+ // Deliberately prefer valid 1.2.x values during this one migration.
+ // This also repairs hosts that already installed the broken 1.3.x model.
+ $this->migrateListener($model->general, 'proxyListen', 'proxyAddress', 'proxyPort');
+ $this->migrateListener($model->general, 'tlsListen', 'tlsAddress', 'tlsPort');
+ $this->migrateListener($model->general, 'adminListen', 'adminAddress', 'adminPort');
+ }
+}
diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml
index 1e56de7..fa791fb 100644
--- a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml
+++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml
@@ -1,6 +1,6 @@
//OPNsense/rustproxy
- 1.3.0
+ 1.4.0
RustProxy service settings
@@ -17,10 +17,14 @@
fields below for upgrade compatibility, but new UI writes these.
-->
+ 0.0.0.0
+ Y
N
Enter a valid HTTP bind address, for example 0.0.0.0.
+ 8080
+ Y
Enter a valid HTTP port between 1 and 65535.
@@ -28,17 +32,25 @@
Y
+ 0.0.0.0
+ Y
N
Enter a valid HTTPS/TLS bind address, for example 0.0.0.0.
+ 8181
+ Y
Enter a valid HTTPS/TLS port between 1 and 65535.
+ 0.0.0.0
+ Y
N
Enter a valid administration bind address, for example 0.0.0.0.
+ 9090
+ Y
Enter a valid administration port between 1 and 65535.
diff --git a/scripts/check.sh b/scripts/check.sh
index 2eb4727..4030d7e 100755
--- a/scripts/check.sh
+++ b/scripts/check.sh
@@ -64,6 +64,16 @@ grep -q 'rustproxy_resolve_listener' "$rc_script"
grep -q 'rustproxy_valid_port' "$rc_script"
grep -q 'pidfile="${rustproxy_run_dir}/daemon.pid"' "$rc_script"
grep -q 'child_pidfile="${rustproxy_run_dir}/rustproxy.pid"' "$rc_script"
+grep -q '1.4.0' "$model"
+grep -q '0.0.0.0' "$model"
+grep -q '8080' "$model"
+grep -q '8181' "$model"
+grep -q '9090' "$model"
+grep -q 'class M1_4_0 extends BaseModelMigration' "$ROOT/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_4_0.php"
+grep -q 'start_postcmd="rustproxy_poststart"' "$rc_script"
+grep -q 'status_cmd="rustproxy_status"' "$rc_script"
+grep -q 'RustProxy exec:' "$rc_script"
+grep -q 'return 1;' "$ROOT/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/ServiceController.php"
grep -q '' "$model"
grep -q '' "$model"
grep -q '' "$model"