Merge branch 'byname' into sam_raet_50

This commit is contained in:
Samuel M Smith 2014-07-14 17:43:33 -06:00
commit e38491d710
4 changed files with 266 additions and 258 deletions

View File

@ -110,7 +110,7 @@ class SaltRaetRoadStackSetup(ioflo.base.deeding.Deed):
'local': {'ipath': 'local',
'ival': {'name': 'master',
'main': False,
'auto': True,
'auto': None,
'eid': 0,
'sigkey': None,
'prikey': None}},
@ -151,16 +151,18 @@ class SaltRaetRoadStackSetup(ioflo.base.deeding.Deed):
prikey=prikey)
txMsgs = self.txmsgs.value
rxMsgs = self.rxmsgs.value
safe = salting.SaltSafe(opts=self.opts.value)
keep = salting.SaltKeep(opts=self.opts.value,
basedirpath=basedirpath,
stackname=name,
auto=auto)
self.stack.value = RoadStack(
local=local,
store=self.store,
name=name,
auto=auto,
main=main,
basedirpath=basedirpath,
safe=safe,
keep=keep,
txMsgs=txMsgs,
rxMsgs=rxMsgs,
period=3.0,

View File

@ -7,6 +7,7 @@ salting.py module of salt specific interfaces to raet
# pylint: disable=W0611
# Import Python libs
import os
# Import ioflo libs
from ioflo.base.odicting import odict
@ -19,123 +20,95 @@ from raet.road.keeping import RoadKeep
from salt.key import RaetKey
class SaltSafe(object):
'''
Interface between Salt Key management and RAET keep key management
'''
LocalFields = ['sighex', 'prihex', 'auto']
RemoteFields = ['uid', 'name', 'acceptance', 'verhex', 'pubhex']
def __init__(self, opts, **kwa):
class SaltKeep(RoadKeep):
'''
RAET protocol estate on road data persistence for a given estate
road specific data
road/
keep/
stackname/
local/
estate.ext
remote/
estate.uid.ext
estate.uid.ext
'''
LocalFields = ['uid', 'name', 'ha', 'main', 'sid', 'neid', 'sighex', 'prihex', 'auto']
LocalDumpFields = ['uid', 'name', 'ha', 'main', 'sid', 'neid']
RemoteFields = ['uid', 'name', 'ha', 'sid', 'joined', 'acceptance', 'verhex', 'pubhex']
RemoteDumpFields = ['uid', 'name', 'ha', 'sid', 'joined']
Auto = False #auto accept
def __init__(self, opts, basedirpath='', auto=None, **kwa):
'''
Setup SaltSafe instance
Setup RoadKeep instance
'''
self.auto = opts['auto_accept']
self.dirpath = opts['pki_dir']
basedirpath = basedirpath or os.path.join(opts['cache_dir'], 'raet')
auto = auto if auto is not None else opts['auto_accept']
super(SaltKeep, self).__init__(basedirpath=basedirpath, auto=auto, **kwa)
self.saltRaetKey = RaetKey(opts)
def verifyLocalData(self, data):
'''
Returns True if the fields in .LocalFields match the fields in data
'''
return (set(self.LocalFields) == set(data.keys()))
def dumpLocalData(self, data):
'''
Dump the key data from the local estate
'''
self.saltRaetKey.write_local(data['prihex'], data['sighex'])
def loadLocalData(self):
'''
Load and Return the data from the local estate
'''
data = self.saltRaetKey.read_local()
data = super(SaltKeep, self).loadLocalData()
if not data:
return None
return (odict(sighex=data['sign'], prihex=data['priv'], auto=self.auto))
def clearLocalData(self):
'''
Load and Return the data from the local estate
'''
pass
def verifyRemoteData(self, data):
'''
Returns True if the fields in .RemoteFields match the fields in data
'''
return (set(self.RemoteFields) == set(data.keys()))
def dumpRemoteData(self, data, uid):
'''
Dump the data from the remote estate given by uid
'''
self.saltRaetKey.status(data['name'],
data['uid'],
data['pubhex'],
data['verhex'])
def loadAllRemoteData(self):
'''
Load and Return the data from the all the remote estate files
'''
data = odict()
for status, mids in self.saltRaetKey.list_keys().items():
for mid in mids:
keydata = self.saltRaetKey.read_remote(mid, status)
if keydata:
rdata = odict()
rdata['uid'] = keydata['device_id']
rdata['name'] = keydata['minion_id']
rdata['acceptance'] = raeting.ACCEPTANCES[status]
rdata['verhex'] = keydata['verify']
rdata['pubhex'] = keydata['pub']
data[str(rdata['uid'])] = rdata
srkdata = self.saltRaetKey.read_local()
if not srkdata:
srkdata = dict(sign=None, priv=None)
data.update(sighex=srkdata['sign'], prihex=srkdata['priv'], auto=self.auto)
return data
def clearAllRemoteData(self):
'''
Remove all the remote estate files
'''
self.saltRaetKey.delete_all()
def dumpLocal(self, local):
'''
Dump the key data from the local estate
Dump local estate
'''
data = odict([
('sighex', local.signer.keyhex),
('prihex', local.priver.keyhex),
('auto', self.auto),
('uid', local.uid),
('name', local.name),
('ha', local.ha),
('main', local.main),
('sid', local.sid),
('neid', local.neid),
])
if self.verifyLocalData(data):
if self.verifyLocalData(data, localFields = self.LocalDumpFields):
self.dumpLocalData(data)
self.saltRaetKey.write_local(local.priver.keyhex, local.signer.keyhex)
def dumpRemote(self, remote):
'''
Dump the data from the remote estate by calling status on it which
will persist the data
Dump remote estate
'''
data = odict([
('uid', remote.uid),
('name', remote.name),
('acceptance', remote.acceptance),
('verhex', remote.verfer.keyhex),
('pubhex', remote.pubber.keyhex),
('ha', remote.ha),
('sid', remote.sid),
('joined', remote.joined),
])
if self.verifyRemoteData(data):
if self.verifyRemoteData(data, remoteFields =self.RemoteDumpFields):
self.dumpRemoteData(data, remote.uid)
self.saltRaetKey.status(remote.name,
remote.uid,
remote.pubber.keyhex,
remote.verfer.keyhex)
def loadRemote(self, remote):
'''
Load and Return the data from the remote estate file
Override this in sub class to change uid
'''
#status = raeting.ACCEPTANCE_NAMES.get(remote.acceptance, 'accepted')
#status='accepted'
data = super(SaltKeep, self).loadRemote(remote)
if not data:
return None
mid = remote.name
statae = raeting.ACCEPTANCES.keys()
@ -147,20 +120,35 @@ class SaltSafe(object):
if not keydata:
return None
data = odict()
data['uid'] = keydata['device_id']
data['name'] = keydata['minion_id']
data['acceptance'] = raeting.ACCEPTANCES[status]
data['verhex'] = keydata['verify']
data['pubhex'] = keydata['pub']
data.update(acceptance=raeting.ACCEPTANCES[status],
verhex=keydata['verify'],
pubhex=keydata['pub'])
return data
def clearRemote(self, remote):
def loadAllRemoteData(self):
'''
Salt level keys should not be auto removed with cache changes
Load and Return the data from the all the remote estate files
'''
pass
data = super(SaltKeep, self).loadAllRemoteData()
for status, mids in self.saltRaetKey.list_keys().items():
for mid in mids:
keydata = self.saltRaetKey.read_remote(mid, status)
if keydata:
uid = str(keydata['device_id'])
if uid in data:
data[uid].update(acceptance=raeting.ACCEPTANCES[status],
verhex=keydata['verify'],
pubhex=keydata['pub'])
return data
def clearAllRemoteData(self):
'''
Remove all the remote estate files
'''
super(SaltKeep, self).clearAllRemoteData()
self.saltRaetKey.delete_all()
def replaceRemote(self, remote, old):
'''
@ -219,14 +207,11 @@ class SaltSafe(object):
mid = remote.name
self.saltRaetKey.accept(match=mid, include_rejected=True)
def clearAllKeepSafe(dirpath, opts):
def clearAllKeep(dirpath):
'''
Convenience function to clear all road and safe keep data in dirpath
Convenience function to clear all road keep data in dirpath
'''
road = RoadKeep(dirpath=dirpath)
road.clearLocalData()
road.clearAllRemoteData()
safe = SaltSafe(opts=opts)
safe.clearLocalData()
safe.clearAllRemoteData()

View File

@ -42,32 +42,18 @@ class BasicTestCase(unittest.TestCase):
self.store = storing.Store(stamp=0.0)
self.timer = StoreTimer(store=self.store, duration=1.0)
self.mainDirpath = tempfile.mkdtemp(prefix="salt", suffix='main', dir='/tmp')
opts = self.createOpts(self.mainDirpath, openMode=True, autoAccept=True)
self.mainSafe = salting.SaltSafe(opts=opts)
self.otherDirpath = tempfile.mkdtemp(prefix="salt", suffix='other', dir='/tmp')
opts = self.createOpts(self.otherDirpath, openMode=True, autoAccept=True)
self.otherSafe = salting.SaltSafe(opts=opts)
self.baseDirpath = tempfile.mkdtemp(prefix="raet", suffix="base", dir='/tmp')
self.tempDirpath = tempfile.mkdtemp(prefix="salt", suffix='keep', dir='/tmp')
def tearDown(self):
if os.path.exists(self.mainDirpath):
shutil.rmtree(self.mainDirpath)
if os.path.exists(self.tempDirpath):
shutil.rmtree(self.tempDirpath)
if os.path.exists(self.otherDirpath):
shutil.rmtree(self.otherDirpath)
if os.path.exists(self.baseDirpath):
shutil.rmtree(self.baseDirpath)
def createOpts(self, dirpath, openMode=False, autoAccept=True):
def createOpts(self, name, dirpath, openMode=False, autoAccept=True):
'''
Create associated pki directories for stack and return opts
'''
pkiDirpath = os.path.join(dirpath, 'pki')
pkiDirpath = os.path.join(dirpath, 'pki', name, 'raet')
if not os.path.exists(pkiDirpath):
os.makedirs(pkiDirpath)
@ -89,8 +75,8 @@ class BasicTestCase(unittest.TestCase):
print mode
os.chmod(localFilepath, mode | stat.S_IWUSR | stat.S_IWUSR)
cacheDirpath = os.path.join(dirpath, 'cache')
sockDirpath = os.path.join(dirpath, 'sock')
cacheDirpath = os.path.join(dirpath, 'cache', name)
sockDirpath = os.path.join(dirpath, 'sock', name)
opts = dict(
pki_dir=pkiDirpath,
@ -102,7 +88,7 @@ class BasicTestCase(unittest.TestCase):
)
return opts
def createRoadData(self, name, base):
def createRoadData(self, name, cachedirpath):
'''
Creates odict and populates with data to setup road stack
{
@ -116,7 +102,7 @@ class BasicTestCase(unittest.TestCase):
'''
data = odict()
data['name'] = name
data['dirpath'] = os.path.join(base, 'road', 'keep', name)
data['basedirpath'] = os.path.join(cachedirpath, 'raet')
signer = nacling.Signer()
data['sighex'] = signer.keyhex
data['verhex'] = signer.verhex
@ -126,7 +112,7 @@ class BasicTestCase(unittest.TestCase):
return data
def createRoadStack(self, data, eid=0, main=None, auto=None, ha=None, safe=None):
def createRoadStack(self, data, keep, eid=0, main=None, ha=None):
'''
Creates stack and local estate from data with
local estate.eid = eid
@ -148,10 +134,8 @@ class BasicTestCase(unittest.TestCase):
stack = stacking.RoadStack(name=data['name'],
local=local,
main=main,
dirpath=data['dirpath'],
store=self.store,
safe=safe,
auto=auto,)
keep=keep)
return stack
@ -201,35 +185,41 @@ class BasicTestCase(unittest.TestCase):
'''
console.terse("{0}\n".format(self.testBasic.__doc__))
self.assertEqual(self.mainSafe.loadLocalData(), None)
self.assertEqual(self.mainSafe.loadAllRemoteData(), {})
opts = self.createOpts(name='main',
dirpath=self.tempDirpath,
openMode=True,
autoAccept=True)
mainData = self.createRoadData(name='main', cachedirpath=opts['cachedir'] )
mainKeep = salting.SaltKeep(opts=opts,
basedirpath=mainData['basedirpath'],
stackname=mainData['name'])
dataMain = self.createRoadData(name='main', base=self.baseDirpath)
main = self.createRoadStack(data=dataMain,
self.assertEqual(mainKeep.loadLocalData(), None)
self.assertEqual(mainKeep.loadAllRemoteData(), {})
main = self.createRoadStack(data=mainData,
eid=1,
main=True,
ha=None, #default ha is ("", raeting.RAET_PORT)
safe=self.mainSafe)
keep=mainKeep)
console.terse("{0}\nkeep dirpath = {1}\nsafe dirpath = {2}\n".format(
main.name, main.keep.dirpath, main.safe.dirpath))
self.assertTrue(main.keep.dirpath.endswith('road/keep/main'))
self.assertTrue(main.safe.dirpath.endswith('pki'))
console.terse("{0}\nkeep dirpath = {1}\n".format(
main.name, main.keep.dirpath))
self.assertTrue(main.keep.dirpath.endswith('main/raet/main'))
self.assertTrue(main.local.ha, ("0.0.0.0", raeting.RAET_PORT))
self.assertTrue(main.safe.auto)
self.assertTrue(main.keep.auto)
self.assertDictEqual(main.keep.loadLocalData(), {'uid': 1,
'name': 'main',
'ha': ['0.0.0.0', 7530],
'main': True,
'sid': 0,
'stack': 'main',
'neid': 1,})
self.assertDictEqual(main.safe.loadLocalData(), {'prihex': dataMain['prihex'],
'sighex': dataMain['sighex'],
'auto': True})
'neid': 1,
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'auto': True,
})
data1 = self.createRoadData(name='remote1', base=self.baseDirpath)
data1 = self.createRoadData(name='remote1', cachedirpath=opts['cachedir'])
main.addRemote(estating.RemoteEstate(stack=main,
eid=3,
name=data1['name'],
@ -239,7 +229,7 @@ class BasicTestCase(unittest.TestCase):
period=main.period,
offset=main.offset, ))
data2 = self.createRoadData(name='remote2', base=self.baseDirpath)
data2 = self.createRoadData(name='remote2', cachedirpath=opts['cachedir'])
main.addRemote(estating.RemoteEstate(stack=main,
eid=4,
name=data2['name'],
@ -251,69 +241,78 @@ class BasicTestCase(unittest.TestCase):
main.dumpRemotes()
self.assertDictEqual(main.safe.loadAllRemoteData(),
self.assertDictEqual(main.keep.loadAllRemoteData(),
{'3':
{'uid': 3,
'name': data1['name'],
'ha': ['127.0.0.1', 7532],
'sid': 0,
'joined': None,
'acceptance': 1,
'verhex': data1['verhex'],
'pubhex': data1['pubhex']},
'4':
{'uid': 4,
'name': data2['name'],
'ha': ['127.0.0.1', 7533],
'sid': 0,
'joined': None,
'acceptance': 1,
'verhex': data2['verhex'],
'pubhex': data2['pubhex']}})
self.assertDictEqual(main.keep.loadAllRemoteData(),
{'3':
{'uid': 3,
'name': 'remote1',
'ha': ['127.0.0.1', 7532],
'sid': 0,
'joined': None,},
'4':
{'uid': 4,
'name': 'remote2',
'ha': ['127.0.0.1', 7533],
'sid': 0,
'joined': None,}})
# now recreate with saved data
main.server.close()
main = stacking.RoadStack(name='main',
dirpath=dataMain['dirpath'],
mainKeep = salting.SaltKeep(opts=opts,
basedirpath=mainData['basedirpath'],
stackname=mainData['name'])
main = stacking.RoadStack(name=mainData['name'],
store=self.store,
safe=self.mainSafe)
keep=mainKeep)
self.assertEqual(main.local.priver.keyhex, dataMain['prihex'])
self.assertEqual(main.local.signer.keyhex, dataMain['sighex'])
self.assertEqual(main.local.priver.keyhex, mainData['prihex'])
self.assertEqual(main.local.signer.keyhex, mainData['sighex'])
self.assertEqual(len(main.remotes.values()), 2)
self.assertEqual(self.otherSafe.loadLocalData(), None)
self.assertEqual(self.otherSafe.loadAllRemoteData(), {})
# other stack
opts = self.createOpts(name='other',
dirpath=self.tempDirpath,
openMode=True,
autoAccept=True)
otherData = self.createRoadData(name='other', cachedirpath=opts['cachedir'] )
otherKeep = salting.SaltKeep(opts=opts,
basedirpath=otherData['basedirpath'],
stackname=otherData['name'])
dataOther = self.createRoadData(name='other', base=self.baseDirpath)
other = self.createRoadStack(data=dataOther,
self.assertEqual(otherKeep.loadLocalData(), None)
self.assertEqual(otherKeep.loadAllRemoteData(), {})
other = self.createRoadStack(data=otherData,
eid=0,
main=None,
ha=("", raeting.RAET_TEST_PORT),
safe=self.otherSafe)
keep=otherKeep)
console.terse("{0} keep dirpath = {1} safe dirpath = {2}\n".format(
other.name, other.keep.dirpath, other.safe.dirpath))
self.assertTrue(other.keep.dirpath.endswith('road/keep/other'))
self.assertTrue(other.safe.dirpath.endswith('pki'))
console.terse("{0} keep dirpath = {1}\n".format(
other.name, other.keep.dirpath))
self.assertTrue(other.keep.dirpath.endswith('other/raet/other'))
self.assertEqual(other.local.ha, ("0.0.0.0", raeting.RAET_TEST_PORT))
self.assertDictEqual(other.safe.loadLocalData(), {'prihex': dataOther['prihex'],
'sighex': dataOther['sighex'],
'auto': True,})
self.assertDictEqual(other.keep.loadLocalData(),
{
'uid': 0,
'name': 'other',
'ha': ['0.0.0.0', 7531],
'main': None,
'sid': 0,
'neid': 1,
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'auto': True,
})
data3 = self.createRoadData(name='remote3', base=self.baseDirpath)
data3 = self.createRoadData(name='remote3', cachedirpath=opts['cachedir'])
other.addRemote(estating.RemoteEstate(stack=other,
eid=3,
name=data3['name'],
@ -323,7 +322,7 @@ class BasicTestCase(unittest.TestCase):
period=main.period,
offset=main.offset,))
data4 = self.createRoadData(name='remote4', base=self.baseDirpath)
data4 = self.createRoadData(name='remote4', cachedirpath=opts['cachedir'])
other.addRemote(estating.RemoteEstate(stack=other,
eid=4,
name=data4['name'],
@ -334,34 +333,31 @@ class BasicTestCase(unittest.TestCase):
offset=main.offset,))
other.dumpRemotes()
self.assertDictEqual(other.safe.loadAllRemoteData(),
{'3':
{'uid': 3,
'name': data3['name'],
'acceptance': 1,
'verhex': data3['verhex'],
'pubhex': data3['pubhex']},
'4':
{'uid': 4,
'name': data4['name'],
'acceptance': 1,
'verhex': data4['verhex'],
'pubhex': data4['pubhex']}})
other.server.close()
self.assertDictEqual(other.keep.loadAllRemoteData(),
{'3':
{'uid': 3,
'name': 'remote3',
'ha': ['127.0.0.1', 7534],
'sid': 0,
'joined': None,},
'4':
{'uid': 4,
'name': 'remote4',
'ha': ['127.0.0.1', 7535],
'sid': 0,
'joined': None,}})
{
'3':
{
'uid': 3,
'name': data3['name'],
'ha': ['127.0.0.1', 7534],
'sid': 0,
'joined': None,
'acceptance': 1,
'verhex': data3['verhex'],
'pubhex': data3['pubhex']
},
'4':
{
'uid': 4,
'name': data4['name'],
'ha': ['127.0.0.1', 7535],
'sid': 0,
'joined': None,
'acceptance': 1,
'verhex': data4['verhex'],
'pubhex': data4['pubhex']
}
})
main.server.close()
other.server.close()
@ -370,53 +366,76 @@ class BasicTestCase(unittest.TestCase):
'''
Basic keep setup for stack keep and safe persistence load and dump
'''
console.terse("{0}\n".format(self.testBasic.__doc__))
console.terse("{0}\n".format(self.testBootstrapClean.__doc__))
self.assertEqual(self.mainSafe.loadLocalData(), None)
self.assertEqual(self.mainSafe.loadAllRemoteData(), {})
opts = self.createOpts(name='main',
dirpath=self.tempDirpath,
openMode=True,
autoAccept=True)
mainData = self.createRoadData(name='main', cachedirpath=opts['cachedir'] )
mainKeep = salting.SaltKeep(opts=opts,
basedirpath=mainData['basedirpath'],
stackname=mainData['name'])
dataMain = self.createRoadData(name='main', base=self.baseDirpath)
main = self.createRoadStack(data=dataMain,
self.assertEqual(mainKeep.loadLocalData(), None)
self.assertEqual(mainKeep.loadAllRemoteData(), {})
main = self.createRoadStack(data=mainData,
eid=1,
main=True,
ha=None, #default ha is ("", raeting.RAET_PORT)
safe=self.mainSafe)
keep=mainKeep)
self.assertTrue(main.keep.dirpath.endswith('road/keep/main'))
self.assertTrue(main.safe.dirpath.endswith('pki'))
console.terse("{0}\nkeep dirpath = {1}\n".format(
main.name, main.keep.dirpath))
self.assertTrue(main.keep.dirpath.endswith('main/raet/main'))
self.assertTrue(main.local.ha, ("0.0.0.0", raeting.RAET_PORT))
self.assertTrue(main.safe.auto)
self.assertTrue(main.keep.auto)
self.assertDictEqual(main.keep.loadLocalData(), {'uid': 1,
'name': 'main',
'ha': ['0.0.0.0', 7530],
'main': True,
'sid': 0,
'stack': 'main',
'neid': 1,})
self.assertDictEqual(main.safe.loadLocalData(), {'prihex': dataMain['prihex'],
'sighex': dataMain['sighex'],
'auto': True,})
'neid': 1,
'sighex': mainData['sighex'],
'prihex': mainData['prihex'],
'auto': True,
})
self.assertEqual(self.otherSafe.loadLocalData(), None)
self.assertEqual(self.otherSafe.loadAllRemoteData(), {})
opts = self.createOpts(name='other',
dirpath=self.tempDirpath,
openMode=True,
autoAccept=True)
otherData = self.createRoadData(name='other', cachedirpath=opts['cachedir'] )
otherKeep = salting.SaltKeep(opts=opts,
basedirpath=otherData['basedirpath'],
stackname=otherData['name'])
dataOther = self.createRoadData(name='other', base=self.baseDirpath)
other = self.createRoadStack(data=dataOther,
self.assertEqual(otherKeep.loadLocalData(), None)
self.assertEqual(otherKeep.loadAllRemoteData(), {})
other = self.createRoadStack(data=otherData,
eid=0,
main=None,
ha=("", raeting.RAET_TEST_PORT),
safe=self.otherSafe)
keep=otherKeep)
console.terse("{0} keep dirpath = {1} safe dirpath = {2}\n".format(
other.name, other.keep.dirpath, other.safe.dirpath))
self.assertTrue(other.keep.dirpath.endswith('road/keep/other'))
self.assertTrue(other.safe.dirpath.endswith('pki'))
console.terse("{0} keep dirpath = {1}\n".format(
other.name, other.keep.dirpath))
self.assertTrue(other.keep.dirpath.endswith('other/raet/other'))
self.assertEqual(other.local.ha, ("0.0.0.0", raeting.RAET_TEST_PORT))
self.assertTrue(other.safe.auto)
self.assertDictEqual(other.safe.loadLocalData(), {'prihex': dataOther['prihex'],
'sighex': dataOther['sighex'],
'auto': True,})
self.assertDictEqual(other.keep.loadLocalData(),
{
'uid': 0,
'name': 'other',
'ha': ['0.0.0.0', 7531],
'main': None,
'sid': 0,
'neid': 1,
'sighex': otherData['sighex'],
'prihex': otherData['prihex'],
'auto': True,
})
self.join(other, main)
self.assertEqual(len(main.transactions), 0)
@ -452,7 +471,8 @@ def runSome():
Unittest runner
'''
tests = []
names = ['testBasic',]
names = ['testBasic',
'testBootstrapClean', ]
tests.extend(map(BasicTestCase, names))
@ -472,8 +492,8 @@ if __name__ == '__main__' and __package__ is None:
#console.reinit(verbosity=console.Wordage.concise)
runAll() #run all unittests
#runAll() #run all unittests
#runSome()#only run some
runSome()#only run some
#runOne('testBootstrap')
#runOne('testBootstrapClean')

View File

@ -94,22 +94,23 @@ class Depends(object):
)
)
# if not, unload dependent_set
mod_key = '{0}.{1}'.format(module.__name__.split('.')[-1],
func.__name__)
if module:
mod_key = '{0}.{1}'.format(module.__name__.split('.')[-1],
func.__name__)
# if we don't have this module loaded, skip it!
if mod_key not in functions:
continue
# if we don't have this module loaded, skip it!
if mod_key not in functions:
continue
try:
if fallback_function is not None:
functions[mod_key] = fallback_function
else:
del functions[mod_key]
except AttributeError:
# we already did???
log.trace('{0} already removed, skipping'.format(mod_key))
continue
try:
if fallback_function is not None:
functions[mod_key] = fallback_function
else:
del functions[mod_key]
except AttributeError:
# we already did???
log.trace('{0} already removed, skipping'.format(mod_key))
continue
class depends(Depends): # pylint: disable=C0103