Add locks to cache and cleanup kinit logic
After reviewing reports of multiple CCache cropping up in logs, we found an issue in the way novajoin is initiating and updating cache files containing keytabs. The result was numerous extra cache files being created and overwritten. With this change we ensure that the credentials cache is properly shared across workers and that when new credentials are being created, the cache files are locked to avoid potential conflicts. Updates DEBUG level logging to include useful cache troubleshooting breadcrumbs. Change-Id: I07e0004f77e0d52ab2a2707c5fe50f48f718b717 Co-Authored-By: Ade Lee <alee@redhat.com>
This commit is contained in:
parent
e418762753
commit
a278acc7b2
@ -15,6 +15,7 @@
|
||||
import cachetools
|
||||
import json
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
import uuid
|
||||
|
||||
@ -53,6 +54,8 @@ CONF = cfg.CONF
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
CCACHE_LOCK = threading.RLock()
|
||||
|
||||
|
||||
class IPANovaJoinBase(object):
|
||||
|
||||
@ -63,15 +66,33 @@ class IPANovaJoinBase(object):
|
||||
self.ntries = CONF.connect_retries
|
||||
self.retry_delay = CONF.retry_delay
|
||||
self.initial_backoff = CONF.connect_backoff
|
||||
self.ccache = "MEMORY:" + str(uuid.uuid4())
|
||||
LOG.debug("cache: %s", self.ccache)
|
||||
os.environ['KRB5CCNAME'] = self.ccache
|
||||
|
||||
if self._ipa_client_configured() and not api.isdone('finalize'):
|
||||
self.ccache = "MEMORY:" + str(uuid.uuid4())
|
||||
os.environ['KRB5CCNAME'] = self.ccache
|
||||
(hostname, realm) = self.get_host_and_realm()
|
||||
LOG.debug("Establishing new ccache for ipalib API...")
|
||||
kinit_keytab(str('nova/%s@%s' % (hostname, realm)),
|
||||
CONF.keytab, self.ccache)
|
||||
api.bootstrap(context='novajoin')
|
||||
api.finalize()
|
||||
|
||||
LOG.debug("hr -- testing start")
|
||||
LOG.debug("hash of self: %s, hash of API: %s",
|
||||
str(hash(self)), str(hash(api)))
|
||||
LOG.debug("hr -- testting stop")
|
||||
# NOTE(hrybacki): Functional tests will raise an AttributeError
|
||||
# when run. This ensures upstream gates run while
|
||||
# still dumping useful debug logs under normal
|
||||
# operations.
|
||||
try:
|
||||
LOG.debug("Cache: %s -- PID: %s -- API hash: %s",
|
||||
self.ccache, os.getpid(), str(hash(api)))
|
||||
except AttributeError:
|
||||
LOG.debug("Failed to access ccache in IPANovaJoinBase init. If "
|
||||
"this happened outside of a functional test run, "
|
||||
"please investigate further.")
|
||||
|
||||
self.batch_args = list()
|
||||
self.backoff = self.initial_backoff
|
||||
|
||||
@ -158,15 +179,23 @@ class IPANovaJoinBase(object):
|
||||
errors.TicketExpired,
|
||||
errors.KerberosError) as e:
|
||||
tries += 1
|
||||
LOG.debug("[%s] kinit again: %s", message_id, e)
|
||||
|
||||
# pylint: disable=no-member
|
||||
LOG.debug("[%s] kinit new ccache in get_connection: %s",
|
||||
message_id, e)
|
||||
CCACHE_LOCK.acquire()
|
||||
try:
|
||||
kinit_keytab(str('nova/%s@%s' %
|
||||
(api.env.host, api.env.realm)),
|
||||
CONF.keytab,
|
||||
self.ccache)
|
||||
CCACHE_LOCK.release()
|
||||
LOG.debug("[%s] Cache: %s -- PID: %s -- API hash: %s",
|
||||
message_id, self.ccache, os.getpid(),
|
||||
str(hash(api)))
|
||||
except GSSError as e:
|
||||
LOG.debug("[%s] kinit failed: %s", message_id, e)
|
||||
CCACHE_LOCK.release()
|
||||
if self.backoff:
|
||||
self.__backoff(message_id)
|
||||
except errors.NetworkError:
|
||||
|
Loading…
Reference in New Issue
Block a user