Skip to content
This repository has been archived by the owner on Nov 29, 2021. It is now read-only.

Improve log and queued scans handling #279

Merged
merged 7 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions ospd/command/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,13 +478,19 @@ def handle_xml(self, xml: Element) -> bytes:
Response string for <start_scan> command.
"""

current_queued_scans = self._daemon.get_count_queued_scans()
if (
self._daemon.max_queued_scans
and self._daemon.get_count_queued_scans()
>= self._daemon.max_queued_scans
and current_queued_scans >= self._daemon.max_queued_scans
):
logger.info(
'Maximum number of queued scans set to %d reached.',
self._daemon.max_queued_scans,
)
raise OspdCommandError(
'Maximum number of queued scans reached.', 'start_scan'
'Maximum number of queued scans set to %d reached.'
% self._daemon.max_queued_scans,
'start_scan',
)

target_str = xml.get('target')
Expand Down Expand Up @@ -555,6 +561,12 @@ def handle_xml(self, xml: Element) -> bytes:
id_.text = scan_id_aux
return simple_response_str('start_scan', 100, 'Continue', id_)

logger.info(
'Scan %s added to the queue in position %d.',
scan_id,
current_queued_scans + 1,
)

if dry_run:
scan_func = self._daemon.dry_run_scan
scan_process = create_process(
Expand Down
6 changes: 6 additions & 0 deletions ospd/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ def main(
if not daemon.check():
return 1

LOGGER.info(
"Starting %s version %s.",
daemon.daemon_info['name'],
daemon.daemon_info['version'],
)

daemon.init(server)
daemon.run()

Expand Down
54 changes: 37 additions & 17 deletions ospd/ospd.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,10 @@ def stop_scan(self, scan_id: str) -> None:
scan_id in self.scan_collection.ids_iterator()
and self.get_scan_status(scan_id) == ScanStatus.QUEUED
):
logger.info('Scan %s has been removed from the queue.', scan_id)
self.scan_collection.remove_file_pickled_scan_info(scan_id)
self.set_scan_status(scan_id, ScanStatus.STOPPED)

return

scan_process = self.scan_processes.get(scan_id)
Expand Down Expand Up @@ -1213,20 +1215,19 @@ def run(self) -> None:
def start_queued_scans(self) -> None:
""" Starts a queued scan if it is allowed """

for scan_id in self.scan_collection.ids_iterator():
if not self.is_new_scan_allowed():
logger.debug(
'Not possible to run a new scan. Max scan limit reached.'
)
return
current_queued_scans = self.get_count_queued_scans()
if not current_queued_scans:
return

if not self.is_enough_free_memory():
logger.debug(
'Not possible to run a new scan. Not enough free memory.'
)
return
logger.info('Currently %d queued scans.', current_queued_scans)

if self.get_scan_status(scan_id) == ScanStatus.QUEUED:
for scan_id in self.scan_collection.ids_iterator():
scan_allowed = (
self.is_new_scan_allowed() and self.is_enough_free_memory()
)
scan_is_queued = self.get_scan_status(scan_id) == ScanStatus.QUEUED

if scan_is_queued and scan_allowed:
try:
self.scan_collection.unpickle_scan_info(scan_id)
except OspdCommandError as e:
Expand All @@ -1240,16 +1241,28 @@ def start_queued_scans(self) -> None:
scan_process.start()
self.set_scan_status(scan_id, ScanStatus.INIT)

current_queued_scans = current_queued_scans - 1
logger.info('Starting scan %s.', scan_id)
elif scan_is_queued and not scan_allowed:
return

def is_new_scan_allowed(self) -> bool:
""" Check if max_scans has been reached.

Return:
True if a new scan can be launch.
"""
if (self.max_scans == 0) or (len(self.scan_processes) < self.max_scans):
return True
if (self.max_scans != 0) and (
len(self.scan_processes) >= self.max_scans
):
logger.info(
'Not possible to run a new scan. Max scan limit set '
'to %d reached.',
self.max_scans,
)
return False

return False
return True

def is_enough_free_memory(self) -> bool:
""" Check if there is enough free memory in the system to run
Expand All @@ -1262,11 +1275,18 @@ def is_enough_free_memory(self) -> bool:
if not self.min_free_mem_scan_queue:
return True

free_mem = psutil.virtual_memory().free
free_mem = psutil.virtual_memory().free / (1024 * 1024)

if (free_mem / (1024 * 1024)) > self.min_free_mem_scan_queue:
if free_mem > self.min_free_mem_scan_queue:
return True

logger.info(
'Not possible to run a new scan. Not enough free memory. '
'Only %d MB available but at least %d are required',
free_mem,
self.min_free_mem_scan_queue,
)

return False

def scheduler(self):
Expand Down
2 changes: 1 addition & 1 deletion ospd/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def __init__(self, description: str) -> None:
parser.add_argument(
'-L',
'--log-level',
default='WARNING',
default='INFO',
type=self.log_level,
help='Wished level of logging. Default: %(default)s',
)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_argument_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def test_defaults(self):

self.assertEqual(args.key_file, DEFAULT_KEY_FILE)
self.assertEqual(args.niceness, DEFAULT_NICENESS)
self.assertEqual(args.log_level, logging.WARNING)
self.assertEqual(args.log_level, logging.INFO)
self.assertEqual(args.address, DEFAULT_ADDRESS)
self.assertEqual(args.port, DEFAULT_PORT)
self.assertEqual(args.scaninfo_store_time, DEFAULT_SCANINFO_STORE_TIME)
Expand Down