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; } diff --git a/src/RaspAP/Plugins/PluginInstaller.php b/src/RaspAP/Plugins/PluginInstaller.php index e6043c8e..c8ad8a6f 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 * @@ -317,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);