From 4c0ce70364037effc4d37529c41b6f0126100a24 Mon Sep 17 00:00:00 2001 From: Onelevenvy Date: Thu, 2 Jul 2026 13:47:58 +0800 Subject: [PATCH 01/12] chore: update default E2B template ID and translate builder logs/error messages to English --- .../flock-tools/src/sandbox_core/e2b/builder.rs | 16 ++++------------ .../src/sandbox_core/e2b/lifecycle.rs | 2 +- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/crates/flock-tools/src/sandbox_core/e2b/builder.rs b/crates/flock-tools/src/sandbox_core/e2b/builder.rs index 9f66a2aa..4e4605dc 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/builder.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/builder.rs @@ -71,7 +71,7 @@ USER user std::fs::write(&dockerfile_path, dockerfile_content) .context("Failed to write Dockerfile")?; - on_log("环境准备完毕,开始调用 E2B CLI 构建镜像 (E2B 2.0 在云端构建,不需要本地安装 Docker)...\n".to_string()); + on_log("Environment setup complete. Invoking E2B CLI to build the image (E2B 2.0 builds in the cloud; no local Docker installation is required)...\n".to_string()); // 3. 执行 npx @e2b/cli template create // 在 Windows 下需要调用 npx.cmd @@ -137,23 +137,15 @@ USER user anyhow::bail!("E2B template build failed with exit code: {}.\nError details:\n{}", status, full_output); } - on_log("构建成功!正在解析 Template ID...\n".to_string()); + on_log("Build succeeded! Parsing Template ID...\n".to_string()); // 解析出 template ID let re = regex::Regex::new(r"(?i)\b(?:id|template_id)[:\s]+([a-z0-9]{20})\b").unwrap(); if let Some(cap) = re.captures(&full_output) { let id = cap.get(1).unwrap().as_str().to_string(); + on_log(format!("Template ID successfully parsed: {}\n", id)); return Ok(id); } - // 回退解析:寻找任何非 "dockerfile" 的 20 位字母数字组合作为 ID - let re_fallback = regex::Regex::new(r"\b([a-z0-9]{20})\b").unwrap(); - for cap in re_fallback.captures_iter(&full_output) { - let matched = cap.get(1).unwrap().as_str(); - if matched != "dockerfile" && matched != "template" { - return Ok(matched.to_string()); - } - } - - anyhow::bail!("构建成功,但未能从 E2B CLI 输出日志中提取出生成的 template_id") + anyhow::bail!("Template build succeeded, but failed to extract the generated templateID from E2B CLI logs") } diff --git a/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs b/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs index 4a9ba854..2f0ed34b 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs @@ -46,7 +46,7 @@ pub async fn create_sandbox(cfg: &SandboxConfig) -> anyhow::Result { .unwrap_or("") .trim(); if template_id.is_empty() { - template_id = "jj17rl441iqdc6ea5mkb"; // 使用您发布的公共模版 ID 作为默认兜底 + template_id = "v4xxy6d1lhj8296ejotm"; // 使用您发布的公共模版 ID 作为默认兜底 } let client = reqwest::Client::new(); From 6bc81543c3faafd76d26311dc5a63aaa56f7de09 Mon Sep 17 00:00:00 2001 From: Onelevenvy Date: Thu, 2 Jul 2026 14:37:36 +0800 Subject: [PATCH 02/12] fix: add memory allocation flags to e2b template builder to avoid chromium oom crashes --- .../src/sandbox_core/e2b/builder.rs | 4 ++ .../flock-tools/src/sandbox_core/e2b/exec.rs | 9 +++- .../src/sandbox_core/e2b/lifecycle.rs | 2 +- .../src/tools/sandbox/browser/mod.rs | 6 +-- crates/flock-tools/tests/diagnose_e2b.rs | 54 +++++++++++-------- .../src-tauri/src/commands/common/sandbox.rs | 2 +- 6 files changed, 49 insertions(+), 28 deletions(-) diff --git a/crates/flock-tools/src/sandbox_core/e2b/builder.rs b/crates/flock-tools/src/sandbox_core/e2b/builder.rs index 4e4605dc..87d7d5c1 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/builder.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/builder.rs @@ -88,6 +88,10 @@ USER user .arg("/start_command.sh") .arg("--ready-cmd") .arg("python3 -c \"import socket; s = socket.socket(); s.connect(('127.0.0.1', 6080))\"") + .arg("--cpu-count") + .arg("2") + .arg("--memory-mb") + .arg("2048") .arg(name) .env("E2B_API_KEY", api_key) .current_dir(&builder_dir) diff --git a/crates/flock-tools/src/sandbox_core/e2b/exec.rs b/crates/flock-tools/src/sandbox_core/e2b/exec.rs index 4006e17f..f93ab28f 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/exec.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/exec.rs @@ -36,13 +36,18 @@ pub async fn execute_command( }; let body_str = serde_json::to_string(&payload)?; + let payload_bytes = body_str.as_bytes(); + let mut enveloped = Vec::with_capacity(5 + payload_bytes.len()); + enveloped.push(0x00); // flags + enveloped.extend_from_slice(&(payload_bytes.len() as u32).to_be_bytes()); // length + enveloped.extend_from_slice(payload_bytes); let resp = client.post(&url) .header("X-API-Key", api_key) .header("Connect-Protocol-Version", "1") .header("Content-Type", "application/connect+json") .header(reqwest::header::USER_AGENT, "flock-agent") - .body(body_str) + .body(enveloped) .send() .await?; @@ -121,7 +126,7 @@ pub async fn execute_command( /// 直接返回固定格式 URL,不检查端口,不拉起任何进程。 pub fn get_vnc_url(sandbox_id: &str) -> String { format!( - "https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&skip-preview-warning=true&skip_preview_warning=true", + "https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&skip-preview-warning=true&skip_preview_warning=true&path=", sandbox_id ) } diff --git a/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs b/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs index 2f0ed34b..f3fb03b4 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs @@ -46,7 +46,7 @@ pub async fn create_sandbox(cfg: &SandboxConfig) -> anyhow::Result { .unwrap_or("") .trim(); if template_id.is_empty() { - template_id = "v4xxy6d1lhj8296ejotm"; // 使用您发布的公共模版 ID 作为默认兜底 + template_id = "p6x9dn3ltcjj83nxhz6w"; // 使用您发布的公共模版 ID 作为默认兜底 } let client = reqwest::Client::new(); diff --git a/crates/flock-tools/src/tools/sandbox/browser/mod.rs b/crates/flock-tools/src/tools/sandbox/browser/mod.rs index 1fb588fa..aa75ad2a 100644 --- a/crates/flock-tools/src/tools/sandbox/browser/mod.rs +++ b/crates/flock-tools/src/tools/sandbox/browser/mod.rs @@ -152,11 +152,11 @@ async fn execute_regular_action( if ! python3 -c 'import socket; s = socket.socket(); s.connect((\"127.0.0.1\", 9222))' >/dev/null 2>&1; then \ echo 'Starting headful chromium with remote debugging on DISPLAY={display}...' && \ if command -v chromium >/dev/null 2>&1; then \ - setsid nohup chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ elif command -v chromium-browser >/dev/null 2>&1; then \ - setsid nohup chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ elif command -v google-chrome >/dev/null 2>&1; then \ - setsid nohup google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ fi && \ sleep 3; \ fi; \ diff --git a/crates/flock-tools/tests/diagnose_e2b.rs b/crates/flock-tools/tests/diagnose_e2b.rs index 4ed70287..14caa648 100644 --- a/crates/flock-tools/tests/diagnose_e2b.rs +++ b/crates/flock-tools/tests/diagnose_e2b.rs @@ -9,29 +9,41 @@ async fn test_diagnose_e2b() { .expect("No active sandbox config"); let api_key = cfg.e2b_api_key.as_ref().expect("E2B API key is missing"); - let base_url = cfg.e2b_api_url.as_deref().unwrap_or("https://api.e2b.app").trim_end_matches('/'); + println!("API Key found: {}", api_key); - let client = reqwest::Client::new(); - let url = format!("{}/sandboxes", base_url); - let resp = client.get(&url) - .header("X-API-Key", api_key) - .send() - .await - .expect("Failed to get E2B sandboxes"); + // Create a new sandbox for testing + println!("Creating a new E2B sandbox..."); + let sandbox_id = match flock_tools::sandbox_core::e2b::lifecycle::create_sandbox(&cfg).await { + Ok(id) => id, + Err(e) => { + println!("Failed to create sandbox: {:?}", e); + return; + } + }; + println!("Created sandbox ID: {}", sandbox_id); - let text = resp.text().await.unwrap_or_default(); - println!("Running E2B Sandboxes: {}", text); + // Wait a few seconds for VNC processes to fully initialize + println!("Waiting for processes to initialize..."); + tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; - let val: serde_json::Value = serde_json::from_str(&text).expect("Failed to parse JSON"); - if let Some(arr) = val.as_array() { - for sb in arr { - if let Some(sandbox_id) = sb.get("sandboxID").or_else(|| sb.get("sandbox_id")).and_then(|v| v.as_str()) { - println!("Diagnosing E2B Sandbox: {}", sandbox_id); - let diag_cmd = "echo '--- websockify.log ---'; cat /tmp/websockify.log; echo '--- x11vnc.log ---'; cat /tmp/x11vnc.log"; - if let Ok((stdout, _exit_code)) = flock_tools::sandbox_core::e2b::exec::execute_command(&cfg, sandbox_id, diag_cmd).await { - println!("Diagnostics output:\n{}", stdout); - } - } - } + // Check logs and processes using execute_command helper + println!("--- Process status ---"); + let check_ps = "ps aux | grep -E 'Xvfb|fluxbox|x11vnc|websockify'"; + match flock_tools::sandbox_core::e2b::exec::execute_command(&cfg, &sandbox_id, check_ps).await { + Ok((stdout, code)) => println!("Exit code: {}\nStdout:\n{}", code, stdout), + Err(e) => println!("Error running ps check: {:?}", e), } + + // Check logs + let diag_cmd = "echo '=== xvfb.log ==='; cat /tmp/xvfb.log; echo '=== fluxbox.log ==='; cat /tmp/x11vnc.log; echo '=== websockify.log ==='; cat /tmp/websockify.log"; + println!("--- Logs ---"); + match flock_tools::sandbox_core::e2b::exec::execute_command(&cfg, &sandbox_id, diag_cmd).await { + Ok((stdout, code)) => println!("Exit code: {}\nStdout:\n{}", code, stdout), + Err(e) => println!("Error running logs check: {:?}", e), + } + + // Destroy the sandbox + println!("Destroying sandbox {}...", sandbox_id); + let _ = flock_tools::sandbox_core::e2b::lifecycle::destroy_sandbox(&cfg, &sandbox_id).await; + println!("Done."); } diff --git a/flock-ui/src-tauri/src/commands/common/sandbox.rs b/flock-ui/src-tauri/src/commands/common/sandbox.rs index 50e20862..14dadc2a 100644 --- a/flock-ui/src-tauri/src/commands/common/sandbox.rs +++ b/flock-ui/src-tauri/src/commands/common/sandbox.rs @@ -43,7 +43,7 @@ pub async fn get_active_sandbox_vnc_url( let provider = flock_tools::sandbox_core::manager::get_provider(provider_name); provider.get_vnc_url(&*db, &cfg, &sandbox_id).await.unwrap_or_else(|_| { if provider_name == "e2b" { - format!("https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&skip-preview-warning=true&skip_preview_warning=true", sandbox_id) + format!("https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&skip-preview-warning=true&skip_preview_warning=true&path=", sandbox_id) } else { format!("https://6080-{}.proxy.app.daytona.io/vnc.html?autoconnect=true&resize=scale", sandbox_id) } From 88aa88214db5e621709a67d1639bf57d3217723f Mon Sep 17 00:00:00 2001 From: Onelevenvy Date: Thu, 2 Jul 2026 14:44:31 +0800 Subject: [PATCH 03/12] fix: restore unenveloped request payload format for E2B process start --- crates/flock-tools/src/sandbox_core/e2b/exec.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/flock-tools/src/sandbox_core/e2b/exec.rs b/crates/flock-tools/src/sandbox_core/e2b/exec.rs index f93ab28f..f7e9bbed 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/exec.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/exec.rs @@ -36,18 +36,13 @@ pub async fn execute_command( }; let body_str = serde_json::to_string(&payload)?; - let payload_bytes = body_str.as_bytes(); - let mut enveloped = Vec::with_capacity(5 + payload_bytes.len()); - enveloped.push(0x00); // flags - enveloped.extend_from_slice(&(payload_bytes.len() as u32).to_be_bytes()); // length - enveloped.extend_from_slice(payload_bytes); let resp = client.post(&url) .header("X-API-Key", api_key) .header("Connect-Protocol-Version", "1") .header("Content-Type", "application/connect+json") .header(reqwest::header::USER_AGENT, "flock-agent") - .body(enveloped) + .body(body_str) .send() .await?; From 43e4b38bb1166e1dbc32c948add2cf4bb8544e97 Mon Sep 17 00:00:00 2001 From: Onelevenvy Date: Thu, 2 Jul 2026 14:54:46 +0800 Subject: [PATCH 04/12] fix: pass DISPLAY env explicitly to fluxbox, x11vnc, and chrome in setsid/nohup to prevent display inheritance failure --- crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs | 3 +++ crates/flock-tools/src/sandbox_core/vnc_helper.rs | 4 ++-- crates/flock-tools/src/tools/sandbox/browser/mod.rs | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs b/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs index f3fb03b4..587488cd 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/lifecycle.rs @@ -5,6 +5,8 @@ use serde::{Deserialize, Serialize}; pub struct E2BCreateSandboxRequest { #[serde(rename = "templateID")] pub template_id: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub timeout: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -52,6 +54,7 @@ pub async fn create_sandbox(cfg: &SandboxConfig) -> anyhow::Result { let client = reqwest::Client::new(); let payload = E2BCreateSandboxRequest { template_id: template_id.to_string(), + timeout: Some(3600), // 1 hour sandbox lifetime }; crate::emit_info(&flock_core::tr( diff --git a/crates/flock-tools/src/sandbox_core/vnc_helper.rs b/crates/flock-tools/src/sandbox_core/vnc_helper.rs index 3625df7c..50e2f784 100644 --- a/crates/flock-tools/src/sandbox_core/vnc_helper.rs +++ b/crates/flock-tools/src/sandbox_core/vnc_helper.rs @@ -33,9 +33,9 @@ pub async fn ensure_vnc_running_in_sandbox(db: &DbManager, sandbox_id: &str) -> rm -f /tmp/.X0-lock && \ setsid nohup Xvfb {display} -screen 0 {res} >/tmp/xvfb.log 2>&1 & \ sleep 1 && \ - setsid nohup fluxbox >/tmp/fluxbox.log 2>&1 & \ + setsid nohup env DISPLAY={display} fluxbox >/tmp/fluxbox.log 2>&1 & \ sleep 1 && \ - setsid nohup x11vnc -display {display} -forever -shared -nopw -rfbport {vnc_port} >/tmp/x11vnc.log 2>&1 & \ + setsid nohup env DISPLAY={display} x11vnc -display {display} -forever -shared -nopw -rfbport {vnc_port} >/tmp/x11vnc.log 2>&1 & \ sleep 1 && \ setsid nohup websockify --web /usr/share/novnc 0.0.0.0:{web_port} localhost:{vnc_port} >/tmp/websockify.log 2>&1 & \ sleep 1; \ diff --git a/crates/flock-tools/src/tools/sandbox/browser/mod.rs b/crates/flock-tools/src/tools/sandbox/browser/mod.rs index aa75ad2a..23dcb698 100644 --- a/crates/flock-tools/src/tools/sandbox/browser/mod.rs +++ b/crates/flock-tools/src/tools/sandbox/browser/mod.rs @@ -152,11 +152,11 @@ async fn execute_regular_action( if ! python3 -c 'import socket; s = socket.socket(); s.connect((\"127.0.0.1\", 9222))' >/dev/null 2>&1; then \ echo 'Starting headful chromium with remote debugging on DISPLAY={display}...' && \ if command -v chromium >/dev/null 2>&1; then \ - setsid nohup chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup env DISPLAY={display} chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ elif command -v chromium-browser >/dev/null 2>&1; then \ - setsid nohup chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup env DISPLAY={display} chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ elif command -v google-chrome >/dev/null 2>&1; then \ - setsid nohup google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup env DISPLAY={display} google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ fi && \ sleep 3; \ fi; \ From ab1c319be016acb0403d3a10caa158c5f90950fc Mon Sep 17 00:00:00 2001 From: Onelevenvy Date: Fri, 3 Jul 2026 09:00:13 +0800 Subject: [PATCH 05/12] fix: remove --disable-software-rasterizer from chromium launch args to restore visual rendering in VNC --- .../flock-tools/src/sandbox_core/e2b/exec.rs | 2 +- .../src/sandbox_core/vnc_helper.rs | 21 ++++++++-- .../src/tools/sandbox/browser/interactive.rs | 6 +-- .../src/tools/sandbox/browser/mod.rs | 6 +-- .../src-tauri/src/commands/common/sandbox.rs | 2 +- .../EnvironmentPanel/components/VncView.tsx | 41 ++++++++++++------- .../EnvironmentPanel/hooks/usePreviewState.ts | 20 ++++++--- 7 files changed, 67 insertions(+), 31 deletions(-) diff --git a/crates/flock-tools/src/sandbox_core/e2b/exec.rs b/crates/flock-tools/src/sandbox_core/e2b/exec.rs index f7e9bbed..ad4eaa92 100644 --- a/crates/flock-tools/src/sandbox_core/e2b/exec.rs +++ b/crates/flock-tools/src/sandbox_core/e2b/exec.rs @@ -121,7 +121,7 @@ pub async fn execute_command( /// 直接返回固定格式 URL,不检查端口,不拉起任何进程。 pub fn get_vnc_url(sandbox_id: &str) -> String { format!( - "https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&skip-preview-warning=true&skip_preview_warning=true&path=", + "https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&path=websockify", sandbox_id ) } diff --git a/crates/flock-tools/src/sandbox_core/vnc_helper.rs b/crates/flock-tools/src/sandbox_core/vnc_helper.rs index 50e2f784..e33badd8 100644 --- a/crates/flock-tools/src/sandbox_core/vnc_helper.rs +++ b/crates/flock-tools/src/sandbox_core/vnc_helper.rs @@ -19,7 +19,22 @@ pub async fn ensure_vnc_running_in_sandbox(db: &DbManager, sandbox_id: &str) -> let check_cmd = format!("python3 -c \"import socket; s = socket.socket(); s.connect(('127.0.0.1', {}))\"", WEBSOCKIFY_PORT); let (_, exit_code) = execute_command_in_sandbox(db, sandbox_id, &check_cmd).await.unwrap_or(("-1".to_string(), -1)); if exit_code == 0 { - crate::emit_info(&flock_core::tr("检测到 VNC 桌面服务已经在运行。", "Detected VNC desktop service is already running.")); + // websockify 在跑,额外检查 fluxbox 是否存活(防止桌面黑屏) + let fluxbox_check = "pgrep -x fluxbox >/dev/null 2>&1 && echo ok || echo missing"; + let (fluxbox_out, _) = execute_command_in_sandbox(db, sandbox_id, fluxbox_check) + .await + .unwrap_or(("missing".to_string(), 1)); + if fluxbox_out.trim() == "ok" { + crate::emit_info(&flock_core::tr("检测到 VNC 桌面服务已经在运行。", "Detected VNC desktop service is already running.")); + return Ok(()); + } + // fluxbox 未运行,只补启 fluxbox + crate::emit_info(&flock_core::tr("VNC 端口在线但桌面管理器未运行,正在补启 fluxbox...", "VNC port active but window manager not running, restarting fluxbox...")); + let restart_fluxbox = format!( + "setsid nohup env DISPLAY={display} fluxbox >/tmp/fluxbox.log 2>&1 & sleep 2", + display = DISPLAY_ID + ); + let _ = execute_command_in_sandbox(db, sandbox_id, &restart_fluxbox).await; return Ok(()); } @@ -27,7 +42,7 @@ pub async fn ensure_vnc_running_in_sandbox(db: &DbManager, sandbox_id: &str) -> let launch_cmd = format!("sh -c '\ if command -v start-vnc >/dev/null 2>&1; then \ setsid nohup start-vnc >/tmp/vnc_start.log 2>&1 & \ - sleep 2; \ + sleep 3; \ else \ export DISPLAY={display} && \ rm -f /tmp/.X0-lock && \ @@ -38,7 +53,7 @@ pub async fn ensure_vnc_running_in_sandbox(db: &DbManager, sandbox_id: &str) -> setsid nohup env DISPLAY={display} x11vnc -display {display} -forever -shared -nopw -rfbport {vnc_port} >/tmp/x11vnc.log 2>&1 & \ sleep 1 && \ setsid nohup websockify --web /usr/share/novnc 0.0.0.0:{web_port} localhost:{vnc_port} >/tmp/websockify.log 2>&1 & \ - sleep 1; \ + sleep 2; \ fi'", display = DISPLAY_ID, res = SCREEN_RESOLUTION, diff --git a/crates/flock-tools/src/tools/sandbox/browser/interactive.rs b/crates/flock-tools/src/tools/sandbox/browser/interactive.rs index e0ed66e5..113590a5 100644 --- a/crates/flock-tools/src/tools/sandbox/browser/interactive.rs +++ b/crates/flock-tools/src/tools/sandbox/browser/interactive.rs @@ -58,11 +58,11 @@ pub async fn handle_interactive( if ! python3 -c 'import socket; s = socket.socket(); s.connect((\"127.0.0.1\", 9222))' >/dev/null 2>&1; then \ echo 'Starting chromium exposing 9222 debugger port on DISPLAY={display}...' && \ if command -v chromium >/dev/null 2>&1; then \ - setsid nohup chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer >/tmp/interactive_chrome.log 2>&1 & \ + setsid nohup chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-dev-shm-usage --window-size=1280,1024 >/tmp/interactive_chrome.log 2>&1 & \ elif command -v chromium-browser >/dev/null 2>&1; then \ - setsid nohup chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer >/tmp/interactive_chrome.log 2>&1 & \ + setsid nohup chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-dev-shm-usage --window-size=1280,1024 >/tmp/interactive_chrome.log 2>&1 & \ elif command -v google-chrome >/dev/null 2>&1; then \ - setsid nohup google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu >/tmp/interactive_chrome.log 2>&1 & \ + setsid nohup google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-dev-shm-usage --window-size=1280,1024 >/tmp/interactive_chrome.log 2>&1 & \ fi && \ sleep 3; \ fi", diff --git a/crates/flock-tools/src/tools/sandbox/browser/mod.rs b/crates/flock-tools/src/tools/sandbox/browser/mod.rs index 23dcb698..8bab219a 100644 --- a/crates/flock-tools/src/tools/sandbox/browser/mod.rs +++ b/crates/flock-tools/src/tools/sandbox/browser/mod.rs @@ -152,11 +152,11 @@ async fn execute_regular_action( if ! python3 -c 'import socket; s = socket.socket(); s.connect((\"127.0.0.1\", 9222))' >/dev/null 2>&1; then \ echo 'Starting headful chromium with remote debugging on DISPLAY={display}...' && \ if command -v chromium >/dev/null 2>&1; then \ - setsid nohup env DISPLAY={display} chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup env DISPLAY={display} chromium --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-dev-shm-usage --window-size=1280,1024 >/tmp/headless_chrome.log 2>&1 & \ elif command -v chromium-browser >/dev/null 2>&1; then \ - setsid nohup env DISPLAY={display} chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup env DISPLAY={display} chromium-browser --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-dev-shm-usage --window-size=1280,1024 >/tmp/headless_chrome.log 2>&1 & \ elif command -v google-chrome >/dev/null 2>&1; then \ - setsid nohup env DISPLAY={display} google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-software-rasterizer --disable-dev-shm-usage >/tmp/headless_chrome.log 2>&1 & \ + setsid nohup env DISPLAY={display} google-chrome --no-sandbox --remote-debugging-port=9222 --disable-gpu --disable-dev-shm-usage --window-size=1280,1024 >/tmp/headless_chrome.log 2>&1 & \ fi && \ sleep 3; \ fi; \ diff --git a/flock-ui/src-tauri/src/commands/common/sandbox.rs b/flock-ui/src-tauri/src/commands/common/sandbox.rs index 14dadc2a..1b2afebd 100644 --- a/flock-ui/src-tauri/src/commands/common/sandbox.rs +++ b/flock-ui/src-tauri/src/commands/common/sandbox.rs @@ -43,7 +43,7 @@ pub async fn get_active_sandbox_vnc_url( let provider = flock_tools::sandbox_core::manager::get_provider(provider_name); provider.get_vnc_url(&*db, &cfg, &sandbox_id).await.unwrap_or_else(|_| { if provider_name == "e2b" { - format!("https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&skip-preview-warning=true&skip_preview_warning=true&path=", sandbox_id) + format!("https://6080-{}.e2b.app/vnc.html?autoconnect=true&resize=scale&path=websockify", sandbox_id) } else { format!("https://6080-{}.proxy.app.daytona.io/vnc.html?autoconnect=true&resize=scale", sandbox_id) } diff --git a/flock-ui/src/pages/Workspace/components/EnvironmentPanel/components/VncView.tsx b/flock-ui/src/pages/Workspace/components/EnvironmentPanel/components/VncView.tsx index d46c2936..bce2be94 100644 --- a/flock-ui/src/pages/Workspace/components/EnvironmentPanel/components/VncView.tsx +++ b/flock-ui/src/pages/Workspace/components/EnvironmentPanel/components/VncView.tsx @@ -1,3 +1,4 @@ +import { memo } from 'react'; import { Box } from '@mantine/core'; import { ImageView } from '@/pages/Workspace/components/EnvironmentPanel/ImageView'; import { useWorkspaceStore } from '@/store/workspaceStore'; @@ -121,21 +122,7 @@ export function VncView({ {!isPlaybackMode && activeTab === 'vnc' && !isOfflineMode && ( -