#xPc@sdZddkZddkZddkZddkZddkZddklZddkZddkZddk Z ddk l Z ddk Z ddk Z ddk lZddklZlZlZlZlZddklZddkTd Zd Zd efd YZd efdYZdefdYZdefdYZdefdYZdefdYZdS(s Plugin framework. The classes in this module make heavy use of Python container emulation. If you are unfamiliar with this Python feature, see http://docs.python.org/ref/sequence-types.html iN(tpath(tEnv(t_(tReadOnlyt NameSpacetlocktislockedt check_name(tDEFAULT_CONFIG(t*s%s: need a %r; got a %r: %rcCsOt|dddjotSt|idddjotS|iidjS(sv If the object has self.env.mode defined and that mode is production return True, otherwise return False. tenvtmodet productionN(tgetattrtNonetFalseR R (tobj((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pytis_production_mode0s tSetProxycBs2eZdZdZdZdZdZRS(sc A read-only container with set/sequence behaviour. This container acts as a proxy to an actual set-like object (a set, frozenset, or dict) that is passed to the constructor. To the extent possible in Python, this underlying set-like object cannot be modified through the SetProxy... which just means you wont do it accidentally. cCsjtttf}t||jo tdt||fn||_t|pt|ndS(sR :param s: The target set-like object (a set, frozenset, or dict) s %r not in %rN(tsett frozensettdictttypet TypeErrort _SetProxy__sRR(tselftstallowed((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt__init__Es    cCs t|iS(s? Return the number of items in this container. (tlenR(R((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt__len__Psccs#xt|iD] }|VqWdS(s< Iterate (in ascending order) through keys. N(tsortedR(Rtkey((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt__iter__VscCs ||ijS(sv Return True if this container contains ``key``. :param key: The key to test for membership. (R(RR ((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt __contains__]s(t__name__t __module__t__doc__RRR!R"(((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyR<s   t DictProxycBs)eZdZdZdZdZRS(sd A read-only container with mapping behaviour. This container acts as a proxy to an actual mapping object (a dict) that is passed to the constructor. To the extent possible in Python, this underlying mapping object cannot be modified through the DictProxy... which just means you wont do it accidentally. Also see `SetProxy`. cCsVt|tj o tdt|tfn||_tt|i|dS(s> :param d: The target mapping object (a dict) s %r is not %rN(RRRt _DictProxy__dtsuperR&R(Rtd((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRqs  cCs |i|S(s| Return the value corresponding to ``key``. :param key: The key of the value you wish to retrieve. (R'(RR ((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt __getitem__zsccs!x|D]}|i|VqWdS(sE Iterate (in ascending order by key) through values. N(R'(RR ((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt__call__s(R#R$R%RR*R+(((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyR&fs  t MagicDictcBseZdZdZRS(s A mapping container whose values can be accessed as attributes. For example: >>> magic = MagicDict({'the_key': 'the value'}) >>> magic['the_key'] 'the value' >>> magic.the_key 'the value' This container acts as a proxy to an actual mapping object (a dict) that is passed to the constructor. To the extent possible in Python, this underlying mapping object cannot be modified through the MagicDict... which just means you wont do it accidentally. Also see `DictProxy` and `SetProxy`. cCs6y ||SWn#tj otd|nXdS(s Return the value corresponding to ``name``. :param name: The name of the attribute you wish to retrieve. sno magic attribute %rN(tKeyErrortAttributeError(Rtname((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt __getattr__s (R#R$R%R0(((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyR,stPlugincBseZdZeZd ZdZdZe eZ dZ dZ dZ defdYZdZd Zd ZRS( s% Base class for all plugins. cCshd|_t|_t|_ti|_|i}|i |_ |i |_ d|i |i f|_ td|iD|_t|i|_|iipd|i |_n)t|iidddi|_ti|t|idjoti|i d|_nt|iti p6t!t"|i dti t#|i|ifndS(Ns%s.%scss)x"|]}d|i|ifVqWdS(s%s.%sN(R$R#(t.0tb((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pys s s<%s>s iis.label($Rt _Plugin__apiRt_Plugin__finalize_calledt_Plugin__finalizedt threadingtRLockt_Plugin__finalize_lockt __class__R#R/R$tmoduletfullnamettuplet __bases__tbasesRR%tdoctmsgtsummarytunicodetsplittstriptlog_mgrt get_loggertTruetlabelttexttFixMet isinstancetLazyTextRt TYPE_ERRORR(Rtcls((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRs0       (  cCs|iS(s Return `API` instance passed to `set_api()`. If `set_api()` has not yet been called, None is returned. (R4(R((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt __get_apiscCse|iiizJ|iodSt|_|it|_t|pt|nWdQXdS(s Finalize plugin initialization. This method calls `_on_finalize()` and locks the plugin object. Subclasses should not override this method. Custom finalization is done in `_on_finalize()`. N( R9t__exit__t __enter__R5RHt _on_finalizeR6RR(R((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pytfinalizes      cCsdS(s Do custom finalization. This method is called from `finalize()`. Subclasses can override this method in order to add custom finalization. N((R((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRSscCs7|iiiz|ip|inWdQXdS(sR Finalize plugin initialization if it has not yet been finalized. N(R9RQRRR6RT(R((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pytensure_finalizeds t finalize_attrcBs)eZdZdZddZdZRS(s/ Create a stub object for plugin attribute that isn't set until the finalization of the plugin initialization. When the stub object is accessed, it calls `ensure_finalized()` to make sure the plugin initialization is finalized. The stub object is expected to be replaced with the actual attribute value during the finalization (preferably in `_on_finalize()`), otherwise an `AttributeError` is raised. This is used to implement on-demand finalization of plugin initialization. R/tvaluecCs||_||_dS(N(R/RW(RR/RW((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRs cCsy|djp|idjo|iS|iyt||iSWn/tj o#td|i|ifnXdS(Ns7attribute '%s' of plugin '%s' was not set in finalize()(RtapiRWRUR R/t RuntimeErrorR.(RRRO((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt__get__s (snamesvalueN(R#R$R%t __slots__RRRZ(((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRVs  c Cs||_t|tpdSx"|D]}t||||q%Wx;dD]3}t||ot||t||qJqJWdS(s2 Set reference to `API` instance. NR tcontext(senvscontext(R4RLtAPItsetattrthasattrR (RRXR/((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pytset_api#s cGsY|f|}|id|ti|}|djotid|d|ndS(s Call ``executable`` with ``args`` using subprocess.call(). If the call exits with a non-zero exit status, `ipalib.errors.SubprocessError` is raised, from which you can retrieve the exit code by checking the SubprocessError.returncode attribute. This method does *not* return what ``executable`` sent to stdout... for that, use `Plugin.callread()`. s Calling %rit returncodetargvN(tdebugt subprocesstcallterrorstSubprocessError(Rt executabletargsRbtcode((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRe4s  cCsd|ii|iifS(s Return 'module_name.class_name()' representation. This representation could be used to instantiate this Plugin instance given the appropriate environment. s%s.%s()(R:R$R#(R((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt__repr__Es N(R#R$R%RHtfinalize_earlyRRIRt_Plugin__get_apitpropertyRXRTRSRUtobjectRVR`ReRk(((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyR1s     $  t RegistrarcBs5eZdZdZdZdZedZRS(s Collects plugin classes as they are registered. The Registrar does not instantiate plugins... it only implements the override logic and stores the plugins in a namespace per allowed base class. The plugins are instantiated when `API.finalize()` is called. cGsKtd|D|_t|_tt|it|idS(sw :param allowed: Base classes from which plugins accepted by this Registrar must subclass. cssx|]}|hfVqWdS(N((R2tbase((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pys as N(Rt_Registrar__allowedRt_Registrar__registeredR(RpRt_Registrar__base_iter(RR((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyR\s ccspxi|iiD]X\}}t|pn|i}t|pnt||t|||fVqWdS(N(Rrt iteritemsRR#R^R,(RRqtsub_dR/((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt __base_itergs    ccst|pnt}xB|iiD]1\}}t||ot}||fVq'q'W|p%tid|d|iindS(s Iterates through allowed bases that ``klass`` is a subclass of. Raises `errors.PluginSubclassError` if ``klass`` is not a subclass of any allowed base. :param klass: The plugin class to find bases for. tpluginR?N( RRRrRut issubclassRHRftPluginSubclassErrortkeys(RtklasstfoundRqRv((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyt __findbasesqs   cCsti|ptd|n||ijotid|nx|i|D]\}}|i|jo3|p(tid|id|id|qn0|o(ti d|id|id|n|||is ( RR|R#R/RR$R;RxR=R?RR(Rtp(R(s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRs  (R#R$R((R(s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRsc3sx|D]}|jo||s t_API__finalizedc3sx|]}|VqWdS(N((R2R(R(s3/usr/lib/python2.6/site-packages/ipalib/plugable.pys s Rc3sx|]}|VqWdS(N((R2R(R(s3/usr/lib/python2.6/site-packages/ipalib/plugable.pys s N(RRRoRRRRR RRRt itervaluesRR`RURHR=(RRtproduction_modeR/Rqt namespaceR((RRRRRRs3/usr/lib/python2.6/site-packages/ipalib/plugable.pyRTs@       "     N(R#R$R%RRRRRRRRRRRT(((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyR]s     <+  .( R%treRRR7RRRdRRftconfigRRRJRRqRRRRRt constantsRtipapython.ipa_log_managerRNRRR&R,R1RpR](((s3/usr/lib/python2.6/site-packages/ipalib/plugable.pyts0          (  *$ ]