diff --git a/Makefile.am b/Makefile.am
index 3314aa2fe492ec15e906abb6a48b49cdbd33eb4c..f9b4a9415a95487be6ef3d3297e3512447e84a13 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1640,7 +1640,10 @@ endif
 
 .PHONY: py-coverage
 py-coverage: $(GENERATED_FILES) $(python_tests)
+	@test -n "$(PYCOVERAGE)" || \
+	    { echo 'python-coverage' not found during configure; exit 1; }
 	set -e; \
+	COVERAGE=$(PYCOVERAGE) \
 	COVERAGE_FILE=$(CURDIR)/$(COVERAGE_PY_DIR)/data \
 	TEXT_COVERAGE=$(CURDIR)/$(COVERAGE_PY_DIR)/report.txt \
 	HTML_COVERAGE=$(CURDIR)/$(COVERAGE_PY_DIR) \
diff --git a/autotools/gen-coverage b/autotools/gen-coverage
index ab16cc51303b5c7a60339befb101a40c520b120c..38bdd38b8d987d78f686bd749c4b8c03cc8923b6 100755
--- a/autotools/gen-coverage
+++ b/autotools/gen-coverage
@@ -21,10 +21,11 @@
 set -e
 set -u
 
-: ${COVERAGE:=coverage}
 : ${PYTHON:=python}
+: ${COVERAGE:?}
 : ${COVERAGE_FILE:?}
 : ${TEXT_COVERAGE:?}
+: ${HTML_COVERAGE:=}
 : ${GANETI_TEMP_DIR:?}
 
 reportargs=(
@@ -34,6 +35,16 @@ reportargs=(
 
 $COVERAGE erase
 
+if [[ -n "$HTML_COVERAGE" ]]; then
+  if [[ ! -d "$HTML_COVERAGE" ]]; then
+    echo "Not a directory: $HTML_COVERAGE" >&2
+    exit 1
+  fi
+
+  # At least coverage 3.4 fails to overwrite files
+  find "$HTML_COVERAGE" \( -type f -o -type l \) -delete
+fi
+
 for script; do
   if [[ "$script" == *-runasroot.py ]]; then
     if [[ -z "$FAKEROOT" ]]; then
diff --git a/configure.ac b/configure.ac
index 3d7eaa34364644c291c0c55f73190f01d0e868eb..da464152b67603f34e5010cf3901c6a25a906c8f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -373,7 +373,16 @@ if test -z "$PEP8"
 then
   AC_MSG_WARN([pep8 not found, checking code will not be complete])
 fi
-AM_CONDITIONAL([HAS_PEP8], [test "$PEP8"])
+AM_CONDITIONAL([HAS_PEP8], [test -n "$PEP8"])
+
+# Check for python-coverage
+AC_ARG_VAR(PYCOVERAGE, [python-coverage path])
+AC_PATH_PROGS(PYCOVERAGE, [python-coverage coverage], [])
+if test -z "$PYCOVERAGE"
+then
+  AC_MSG_WARN(m4_normalize([python-coverage or coverage not found, evaluating
+                            Python test coverage will not be possible]))
+fi
 
 # Check for socat
 AC_ARG_VAR(SOCAT, [socat path])