|
|
""" |
|
|
Modal Container Images for Multi-Language Test Execution. |
|
|
Defines secure, isolated container images for each supported language. |
|
|
""" |
|
|
|
|
|
import logging |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
|
try: |
|
|
import modal |
|
|
MODAL_AVAILABLE = True |
|
|
except ImportError: |
|
|
MODAL_AVAILABLE = False |
|
|
modal = None |
|
|
logger.warning("Modal not available - will use local execution only") |
|
|
|
|
|
|
|
|
if MODAL_AVAILABLE: |
|
|
app = modal.App("legacy-code-validator") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
python_image = ( |
|
|
modal.Image.debian_slim() |
|
|
.pip_install( |
|
|
"pytest>=9.0.0", |
|
|
"pytest-cov>=6.0.0", |
|
|
"pytest-timeout>=2.3.0", |
|
|
"pytest-benchmark>=4.0.0", |
|
|
"pytest-mock>=3.12.0" |
|
|
) |
|
|
) |
|
|
|
|
|
java_image = ( |
|
|
modal.Image.debian_slim() |
|
|
.apt_install("openjdk-17-jdk", "maven", "wget") |
|
|
.run_commands( |
|
|
"mvn --version" |
|
|
) |
|
|
) |
|
|
|
|
|
javascript_image = ( |
|
|
modal.Image.debian_slim() |
|
|
.apt_install( |
|
|
"curl", "ca-certificates", "gnupg", "libxt6", "libxmu6", "libxaw7", |
|
|
"build-essential", "python3", "git" |
|
|
) |
|
|
.run_commands( |
|
|
|
|
|
"mkdir -p /etc/apt/keyrings", |
|
|
"curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg", |
|
|
"echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' | tee /etc/apt/sources.list.d/nodesource.list", |
|
|
"apt-get update", |
|
|
"apt-get install -y nodejs", |
|
|
|
|
|
"npm install -g jest@latest ts-jest@latest typescript@latest @types/jest@latest", |
|
|
|
|
|
"mkdir -p /workspace", |
|
|
"chmod 777 /workspace", |
|
|
"node --version", |
|
|
"npm --version", |
|
|
"jest --version" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
typescript_image = javascript_image |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LANGUAGE_IMAGES = { |
|
|
|
|
|
'python': python_image, |
|
|
'java': java_image, |
|
|
'javascript': javascript_image, |
|
|
'typescript': typescript_image |
|
|
} |
|
|
|
|
|
|
|
|
LANGUAGE_SUPPORT_STATUS = { |
|
|
'python': 'production', |
|
|
'java': 'production', |
|
|
'javascript': 'production', |
|
|
'typescript': 'production' |
|
|
} |
|
|
|
|
|
else: |
|
|
|
|
|
app = None |
|
|
LANGUAGE_IMAGES = {} |
|
|
LANGUAGE_SUPPORT_STATUS = {} |
|
|
python_image = None |
|
|
java_image = None |
|
|
javascript_image = None |
|
|
typescript_image = None |
|
|
|
|
|
|
|
|
def get_image_for_language(language: str): |
|
|
"""Get the appropriate Modal image for a language.""" |
|
|
if not MODAL_AVAILABLE: |
|
|
return None |
|
|
|
|
|
return LANGUAGE_IMAGES.get(language.lower()) |
|
|
|
|
|
|
|
|
def get_support_status(language: str) -> str: |
|
|
"""Get support status for a language: production, experimental, planned, or unsupported.""" |
|
|
if not MODAL_AVAILABLE: |
|
|
return 'local_only' |
|
|
|
|
|
return LANGUAGE_SUPPORT_STATUS.get(language.lower(), 'unsupported') |
|
|
|
|
|
|
|
|
def is_language_supported(language: str) -> bool: |
|
|
"""Check if a language is supported in Modal.""" |
|
|
return language.lower() in LANGUAGE_IMAGES |
|
|
|