🔍 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 "
";
?>