verl-agent / scripts /launch_env.py
zhangzf01
hf run successfully
0eca069
Raw
History Blame Contribute Delete
5.54 kB
"""Launch VisualWebArena / WebArena Docker containers for PoisonClaw.
Usage:
# Start VisualWebArena on port 9999
python scripts/launch_env.py --env visualwebarena --port 9999
# Start WebArena on port 8080
python scripts/launch_env.py --env webarena --port 8080
# Stop all running PoisonClaw containers
python scripts/launch_env.py --stop_all
"""
import argparse
import logging
import subprocess
import sys
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
logger = logging.getLogger("poisonclaw.launch_env")
# Docker image references for each environment
_DOCKER_IMAGES = {
"visualwebarena": {
"image": "ghcr.io/web-arena-x/visualwebarena:latest",
"services": {
"reddit": 9999,
"shopping": 7770,
"classifieds": 9980,
},
"docs": "https://github.com/web-arena-x/visualwebarena",
},
"webarena": {
"image": "ghcr.io/web-arena-x/webarena:latest",
"services": {
"gitlab": 8023,
"reddit": 9999,
"shopping": 7770,
"map": 3000,
},
"docs": "https://github.com/web-arena-x/webarena",
},
}
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Launch web environment Docker containers")
parser.add_argument(
"--env",
choices=list(_DOCKER_IMAGES.keys()),
help="Environment to launch",
)
parser.add_argument(
"--port",
type=int,
default=None,
help="Host port for the main service",
)
parser.add_argument(
"--stop_all",
action="store_true",
help="Stop all running PoisonClaw environment containers",
)
parser.add_argument(
"--status",
action="store_true",
help="Show status of running containers",
)
return parser.parse_args()
def check_docker() -> bool:
"""Check if Docker is available.
Returns:
True if Docker is installed and running.
"""
try:
result = subprocess.run(
["docker", "info"],
capture_output=True,
check=True,
timeout=10,
)
return True
except (subprocess.CalledProcessError, FileNotFoundError, subprocess.TimeoutExpired):
logger.error(
"Docker is not available. Please install Docker to use web environments.\n"
"For local development without Docker, use stub environments by not setting "
"env.vwa_task_file in your config."
)
return False
def launch_env(env_name: str, port: int) -> None:
"""Launch the specified environment Docker container.
Args:
env_name: Environment name (``"visualwebarena"`` or ``"webarena"``).
port: Host port for the main service.
"""
if not check_docker():
sys.exit(1)
env_info = _DOCKER_IMAGES[env_name]
image = env_info["image"]
main_port = port or list(env_info["services"].values())[0]
logger.info("Launching %s (image: %s) on port %d...", env_name, image, main_port)
logger.info("Docs: %s", env_info["docs"])
# Build port mapping args
port_args = []
services = env_info["services"]
base_service_port = list(services.values())[0]
for service, service_port in services.items():
host_port = main_port + (service_port - base_service_port)
port_args += ["-p", f"{host_port}:{service_port}"]
cmd = [
"docker", "run", "-d",
"--name", f"poisonclaw-{env_name}",
*port_args,
image,
]
logger.info("Running: %s", " ".join(cmd))
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
container_id = result.stdout.strip()[:12]
logger.info(
"Container started: %s\n"
"Access at: http://localhost:%d",
container_id,
main_port,
)
except subprocess.CalledProcessError as exc:
logger.error("Failed to start container: %s", exc.stderr)
sys.exit(1)
def stop_all() -> None:
"""Stop all running PoisonClaw environment containers."""
if not check_docker():
return
result = subprocess.run(
["docker", "ps", "--filter", "name=poisonclaw-", "--format", "{{.Names}}"],
capture_output=True,
text=True,
)
containers = [c.strip() for c in result.stdout.splitlines() if c.strip()]
if not containers:
logger.info("No PoisonClaw containers running.")
return
for name in containers:
subprocess.run(["docker", "stop", name], check=False)
subprocess.run(["docker", "rm", name], check=False)
logger.info("Stopped and removed: %s", name)
def show_status() -> None:
"""Show status of running PoisonClaw containers."""
if not check_docker():
return
result = subprocess.run(
[
"docker", "ps",
"--filter", "name=poisonclaw-",
"--format", "table {{.Names}}\t{{.Status}}\t{{.Ports}}",
],
capture_output=True,
text=True,
)
print(result.stdout or "No PoisonClaw containers running.")
def main() -> None:
args = parse_args()
if args.stop_all:
stop_all()
elif args.status:
show_status()
elif args.env:
launch_env(args.env, args.port or 0)
else:
logger.error("Specify --env, --stop_all, or --status.")
sys.exit(1)
if __name__ == "__main__":
main()