The current containerised graphical console approach has a Selenium script managing a Chrome browser session. This change replaces that with firefox and a custom extension to perform the required actions to login and load the BMC console. This supports the same vendors as the previous approach (iDRAC, iLO, Supermicro). This change is required by Red Hat as Chrome is not packaged in RHEL. However switching to firefox has allowed a more robust and featureful implementation so it is presented here on its own merits. This is implemented with bash, calling out to dedicated python scripts for these specific tasks: - Detecting which vendor specific javascript to use for the redfish-graphical driver - Building the required certificate fingerprint when app_info.verify_ca is false, which is written to the profile's cert_override.txt - Building a custom policy.json which is specific to the BMC and vendor implementation. Functional differences with the chrome/selenium version - Firefox kiosk mode has a more locked-down environment, including disabling context menus. This means the brittle workaround to disable them is no longer required. - Firefox global policy allows the environment to be locked down further, including limiting accessing to all URLs except the BMC. - There is now a dedicated loading page which can show status updates until the first BMC page loads. This page shows error messages if any of the early redfish calls fail. - VNC client sessions are now shared with multiple clients, and firefox will be started on the first connection, and stopped when the last connection ends. - Starting Xvfb is now deferred until the first VNC client connection. This results in a never-connected container using 5MB vs 30MB once Xvfb is started. Starting Xvfb has ~1sec time penality on first connection. - The browser now runs in a dedicated non-root user - All redfish consoles now hide toolbar elements with a CSS overlay rather than simulating other methods such as clicking the "Full Screen" button. - ilo6/ilo5 detection is now done by a redfish call and the ilo5 path has less moving parts. Change-Id: Ib42704a016dc891833a0ddbeae8054cac2c57d4d Signed-off-by: Steve Baker <sbaker@redhat.com> Assisted-By: gemini
156 lines
3.7 KiB
HTML
156 lines
3.7 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Starting Console</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
background-color: #000000;
|
|
font-family: 'Arial', sans-serif;
|
|
height: 100vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.loading-container {
|
|
text-align: center;
|
|
color: white;
|
|
}
|
|
|
|
/* Spinning Circle Loader */
|
|
.spinner {
|
|
width: 80px;
|
|
height: 80px;
|
|
border: 8px solid rgba(255, 255, 255, 0.1);
|
|
border-left: 8px solid #00ff88;
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
margin: 0 auto 30px;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
|
|
100% {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
/* Loading Text */
|
|
.loading-text {
|
|
font-size: 24px;
|
|
font-weight: 300;
|
|
letter-spacing: 2px;
|
|
margin-bottom: 20px;
|
|
opacity: 0;
|
|
animation: fadeInOut 2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes fadeInOut {
|
|
|
|
0%,
|
|
100% {
|
|
opacity: 0;
|
|
}
|
|
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes gradientShift {
|
|
|
|
0%,
|
|
100% {
|
|
background-position: 0% 50%;
|
|
}
|
|
|
|
50% {
|
|
background-position: 100% 50%;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.spinner {
|
|
width: 60px;
|
|
height: 60px;
|
|
border-width: 6px;
|
|
}
|
|
|
|
.loading-text {
|
|
font-size: 20px;
|
|
}
|
|
|
|
}
|
|
|
|
#error-messages {
|
|
margin-top: 20px;
|
|
font-size: 16px;
|
|
color: #ff0000;
|
|
text-align: center;
|
|
max-width: 50%;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
#status-messages {
|
|
margin-top: 20px;
|
|
font-size: 16px;
|
|
color: #aaa;
|
|
}
|
|
</style>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const urlParams = new URLSearchParams(window.location.search);
|
|
const errorMessage = urlParams.get('error');
|
|
const statusMessage = urlParams.get('status');
|
|
statusText = document.getElementById("status-messages")
|
|
if (statusMessage){
|
|
statusText.textContent = statusMessage;
|
|
}
|
|
if (errorMessage) {
|
|
document.querySelector('.spinner').style.animation = 'none';
|
|
loadingText = document.querySelector('.loading-text')
|
|
loadingText.style.animation = 'none';
|
|
loadingText.style.opacity = 1;
|
|
loadingText.textContent = "ERROR LOADING CONSOLE"
|
|
statusText.textContent = "";
|
|
document.getElementById('error-messages').textContent = decodeURIComponent(errorMessage);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<div class="loading-container">
|
|
|
|
<!-- Main Spinner -->
|
|
<div class="spinner"></div>
|
|
|
|
<!-- Loading Text -->
|
|
<div class="loading-text">STARTING CONSOLE</div>
|
|
|
|
<div id="status-messages"></div>
|
|
|
|
<div id="error-messages"></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html> |