diff --git a/frigate/record/maintainer.py b/frigate/record/maintainer.py index 814611df0..99f9acc0a 100644 --- a/frigate/record/maintainer.py +++ b/frigate/record/maintainer.py @@ -620,6 +620,7 @@ class RecordingMaintainer(threading.Thread): if p.returncode != 0: logger.error(f"Unable to convert {cache_path} to {file_path}") logger.error((await p.stderr.read()).decode("ascii")) + Path(file_path).unlink(missing_ok=True) return None else: logger.debug( diff --git a/frigate/storage.py b/frigate/storage.py index da5783263..9f92ceb7b 100644 --- a/frigate/storage.py +++ b/frigate/storage.py @@ -205,6 +205,8 @@ class StorageMaintainer(threading.Thread): bandwidth_per_path: dict[str, float] = {} for camera, stats in self.camera_storage_stats.items(): + if camera not in self.config.cameras: + continue path = self.config.get_camera_recordings_path(camera) bandwidth_per_path[path] = bandwidth_per_path.get(path, 0) + stats.get( "bandwidth", 0 @@ -212,24 +214,25 @@ class StorageMaintainer(threading.Thread): return bandwidth_per_path - def check_storage_needs_cleanup(self) -> str | None: - """Return recordings root path that needs cleanup, if any.""" + def check_storage_needs_cleanup(self, recordings_root: str) -> bool: + """Return True if the given recordings root path needs cleanup.""" # currently runs cleanup if less than 1 hour of space is left # disk_usage should not spin up disks - for path, hourly_bandwidth in self._get_path_bandwidths().items(): - try: - remaining_storage = round(shutil.disk_usage(path).free / pow(2, 20), 1) - except (FileNotFoundError, OSError): - continue - - logger.debug( - f"Storage cleanup check: {hourly_bandwidth} hourly with remaining storage: {remaining_storage} for path {path}." + hourly_bandwidth = self._get_path_bandwidths().get(recordings_root, 0) + if not hourly_bandwidth: + return False + try: + remaining_storage = round( + shutil.disk_usage(recordings_root).free / pow(2, 20), 1 ) + except (FileNotFoundError, OSError): + return False - if remaining_storage < hourly_bandwidth: - return path + logger.debug( + f"Storage cleanup check: {hourly_bandwidth} hourly with remaining storage: {remaining_storage} for path {recordings_root}." + ) - return None + return remaining_storage < hourly_bandwidth def reduce_storage_consumption(self, recordings_root: str) -> None: """Remove oldest hour of recordings.""" @@ -403,11 +406,11 @@ class StorageMaintainer(threading.Thread): self.calculate_camera_bandwidth() logger.debug(f"Default camera bandwidths: {self.camera_storage_stats}.") - cleanup_root = self.check_storage_needs_cleanup() - if cleanup_root: - logger.info( - f"Less than 1 hour of recording space left for {cleanup_root}, running storage maintenance..." - ) - self.reduce_storage_consumption(cleanup_root) + for recordings_root in self.config.get_recordings_paths(): + if self.check_storage_needs_cleanup(recordings_root): + logger.info( + f"Less than 1 hour of recording space left for {recordings_root}, running storage maintenance..." + ) + self.reduce_storage_consumption(recordings_root) logger.info("Exiting storage maintainer...")