Update lxc-terminal-modal.tsx

This commit is contained in:
MacRimi
2026-02-01 00:42:51 +01:00
parent 58a4e475ad
commit 08f435597a

View File

@@ -54,9 +54,11 @@ export function LxcTerminalModal({
const [connectionStatus, setConnectionStatus] = useState<"connecting" | "online" | "offline">("connecting") const [connectionStatus, setConnectionStatus] = useState<"connecting" | "online" | "offline">("connecting")
const [isMobile, setIsMobile] = useState(false) const [isMobile, setIsMobile] = useState(false)
const [isTablet, setIsTablet] = useState(false) const [isTablet, setIsTablet] = useState(false)
const isInsideLxcRef = useRef(false)
// Track host prompt to detect when user exits LXC
const hostPromptRef = useRef<string>("")
const insideLxcRef = useRef(false)
const outputBufferRef = useRef<string>("") const outputBufferRef = useRef<string>("")
const hostPromptPatternRef = useRef<string>("")
const [modalHeight, setModalHeight] = useState(500) const [modalHeight, setModalHeight] = useState(500)
const [isResizing, setIsResizing] = useState(false) const [isResizing, setIsResizing] = useState(false)
@@ -91,9 +93,9 @@ export function LxcTerminalModal({
termRef.current = null termRef.current = null
} }
setConnectionStatus("connecting") setConnectionStatus("connecting")
isInsideLxcRef.current = false hostPromptRef.current = ""
insideLxcRef.current = false
outputBufferRef.current = "" outputBufferRef.current = ""
hostPromptPatternRef.current = ""
} }
}, [isOpen]) }, [isOpen])
@@ -225,51 +227,53 @@ export function LxcTerminalModal({
return return
} }
// Buffer output until we detect we're inside the LXC const data = event.data
// pct enter always enters directly without login prompt when run as root
if (!isInsideLxcRef.current) { // Buffer output until we're inside the LXC
outputBufferRef.current += event.data if (!insideLxcRef.current) {
const buffer = outputBufferRef.current outputBufferRef.current += data
// First, capture the host prompt pattern (before pct enter) // Capture host prompt (pattern like "root@hostname" or "[user@hostname")
// This will be something like "[root@hostname" or "user@hostname" if (!hostPromptRef.current) {
if (!hostPromptPatternRef.current) { const hostMatch = outputBufferRef.current.match(/\[?(\w+@[\w-]+)/)
const hostPromptMatch = buffer.match(/\[?(\w+@[\w-]+)/) if (hostMatch) {
if (hostPromptMatch) { hostPromptRef.current = hostMatch[1]
hostPromptPatternRef.current = hostPromptMatch[1]
} }
} }
// Look for pct enter command completion // Detect when we're inside the LXC
const pctEnterMatch = buffer.match(/pct enter \d+\r?\n/) // Look for a prompt that is different from the host prompt after pct enter
if (pctEnterMatch && hostPromptPatternRef.current) { if (hostPromptRef.current && outputBufferRef.current.includes(`pct enter ${vmid}`)) {
const afterPctEnter = buffer.substring(buffer.indexOf(pctEnterMatch[0]) + pctEnterMatch[0].length) const hostName = hostPromptRef.current.split('@')[1]
// Look for a new prompt line that doesn't contain the host name
// Find the LXC prompt - a prompt that does NOT match the host prompt const lines = outputBufferRef.current.split('\n')
// Extract hostname from host prompt (e.g., "root@constructor" -> "constructor") for (let i = lines.length - 1; i >= 0; i--) {
const hostName = hostPromptPatternRef.current.split('@')[1] const line = lines[i]
// Check if this line has a prompt (@) but NOT the host name
// Create regex that matches prompts NOT containing the host name if (line.includes('@') && !line.includes(hostName) && (line.includes('#') || line.includes('$'))) {
const lxcPromptRegex = new RegExp(`\\r?\\n?([^\\r\\n]*@(?!${hostName})[^\\r\\n]*[#$]\\s*)$`) // Found LXC prompt - we're inside
const lxcPromptMatch = afterPctEnter.match(lxcPromptRegex) insideLxcRef.current = true
// Only show from this prompt onwards
if (lxcPromptMatch) { term.write(line)
// Successfully inside LXC - only show from the LXC prompt onwards break
isInsideLxcRef.current = true }
term.write(lxcPromptMatch[1])
return
} }
} }
} else { return
// Already inside LXC, write directly
term.write(event.data)
// Detect if user exited the LXC (returned to host prompt)
if (hostPromptPatternRef.current && event.data.includes(hostPromptPatternRef.current)) {
// User exited the LXC, close the modal
onClose()
}
} }
// Already inside LXC - write directly
// But check if user exited (host prompt appears again)
if (hostPromptRef.current && data.includes(hostPromptRef.current)) {
// User exited LXC, close modal after short delay
term.write(data)
setTimeout(() => {
onClose()
}, 500)
return
}
term.write(data)
} }
} }