Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Update backend_structured/scanners_core.py
Browse files
backend_structured/scanners_core.py
CHANGED
|
@@ -73,7 +73,7 @@ import jwt
|
|
| 73 |
import math
|
| 74 |
import os
|
| 75 |
import re
|
| 76 |
-
import re, time, ipaddress, os, hashlib, threading
|
| 77 |
import requests
|
| 78 |
import socket
|
| 79 |
import sqlite3
|
|
@@ -762,31 +762,79 @@ if CELERY_AVAILABLE and celery:
|
|
| 762 |
run_background_scan_task.delay(new_scan.id)
|
| 763 |
|
| 764 |
|
| 765 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 766 |
|
| 767 |
def launch_scan(app, scan_id: str) -> bool:
|
| 768 |
"""
|
| 769 |
-
Launch a scan using
|
| 770 |
-
|
|
|
|
| 771 |
"""
|
|
|
|
|
|
|
| 772 |
use_celery = os.getenv('USE_CELERY', 'false').lower() == 'true'
|
| 773 |
if use_celery and CELERY_AVAILABLE and celery:
|
| 774 |
run_background_scan_task.delay(scan_id)
|
| 775 |
print(f"[Scanner] Background scan dispatched to Celery for scan {scan_id}", flush=True)
|
| 776 |
return True
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
| 780 |
-
|
| 781 |
-
|
| 782 |
-
|
| 783 |
-
|
| 784 |
-
|
| 785 |
-
|
| 786 |
-
|
| 787 |
-
|
| 788 |
-
|
| 789 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 790 |
return True
|
| 791 |
|
| 792 |
|
|
|
|
| 73 |
import math
|
| 74 |
import os
|
| 75 |
import re
|
| 76 |
+
import re, time, ipaddress, os, hashlib, threading, queue
|
| 77 |
import requests
|
| 78 |
import socket
|
| 79 |
import sqlite3
|
|
|
|
| 762 |
run_background_scan_task.delay(new_scan.id)
|
| 763 |
|
| 764 |
|
| 765 |
+
# ── Thread-based launcher with Sequential FIFO Queue (One scan at a time) ──
|
| 766 |
+
|
| 767 |
+
_scan_queue = queue.Queue()
|
| 768 |
+
_queue_worker_started = False
|
| 769 |
+
_queue_lock = threading.Lock()
|
| 770 |
+
|
| 771 |
+
def _scan_queue_worker(app):
|
| 772 |
+
print("[ScanQueueWorker] Sequential background worker thread started.", flush=True)
|
| 773 |
+
while True:
|
| 774 |
+
try:
|
| 775 |
+
sid = _scan_queue.get()
|
| 776 |
+
if sid is None:
|
| 777 |
+
break
|
| 778 |
+
|
| 779 |
+
print(f"[ScanQueueWorker] Beginning execution of queued scan {sid}...", flush=True)
|
| 780 |
+
with app.app_context():
|
| 781 |
+
try:
|
| 782 |
+
s = Scan.query.get(sid)
|
| 783 |
+
if s:
|
| 784 |
+
s.status = 'scanning'
|
| 785 |
+
s.started_at = datetime.now(timezone.utc)
|
| 786 |
+
db.session.commit()
|
| 787 |
+
add_log(sid, f"[INFO] Target: {s.target_url} ({s.scan_type} Scan)")
|
| 788 |
+
add_log(sid, "[INFO] Sequential scan worker starting active audit execution...")
|
| 789 |
+
|
| 790 |
+
_run_scan_job(sid)
|
| 791 |
+
except Exception as ex:
|
| 792 |
+
print(f"[ScanQueueWorker] Error executing scan {sid}: {ex}", flush=True)
|
| 793 |
+
traceback.print_exc()
|
| 794 |
+
finally:
|
| 795 |
+
_scan_queue.task_done()
|
| 796 |
+
except Exception as e:
|
| 797 |
+
print(f"[ScanQueueWorker] Queue worker exception: {e}", flush=True)
|
| 798 |
+
time.sleep(1)
|
| 799 |
|
| 800 |
def launch_scan(app, scan_id: str) -> bool:
|
| 801 |
"""
|
| 802 |
+
Launch a scan using a sequential FIFO queue.
|
| 803 |
+
Ensures only ONE active scan executes at any given time.
|
| 804 |
+
Subsequent scans wait in 'queued' state and run automatically when the current scan finishes.
|
| 805 |
"""
|
| 806 |
+
global _queue_worker_started
|
| 807 |
+
|
| 808 |
use_celery = os.getenv('USE_CELERY', 'false').lower() == 'true'
|
| 809 |
if use_celery and CELERY_AVAILABLE and celery:
|
| 810 |
run_background_scan_task.delay(scan_id)
|
| 811 |
print(f"[Scanner] Background scan dispatched to Celery for scan {scan_id}", flush=True)
|
| 812 |
return True
|
| 813 |
+
|
| 814 |
+
with app.app_context():
|
| 815 |
+
try:
|
| 816 |
+
s = Scan.query.get(scan_id)
|
| 817 |
+
if s:
|
| 818 |
+
active_scan = Scan.query.filter(Scan.status == 'scanning', Scan.id != scan_id).first()
|
| 819 |
+
if active_scan or not _scan_queue.empty():
|
| 820 |
+
s.status = 'queued'
|
| 821 |
+
print(f"[Scanner] Active scan in progress ({active_scan.id if active_scan else 'queued item'}). Setting scan {scan_id} to queued.", flush=True)
|
| 822 |
+
else:
|
| 823 |
+
s.status = 'scanning'
|
| 824 |
+
s.started_at = datetime.now(timezone.utc)
|
| 825 |
+
print(f"[Scanner] Queue empty. Setting scan {scan_id} directly to scanning.", flush=True)
|
| 826 |
+
db.session.commit()
|
| 827 |
+
except Exception as err:
|
| 828 |
+
print(f"[Scanner] Failed updating scan status on launch: {err}", flush=True)
|
| 829 |
+
|
| 830 |
+
with _queue_lock:
|
| 831 |
+
if not _queue_worker_started:
|
| 832 |
+
worker_thread = threading.Thread(target=_scan_queue_worker, args=(app,), daemon=True)
|
| 833 |
+
worker_thread.start()
|
| 834 |
+
_queue_worker_started = True
|
| 835 |
+
|
| 836 |
+
_scan_queue.put(scan_id)
|
| 837 |
+
print(f"[Scanner] Scan {scan_id} placed in execution queue (Current queue size: {_scan_queue.qsize()})", flush=True)
|
| 838 |
return True
|
| 839 |
|
| 840 |
|