From 8bf4116b42979b4fd5d14442cf2531c01ca1feee Mon Sep 17 00:00:00 2001 From: billz Date: Fri, 10 Oct 2025 04:21:39 -0700 Subject: [PATCH 1/3] Create installDebianPackages(), select .deb dpkg for current arch --- src/RaspAP/Plugins/PluginInstaller.php | 52 ++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/RaspAP/Plugins/PluginInstaller.php b/src/RaspAP/Plugins/PluginInstaller.php index e6043c8e..df208058 100644 --- a/src/RaspAP/Plugins/PluginInstaller.php +++ b/src/RaspAP/Plugins/PluginInstaller.php @@ -197,6 +197,10 @@ class PluginInstaller $this->installDependencies($manifest['dependencies']); $rollbackStack[] = 'uninstallDependencies'; } + if (!empty($manifest['dpkgs'])) { + $this->installDebianPackages($manifest['dpkgs'], $pluginDir); + $rollbackStack[] = 'uninstallDebianPackages'; + } if (!empty($manifest['user_nonprivileged'])) { $this->createUser($manifest['user_nonprivileged']); $rollbackStack[] = 'deleteUser'; @@ -285,6 +289,54 @@ class PluginInstaller } } + /** + * Installs a Debian package (.deb) for the current architecture + * + * @param array $dpkgs + * @param string $pluginDir + * @return void + * @throws \Exception + */ + private function installDebianPackages(array $dpkgs, string $pluginDir): void + { + $arch = trim(shell_exec('dpkg --print-architecture')); + if (empty($arch)) { + throw new \Exception('Unable to detect system architecture'); + } + + // match .deb file for current arch + $debFile = null; + foreach ($dpkgs as $pkg) { + if (strpos($pkg, $arch) !== false) { + $debFile = $pkg; + break; + } + } + + if (!$debFile) { + throw new \Exception("No matching .deb package found for architecture: $arch"); + } + + $debPath = realpath(rtrim($pluginDir, '/') . '/dpkgs/' . $debFile); + if ($debPath === false || !is_file($debPath)) { + throw new \Exception("Debian package not found: $debFile"); + } + + // invoke the plugin-helper + $cmd = sprintf( + 'sudo %s deb %s 2>&1', + escapeshellcmd($this->helperScriptPath), escapeshellarg($debPath) + ); + $return = shell_exec($cmd); + + // check for success + if (stripos($return, 'ok') === false) { + throw new \Exception("Plugin helper failed to install .deb package: $debFile\nOutput: $return"); + } + + error_log("Installed Debian package: $debFile for arch $arch"); + } + /** * Creates a non-priviledged Linux user * From e3e9adb63efde2e38a380403dd0ba634f50ce28f Mon Sep 17 00:00:00 2001 From: billz Date: Fri, 10 Oct 2025 04:22:10 -0700 Subject: [PATCH 2/3] Extend plugin-helper to install .deb packages --- installers/plugin_helper.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/installers/plugin_helper.sh b/installers/plugin_helper.sh index c980040b..3151256f 100755 --- a/installers/plugin_helper.sh +++ b/installers/plugin_helper.sh @@ -41,6 +41,21 @@ case "$action" in echo "OK" ;; + "deb") + [ $# -lt 1 ] && { echo "Usage: $0 deb "; exit 1; } + deb_file="$1" + + if [ ! -f "$deb_file" ]; then + echo "Error: File not found: $deb_file" + exit 1 + fi + + echo "Installing .deb package: $deb_file" + dpkg -i "$deb_file" + + echo "OK" + ;; + "user") [ $# -lt 2 ] && { echo "Usage: $0 user ."; exit 1; } From a844328da3ff7d4d7033bacec6fa144f8652dd33 Mon Sep 17 00:00:00 2001 From: billz Date: Sat, 11 Oct 2025 00:45:21 -0700 Subject: [PATCH 3/3] php7.4 compatibility: str_starts_with -> strncmp --- src/RaspAP/Plugins/PluginInstaller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RaspAP/Plugins/PluginInstaller.php b/src/RaspAP/Plugins/PluginInstaller.php index df208058..c8ad8a6f 100644 --- a/src/RaspAP/Plugins/PluginInstaller.php +++ b/src/RaspAP/Plugins/PluginInstaller.php @@ -369,7 +369,7 @@ class PluginInstaller $source = escapeshellarg($pluginDir . DIRECTORY_SEPARATOR . $config['source']); $destination = $config['destination']; - if (!str_starts_with($destination, '/')) { + if (strncmp($destination, '/', 1) !== 0) { $destination = $this->rootPath . '/' . ltrim($destination, '/'); } $destination = escapeshellarg($destination);