From 20097801986f92fb74116cc76db2fd310c9fdb2e Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Apr 04 2017 17:45:53 +0000
Subject: [PATCH 1/5] fall back to old behavior if hub doesn't understand all_volumes option


Fixes #366

---

diff --git a/cli/koji b/cli/koji
index 9ac3bac..2ec3c2a 100755
--- a/cli/koji
+++ b/cli/koji
@@ -508,7 +508,7 @@ def watch_logs(session, tasklist, opts):
             if _isDone(session, task_id):
                 tasklist.remove(task_id)
 
-            output = session.listTaskOutput(task_id, all_volumes=True)
+            output = list_task_output_all_volumes(session, task_id)
             # convert to list of (file, volume)
             files = []
             for filename, volumes in output.iteritems():
@@ -542,6 +542,19 @@ def watch_logs(session, tasklist, opts):
 
         time.sleep(options.poll_interval)
 
+
+def list_task_output_all_volumes(session, task_id):
+    """List task output with all volumes, or fake it"""
+    try:
+        return session.listTaskOutput(task_id, all_volumes=True)
+    except koji.GenericError, e:
+        if 'got an unexpected keyword argument' not in str(e):
+            raise
+    # otherwise leave off the option and fake it
+    output = session.listTaskOutput(task_id)
+    return dict([fn, ['DEFAULT']] for fn in output)
+
+
 def handle_add_group(options, session, args):
     "[admin] Add a group to a tag"
     usage = _("usage: %prog add-group <tag> <group>")
@@ -4690,7 +4703,7 @@ def _printTaskInfo(session, task_id, level=0, recurse=True, verbose=True):
     buildroot_infos = session.listBuildroots(taskID=task_id)
     build_info = session.listBuilds(taskID=task_id)
 
-    files = session.listTaskOutput(task_id, all_volumes=True)
+    files = list_task_output_all_volumes(session, task_id)
     logs = []
     output = []
     for filename in files:
@@ -6820,7 +6833,7 @@ def anon_handle_download_logs(options, session, args):
         task_info = session.getTaskInfo(task_id)
         if task_info is None:
             error(_("No such task id: %i" % task_id))
-        files = session.listTaskOutput(task_id, all_volumes=True)
+        files = list_task_output_all_volumes(session, task_id)
         logs = [] # list of tuples (filename, volume)
         for filename in files:
             if not filename.endswith(".log"):
@@ -7324,7 +7337,7 @@ def handle_runroot(options, session, args):
         print("User interrupt: canceling runroot task")
         session.cancelTask(task_id)
         raise
-    output = session.listTaskOutput(task_id, all_volumes=True)
+    output = list_task_output_all_volumes(session, task_id)
     if 'runroot.log' in output:
         for volume in output['runroot.log']:
             log = session.downloadTaskOutput(task_id, 'runroot.log', volume=volume)

From df416f7c3cd9a03a1c72a0c78accc8f429baca14 Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Apr 04 2017 21:48:59 +0000
Subject: [PATCH 2/5] missed one listTaskOutput call


---

diff --git a/cli/koji b/cli/koji
index 2ec3c2a..ca8631e 100755
--- a/cli/koji
+++ b/cli/koji
@@ -6921,7 +6921,7 @@ def anon_handle_download_task(options, session, args):
     downloads = []
 
     for task in downloadable_tasks:
-        files = session.listTaskOutput(task["id"], all_volumes=True)
+        files = list_task_output_all_volumes(session, task["id"])
         for filename in files:
             if filename.endswith(".log") and suboptions.logs:
                 for volume in files[filename]:

From 5231105478346aabc1702e8fd55fa61684173feb Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Apr 04 2017 21:50:55 +0000
Subject: [PATCH 3/5] only pass volume opt to downloadTaskOutput if needed


Fixes #368

---

diff --git a/koji/__init__.py b/koji/__init__.py
index 8509f80..8319cb2 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -2623,7 +2623,10 @@ class ClientSession(object):
         """
         if self.multicall:
             raise GenericError('downloadTaskOutput() may not be called during a multicall')
-        result = self.callMethod('downloadTaskOutput', taskID, fileName, offset=offset, size=size, volume=volume)
+        dlopts = {'offset': offset, 'size': size}
+        if volume and volume != 'DEFAULT':
+            dlopts['volume'] = volume
+        result = self.callMethod('downloadTaskOutput', taskID, fileName, **dlopts)
         return base64.decodestring(result)
 
 class DBHandler(logging.Handler):

From 649a6e710f87a689799afc4b554886c4858701fd Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Apr 05 2017 01:09:24 +0000
Subject: [PATCH 4/5] for volume compat fixes


---

diff --git a/koji/__init__.py b/koji/__init__.py
index 8319cb2..95f4fc7 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -2474,13 +2474,16 @@ class ClientSession(object):
         full_chksum = util.adler32_constructor()
         # cycle is need to run at least once (for empty files)
         first_cycle = True
+        callopts = {'overwrite': overwrite}
+        if volume and volume != 'DEFAULT':
+            callopts['volume'] = volume
         while True:
             lap = time.time()
             chunk = fo.read(blocksize)
             if not chunk and not first_cycle:
                 break
             first_cycle = False
-            result = self._callMethod('rawUpload', (chunk, ofs, path, name), {'overwrite':overwrite, 'volume': volume})
+            result = self._callMethod('rawUpload', (chunk, ofs, path, name), callopts)
             if self.retries > 1:
                 problems = True
             hexdigest = util.adler32_constructor(chunk).hexdigest()
@@ -2499,7 +2502,9 @@ class ClientSession(object):
                 callback(ofs, size, len(chunk), t1, t2)
         if ofs != size:
             self.logger.error("Local file changed size: %s, %s -> %s", localfile, size, ofs)
-        chk_opts = {'volume': volume}
+        chk_opts = {}
+        if volume and volume != 'DEFAULT':
+            chk_opts['volume'] = volume
         if problems:
             chk_opts['verify'] = 'adler32'
         result = self._callMethod('checkUpload', (path, name), chk_opts)
@@ -2549,9 +2554,13 @@ class ClientSession(object):
         if name is None:
             name = os.path.basename(localfile)
 
+        volopts = {}
+        if volume and volume != 'DEFAULT':
+            volopts['volume'] = volume
+
         # check if server supports fast upload
         try:
-            self._callMethod('checkUpload', (path, name), {'volume': volume})
+            self._callMethod('checkUpload', (path, name), volopts)
             # fast upload was introduced in 1.7.1, earlier servers will not
             # recognise this call and return an error
         except GenericError:
@@ -2590,7 +2599,7 @@ class ClientSession(object):
             while True:
                 if debug:
                     self.logger.debug("uploadFile(%r,%r,%r,%r,%r,...)" %(path, name, sz, digest, offset))
-                if self.callMethod('uploadFile', path, name, encode_int(sz), digest, encode_int(offset), data, volume=volume):
+                if self.callMethod('uploadFile', path, name, encode_int(sz), digest, encode_int(offset), data, *volopts):
                     break
                 if tries <= retries:
                     tries += 1

From 0189cf98eaeb201d7e2286d0c6ff60d6d0b19a9c Mon Sep 17 00:00:00 2001
From: Mike McLean <mikem@redhat.com>
Date: Apr 05 2017 16:29:23 +0000
Subject: [PATCH 5/5] typo


---

diff --git a/koji/__init__.py b/koji/__init__.py
index 95f4fc7..cf21abd 100644
--- a/koji/__init__.py
+++ b/koji/__init__.py
@@ -2599,7 +2599,7 @@ class ClientSession(object):
             while True:
                 if debug:
                     self.logger.debug("uploadFile(%r,%r,%r,%r,%r,...)" %(path, name, sz, digest, offset))
-                if self.callMethod('uploadFile', path, name, encode_int(sz), digest, encode_int(offset), data, *volopts):
+                if self.callMethod('uploadFile', path, name, encode_int(sz), digest, encode_int(offset), data, **volopts):
                     break
                 if tries <= retries:
                     tries += 1

