feat: install, update and remove Mudfish from the panel

- Install: download the latest package from mudfish.net, verify the
  Makeself MD5, unpack the bzip2 tar ourselves (no installer script is
  executed; path traversal and links rejected) into /opt/mudfish/<ver>.
- Update: checked at most daily; button-only; refused while the tunnel is
  up; carries the saved login (.conf, .conf.db) into the new version,
  restarts the daemon and keeps only the previous version.
- Remove: button with confirmation, and automatically when the plugin is
  uninstalled: VPN off, daemon stopped, mudfish-tap removed,
  /opt/mudfish deleted, plugin settings cleared.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ysj7705andClaude Opus 5.5 committed 2026-10-24 21:58:32 +09:00
1 parent 027a029b47
commit 3c28c9dac2
9 files changed
+718 -27

No files matched your search

+13
View File
@@ -35,6 +35,19 @@ class SystemTest(unittest.TestCase):
with tempfile.TemporaryDirectory() as var:
self.assertEqual(api_base(var), "http://127.0.0.1:8282")
def test_version_of_binary_path(self):
from mudfish_decky.system import version_of
self.assertEqual(version_of("/opt/mudfish/6.6.0/bin/mudrun-headless"), "6.6.0")
def test_stop_daemon_and_remove_nm_connection_commands(self):
from mudfish_decky.system import remove_nm_connection, stop_daemon
calls = []
run = lambda cmd, **kw: calls.append(cmd) # noqa: E731
stop_daemon(run=run)
remove_nm_connection(run=run)
self.assertEqual(calls, [["systemctl", "stop", "mudfish-decky"],
["nmcli", "connection", "delete", "mudfish-tap"]])
def test_lan_ip_from_route_get(self):
from mudfish_decky.system import lan_ip
out = "1.1.1.1 via 192.168.1.1 dev wlan0 src 192.168.1.50 uid 0 \n cache \n"