fixed script new2
This commit is contained in:
parent
360249f22e
commit
8e225fdedd
|
|
@ -0,0 +1,357 @@
|
|||
<?php
|
||||
/**
|
||||
* Command Execution Diagnostic Script
|
||||
* Tests various aspects of command execution, permissions, and environment
|
||||
* to identify issues with GPG key installation on CloudStack instances
|
||||
*/
|
||||
|
||||
// Include config for logging functions
|
||||
require_once 'includes/config.php';
|
||||
|
||||
// Start output buffering for clean HTML output
|
||||
ob_start();
|
||||
|
||||
// Set content type
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Command Execution Diagnostics</title>
|
||||
<style>
|
||||
body { font-family: monospace; margin: 20px; background: #f5f5f5; }
|
||||
.container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
||||
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
|
||||
.test-section h3 { margin-top: 0; color: #333; border-bottom: 2px solid #007bff; padding-bottom: 5px; }
|
||||
.success { background-color: #d4edda; border-color: #c3e6cb; color: #155724; }
|
||||
.warning { background-color: #fff3cd; border-color: #ffeaa7; color: #856404; }
|
||||
.error { background-color: #f8d7da; border-color: #f5c6cb; color: #721c24; }
|
||||
.info { background-color: #d1ecf1; border-color: #bee5eb; color: #0c5460; }
|
||||
.command { background: #f8f9fa; padding: 10px; border-left: 4px solid #007bff; margin: 10px 0; font-family: 'Courier New', monospace; }
|
||||
.output { background: #2d3748; color: #e2e8f0; padding: 10px; border-radius: 4px; margin: 10px 0; white-space: pre-wrap; font-family: 'Courier New', monospace; }
|
||||
.summary { background: #e3f2fd; padding: 15px; border-radius: 5px; margin: 20px 0; }
|
||||
table { width: 100%; border-collapse: collapse; margin: 10px 0; }
|
||||
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
|
||||
th { background-color: #f2f2f2; }
|
||||
.btn { display: inline-block; padding: 10px 20px; background: #007bff; color: white; text-decoration: none; border-radius: 4px; margin: 5px; }
|
||||
.btn:hover { background: #0056b3; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔍 Command Execution Diagnostics</h1>
|
||||
<p><strong>Purpose:</strong> Diagnose why GPG key installation fails on CloudStack instance</p>
|
||||
<p><strong>Time:</strong> <?php echo date('Y-m-d H:i:s T'); ?></p>
|
||||
|
||||
<?php
|
||||
|
||||
// Initialize results array
|
||||
$results = [];
|
||||
$issues = [];
|
||||
$recommendations = [];
|
||||
|
||||
/**
|
||||
* Helper function to execute command and capture detailed output
|
||||
*/
|
||||
function testCommand($description, $command, $expectSuccess = true) {
|
||||
global $results, $issues;
|
||||
|
||||
echo "<div class='test-section'>";
|
||||
echo "<h3>$description</h3>";
|
||||
echo "<div class='command'>Command: $command</div>";
|
||||
|
||||
$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 "<div class='$statusClass'>";
|
||||
echo "<strong>Status:</strong> " . ($success ? "✅ SUCCESS" : "❌ FAILED") . "<br>";
|
||||
echo "<strong>Return Code:</strong> $returnCode<br>";
|
||||
echo "<strong>Duration:</strong> {$duration}ms<br>";
|
||||
echo "</div>";
|
||||
|
||||
if ($output) {
|
||||
echo "<div class='output'>$output</div>";
|
||||
}
|
||||
|
||||
// Track issues
|
||||
if ($expectSuccess && !$success) {
|
||||
$issues[] = "$description failed: $output";
|
||||
}
|
||||
|
||||
echo "</div>";
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test PHP environment information
|
||||
*/
|
||||
echo "<div class='test-section info'>";
|
||||
echo "<h3>📋 PHP Environment Information</h3>";
|
||||
echo "<table>";
|
||||
echo "<tr><th>Property</th><th>Value</th></tr>";
|
||||
echo "<tr><td>PHP Version</td><td>" . PHP_VERSION . "</td></tr>";
|
||||
echo "<tr><td>PHP SAPI</td><td>" . php_sapi_name() . "</td></tr>";
|
||||
echo "<tr><td>Operating System</td><td>" . PHP_OS . "</td></tr>";
|
||||
echo "<tr><td>Current User (PHP)</td><td>" . get_current_user() . "</td></tr>";
|
||||
echo "<tr><td>Process UID</td><td>" . (function_exists('posix_getuid') ? posix_getuid() : 'N/A') . "</td></tr>";
|
||||
echo "<tr><td>Process GID</td><td>" . (function_exists('posix_getgid') ? posix_getgid() : 'N/A') . "</td></tr>";
|
||||
echo "<tr><td>Process PID</td><td>" . getmypid() . "</td></tr>";
|
||||
echo "<tr><td>Memory Limit</td><td>" . ini_get('memory_limit') . "</td></tr>";
|
||||
echo "<tr><td>Max Execution Time</td><td>" . ini_get('max_execution_time') . "s</td></tr>";
|
||||
echo "<tr><td>Disable Functions</td><td>" . (ini_get('disable_functions') ?: 'None') . "</td></tr>";
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
/**
|
||||
* Test environment variables
|
||||
*/
|
||||
echo "<div class='test-section info'>";
|
||||
echo "<h3>🌍 Environment Variables</h3>";
|
||||
$envVars = ['PATH', 'HOME', 'USER', 'SHELL', 'TERM', 'PWD', 'SUDO_USER', 'SUDO_UID', 'SUDO_GID'];
|
||||
echo "<table>";
|
||||
echo "<tr><th>Variable</th><th>Value</th></tr>";
|
||||
foreach ($envVars as $var) {
|
||||
$value = getenv($var) ?: $_SERVER[$var] ?? 'Not Set';
|
||||
echo "<tr><td>$var</td><td>$value</td></tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
/**
|
||||
* Test basic command execution
|
||||
*/
|
||||
echo "<h2>🔧 Basic Command Tests</h2>";
|
||||
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 "<h2>🔐 Sudo Access Tests</h2>";
|
||||
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 "<h2>🌐 Network Connectivity Tests</h2>";
|
||||
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 "<h2>🔑 GPG Functionality Tests</h2>";
|
||||
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 "<h2>📁 File System Permission Tests</h2>";
|
||||
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 "<h2>🎯 Specific GPG Key Installation Tests</h2>";
|
||||
|
||||
$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 "<h2>🔄 Alternative Execution Method Tests</h2>";
|
||||
|
||||
// Test direct proc_open
|
||||
echo "<div class='test-section'>";
|
||||
echo "<h3>Direct proc_open Test</h3>";
|
||||
$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 "<div class='command'>Command: $cmd</div>";
|
||||
echo "<div class='" . ($return_value === 0 ? 'success' : 'error') . "'>";
|
||||
echo "<strong>Return Code:</strong> $return_value<br>";
|
||||
echo "</div>";
|
||||
echo "<div class='output'>STDOUT: " . substr($stdout, 0, 200) . "\nSTDERR: $stderr</div>";
|
||||
}
|
||||
echo "</div>";
|
||||
|
||||
/**
|
||||
* Summary and recommendations
|
||||
*/
|
||||
echo "<div class='summary'>";
|
||||
echo "<h2>📊 Diagnostic Summary</h2>";
|
||||
|
||||
$totalTests = count($results);
|
||||
$successfulTests = count(array_filter($results, function($r) { return $r['success']; }));
|
||||
$failedTests = $totalTests - $successfulTests;
|
||||
|
||||
echo "<p><strong>Total Tests:</strong> $totalTests</p>";
|
||||
echo "<p><strong>Successful:</strong> $successfulTests</p>";
|
||||
echo "<p><strong>Failed:</strong> $failedTests</p>";
|
||||
|
||||
if (!empty($issues)) {
|
||||
echo "<h3>🚨 Issues Identified:</h3>";
|
||||
echo "<ul>";
|
||||
foreach ($issues as $issue) {
|
||||
echo "<li>$issue</li>";
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
|
||||
// Generate recommendations based on results
|
||||
$phpSapi = php_sapi_name();
|
||||
$currentUser = get_current_user();
|
||||
$processUid = function_exists('posix_getuid') ? posix_getuid() : null;
|
||||
|
||||
echo "<h3>💡 Recommendations:</h3>";
|
||||
echo "<ul>";
|
||||
|
||||
if ($phpSapi === 'fpm-fcgi') {
|
||||
echo "<li><strong>PHP-FPM Detected:</strong> You're running PHP-FPM which has restricted execution permissions. Consider running the enrollment script via CLI instead.</li>";
|
||||
}
|
||||
|
||||
if ($processUid !== 0 && $currentUser !== 'root') {
|
||||
echo "<li><strong>Non-Root Execution:</strong> PHP is running as user '$currentUser' (UID: $processUid). Ensure sudo permissions are properly configured for this user.</li>";
|
||||
}
|
||||
|
||||
$sudoTest = array_filter($results, function($r) { return strpos($r['command'], 'sudo -n whoami') !== false; });
|
||||
if (!empty($sudoTest) && !reset($sudoTest)['success']) {
|
||||
echo "<li><strong>Sudo Configuration:</strong> Non-interactive sudo failed. Configure passwordless sudo for the web server user or run enrollment via CLI.</li>";
|
||||
}
|
||||
|
||||
$curlTest = array_filter($results, function($r) { return strpos($r['command'], 'curl') !== false && strpos($r['command'], 'openziti') !== false; });
|
||||
if (!empty($curlTest) && !reset($curlTest)['success']) {
|
||||
echo "<li><strong>Network Issues:</strong> Cannot reach OpenZiti servers. Check firewall, proxy settings, or DNS resolution.</li>";
|
||||
}
|
||||
|
||||
$gpgTest = array_filter($results, function($r) { return strpos($r['command'], 'gpg --version') !== false; });
|
||||
if (!empty($gpgTest) && !reset($gpgTest)['success']) {
|
||||
echo "<li><strong>GPG Missing:</strong> GPG is not installed or not accessible. Install gnupg package.</li>";
|
||||
}
|
||||
|
||||
echo "<li><strong>Alternative Solution:</strong> Consider running the enrollment script directly via SSH as root user instead of through the web interface.</li>";
|
||||
echo "<li><strong>Web Server Configuration:</strong> If you must use the web interface, configure your web server to run with appropriate permissions or use a different execution method.</li>";
|
||||
echo "</ul>";
|
||||
|
||||
echo "</div>";
|
||||
|
||||
// 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 "<div class='info'>";
|
||||
echo "<h3>📄 Detailed Results Saved</h3>";
|
||||
echo "<p>Complete diagnostic results saved to: <code>$logFile</code></p>";
|
||||
echo "<a href='?download_log=" . basename($logFile) . "' class='btn'>Download Log File</a>";
|
||||
echo "</div>";
|
||||
|
||||
?>
|
||||
|
||||
<div style="margin-top: 30px; text-align: center;">
|
||||
<a href="dashboard.php" class="btn">← Back to Dashboard</a>
|
||||
<a href="?refresh=1" class="btn">🔄 Run Diagnostics Again</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
|
||||
// Handle log file download
|
||||
if (isset($_GET['download_log'])) {
|
||||
$logFileName = basename($_GET['download_log']);
|
||||
$logFilePath = UI_LOG_DIR . '/' . $logFileName;
|
||||
|
||||
if (file_exists($logFilePath) && strpos($logFileName, 'command-execution-diagnostics-') === 0) {
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Disposition: attachment; filename="' . $logFileName . '"');
|
||||
header('Content-Length: ' . filesize($logFilePath));
|
||||
readfile($logFilePath);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush output
|
||||
ob_end_flush();
|
||||
?>
|
||||
Loading…
Reference in New Issue