Save the configuration to the shared configuration JSON file. Holds _config_lock so concurrent writers to self.config can't change the dict mid-serialization (would raise "dictionary changed size during iteration"). Serializes a shallow snapshot to keep the lock wind
(self)
| 1550 | csvwriter.writerow(['Total Open Ports', 'Alive Hosts Count', 'All Known Hosts Count', 'Vulnerabilities Count']) |
| 1551 | csvwriter.writerow([0, 0, 0, 0]) |
| 1552 | logger.info(f"Created live status file at {self.livestatusfile}") |
| 1553 | else: |
| 1554 | logger.info(f"Live status file already exists at {self.livestatusfile}") |
| 1555 | except OSError as e: |
| 1556 | logger.error(f"OS error occurred while creating live status file: {e}") |
| 1557 | except Exception as e: |
| 1558 | logger.error(f"Unexpected error occurred while creating live status file: {e}") |
| 1559 | |
| 1560 | |
| 1561 | def _generate_actions_json_if_needed(self): |
| 1562 | """Only regenerate actions.json if the action modules have changed. |
| 1563 | |
| 1564 | Compares the modification time of the actions directory against the |
| 1565 | existing actions.json file. If no .py file is newer, we also verify |
| 1566 | that every action .py has a corresponding entry in the JSON — a |
| 1567 | previous generation may have missed modules due to transient import |
| 1568 | errors (e.g. scanning.py failing once). |
| 1569 | """ |
| 1570 | try: |
| 1571 | if os.path.exists(self.actions_file): |
| 1572 | json_mtime = os.path.getmtime(self.actions_file) |
| 1573 | # Check if any action .py file is newer than actions.json |
| 1574 | needs_regen = False |
| 1575 | py_modules = set() |
| 1576 | for filename in os.listdir(self.actions_dir): |
| 1577 | if filename.endswith('.py') and filename != '__init__.py': |
| 1578 | py_modules.add(filename[:-3]) |
| 1579 | py_path = os.path.join(self.actions_dir, filename) |
| 1580 | if os.path.getmtime(py_path) > json_mtime: |
| 1581 | needs_regen = True |
| 1582 |
no test coverage detected