From d574844d17184496f7381f921cf5e53afcbc0d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Tue, 10 Dec 2019 11:28:03 +0000 Subject: [PATCH] add timeout when downloading repositories --- nur/prefetch.py | 21 ++++++++++++++------- nur/update.py | 4 ++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/nur/prefetch.py b/nur/prefetch.py index fc077accf..4c175c4ed 100644 --- a/nur/prefetch.py +++ b/nur/prefetch.py @@ -5,7 +5,7 @@ import urllib.error import urllib.request import xml.etree.ElementTree as ET from pathlib import Path -from typing import Optional, Tuple, List +from typing import List, Optional, Tuple from urllib.parse import urljoin, urlparse from .error import NurError @@ -73,15 +73,22 @@ def prefetch_git(repo: Repo) -> Tuple[LockedVersion, Path]: if repo.submodules: cmd += ["--fetch-submodules"] cmd += [repo.url.geturl()] - result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if result.returncode != 0: - stderr = result.stderr.decode("utf-8") + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + stdout, stderr = proc.communicate(timeout=30) + except subprocess.TimeoutExpired: + proc.kill() raise NurError( - f"Failed to prefetch git repository {repo.url.geturl()}: {stderr}" + f"Timeout expired while prefetching git repository {repo.url.geturl()}" ) - metadata = json.loads(result.stdout) - lines = result.stderr.decode("utf-8").split("\n") + if proc.returncode != 0: + raise NurError( + f"Failed to prefetch git repository {repo.url.geturl()}: {stderr.decode('utf-8')}" + ) + + metadata = json.loads(stdout) + lines = stderr.decode("utf-8").split("\n") repo_path = re.search("path is (.+)", lines[-5]) assert repo_path is not None path = Path(repo_path.group(1)) diff --git a/nur/update.py b/nur/update.py index 1cc7202d0..8a394b10b 100644 --- a/nur/update.py +++ b/nur/update.py @@ -78,12 +78,12 @@ def update_command(args: Namespace) -> None: for repo in manifest.repos: try: update(repo) - except EvalError as e: + except EvalError as err: if repo.locked_version is None: # likely a repository added in a pull request, make it fatal then raise # Do not print stack traces - logger.error(f"repository {repo.name} failed to evaluate: {e}") + logger.error(f"repository {repo.name} failed to evaluate: {err}") except Exception: # for non-evaluation errors we want the stack trace logger.exception(f"Failed to updated repository {repo.name}")