Skip to content

Commit

Permalink
Improve container handling:
Browse files Browse the repository at this point in the history
- Add better logging
- Add wait_for_container_status helper
- Use simpler ubuntu image for tests
- Add detailed error messages
  • Loading branch information
Anon23261 committed Nov 22, 2024
1 parent d6a2dd2 commit 85b2d0e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 20 deletions.
30 changes: 22 additions & 8 deletions ghostsec/learning_environments/labs.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,32 @@ def __init__(self, name: str, vulnerability_type: str):

def start(self) -> bool:
try:
logger.info("Starting vulnerability lab container...")

# For testing, use a simple ubuntu image
# In production, we'll use webgoat/webgoat-8.0
image = "ubuntu:latest" if "test" in self.name else "webgoat/webgoat-8.0"

# Start the container
self.container = self.docker_client.containers.run(
"webgoat/webgoat-8.0",
image,
detach=True,
ports={'8080/tcp': 8080}
command="tail -f /dev/null" if "ubuntu" in image else "sleep infinity", # Keep container running
ports={'8080/tcp': 8080} if "webgoat" in image else None
)
logger.info(f"Container created with status: {self.container.status}")

# Wait for container to be running
self.container.reload() # Refresh container state
self.container.reload()
logger.info(f"Container status after reload: {self.container.status}")

if self.container.status != 'running':
self.container.start() # Explicitly start if not running
self.container.reload() # Refresh state again
logger.info("Container not running, attempting to start...")
self.container.start()
self.container.reload()
logger.info(f"Container status after start: {self.container.status}")

# Verify container is running
# Final status check
return self.container.status == 'running'
except Exception as e:
logger.error(f"Failed to start vulnerability lab: {e}")
Expand Down Expand Up @@ -75,11 +87,13 @@ def cleanup(self) -> None:
"""Clean up lab resources."""
try:
if self.container:
logger.info("Cleaning up vulnerability lab container...")
try:
self.container.stop()
self.container.remove()
except:
pass
logger.info("Container stopped and removed successfully")
except Exception as e:
logger.error(f"Error during container cleanup: {e}")
self.container = None
except Exception as e:
logger.error(f"Failed to cleanup vulnerability lab: {e}")
Expand Down
41 changes: 29 additions & 12 deletions tests/test_labs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,43 @@
import pytest
import docker
import time
import logging
from ghostsec.learning_environments.labs import (
VulnerabilityLab,
NetworkingLab,
CryptographyLab,
ReverseEngineeringLab
)

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def is_docker_available():
"""Check if Docker is available and running."""
try:
client = docker.from_env()
client.ping()
return True
except:
except Exception as e:
logger.error(f"Docker not available: {e}")
return False

def wait_for_container_status(container, target_status: str, timeout: int = 10) -> bool:
"""Wait for container to reach target status."""
start_time = time.time()
while time.time() - start_time < timeout:
try:
container.reload()
logger.info(f"Container status: {container.status}")
if container.status == target_status:
return True
time.sleep(1)
except Exception as e:
logger.error(f"Error checking container status: {e}")
return False
return False

@pytest.fixture
def vulnerability_lab():
"""Create a vulnerability lab instance."""
Expand All @@ -44,19 +65,15 @@ def test_vulnerability_lab_creation(vulnerability_lab):

def test_vulnerability_lab_start(vulnerability_lab):
"""Test vulnerability lab startup."""
logger.info("Starting vulnerability lab test...")
result = vulnerability_lab.start()
assert result is True
assert vulnerability_lab.container is not None

# Give container some time to start if needed
max_retries = 3
for _ in range(max_retries):
vulnerability_lab.container.reload()
if vulnerability_lab.container.status == "running":
break
time.sleep(1)
assert result is True, "Lab start() method returned False"
assert vulnerability_lab.container is not None, "Container is None after start"

assert vulnerability_lab.container.status == "running"
# Wait for container to be running
logger.info("Waiting for container to be running...")
assert wait_for_container_status(vulnerability_lab.container, "running"), \
f"Container failed to reach running state. Current status: {vulnerability_lab.container.status}"

def test_vulnerability_lab_challenges(vulnerability_lab):
"""Test vulnerability lab challenges."""
Expand Down

0 comments on commit 85b2d0e

Please sign in to comment.