diff --git a/config.py b/config.py index e4d31bf..7a6cb76 100644 --- a/config.py +++ b/config.py @@ -316,13 +316,6 @@ ENABLE_MALICIOUS_CONTENT_SCAN = True # Logging configuration - can be overridden in local config # Example: LOGS_DIR = "/var/log/ivatar" # For production deployments -# OpenTelemetry feature flag - can be disabled for F/LOSS deployments -ENABLE_OPENTELEMETRY = os.environ.get("ENABLE_OPENTELEMETRY", "false").lower() in ( - "true", - "1", - "yes", -) - # This MUST BE THE LAST! if os.path.isfile(os.path.join(BASE_DIR, "config_local.py")): from config_local import * # noqa # flake8: noqa # NOQA # pragma: no cover diff --git a/ivatar/settings.py b/ivatar/settings.py index 45bfc00..3c28237 100644 --- a/ivatar/settings.py +++ b/ivatar/settings.py @@ -311,16 +311,14 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" from config import * # pylint: disable=wildcard-import,wrong-import-position,unused-wildcard-import # noqa # OpenTelemetry setup - must be after config import -# Only setup if feature flag is enabled +# Always setup OpenTelemetry (instrumentation always enabled, export controlled by OTEL_EXPORT_ENABLED) try: - if getattr(globals(), "ENABLE_OPENTELEMETRY", False): - from ivatar.opentelemetry_config import setup_opentelemetry + from ivatar.opentelemetry_config import setup_opentelemetry - setup_opentelemetry() + setup_opentelemetry() - # Add OpenTelemetry middleware if enabled - MIDDLEWARE.append("ivatar.opentelemetry_middleware.OpenTelemetryMiddleware") + # Add OpenTelemetry middleware (always enabled) + MIDDLEWARE.append("ivatar.opentelemetry_middleware.OpenTelemetryMiddleware") except (ImportError, NameError): # OpenTelemetry packages not installed or configuration failed - # ENABLE_OPENTELEMETRY not defined (shouldn't happen but be safe) pass diff --git a/ivatar/views.py b/ivatar/views.py index 4bbf795..5831bef 100644 --- a/ivatar/views.py +++ b/ivatar/views.py @@ -40,41 +40,13 @@ from .ivataraccount.models import Photo from .ivataraccount.models import pil_format, file_format from .utils import is_trusted_url, mm_ng, resize_animated_gif -# Import OpenTelemetry only if feature flag is enabled +# Import OpenTelemetry (always enabled, export controlled by OTEL_EXPORT_ENABLED) try: - from django.conf import settings + from .opentelemetry_middleware import trace_avatar_operation, get_avatar_metrics - if getattr(settings, "ENABLE_OPENTELEMETRY", False): - from .opentelemetry_middleware import trace_avatar_operation, get_avatar_metrics - - avatar_metrics = get_avatar_metrics() - else: - # Create no-op decorators and metrics when OpenTelemetry is disabled - def trace_avatar_operation(operation_name): - def decorator(func): - return func - - return decorator - - class NoOpMetrics: - def record_avatar_generated(self, *args, **kwargs): - pass - - def record_cache_hit(self, *args, **kwargs): - pass - - def record_cache_miss(self, *args, **kwargs): - pass - - def record_external_request(self, *args, **kwargs): - pass - - def record_file_upload(self, *args, **kwargs): - pass - - avatar_metrics = NoOpMetrics() + avatar_metrics = get_avatar_metrics() except ImportError: - # Django not available or settings not loaded + # OpenTelemetry packages not installed def trace_avatar_operation(operation_name): def decorator(func): return func diff --git a/scripts/check_deployment.py b/scripts/check_deployment.py index e2a16d4..45c09d8 100755 --- a/scripts/check_deployment.py +++ b/scripts/check_deployment.py @@ -20,6 +20,7 @@ import argparse import json import random import ssl +import subprocess import sys import tempfile import time @@ -57,6 +58,52 @@ def colored_print(message: str, color: str = Colors.NC) -> None: print(f"{color}{message}{Colors.NC}") +def get_current_commit_hash() -> Optional[str]: + """Get the current commit hash from git.""" + try: + result = subprocess.run( + ["git", "rev-parse", "HEAD"], + capture_output=True, + text=True, + check=True, + ) + return result.stdout.strip() + except (subprocess.CalledProcessError, FileNotFoundError): + return None + + +def is_commit_newer_or_equal(commit1: str, commit2: str) -> Optional[bool]: + """ + Check if commit1 is newer than or equal to commit2 in git history. + + Returns: + True if commit1 is newer or equal to commit2 + False if commit1 is older than commit2 + None if comparison fails + """ + try: + # Use git merge-base to check if commit1 is reachable from commit2 + # If commit1 is newer or equal, it should be reachable from commit2 + subprocess.run( + ["git", "merge-base", "--is-ancestor", commit2, commit1], + capture_output=True, + check=True, + ) + return True + except subprocess.CalledProcessError: + # If the above fails, try the reverse - check if commit2 is newer + try: + result = subprocess.run( + ["git", "merge-base", "--is-ancestor", commit1, commit2], + capture_output=True, + check=True, + ) + return False + except subprocess.CalledProcessError: + # If both fail, we can't determine the relationship + return None + + def make_request( url: str, method: str = "GET", @@ -289,14 +336,43 @@ def test_deployment( ) # Display version information - commit_hash = version_info.get("commit_hash", "Unknown") + deployed_commit = version_info.get("commit_hash", "Unknown") branch = version_info.get("branch", "Unknown") version = version_info.get("version", "Unknown") - colored_print(f"Deployed commit: {commit_hash}", Colors.BLUE) + colored_print(f"Deployed commit: {deployed_commit}", Colors.BLUE) colored_print(f"Deployed branch: {branch}", Colors.BLUE) colored_print(f"Deployed version: {version}", Colors.BLUE) + # Check if we're looking for a specific version and compare + current_commit = get_current_commit_hash() + if current_commit and deployed_commit != "Unknown": + if deployed_commit == current_commit: + colored_print( + "✅ Exact version match - deployment is up to date!", + Colors.GREEN, + ) + else: + # Check if deployed version is newer + comparison = is_commit_newer_or_equal( + deployed_commit, current_commit + ) + if comparison is True: + colored_print( + "ℹ️ Note: A newer version is already deployed (this is fine!)", + Colors.YELLOW, + ) + elif comparison is False: + colored_print( + "⚠️ Warning: Deployed version appears to be older than expected", + Colors.YELLOW, + ) + else: + colored_print( + "⚠️ Warning: Could not determine version relationship", + Colors.YELLOW, + ) + # Run functionality tests colored_print("Running basic functionality tests...", Colors.YELLOW)