|
<!DOCTYPE html> |
|
<html lang="en" style="height: 100%;"> |
|
<head> |
|
<meta charset="utf-8" /> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Real Web VM Terminal</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet"> |
|
<style> |
|
body { |
|
font-family: 'Inter', sans-serif; |
|
background-color: #1a202c; |
|
color: #e2e8f0; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
min-height: 100vh; |
|
padding: 1rem; |
|
overflow: hidden; |
|
margin: 0; |
|
} |
|
.container { |
|
background-color: #2d3748; |
|
padding: 1.5rem; |
|
border-radius: 1rem; |
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); |
|
max-width: 90%; |
|
width: 800px; |
|
height: 600px; |
|
display: flex; |
|
flex-direction: column; |
|
overflow: hidden; |
|
} |
|
h1 { |
|
color: #63b3ed; |
|
margin-bottom: 1rem; |
|
font-size: 1.75rem; |
|
font-weight: 700; |
|
text-align: center; |
|
} |
|
#console-container { |
|
flex-grow: 1; |
|
background-color: #000; |
|
border-radius: 0.5rem; |
|
overflow: hidden; |
|
border: 1px solid #4a5568; |
|
color: #68d391; |
|
white-space: pre-wrap; |
|
font-family: 'monospace', 'Courier New', Courier, monospace; |
|
padding: 10px; |
|
text-align: left; |
|
outline: none; |
|
} |
|
#loading-message { |
|
text-align: center; |
|
color: #ecc94b; |
|
margin-top: 1rem; |
|
font-size: 1.1rem; |
|
margin-bottom: 1rem; |
|
} |
|
#error-message { |
|
text-align: center; |
|
color: #f56565; |
|
margin-top: 1rem; |
|
font-size: 1.1rem; |
|
font-weight: 600; |
|
display: none; |
|
} |
|
</style> |
|
|
|
|
|
<script src="https://cxrtnc.leaningtech.com/1.1.5/cx.js"></script> |
|
</head> |
|
<body style="height: 100%;"> |
|
<div class="container"> |
|
<h1>Real Web VM Terminal</h1> |
|
<div id="loading-message">Loading Web VM... This may take a moment.</div> |
|
<div id="error-message"></div> |
|
|
|
<pre id="console-container" tabindex="0"></pre> |
|
</div> |
|
|
|
<script type="module"> |
|
|
|
import * as CheerpX from "https://cxrtnc.leaningtech.com/1.1.5/cx.esm.js"; |
|
|
|
self.CheerpX = CheerpX; |
|
|
|
const consoleContainer = document.getElementById('console-container'); |
|
const loadingMessage = document.getElementById('loading-message'); |
|
const errorMessage = document.getElementById('error-message'); |
|
|
|
async function initializeWebVM() { |
|
try { |
|
|
|
|
|
|
|
|
|
if (typeof SharedArrayBuffer === 'undefined') { |
|
loadingMessage.style.display = 'none'; |
|
errorMessage.textContent = 'Error: SharedArrayBuffer is not available. This typically means your page is not served with the required Cross-Origin-Embedder-Policy (COEP) and Cross-Origin-Opener-Policy (COOP) headers, or it is not served over HTTPS. Please serve this file using a local web server (e.g., `python -m http.server`) and access it via `http://localhost:...` or `https://...`.'; |
|
errorMessage.style.display = 'block'; |
|
console.error('SharedArrayBuffer not available. Missing COEP/COOP headers or not HTTPS.'); |
|
return; |
|
} |
|
|
|
|
|
|
|
const cloudDevice = await CheerpX.CloudDevice.create( |
|
"wss://disks.webvm.io/debian_mini_20230519_5022088024.ext2" |
|
); |
|
|
|
|
|
|
|
const idbDevice = await CheerpX.IDBDevice.create("webvm-disk-storage"); |
|
|
|
|
|
const overlayDevice = await CheerpX.OverlayDevice.create( |
|
cloudDevice, |
|
idbDevice |
|
); |
|
|
|
|
|
const cx = await CheerpX.Linux.create({ |
|
mounts: [ |
|
{ type: "ext2", path: "/", dev: overlayDevice }, |
|
{ type: "devs", path: "/dev" }, |
|
], |
|
}); |
|
|
|
|
|
cx.setConsole(consoleContainer); |
|
|
|
|
|
loadingMessage.style.display = 'none'; |
|
errorMessage.style.display = 'none'; |
|
|
|
|
|
consoleContainer.focus(); |
|
|
|
|
|
|
|
await cx.run("/bin/bash", ["--login"], { |
|
env: [ |
|
"HOME=/root", |
|
"USER=root", |
|
"SHELL=/bin/bash", |
|
"TERM=xterm-256color", |
|
"EDITOR=vi", |
|
"LANG=en_US.UTF-8", |
|
"LC_ALL=C", |
|
], |
|
cwd: "/root", |
|
uid: 0, |
|
gid: 0, |
|
}); |
|
|
|
} catch (error) { |
|
console.error("Failed to initialize Web VM:", error); |
|
loadingMessage.style.display = 'none'; |
|
errorMessage.textContent = `Error loading Web VM: ${error.message}. Please check your browser console for more details. Ensure your internet connection is stable as disk images are streamed.`; |
|
errorMessage.style.display = 'block'; |
|
errorMessage.style.color = '#f56565'; |
|
} |
|
} |
|
|
|
|
|
window.onload = initializeWebVM; |
|
</script> |
|
</body> |
|
</html> |
|
|