diff --git a/UI/debug-command-execution.php b/UI/debug-command-execution.php
new file mode 100644
index 0000000..7925928
--- /dev/null
+++ b/UI/debug-command-execution.php
@@ -0,0 +1,357 @@
+
+
+
+
+
+
+ Command Execution Diagnostics
+
+
+
+
+
🔍 Command Execution Diagnostics
+
Purpose: Diagnose why GPG key installation fails on CloudStack instance
+
Time:
+
+ ";
+ echo "
$description
";
+ echo "
Command: $command
";
+
+ $startTime = microtime(true);
+
+ // Test using our executeCommand function
+ $output = '';
+ $returnCode = null;
+ $success = executeCommand($command, $output, $returnCode);
+
+ $endTime = microtime(true);
+ $duration = round(($endTime - $startTime) * 1000, 2);
+
+ $result = [
+ 'description' => $description,
+ 'command' => $command,
+ 'success' => $success,
+ 'return_code' => $returnCode,
+ 'output' => $output,
+ 'duration_ms' => $duration,
+ 'expected_success' => $expectSuccess
+ ];
+
+ $results[] = $result;
+
+ // Display result
+ $statusClass = $success ? 'success' : 'error';
+ if ($success && !$expectSuccess) $statusClass = 'warning';
+ if (!$success && !$expectSuccess) $statusClass = 'info';
+
+ echo "
";
+ echo "Status: " . ($success ? "✅ SUCCESS" : "❌ FAILED") . "
";
+ echo "Return Code: $returnCode
";
+ echo "Duration: {$duration}ms
";
+ echo "
";
+
+ if ($output) {
+ echo "
$output
";
+ }
+
+ // Track issues
+ if ($expectSuccess && !$success) {
+ $issues[] = "$description failed: $output";
+ }
+
+ echo "
";
+
+ return $result;
+ }
+
+ /**
+ * Test PHP environment information
+ */
+ echo "";
+ echo "
📋 PHP Environment Information
";
+ echo "
";
+ echo "| Property | Value |
";
+ echo "| PHP Version | " . PHP_VERSION . " |
";
+ echo "| PHP SAPI | " . php_sapi_name() . " |
";
+ echo "| Operating System | " . PHP_OS . " |
";
+ echo "| Current User (PHP) | " . get_current_user() . " |
";
+ echo "| Process UID | " . (function_exists('posix_getuid') ? posix_getuid() : 'N/A') . " |
";
+ echo "| Process GID | " . (function_exists('posix_getgid') ? posix_getgid() : 'N/A') . " |
";
+ echo "| Process PID | " . getmypid() . " |
";
+ echo "| Memory Limit | " . ini_get('memory_limit') . " |
";
+ echo "| Max Execution Time | " . ini_get('max_execution_time') . "s |
";
+ echo "| Disable Functions | " . (ini_get('disable_functions') ?: 'None') . " |
";
+ echo "
";
+ echo "
";
+
+ /**
+ * Test environment variables
+ */
+ echo "";
+ echo "
🌍 Environment Variables
";
+ $envVars = ['PATH', 'HOME', 'USER', 'SHELL', 'TERM', 'PWD', 'SUDO_USER', 'SUDO_UID', 'SUDO_GID'];
+ echo "
";
+ echo "| Variable | Value |
";
+ foreach ($envVars as $var) {
+ $value = getenv($var) ?: $_SERVER[$var] ?? 'Not Set';
+ echo "| $var | $value |
";
+ }
+ echo "
";
+ echo "
";
+
+ /**
+ * Test basic command execution
+ */
+ echo "🔧 Basic Command Tests
";
+ testCommand("Current Working Directory", "pwd");
+ testCommand("Current User Identity", "whoami");
+ testCommand("Detailed User Info", "id");
+ testCommand("Hostname", "hostname");
+ testCommand("Date/Time", "date");
+
+ /**
+ * Test sudo access
+ */
+ echo "🔐 Sudo Access Tests
";
+ testCommand("Sudo Version", "sudo --version");
+ testCommand("Sudo Non-Interactive Test", "sudo -n whoami");
+ testCommand("Sudo List Permissions", "sudo -l", false); // May fail, that's ok
+ testCommand("Test Sudo Echo", "sudo echo 'sudo test successful'");
+
+ /**
+ * Test network connectivity
+ */
+ echo "🌐 Network Connectivity Tests
";
+ testCommand("Curl Version", "curl --version");
+ testCommand("Test DNS Resolution", "nslookup get.openziti.io", false);
+ testCommand("Test Ping to OpenZiti", "ping -c 1 get.openziti.io", false);
+ testCommand("Test HTTPS Connection", "curl -I https://get.openziti.io", false);
+ testCommand("Test GPG Key URL", "curl -sSLf https://get.openziti.io/tun/package-repos.gpg -o /dev/null");
+
+ /**
+ * Test GPG functionality
+ */
+ echo "🔑 GPG Functionality Tests
";
+ testCommand("GPG Version", "gpg --version");
+ testCommand("Which GPG", "which gpg");
+ testCommand("GPG List Keys", "gpg --list-keys", false);
+ testCommand("Test GPG Dearmor", "echo 'test' | gpg --dearmor", false);
+
+ /**
+ * Test file system permissions
+ */
+ echo "📁 File System Permission Tests
";
+ testCommand("Test /tmp Write", "touch /tmp/test-write-" . uniqid() . " && echo 'Write test successful'");
+ testCommand("Test /usr/share Access", "ls -la /usr/share/", false);
+ testCommand("Test /usr/share/keyrings Directory", "ls -la /usr/share/keyrings/", false);
+ testCommand("Test Create Keyrings Directory", "sudo mkdir -p /usr/share/keyrings && echo 'Directory creation successful'");
+ testCommand("Test Write to Keyrings", "sudo touch /usr/share/keyrings/test-" . uniqid() . " && echo 'Keyring write test successful'");
+
+ /**
+ * Test the specific failing GPG command step by step
+ */
+ echo "🎯 Specific GPG Key Installation Tests
";
+
+ $tempFile = '/tmp/openziti-gpg-test-' . uniqid();
+ $keyringFile = '/usr/share/keyrings/openziti-test.gpg';
+
+ testCommand("Step 1: Download GPG Key", "curl -sSLf https://get.openziti.io/tun/package-repos.gpg -o $tempFile");
+ testCommand("Step 2: Verify Downloaded File", "ls -la $tempFile && wc -c $tempFile");
+ testCommand("Step 3: Test GPG Dearmor on File", "sudo gpg --dearmor --output $keyringFile $tempFile");
+ testCommand("Step 4: Verify Output File", "ls -la $keyringFile", false);
+ testCommand("Step 5: Test Original Piped Command", "curl -sSLf https://get.openziti.io/tun/package-repos.gpg | sudo gpg --dearmor --output /usr/share/keyrings/openziti-test2.gpg");
+
+ // Clean up test files
+ testCommand("Cleanup: Remove Test Files", "sudo rm -f $tempFile $keyringFile /usr/share/keyrings/openziti-test2.gpg", false);
+
+ /**
+ * Test alternative execution methods
+ */
+ echo "🔄 Alternative Execution Method Tests
";
+
+ // Test direct proc_open
+ echo "";
+ echo "
Direct proc_open Test
";
+ $cmd = "curl -sSLf https://get.openziti.io/tun/package-repos.gpg | head -c 100";
+ $descriptorspec = [
+ 0 => ['pipe', 'r'],
+ 1 => ['pipe', 'w'],
+ 2 => ['pipe', 'w']
+ ];
+ $process = proc_open($cmd, $descriptorspec, $pipes);
+ if (is_resource($process)) {
+ fclose($pipes[0]);
+ $stdout = stream_get_contents($pipes[1]);
+ $stderr = stream_get_contents($pipes[2]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ $return_value = proc_close($process);
+
+ echo "
Command: $cmd
";
+ echo "
";
+ echo "Return Code: $return_value
";
+ echo "
";
+ echo "
STDOUT: " . substr($stdout, 0, 200) . "\nSTDERR: $stderr
";
+ }
+ echo "
";
+
+ /**
+ * Summary and recommendations
+ */
+ echo "";
+ echo "
📊 Diagnostic Summary
";
+
+ $totalTests = count($results);
+ $successfulTests = count(array_filter($results, function($r) { return $r['success']; }));
+ $failedTests = $totalTests - $successfulTests;
+
+ echo "
Total Tests: $totalTests
";
+ echo "
Successful: $successfulTests
";
+ echo "
Failed: $failedTests
";
+
+ if (!empty($issues)) {
+ echo "
🚨 Issues Identified:
";
+ echo "
";
+ foreach ($issues as $issue) {
+ echo "- $issue
";
+ }
+ echo "
";
+ }
+
+ // Generate recommendations based on results
+ $phpSapi = php_sapi_name();
+ $currentUser = get_current_user();
+ $processUid = function_exists('posix_getuid') ? posix_getuid() : null;
+
+ echo "
💡 Recommendations:
";
+ echo "
";
+
+ if ($phpSapi === 'fpm-fcgi') {
+ echo "- PHP-FPM Detected: You're running PHP-FPM which has restricted execution permissions. Consider running the enrollment script via CLI instead.
";
+ }
+
+ if ($processUid !== 0 && $currentUser !== 'root') {
+ echo "- Non-Root Execution: PHP is running as user '$currentUser' (UID: $processUid). Ensure sudo permissions are properly configured for this user.
";
+ }
+
+ $sudoTest = array_filter($results, function($r) { return strpos($r['command'], 'sudo -n whoami') !== false; });
+ if (!empty($sudoTest) && !reset($sudoTest)['success']) {
+ echo "- Sudo Configuration: Non-interactive sudo failed. Configure passwordless sudo for the web server user or run enrollment via CLI.
";
+ }
+
+ $curlTest = array_filter($results, function($r) { return strpos($r['command'], 'curl') !== false && strpos($r['command'], 'openziti') !== false; });
+ if (!empty($curlTest) && !reset($curlTest)['success']) {
+ echo "- Network Issues: Cannot reach OpenZiti servers. Check firewall, proxy settings, or DNS resolution.
";
+ }
+
+ $gpgTest = array_filter($results, function($r) { return strpos($r['command'], 'gpg --version') !== false; });
+ if (!empty($gpgTest) && !reset($gpgTest)['success']) {
+ echo "- GPG Missing: GPG is not installed or not accessible. Install gnupg package.
";
+ }
+
+ echo "- Alternative Solution: Consider running the enrollment script directly via SSH as root user instead of through the web interface.
";
+ echo "- Web Server Configuration: If you must use the web interface, configure your web server to run with appropriate permissions or use a different execution method.
";
+ echo "
";
+
+ echo "
";
+
+ // Export results to log file
+ $logData = [
+ 'timestamp' => date('c'),
+ 'php_sapi' => $phpSapi,
+ 'current_user' => $currentUser,
+ 'process_uid' => $processUid,
+ 'total_tests' => $totalTests,
+ 'successful_tests' => $successfulTests,
+ 'failed_tests' => $failedTests,
+ 'issues' => $issues,
+ 'detailed_results' => $results
+ ];
+
+ $logFile = UI_LOG_DIR . '/command-execution-diagnostics-' . date('Y-m-d-H-i-s') . '.json';
+ if (!is_dir(UI_LOG_DIR)) {
+ mkdir(UI_LOG_DIR, 0755, true);
+ }
+ file_put_contents($logFile, json_encode($logData, JSON_PRETTY_PRINT));
+
+ echo "";
+ echo "
📄 Detailed Results Saved
";
+ echo "
Complete diagnostic results saved to: $logFile
";
+ echo "
Download Log File";
+ echo "
";
+
+ ?>
+
+
+
+
+
+
+