Changeset View
Changeset View
Standalone View
Standalone View
swh/loader/core/utils.py
# Copyright (C) 2018 The Software Heritage developers | # Copyright (C) 2018-2021 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import os | import os | ||||
import shutil | import shutil | ||||
import psutil | import psutil | ||||
def clean_dangling_folders(dirpath, pattern_check, log=None): | def clean_dangling_folders(dirpath: str, pattern_check: str, log=None) -> None: | ||||
"""Clean up potential dangling temporary working folder rooted at | """Clean up potential dangling temporary working folder rooted at `dirpath`. Those | ||||
`dirpath`. Those folders must match a dedicated pattern and not | folders must match a dedicated pattern and not belonging to a live pid. | ||||
belonging to a live pid. | |||||
Args: | Args: | ||||
dirpath (str): Path to check for dangling files | dirpath: Path to check for dangling files | ||||
pattern_check (str): A dedicated pattern to check on first | pattern_check: A dedicated pattern to check on first level directory (e.g | ||||
level directory (e.g `swh.loader.mercurial.`, | `swh.loader.mercurial.`, `swh.loader.svn.`) | ||||
`swh.loader.svn.`) | |||||
log (Logger): Optional logger | log (Logger): Optional logger | ||||
""" | """ | ||||
if not os.path.exists(dirpath): | if not os.path.exists(dirpath): | ||||
return | return | ||||
for filename in os.listdir(dirpath): | for filename in os.listdir(dirpath): | ||||
path_to_cleanup = os.path.join(dirpath, filename) | path_to_cleanup = os.path.join(dirpath, filename) | ||||
try: | try: | ||||
# pattern: `swh.loader.svn-pid.{noise}` | # pattern: `swh.loader.{loader-type}-pid.{noise}` | ||||
if ( | if ( | ||||
pattern_check not in filename or "-" not in filename | pattern_check not in filename or "-" not in filename | ||||
): # silently ignore unknown patterns | ): # silently ignore unknown patterns | ||||
continue | continue | ||||
_, pid = filename.split("-") | _, pid_ = filename.split("-") | ||||
pid = int(pid.split(".")[0]) | pid = int(pid_.split(".")[0]) | ||||
if psutil.pid_exists(pid): | if psutil.pid_exists(pid): | ||||
if log: | if log: | ||||
log.debug("PID %s is live, skipping" % pid) | log.debug("PID %s is live, skipping", pid) | ||||
continue | continue | ||||
# could be removed concurrently, so check before removal | # could be removed concurrently, so check before removal | ||||
if os.path.exists(path_to_cleanup): | if os.path.exists(path_to_cleanup): | ||||
shutil.rmtree(path_to_cleanup) | shutil.rmtree(path_to_cleanup) | ||||
except Exception as e: | except Exception as e: | ||||
if log: | if log: | ||||
msg = "Fail to clean dangling path %s: %s" % (path_to_cleanup, e) | log.warn("Fail to clean dangling path %s: %s", path_to_cleanup, e) | ||||
log.warn(msg) |