Blame SOURCES/0054-v2v-o-rhv-upload-Log-full-imageio-response-on-failur.patch

e9bfca
From ed2835440ba7d1a4bc4f9aeb92a14c644522bbfd Mon Sep 17 00:00:00 2001
e9bfca
From: "Richard W.M. Jones" <rjones@redhat.com>
e9bfca
Date: Tue, 5 Jun 2018 13:27:43 +0100
e9bfca
Subject: [PATCH] v2v: -o rhv-upload: Log full imageio response on failure.
e9bfca
e9bfca
Thanks: Nir Soffer
e9bfca
(cherry picked from commit 831a75cd11c5a87e40fccdadcb62353f6a4d5a72)
e9bfca
---
e9bfca
 v2v/rhv-upload-plugin.py | 69 ++++++++++++++++++++++++----------------
e9bfca
 1 file changed, 42 insertions(+), 27 deletions(-)
e9bfca
e9bfca
diff --git a/v2v/rhv-upload-plugin.py b/v2v/rhv-upload-plugin.py
e9bfca
index 9ad354b84..7c5084efd 100644
e9bfca
--- a/v2v/rhv-upload-plugin.py
e9bfca
+++ b/v2v/rhv-upload-plugin.py
e9bfca
@@ -227,6 +227,32 @@ def can_flush(h):
e9bfca
 def get_size(h):
e9bfca
     return params['disk_size']
e9bfca
 
e9bfca
+# Any unexpected HTTP response status from the server will end up
e9bfca
+# calling this function which logs the full error, pauses the
e9bfca
+# transfer, sets the failed state, and raises a RuntimeError
e9bfca
+# exception.
e9bfca
+def request_failed(h, r, msg):
e9bfca
+    # Setting the failed flag in the handle causes the disk to be
e9bfca
+    # cleaned up on close.
e9bfca
+    h['failed'] = True
e9bfca
+    h['transfer_service'].pause()
e9bfca
+
e9bfca
+    status = r.status
e9bfca
+    reason = r.reason
e9bfca
+    try:
e9bfca
+        body = r.read()
e9bfca
+    except EnvironmentError as e:
e9bfca
+        body = "(Unable to read response body: %s)" % e
e9bfca
+
e9bfca
+    # Log the full error if we're verbose.
e9bfca
+    debug("unexpected response from imageio server:")
e9bfca
+    debug(msg)
e9bfca
+    debug("%d: %s" % (status, reason))
e9bfca
+    debug(body)
e9bfca
+
e9bfca
+    # Only a short error is included in the exception.
e9bfca
+    raise RuntimeError("%s: %d %s: %r", msg, status, reason, body[:200])
e9bfca
+
e9bfca
 # For documentation see:
e9bfca
 # https://github.com/oVirt/ovirt-imageio/blob/master/docs/random-io.md
e9bfca
 # For examples of working code to read/write from the server, see:
e9bfca
@@ -247,16 +273,14 @@ def pread(h, count, offset):
e9bfca
     r = http.getresponse()
e9bfca
     # 206 = HTTP Partial Content.
e9bfca
     if r.status != 206:
e9bfca
-        h['transfer_service'].pause()
e9bfca
-        h['failed'] = True
e9bfca
-        raise RuntimeError("could not read sector (%d, %d): %d: %s" %
e9bfca
-                           (offset, count, r.status, r.reason))
e9bfca
+        request_failed(h, r,
e9bfca
+                       "could not read sector offset %d size %d" %
e9bfca
+                       (offset, count))
e9bfca
     return r.read()
e9bfca
 
e9bfca
 def pwrite(h, buf, offset):
e9bfca
     http = h['http']
e9bfca
     transfer = h['transfer']
e9bfca
-    transfer_service = h['transfer_service']
e9bfca
 
e9bfca
     count = len(buf)
e9bfca
     h['highestwrite'] = max(h['highestwrite'], offset+count)
e9bfca
@@ -274,15 +298,13 @@ def pwrite(h, buf, offset):
e9bfca
 
e9bfca
     r = http.getresponse()
e9bfca
     if r.status != 200:
e9bfca
-        transfer_service.pause()
e9bfca
-        h['failed'] = True
e9bfca
-        raise RuntimeError("could not write sector (%d, %d): %d: %s" %
e9bfca
-                           (offset, count, r.status, r.reason))
e9bfca
+        request_failed(h, r,
e9bfca
+                       "could not write sector offset %d size %d" %
e9bfca
+                       (offset, count))
e9bfca
 
e9bfca
 def zero(h, count, offset, may_trim):
e9bfca
     http = h['http']
e9bfca
     transfer = h['transfer']
e9bfca
-    transfer_service = h['transfer_service']
e9bfca
 
e9bfca
     # Unlike the trim and flush calls, there is no 'can_zero' method
e9bfca
     # so nbdkit could call this even if the server doesn't support
e9bfca
@@ -304,10 +326,9 @@ def zero(h, count, offset, may_trim):
e9bfca
 
e9bfca
     r = http.getresponse()
e9bfca
     if r.status != 200:
e9bfca
-        transfer_service.pause()
e9bfca
-        h['failed'] = True
e9bfca
-        raise RuntimeError("could not zero sector (%d, %d): %d: %s" %
e9bfca
-                           (offset, count, r.status, r.reason))
e9bfca
+        request_failed(h, r,
e9bfca
+                       "could not zero sector offset %d size %d" %
e9bfca
+                       (offset, count))
e9bfca
 
e9bfca
 def emulate_zero(h, count, offset):
e9bfca
     # qemu-img convert starts by trying to zero/trim the whole device.
e9bfca
@@ -332,15 +353,13 @@ def emulate_zero(h, count, offset):
e9bfca
 
e9bfca
         r = http.getresponse()
e9bfca
         if r.status != 200:
e9bfca
-            transfer_service.pause()
e9bfca
-            h['failed'] = True
e9bfca
-            raise RuntimeError("could not write zeroes (%d, %d): %d: %s" %
e9bfca
-                               (offset, count, r.status, r.reason))
e9bfca
+            request_failed(h, r,
e9bfca
+                           "could not write zeroes offset %d size %d" %
e9bfca
+                           (offset, count))
e9bfca
 
e9bfca
 def trim(h, count, offset):
e9bfca
     http = h['http']
e9bfca
     transfer = h['transfer']
e9bfca
-    transfer_service = h['transfer_service']
e9bfca
 
e9bfca
     # Construct the JSON request for trimming.
e9bfca
     buf = json.dumps({'op': "trim",
e9bfca
@@ -355,15 +374,13 @@ def trim(h, count, offset):
e9bfca
 
e9bfca
     r = http.getresponse()
e9bfca
     if r.status != 200:
e9bfca
-        transfer_service.pause()
e9bfca
-        h['failed'] = True
e9bfca
-        raise RuntimeError("could not trim sector (%d, %d): %d: %s" %
e9bfca
-                           (offset, count, r.status, r.reason))
e9bfca
+        request_failed(h, r,
e9bfca
+                       "could not trim sector offset %d size %d" %
e9bfca
+                       (offset, count))
e9bfca
 
e9bfca
 def flush(h):
e9bfca
     http = h['http']
e9bfca
     transfer = h['transfer']
e9bfca
-    transfer_service = h['transfer_service']
e9bfca
 
e9bfca
     # Construct the JSON request for flushing.
e9bfca
     buf = json.dumps({'op': "flush"}).encode()
e9bfca
@@ -375,9 +392,7 @@ def flush(h):
e9bfca
 
e9bfca
     r = http.getresponse()
e9bfca
     if r.status != 200:
e9bfca
-        transfer_service.pause()
e9bfca
-        h['failed'] = True
e9bfca
-        raise RuntimeError("could not flush: %d: %s" % (r.status, r.reason))
e9bfca
+        request_failed(h, r, "could not flush")
e9bfca
 
e9bfca
 def delete_disk_on_failure(h):
e9bfca
     disk_service = h['disk_service']
e9bfca
-- 
8ff76f
2.20.1
e9bfca