mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-09 13:27:59 -05:00
chore(bench): added headed mode for debugging (#1073)
This commit is contained in:
@@ -16,6 +16,10 @@ pub struct Cli {
|
|||||||
/// Subnet to assign harness network interfaces.
|
/// Subnet to assign harness network interfaces.
|
||||||
#[arg(long, default_value = "10.250.0.0/24", env = "SUBNET")]
|
#[arg(long, default_value = "10.250.0.0/24", env = "SUBNET")]
|
||||||
pub subnet: Ipv4Net,
|
pub subnet: Ipv4Net,
|
||||||
|
/// Run browser in headed mode (visible window) for debugging.
|
||||||
|
/// Works with both X11 and Wayland.
|
||||||
|
#[arg(long)]
|
||||||
|
pub headed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ pub struct Executor {
|
|||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
config: ExecutorConfig,
|
config: ExecutorConfig,
|
||||||
target: Target,
|
target: Target,
|
||||||
|
/// Display environment variables for headed mode (X11/Wayland).
|
||||||
|
/// Empty means headless mode.
|
||||||
|
display_env: Vec<String>,
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,11 +52,17 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl Executor {
|
||||||
pub fn new(ns: Namespace, config: ExecutorConfig, target: Target) -> Self {
|
pub fn new(
|
||||||
|
ns: Namespace,
|
||||||
|
config: ExecutorConfig,
|
||||||
|
target: Target,
|
||||||
|
display_env: Vec<String>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ns,
|
ns,
|
||||||
config,
|
config,
|
||||||
target,
|
target,
|
||||||
|
display_env,
|
||||||
state: State::Init,
|
state: State::Init,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,23 +129,49 @@ impl Executor {
|
|||||||
let tmp = duct::cmd!("mktemp", "-d").read()?;
|
let tmp = duct::cmd!("mktemp", "-d").read()?;
|
||||||
let tmp = tmp.trim();
|
let tmp = tmp.trim();
|
||||||
|
|
||||||
let process = duct::cmd!(
|
let headed = !self.display_env.is_empty();
|
||||||
"sudo",
|
|
||||||
"ip",
|
// Build command args based on headed/headless mode
|
||||||
"netns",
|
let mut args: Vec<String> = vec![
|
||||||
"exec",
|
"ip".into(),
|
||||||
self.ns.name(),
|
"netns".into(),
|
||||||
chrome_path,
|
"exec".into(),
|
||||||
format!("--remote-debugging-port={PORT_BROWSER}"),
|
self.ns.name().into(),
|
||||||
"--headless",
|
];
|
||||||
"--disable-dev-shm-usage",
|
|
||||||
"--disable-gpu",
|
if headed {
|
||||||
"--disable-cache",
|
// For headed mode: drop back to the current user and pass display env vars
|
||||||
"--disable-application-cache",
|
// This allows the browser to connect to X11/Wayland while in the namespace
|
||||||
"--no-sandbox",
|
let user =
|
||||||
|
std::env::var("USER").context("USER environment variable not set")?;
|
||||||
|
args.extend(["sudo".into(), "-E".into(), "-u".into(), user, "env".into()]);
|
||||||
|
args.extend(self.display_env.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push(chrome_path.to_string_lossy().into());
|
||||||
|
args.push(format!("--remote-debugging-port={PORT_BROWSER}"));
|
||||||
|
|
||||||
|
if headed {
|
||||||
|
// Headed mode: no headless, add flags to suppress first-run dialogs
|
||||||
|
args.extend(["--no-first-run".into(), "--no-default-browser-check".into()]);
|
||||||
|
} else {
|
||||||
|
// Headless mode: original flags
|
||||||
|
args.extend([
|
||||||
|
"--headless".into(),
|
||||||
|
"--disable-dev-shm-usage".into(),
|
||||||
|
"--disable-gpu".into(),
|
||||||
|
"--disable-cache".into(),
|
||||||
|
"--disable-application-cache".into(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.extend([
|
||||||
|
"--no-sandbox".into(),
|
||||||
format!("--user-data-dir={tmp}"),
|
format!("--user-data-dir={tmp}"),
|
||||||
format!("--allowed-ips=10.250.0.1"),
|
"--allowed-ips=10.250.0.1".into(),
|
||||||
);
|
]);
|
||||||
|
|
||||||
|
let process = duct::cmd("sudo", &args);
|
||||||
|
|
||||||
let process = if !cfg!(feature = "debug") {
|
let process = if !cfg!(feature = "debug") {
|
||||||
process.stderr_capture().stdout_capture().start()?
|
process.stderr_capture().stdout_capture().start()?
|
||||||
|
|||||||
@@ -105,14 +105,46 @@ struct Runner {
|
|||||||
started: bool,
|
started: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Collects display-related environment variables for headed browser mode.
|
||||||
|
/// Works with both X11 and Wayland by collecting whichever vars are present.
|
||||||
|
fn collect_display_env_vars() -> Vec<String> {
|
||||||
|
const DISPLAY_VARS: &[&str] = &[
|
||||||
|
"DISPLAY", // X11
|
||||||
|
"XAUTHORITY", // X11 auth
|
||||||
|
"WAYLAND_DISPLAY", // Wayland
|
||||||
|
"XDG_RUNTIME_DIR", // Wayland runtime dir
|
||||||
|
];
|
||||||
|
|
||||||
|
DISPLAY_VARS
|
||||||
|
.iter()
|
||||||
|
.filter_map(|&var| {
|
||||||
|
std::env::var(var)
|
||||||
|
.ok()
|
||||||
|
.map(|val| format!("{}={}", var, val))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
impl Runner {
|
impl Runner {
|
||||||
fn new(cli: &Cli) -> Result<Self> {
|
fn new(cli: &Cli) -> Result<Self> {
|
||||||
let Cli { target, subnet, .. } = cli;
|
let Cli {
|
||||||
|
target,
|
||||||
|
subnet,
|
||||||
|
headed,
|
||||||
|
..
|
||||||
|
} = cli;
|
||||||
let current_path = std::env::current_exe().unwrap();
|
let current_path = std::env::current_exe().unwrap();
|
||||||
let fixture_path = current_path.parent().unwrap().join("server-fixture");
|
let fixture_path = current_path.parent().unwrap().join("server-fixture");
|
||||||
let network_config = NetworkConfig::new(*subnet);
|
let network_config = NetworkConfig::new(*subnet);
|
||||||
let network = Network::new(network_config.clone())?;
|
let network = Network::new(network_config.clone())?;
|
||||||
|
|
||||||
|
// Collect display env vars once if headed mode is enabled
|
||||||
|
let display_env = if *headed {
|
||||||
|
collect_display_env_vars()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
let server_fixture =
|
let server_fixture =
|
||||||
ServerFixture::new(fixture_path, network.ns_app().clone(), network_config.app);
|
ServerFixture::new(fixture_path, network.ns_app().clone(), network_config.app);
|
||||||
let wasm_server = WasmServer::new(
|
let wasm_server = WasmServer::new(
|
||||||
@@ -130,6 +162,7 @@ impl Runner {
|
|||||||
.network_config(network_config.clone())
|
.network_config(network_config.clone())
|
||||||
.build(),
|
.build(),
|
||||||
*target,
|
*target,
|
||||||
|
display_env.clone(),
|
||||||
);
|
);
|
||||||
let exec_v = Executor::new(
|
let exec_v = Executor::new(
|
||||||
network.ns_1().clone(),
|
network.ns_1().clone(),
|
||||||
@@ -139,6 +172,7 @@ impl Runner {
|
|||||||
.network_config(network_config.clone())
|
.network_config(network_config.clone())
|
||||||
.build(),
|
.build(),
|
||||||
Target::Native,
|
Target::Native,
|
||||||
|
Vec::new(), // Verifier doesn't need display env
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -173,6 +207,12 @@ pub async fn main() -> Result<()> {
|
|||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
// Validate --headed requires --target browser
|
||||||
|
if cli.headed && cli.target != Target::Browser {
|
||||||
|
anyhow::bail!("--headed can only be used with --target browser");
|
||||||
|
}
|
||||||
|
|
||||||
let mut runner = Runner::new(&cli)?;
|
let mut runner = Runner::new(&cli)?;
|
||||||
|
|
||||||
let mut exit_code = 0;
|
let mut exit_code = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user