From ffd659b658b0046db7f296e0c510a9a7a23d9ba0 Mon Sep 17 00:00:00 2001
From: Jan Kaluza <jkaluza@redhat.com>
Date: May 17 2018 09:03:24 +0000
Subject: Support creating per-thread CCACHE file. Use krb_context() in Errata class.


---

diff --git a/conf/config.py b/conf/config.py
index 0630e68..e3384c3 100644
--- a/conf/config.py
+++ b/conf/config.py
@@ -322,6 +322,7 @@ class TestConfiguration(BaseConfiguration):
         },
     }
 
+    KRB_AUTH_CCACHE_FILE = "freshmaker_cc_$pid_$tid"
 
 class ProdConfiguration(BaseConfiguration):
     pass
diff --git a/freshmaker/config.py b/freshmaker/config.py
index 4964ef5..abf7f9c 100644
--- a/freshmaker/config.py
+++ b/freshmaker/config.py
@@ -26,6 +26,7 @@
 
 import imp
 import os
+import threading
 
 from os import sys
 from freshmaker import logger
@@ -305,7 +306,9 @@ class Config(object):
         'krb_auth_ccache_file': {
             'type': str,
             'default': '',
-            'desc': 'Path to credential cache file.'},
+            'desc': 'Path to credential cache file. '
+                    'The "$pid" is replaced by process ID. '
+                    'The "$tid" is replaced by thread ID'},
         'oidc_base_namespace': {
             'type': str,
             'default': 'https://pagure.io/freshmaker/',
@@ -360,7 +363,11 @@ class Config(object):
             setx = lambda self, val: getattr(self, setifok_func)(val)
         else:
             setx = lambda self, val: setattr(self, "_" + key, val)
-        getx = lambda self: getattr(self, "_" + key)
+        get_func = '_get_{}'.format(key)
+        if hasattr(self, get_func):
+            getx = lambda self: getattr(self, get_func)()
+        else:
+            getx = lambda self: getattr(self, "_" + key)
         delx = lambda self: delattr(self, "_" + key)
         setattr(Config, key, property(getx, setx, delx))
 
@@ -414,3 +421,13 @@ class Config(object):
         if s not in ("fedmsg", "amq", "in_memory", "rhmsg"):
             raise ValueError("Unsupported messaging system.")
         self._messaging_sender = s
+
+    def _get_krb_auth_ccache_file(self):
+        if not self._krb_auth_ccache_file:
+            return self._krb_auth_ccache_file
+        ccache_file = str(self._krb_auth_ccache_file)
+        ccache_file = ccache_file.replace(
+            "$tid", str(threading.current_thread().ident))
+        ccache_file = ccache_file.replace(
+            "$pid", str(os.getpid()))
+        return ccache_file
diff --git a/freshmaker/errata.py b/freshmaker/errata.py
index f3f290c..b33fa7b 100644
--- a/freshmaker/errata.py
+++ b/freshmaker/errata.py
@@ -30,6 +30,7 @@ from freshmaker.events import (
     FreshmakerManualRebuildEvent)
 from freshmaker import conf, log
 from freshmaker.security_data import SecurityDataAPI
+from freshmaker.utils import krb_context
 
 
 class ErrataAdvisory(object):
@@ -122,10 +123,11 @@ class Errata(object):
 
         Document: /developer-guide/api-http-api.html
         """
-        r = requests.get("%s/%s/%s" % (self.server_url,
-                                       self._rest_api_ver,
-                                       endpoint.lstrip('/')),
-                         auth=HTTPKerberosAuth())
+        with krb_context():
+            r = requests.get("%s/%s/%s" % (self.server_url,
+                                           self._rest_api_ver,
+                                           endpoint.lstrip('/')),
+                             auth=HTTPKerberosAuth())
         r.raise_for_status()
         return r.json()
 
@@ -134,8 +136,9 @@ class Errata(object):
 
         See also Legacy section in /developer-guide/api-http-api.html
         """
-        r = requests.get('{}/{}'.format(self.server_url, endpoint),
-                         auth=HTTPKerberosAuth())
+        with krb_context():
+            r = requests.get('{}/{}'.format(self.server_url, endpoint),
+                             auth=HTTPKerberosAuth())
         r.raise_for_status()
         return r.json()
 
diff --git a/freshmaker/kojiservice.py b/freshmaker/kojiservice.py
index f2b1895..8d11ae0 100644
--- a/freshmaker/kojiservice.py
+++ b/freshmaker/kojiservice.py
@@ -93,7 +93,8 @@ class KojiService(object):
         # No need to login on dry run, this makes dry run much faster.
         if not self.dry_run:
             self.session.krb_login(principal=conf.krb_auth_principal,
-                                   keytab=conf.krb_auth_client_keytab)
+                                   keytab=conf.krb_auth_client_keytab,
+                                   ccache=conf.krb_auth_ccache_file)
         else:
             log.info("DRY RUN: Skipping login in dry run mode.")
 

