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 ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo "
PropertyValue
PHP Version" . PHP_VERSION . "
PHP SAPI" . php_sapi_name() . "
Operating System" . PHP_OS . "
Current User (PHP)" . get_current_user() . "
Process UID" . (function_exists('posix_getuid') ? posix_getuid() : 'N/A') . "
Process GID" . (function_exists('posix_getgid') ? posix_getgid() : 'N/A') . "
Process PID" . getmypid() . "
Memory Limit" . ini_get('memory_limit') . "
Max Execution Time" . ini_get('max_execution_time') . "s
Disable Functions" . (ini_get('disable_functions') ?: 'None') . "
"; + echo "
"; + + /** + * Test environment variables + */ + echo "
"; + echo "

🌍 Environment Variables

"; + $envVars = ['PATH', 'HOME', 'USER', 'SHELL', 'TERM', 'PWD', 'SUDO_USER', 'SUDO_UID', 'SUDO_GID']; + echo ""; + echo ""; + foreach ($envVars as $var) { + $value = getenv($var) ?: $_SERVER[$var] ?? 'Not Set'; + echo ""; + } + echo "
VariableValue
$var$value
"; + 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 ""; + } + + // Generate recommendations based on results + $phpSapi = php_sapi_name(); + $currentUser = get_current_user(); + $processUid = function_exists('posix_getuid') ? posix_getuid() : null; + + echo "

💡 Recommendations:

"; + 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 "
"; + + ?> + +
+ ← Back to Dashboard + 🔄 Run Diagnostics Again +
+ + + + +