R4Sc @sdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl j Z ddlZ ddljjZddljjZddlZ ddljjZddljjZddlZ ddljjZddlZ ddlZ ddlj Z ddl!Z ddl"Z ddl#m$Z$e$j%Z%dZ&dZ'dZ(dZ)dZ*d Z+d Z,d Z-d Z.d Z/dZ0e1e)e*e+e,e-e.e/e0gZ2e1e)e*e/gZ3dZ4dZ5dZ6e1e5e6gZ7dZ8ej9j:e8dZ;ej9j:e8dZ<ej9j:e8dZ=ej9j:e8dZ>ddfZ?ej@ddZAdZBdZCdZDdZEdeFfdYZGd eFfd!YZHd"eFfd#YZId$eFfd%YZJd&eFfd'YZKd(ZLeMd)ZNeMd*ZOdePd+ZQeRdePeRd,ZSd-ejTfd.YZUd/ZVd0ZWeMeMeMeMeMeMeMeMeMeMeMeMd1 ZXdd2ZYd3ZZd4Z[eRd5Z\d6Z]d7Z^d8Z_d9Z`d:ZadS(;s5 Linked image module classes. The following classes for manipulating linked images are defined here: LinkedImage LinkedImageChild The following template classes which linked image plugins should inherit from are also defined here: LinkedImagePlugin LinkedImageChildPlugin iN(tglobal_settingstparenttselftchildsli-current-parentsli-current-pathsli-modelsli-names li-parentsli-pathsli-path-transforms li-recurset-tpushtpulltlinkedtlinked_pfacetst linked_ppkgst linked_propt linked_ppubst/t LI_RVTuplesrvt_rv rvt_e rvt_p_dictcCst|tkst|\}}}t|tks?t|dksft|tjksft|dkst|tkst|tj tj gks|dkst|tj ks|dkst|S(sSanity check a linked image operation return value tuple. The format of said tuple is: process return code LinkedImageException exception (optional) json dictionary containing planned image changes N( ttypeR tAssertionErrortinttNonetapxtLinkedImageExceptiontdicttpkgdefstEXIT_OKtEXIT_NOP(trvtupletrvtetp_dict((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt_li_rvtuple_checks '$*!cCsgt|tkstxH|jD]:\}}t|tksUtd|ft|q%W|S(sSGiven a linked image return value dictionary, sanity check all the entries.sUnexpected rvdict key: (RRRt iteritemstLinkedImageNameR(trvdicttktv((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt_li_rvdict_checks cCs9t|g|jD]}|jdk r|j^qS(sGiven a linked image return value dictionary, return a list of any exceptions that were encountered while processing children.N(R"tvaluestrvt_eR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt_li_rvdict_exceptionss cCsJt|}t|dkr+|dn|rFtjd|ndS(sIf an exception was encountered while operating on a linked child then raise that exception. If multiple exceptions were encountered while operating on multiple children, then bundle those exceptions together and raise them.iitbundleN(R%tlenRR(Rt exceptions((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt_li_rvdict_raise_exceptionss   tLinkedImagePlugincBskeZdZeZeZdZdZedZeedZ dZ dZ dZ dZ RS( sThis class is a template that all linked image plugins should inherit from. Linked image plugins derived from this class are designed to manage linked aspects of the current image (vs managing linked aspects of a specific child of the current image). All the interfaces exported by this class and its descendants are private to the linked image subsystem and should not be called directly by any other subsystem.cCsdS(sInitialize a linked image plugin. 'pname' is the name of the plugin class derived from this base class. 'linked' is the LinkedImage object initializing this plugin. N((RtpnameR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__init__s cCs tdS(sCalled when the path to the image that we're operating on is changing. This normally occurs when we clone an image after we've planned and prepared to do an operation.N(tNotImplementedError(Rtroot((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt init_rootscCs tdS(sIf the linked image plugin is able to detect that we're operating on an image in an alternate root then return an transform that can be used to translate between the original image path and the current one.N(R-(Rt ignore_errors((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytguess_path_transformscCs tdS(sReturn a list of the child images and paths associated with the current image. The paths that are returned should be absolute paths to the original child image locations.N(R-(RtnocacheR0((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytget_child_listscCs tdS(sZGet the linked image properties associated with the specified child image.N(R-(Rtlin((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytget_child_propsscCs tdS(sgAttach the specified child image. This operation should only affect in-memory state of the current image. It should not update any persistent on-disk linked image state or access the child image in any way. This routine should assume that the linked image properties have already been validated.N(R-(Rtpropst allow_relink((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytattach_child_inmemoryscCs tdS(sDetach the specified child image. This operation should only affect in-memory state of the current image. It should not update any persistent on-disk linked image state or access the child image in any way.N(R-(RR4((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytdetach_child_inmemoryscCs tdS(sPSync out the in-memory linked image state of this image to disk.N(R-(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytsync_children_todisks(t__name__t __module__t__doc__tFalsetsupport_attachtsupport_detachR,R/R1R3R5R8R9R:(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR*s    tLinkedImageChildPlugincBs eZdZdZdZRS(sThis class is a template that all linked image child plugins should inherit from. Linked image child plugins derived from this class are designed to manage linked aspects of children of the current image. (vs managing linked aspects of the current image itself). All the interfaces exported by this class and its descendants are private to the linked image subsystem and should not be called directly by any other subsystem.cCsdS(sInitialize a linked image child plugin. 'lic' is the LinkedImageChild object initializing this plugin. N((Rtlic((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR,*scCs tdS(sCalled before a parent image saves linked image properties into a child image. Gives the linked image child plugin a chance to update the properties that will be saved within the child image.N(R-(RR6((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt munge_props2s(R;R<R=R,RC(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRA s RcBsqeZdZdZed dZed dZdZdZ dZ dZ dZ d Z RS( s`A class for naming child linked images. Linked image names are used for all child images (and only child images), and they encode two pieces of information. The name of the plugin used to manage the image and a linked image name. Linked image names have the following format ":cCst|tkstd|_|_y|jd\|_|_Wn#tk rltj d|nXt |jdkst |jdkrtj d|n|jt j j jkrtj d|ndS(Nt:t lin_malformedi(RtstrRRtlin_typetlin_nametsplitt ValueErrorRRR'tpkgtclientt linkedimagetp_types(Rtname((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR,Cs *cCs t|S(sReturns the serialized state of this object in a format that that can be easily stored using JSON, pickle, etc.(RF(tobjtje_state((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytgetstateSscCs t|S(s`Allocate a new object using previously serialized state obtained via getstate().(R(tstatetjd_state((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt fromstateZscCsd|j|jfS(Ns%s:%s(RGRH(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__str__ascCst|jS(N(R'RV(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__len__dscCst|tkst|s"dS|tkr2dSt|tksJtt|j|j}|dkro|St|j|j}|S(Nii(RRRt PV_NAME_NONEtcmpRGRH(Rtothertc((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__cmp__gs  cCstt|S(N(thashRF(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__hash__tscCs)t|tstSt|t|kS(N(t isinstanceRR>RF(RRZ((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__eq__wscCs|j| S(N(R`(RRZ((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__ne__}sN(R;R<R=R,t staticmethodRRRRURVRWR\R^R`Ra(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR<s     t LinkedImagec BseZdZeegZeeeeegZ eeeee gZ e ee Be B@ sdt dZedZdZdHdZdZedHdHedZedZedZed Zed Zed Zed Zed ZedZ edZ!dZ"dZ#dZ$dZ%dZ&edZ'dZ(edZ)dZ*edZ+dHdZ,dZ-dZ.dZ/dZ0dZ1d Z2dHd!Z3d"Z4ed#Z5d$Z6d%Z7d&Z8ed'Z9dHed(Z:dHd)Z;eed*Z<ed+Z=d,Z>ed-Z?ed.Z@edHd/ZAd0ZBd1ZCd2ZDed3ZEd4ZFeeeeeedHeeGjHeed5 ZId6ZJeeedHeeeGjHeed7 ZKeeeed8ZLeeedHd9ZMeedHeNjOd:ZPdHdHed;ZQd<ZRdHdHd=ZSd>ZTd?ZUed@ZVedAZWdBZXdCZYdDZZdEZ[dFZ\dGZ]RS(IsHA LinkedImage object is used to manage the linked image aspects of an image. This image could be a child image, a parent image, or both a parent and child. This object allows for access to linked image properties and also provides routines that allow operations to be performed on child images.cCs||_t|_t|_d|_tjj |_ d|_ d|_ i|_ d|_d|_d|_d|_d|_t|_|jt|_x:tjjjD])}tjjj||||j|tischildt_LinkedImage__insyncRuRet_LinkedImage__set_current_pathRtRwRR/Rnt itervaluestchild_init_root(Rt first_passR.RytplugintlipRB((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRzs2    cCs|dkrt}nm|r|j|xWtD]L}|tkrVt|krVq2n||ks2td|t|fq2Wn||_t |_ d|_ t j j|_d|_dS(sInternal helper routine used when we want to update any linked image properties. This routine sanity check the new properties, updates them, and resets any cached state that is affected by property values.s'%s' not in %sN(RRt_LinkedImage__verify_propsttemporal_propstPROP_CURRENT_PARENT_PATHtPROP_PARENT_PATHRtsetReRfRgRhRKRiRjRkRl(RR6R|((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__update_props s          cCst|}|t|jkr#|St|krKtd|jdtgnytt|t}Wn4tj k rtd|jdt|tfnX|j |j krtd|jd|d|j nt |krtd|jd|dt gn|t }|t kr9td|jd|dt |fn|tkrz|j|}|rztd|jd|d|qzn|tkr|j|}|rtd|jd|d|qndS(srPerform internal consistency checks for a set of linked image properties. Don't update any state.Rt missing_propstbad_propR4t bad_lin_typeN(RRt_LinkedImage__parent_propst PROP_NAMEt_rterrRoRRFRRRGRwt PROP_MODELt model_valuest PV_MODEL_PUSHt_LinkedImage__push_child_propst PV_MODEL_PULLt_LinkedImage__pull_child_props(RR6t props_setR4tmodeltmissing((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__verify_props's>             cCs |r)t|t@sJtd|n!t|t@ sJtd||dksh|dksht|dk s|dk st|dk rt||}n|dk rt||}n||t<||t<||t" appended to them.s%s.%dRRN(RqRt client_runidt path_existst load_dataRRRRRRRRRRoR(RR~Rtpath_tmpR6ROR4((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__load_ondisk_propss(        cCstj}d|jtjf}|r@t|r@t|}n|j}t|dt}|dkrkdSt j j }x*|j D]\}}|j ||qW|S(s8Load linked image inherited facets from disk. Don't update any internal state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.s%s.%dt missing_okN(tmisct EmptyDictRsRRRRRtRRKRiRjRt_set_inherited(RR~tpfacetsRRR R!((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__load_ondisk_pfacetss     cCsd}d|jtjf}|r=t|r=t|}n|j}t|dt}|dkrhdStg|D]}tj j t |^qrS(s7Load linked image parent packages from disk. Don't update any internal state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.s%s.%dRN( RRpRRRRRtRfRKtfmritPkgFmriRF(RR~t fmri_strsRts((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__load_ondisk_ppkgss    cCs\d}d|jtjf}|r=t|r=t|}n|j}t|dt}|S(s9Load linked image parent publishers from disk. Don't update any internal state. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.s%s.%dRN(RRrRRRRRt(RR~tppubsR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__load_ondisk_ppubss   cCs|jd|}| r0|jdt r0dS|sK|jdt}n |j||j||jsudS|jd|}|dk r||_ n|j d|}|dk r||_ n|j d||_ dS(sLoad linked image properties and constraints from disk. Update the linked image internal state with the loaded data.R~R0N(t_LinkedImage__load_ondisk_propst_LinkedImage__isparentRtt$_LinkedImage__fabricate_parent_propsRRvRt_LinkedImage__load_ondisk_ppkgsRRgt!_LinkedImage__load_ondisk_pfacetsRkt_LinkedImage__load_ondisk_ppubsRh(RR~R6tppkgsR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__load%s"         cCsB|ttgkrtSt|tkr>|jdkr>tStS(s'Verify property value for PROP_RECURSE.ttruetfalse(struesfalse(RtR>RRFtlower(R!((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__validate_prop_recursebs $cCs/i|jt6}|tkr(|j}n|tks:t|j}g}x|jD]\}}||kr|jt j d|qVn|||s|jt j d||fqVn||krV|jt j d|qVqVqVWt |dkr|dn|r+t j d|ndS(sgValidate user supplied linked image attach properties. Don't update any internal state.tattach_bad_proptattach_bad_prop_valueiiR&N( t#_LinkedImage__validate_prop_recurset PROP_RECURSERRRRRRRRRR'(RRR6tvalidate_propst allowed_propsterrsR R!((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__validate_attach_propsks0          cCsytj|Wn#tk r6tjd|nXy+|jjd|dtd|jj}Wn&tj k rtjd|nX|S(sVInitialize an Image object which can be used to access a parent image.tparent_bad_pathR.tuser_provided_dirtcmdpathtparent_bad_img( RtstattOSErrorRRRdtallocRtRtImageNotFoundException(RRtpimg((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __init_pimgs  cCs|j r]|j r]|j|j|j|jg}x|D]}t|r?tSq?WtS|j dt}|dkrt }nt |j t}||krtS|j|j|jg}|jsx|D]}t|rtSqWtSx|D]}t|stSqW|jdt}|j|kr8tS|jdt}|j|kr]tS|jdt}|j|krtStS(sIf our in-memory linked image state matches the on-disk linked image state then there's nothing to do. If the state differs then there is stuff to do since the new state needs to be saved to disk.R~N(tisparentRRsRpRrRqRR>RtRRRt rm_dict_entReRRRkRRgRRh(RtpathsRtli_ondisk_propstli_inmemory_propstli_ondisk_pfacetstli_ondisk_ppkgstli_ondisk_ppubs((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt nothingtodosJ              cCs|jsdS|jjjdr)dSt|j}|j}|dkrQdSt|t|krtj d||fnxGt ||D]6\}}||krqntj d||fqWdS(sUIf we're a child image's, verify that the parent image publisher configuration is a subset of the child images publisher configuration. This means that all publishers configured within the parent image must also be configured within the child image with the same: - publisher rank - sticky and disabled settings The child image may have additional publishers configured but they must all be lower ranked than the parent's publishers. Nsuse-system-repotlinked_pub_error( RRdtcfgt get_policytget_pubsRhRR'RtPlanCreationExceptiontzip(RtpubsRR|tpp((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytpubchecks       cCs|jsdS|jttkr'dS|jsQ|j}|j||_nt|j|_t |j|_ t |j|_ dS(s`Update linked image constraint, publisher data, and state from our parent image.N( RReRRRlt parent_patht_LinkedImage__init_pimgRRht get_packagesRgtget_inheritable_facetsRk(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__syncmd_from_parents   cCsJy|jWn5tjk rE}|s2|nt|j|dSXdS(sUpdate linked image constraint, publisher data, and state from our parent image. If catch_exception is true catch any linked image exceptions and pack them up in a linked image return value tuple.N(t _LinkedImage__syncmd_from_parentRRR t lix_exitrvR(Rtcatch_exceptionR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytsyncmd_from_parent/s cCs9|j|j|j|jg}x1|D])}d|tjf}t|dtq%W|j r|j rx|D]}t|dtqsWdSt |j t }t |j||jst|jdtt|jdtt|jdtdSt |j|jt |j|jt |j|jdS(s+Write in-memory linked image state to disk.s%s.%dtnoent_okN(RsRpRrRqRRt path_unlinkRtRRRReRt save_dataRkRgRh(RRRR6((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytsyncmd=s,     cCs&|js|jn|jtS(sIf the current image is a child image, this function returns a linked image name object which represents the name of the current image.(Rt_LinkedImage__apx_not_childReR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt child_nameds cCs t|jkS(s5Indicates whether the current image is a child image.(RRe(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRnscCst|jd|dkS(sIndicates whether the current image is a parent image. 'ignore_plugin_errors' ignore plugin runtime errors when trying to determine if we're a parent image. R0i(R't_LinkedImage__list_children(RR0((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __isparentss cCst|jd|dkS(s6Indicates whether the current image is a parent image.t li_ignorei(R'R(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR}scCs|jp|jS(s5Indicates wether the current image is already linked.(RR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytislinkedscCs|jjttS(s+Return the current path transform property.(RetgetRR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytget_path_transforms cCs|jtkS(sVCheck if we're accessing a linked image at an alternate location/path.(RR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt inaltrootscCs|jst|jtS(sReport our current image path.(RRReR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRscCs|jst|jtS(sReport our current image path.(RRReR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRscCs:t|jkrdS|jt}|ddks6t|S(sUIf we know where our parent should be, report it's expected location.iR N(RReRRR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRs  cCsu|dkr|jjS|j|dt|j|j}|j|j}|j||j d|t |S(sReturn a dictionary which represents the linked image properties associated with a linked image. 'lin' is the name of the child image. If lin is None then the current image is assumed to be a linked image and it's properties are returned. Always returns a copy of the properties in case the caller tries to update them.t raise_exceptRN( RRetcopyt_LinkedImage__verify_child_nameRtRwRGR5RRR(RR4RR6((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt child_propss   cCstjd|jS(sRRaise an exception because the current image is not a child image.tself_not_child(RRRo(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__apx_not_childscCsrt|tks(tdt|x(|jD]}|d|kr5tSq5W|rntjd|ntS(s'Check if a specific child image exists.s%s == LinkedImageNameit child_unknown(RRRRRtRRR>(RR4Rti((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__verify_child_namescCsYt|ts1tdt|t|fx!|D]}|j|dtq8WdS(s\Given a list of linked image name objects, make sure all the children exist.s)type(lin_list) == %s, str(lin_list) == %sRN(R_RRRRFRRt(Rtlin_listR4((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt verify_namess  cCs|jS(s'Facets inherited from our parent image.(Rk(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytinherited_facetsscCs|jsdS|jS(s1A set of the fmris installed in our parent image.N(RRRg(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt parent_fmriss cCsDt|tkstt|}|s@|j|dtn|S(sGiven a string representing a linked image child name, returns linked image name object representing the same name. 'allow_unknown' indicates whether the name must represent actual children or simply be syntactically correct.R(RRFRRRRt(RROt allow_unknownR4((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt parse_names  c Cs|gkrgSg}x~tjjjD]m}xd|j|jd|D]I\}}|j|ksgtt||j }|j ||gqFWq&Wt |dt j d}|dkr|Stg|D]\}}|^q}gt||D]}tjd|^q}t|dkr5|dn|rPtjd|ng|D]$\}}||krW||f^qWS(sReturns a list of linked child images associated with the current image. 'li_ignore' see list_related() for a description. The returned value is a list of tuples where each tuple contains (
  • ,
  • ).R0tkeyiRiR&N(RKRLRMRNRwR3RGRRRRtsortedtoperatort itemgetterRRRRR'( RRR0t li_childrenR|R4Rtli_allR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__list_childrens.  %, cCs|jd|}g|D]\}}|t|f^q}| rR|j rRgSt}|jrp|j}n|j}|t|f}|j||j}|dk rtt |f}|j|nt |dt j d}|S(s,Returns a list of linked images associated with the current image. This includes both child and parent images. 'li_ignore' is either None or a list. If it's None (the default), all children will be listed. If it's an empty list no children will be listed. Otherwise, any children listed in li_ignore will be ommited from the results. The returned value is a list of tuples where each tuple contains (
  • , ,
  • ).RR$iN(Rt REL_CHILDRRXR RtREL_SELFRRRt REL_PARENTR%R&R'(RRR(R4Rtli_listtli_selft li_parent((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt list_related.s" %      c Csst|tkstt|tks0t|d ksdt|tksdtdt||d kr|t}n|j|j}|jr| rt j d|j n|j r| rt j d|jnt jj|st j d|n|j|}|j}|jjrXt j d|jj|jfn|jt||j||j |j}||ttversiont is_successortCONSTRAINT_AUTO( RtcatRCt sync_fmrisRtat parent_depst ppkgs_dicttpfmri((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__insyncs6  (  cCs|js+|j}ttj|dS|su|jsbtjd|j }ttj |dSttj ddS|j stjd|j }ttj |dSttj ddS(sIf the current image is a child image, this function audits the current image to see if it's in sync with its parent.tchild_divergedN( RR R Rt EXIT_OOPSRRuRRR t EXIT_DIVERGEDRR(Rt latest_mdR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt audit_selfs         cCs3|jjjd|d}|tjkr/tStS(sA convenience wrapper for audit_self(). Note that we consider non-child images as always in sync and ignore any runtime errors.R]i(R}RR^RR\R>Rt(RR]R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytinsyncsc Cs1t|t|tdkrt|tks:txG|D]<\}}t|tksett|tksAtqAWn|sttj ddS|sttj gtj fg}ng|j D]}|j dk r|j ^q}t}tg|j D]}|j ^q}x:|D]2\}} ||krUt| d|S||O}q-Wtj |ksxtg|j D]'}|j r|j |kr|j ^q} t| dkr| d} n!| rtjd| } nd} t|dkrtt|d| |Sttj| |S(sInternal helper function that takes a dictionary returned from an operations on multiple children and merges the results into a single return code.iiR&N(R"RRRRRRR RRRt rvt_p_dicttrvt_rvR$R'RRt EXIT_PARTIAL( Rtrv_maptrv_setRRtp_dictst rv_mappedtrv_seent rv_map_sett rv_map_rvRterr((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __rvdict2rv sB ! " ' cCsdttjgtjfttjgtjfttjtjgtjfg}|j||S(sConvenience function that takes a dictionary returned from an operations on multiple children and merges the results into a single return code.(RRRR\t_LinkedImage__rvdict2rv(RRRc((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytaudit_rvdict2rvGs cCsdttjgtjfttjtjgtjfttjgtjfg}|j||S(sConvenience function that takes a dictionary returned from an operations on multiple children and merges the results into a single return code.(RRRRRl(RRRc((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytsync_rvdict2rvTscCs |j|S(sConvenience function that takes a dictionary returned from an operations on multiple children and merges the results into a single return code.(Rl(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytdetach_rvdict2rv`scCsft|tkstt|tks0tt|tksHt|j|rs| rstjd|n|jt |t j j |stjd|n|j t}t||stjd||dfnytj|}Wn4tk r.}tjd|dd||fnX|sJtjd|ntjj|j\}} |rtt} nt} |jt jt j}|jjt jt j} | r|j|  rtjd || fnt j j|t} ytj|| } Wn"tk r/}tj|nX| rR| rRtjd |n|j | |d S( sgSanity check the parameters associated with a child image that we are trying to attach.t child_duptchild_path_notabstchild_not_in_altrootiR4tchild_op_failedtfindt child_bad_imgtchild_not_nestedt img_linkedN(!RRRRRFRRRR8RRRR7ReRR:tart ar_img_prefixRtbootenvtBootEnvt get_be_nameRoRtR>RRt startswithRRt ar_existst_convert_errorR9(RR4RR6R7Rt img_prefixRtbe_nametbe_uuidtimg_is_clonabletp_roottimg_li_data_propstexists((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__validate_child_attachgsH     c sjtjtjjtjtjkrStjdnjr}tjdfntjkrtjdn|jrtjd|j |j fnfd}tj}j tjdd!}j tjdd!}xEt j ||D]1\}}||krSPntj j||}q7W|jtjtj}|kr|kr||ntj jjtjtj} xct| t|kr4|| tj j| jtj} | tjkr| tj7} qqWtj jjtjtj} xct| t|kr|| tj j| jtj} | tjkr]| tj7} q]q]WdS( sMake sure there are no additional images in between the parent and the child. For example, this prevents linking of images if one of the images is nested within another unrelated image. This is done by looking at all the parent directories for both the parent and the child image until we reach a common ancestor.t link_to_selft parent_nestedtattach_root_as_childR5cs`ytj|}Wn"tk r7}tj|nX|r\tjd|fndS(sNRaise an exception if directory 'd' contains an image.tintermediate_imageN(RxRyRRRR(tdR~R(tcpathtppath(sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytabort_if_imgdirs iiN(RRRRRR}RtliverootRRRRIt itertoolstizipRtdirnameR'( RRRRt dir_commontpdirstcdirstpdirtcdirR((RRsC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__validate_attach_img_pathssH          % % c Cst|tkstt|tks0t|dksdt|tksdtdt||dkr|t}n|j|j}|j r| rt j d|j}t |j |dSt jj|st j d|}t |j |dSt j}yt j|WnDtk r_}t j d|dd||f}t |j |dSXt j}t j|t|jkr|j}|j|ny|j|||d|Wn&t j k r}t |j |dSX|j}||tRtRaRR:RR$R (RR4RR6RR7R<RRRt progtrackRRRRRRtcwdtp_propsRR R!RBRRtrvtuple2((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt attach_childs !                         c Cst|gkrd}n|jd|dt\}}t|jdtjd|jd|dtj dt|S( skAudit one or more children of the current image to see if they are in sync with this image.RtfailfastRRRRRN( Rt_LinkedImage__children_initR>RRRtPKG_OP_AUDIT_LINKEDR#tprogresstQuietProgressTracker(RRtlic_dictR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytaudit_childrenos       c  Cs|dkrtj}n|gkr0d}n|jd|} t} | r^|r^t} ni} t|jdtj d| j d| d|dtdtd| d |d |d |d |d |d|d| d| | S(s/Sync one or more children of the current image.RRRRRRRRRRRRRRRRN( RRtNullProgressTrackerRRtR>RRRRR#(RRRRRRRRRRRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt sync_childrens4         c Cs|gkrd }n|jd|dt\}}xv|D]n}|j|j} | js:|req:ntjd|j} t| j | d ||RwRGR@RRR RRRRRt PKG_OP_DETACHR#RRRR$R9R:RRRvR ( RRR<RRRRRR4RRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytdetach_childrensJ                c ksbx[|jd||| |fgd|d|d|d|d|d| dtjD] } | VqOWd S( slWrapper for __children_op_vec() to stay compatible with old callers which only support one operation for all linked images. '_pkg_op' is the pkg.1 operation that we're going to perform '_lic_list' is a list of linked image child objects to perform the operation on. '_ignore_syncmd_nop' a boolean that indicates if we should always recurse into a child even if the linked image meta data isn't changing. See __children_op_vec() for an explanation of the remaining options.t_lic_op_vectorsRRRRRt_pdtstageN(t_LinkedImage__children_op_vecRtAPI_STAGE_DEFAULT( RRRRRRRt_ignore_syncmd_nopRRtkwargsR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __children_ops   c # csttjg|D]} | d^qg} t| } | tt| ksVt| ttg| D]} | j^qfksttj} t|dkr|dd} | t j t j gkrtj sd} qqnd} | r|j | | n|dk rt}ng}x|D] \} }}}|t jkr^|j}||dRtpdc ss|jst|j||j|\}}}t||||j<|rt|rx|D]}|jqgWt|n|j t j t j gkr|j |j||n|r|j t j kr|jVndS(scAn iterator function invoked when a child has finished an operation. 'lic' is the child that has finished execution. 'lic_list' a list of children to remove 'lic' from. See __children_op() for an explanation of the other parameters.N(tchild_op_is_doneRtremovet child_op_rvRR R%tchild_op_abortR)RaRRRtli_recurse_outputR`( RBtlic_listRRRRRtstdouttstderr((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_op_finishs         N(0treduceR&taddR'RRR Rtclient_concurrencyRRtPKG_OP_PUBCHECKtclient_concurrency_settli_recurse_startRRtRRRRRdRRtchild_op_setupRRRR RR%RR)RR>tpoptchild_op_startR%tli_recurse_statusRtfilenotselecttpolltkeystregistertPOLLINtli_recurse_progressR"tli_recurse_end(#RRRRRRRRRRtlic_alltlic_numt concurrencytpkg_opt lic_setupRRtignore_syncmd_nopt_pmdRRRRBRt_LinkedImage__child_op_finishRt lic_runningtprogtrack_updatetdonet lin_runningtfd_hashR|tfdteventstevent((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__children_op_vec s" # 4            (   2             %  !     c Cs|dks|dkst|dkrSg|j|D]}|d^q:}n |j|i}i}x]|D]U}yt||}|||R)(RRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytapi_recurse_pubcheck/ s   ccs*|jjj}|jj}|tjtjtjgksBt |j gksc|gksct |tjkr|j gkst |j gksot n|j gks|j |j kogknst t |j t |j @ st |j rKt |j t |j @ s%t t |j t |j @ sKt nt |jt |j ksot t}|tjkrt}ng}x|jD]\}}} } d| kst g}x:|D]2} y|j|j| Wqtk rqXqW|j||| | fqWi} xC|jd|d| d|dtd|d|d|D] } | Vq^Wt|  st x| D]}| |jtjkr||j kst |j j||j|=n|tjkr| |jtjkr||j kst |j j|qqWdS( sThis is an iterator function. It recurses into linked image children to perform the specified operation. RRRRRRRN(Rdt imageplanRRnR#RtAPI_STAGE_PLANtAPI_STAGE_PREPAREtAPI_STAGE_EXECUTERtchildren_ignoredtchildren_plannedt children_nopRR>Rttchild_op_vectorsRtKeyErrorRR%RaRR(RRRRRt expect_plantlic_op_vectorstopRRRtlRRR4((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __api_recurseB sj !(    $        cCst}d}|tjkr-tj}t}nl|tjkrQtj}tj}nH|tjkrutj}tj }n$|tj krtj}tj }n|tj krtj}tj }n-|tjkrtj}tj}n tj}|||fS(sSDetermine what pkg command to use when recursing into child images.N(R>RRt API_OP_SYNCRRttAPI_OP_INSTALLtPKG_OP_INSTALLtAPI_OP_CHANGE_FACETtPKG_OP_CHANGE_FACETtAPI_OP_CHANGE_VARIANTtPKG_OP_CHANGE_VARIANTt API_OP_UPDATEt PKG_OP_UPDATEtAPI_OP_UNINSTALLtPKG_OP_UNINSTALL(tapi_opRtpkg_op_erecursetpkg_op_irecurse((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__recursion_ops s,             cCsi}|d|d<||dRtRRRRRRRR(R RRt api_kwargsR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__recursion_args sB         ccs|jjj}|j}g|_|jj}|j|\} } } |r| sZtt t |t |}|j | |||} |jj | t || t fn|j | |||} |jj | || | f|j|_x"|jtj|D] }|Vq WdS(sPlan child image updates.N(RdRRt plan_typeRRnRt_LinkedImage__recursion_opsRRRt_LinkedImage__recursion_argsRRtRmRt_LinkedImage__api_recurseRR(RRt erecurse_listRRRRRRRRRterecurse_kwargstirecurse_kwargsR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytapi_recurse_plan s(         cCst|jtj|dS(sPrepare child image updates.N(RR$RR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytapi_recurse_prepare= scCst|jtj|dS(sExecute child image updates.N(RR$RR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytapi_recurse_executeA scCsCt|jjt|_|j|_|j|_|j |_ dS(s,Initialize our state in the PlanDescription.N( RReRRtli_propsRgtli_ppkgsRhtli_ppubsRkt li_pfacets(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt init_planE s  cCs|jj}|r%|j|n|j||j|_|j|_|j|_ tj|j }|gkr|j r|dkrg}n||j 7}n|j d|dS(s!Reload a previously created plan.RN(R+RRRvR-RhR,RgR.RkRRRR(RRR6R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt setup_planO s      cCs=x6|jjD]%}|j|jjjjkrtSqWtS(sMReturn True if there is no planned work to do on child image.( RnRR RdRRRR>Rt(RRB((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytrecurse_nothingtodor s N(^R;R<R=RfRRRRRRRRRRR,tpropertyR}RzRRvRRbR>RRRRRtRRRRRRR8RRRRRR R RRRRRRRRRRR RRR R!R#RR1R=RBRR^R_RlRmRnRoRR9RtEmptyIRRRRRRRRRRRRR$R"R#R(R)R*R/R0R1(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRcs    & <  0  $ '    = ,  E *   '            - * F  ,  9  @ N  v   "E "   _5? (   #Rc BsaeZdZdZedZedZedZdZe e dZ e e dZ e e dZ e e d Z e e d Zee e ejd Ze e ee eeje ejed Zd ZdZdZdZe ee dZdZdZdZdZdZdZ dZ!dZ"dZ#RS(sVA LinkedImageChild object is used when a parent image wants to access a child image. These accesses may include things like: saving/pushing linked image metadata into a child image, syncing or auditing a child image, or recursing into a child image to keep it in sync with planned changes in the parent image.cCst|ts%tdt|t|tsJtdt|||_|j|_|jj||_ |j t |kstyt j |j }Wn7tk r}tjd|dd|j |fnX|stjd|d|j ntjj|t|_tjj|t|_tjj|t|_tjj|t|_tjjj|j ||_!tjj"j#|_$d|_&d|_'dS(Nsisinstance(%s, LinkedImage)sisinstance(%s, LinkedImageName)R4RsRtRu((R_RcRRRt_LinkedImageChild__linkedR}t_LinkedImageChild__imgRt_LinkedImageChild__propsRRxRyt child_pathRRRRRRRt_LinkedImageChild__path_ppkgsRt_LinkedImageChild__path_propRt_LinkedImageChild__path_ppubsRt_LinkedImageChild__path_pfacetsRKRLRMtp_classes_childRGt_LinkedImageChild__plugint pkgremotet PkgRemotet_LinkedImageChild__pkg_remoteRt#_LinkedImageChild__child_op_rvtuplet_LinkedImageChild__child_op(RRR4RyR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR, s0    cCs |jtS(s+Get the name associated with a child image.(R6R(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR  scCs%|jjr|jtS|jtS(s+Get the path associated with a child image.(R4RR6RR(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR7 s cCs|jS(sTGet a pointer to the parent image object associated with this child.(R5(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt child_pimage sc Csyd|tjf}t||d|dtt}t|dtd|dtdt}|d k rt|d|dtdt} || krt}qn| s|rtj|||S|stj |||nWn:t k r} t j d|j dd|j| fnXtS( sWrite data to a child image.s%s.%sR.RRtdecodeR4Rssmetadata updateN(RRR R>RtRRRxt ar_unlinkt ar_renameRRRR R7( RR.RtdataR~ttestRtupdatedtold_datatnew_dataR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __push_data s2          cCs|j|j|j|||S(sSync linked image parent constraint data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.(t_LinkedImageChild__push_dataR7R8(RRR~RH((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __push_ppkgs scCs|j|j|j|||S(sSync linked image parent facet data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.(RMR7R;(RRR~RH((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__push_pfacets scCs_|jj}t|ks!t|jj|t|t}|j|j |j |||S(s Sync linked image properties data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.( R6RRRR=RCRRRMR7R9(RR~RHR6((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __push_props s cCs|j|j|j|||S(sSync linked image parent publisher data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.(RMR7R:(RRR~RH((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt __push_ppubs sc Csv|\}}}|j|||}|j||}|j|||} |j|||} |pu|pu| pu| S(sSync linked image data to a child image. 'tmp' determines if we should read/write to the official linked image metadata files, or if we should access temporary versions (which have "." appended to them.(t_LinkedImageChild__push_ppkgst_LinkedImageChild__push_propst_LinkedImageChild__push_ppubst_LinkedImageChild__push_pfacets( RtpmdR~RHRRRt ppkgs_updatedt props_updatedt pubs_updatedtpfacets_updated((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__syncmd scCs|tjtjgkrtSy|j|d|d|}Wn/tjk rl}t|j|d|_ t SX|rwtS|rtSttj dd|_ t S(sPrepare to perform an operation on a child image by syncing the latest linked image data to that image. As part of this operation, if we discover that the meta data hasn't changed we may report back that there is nothing to do (EXIT_NOP). 'pmd' is a tuple that contains parent metadata that we will sync to the child image. Note this is not all the metadata that we will sync, just the set which is common to all children. 'ignore_syncmd_nop' a boolean that indicates if we should always recurse into a child even if the linked image meta data isn't changing. 'tmp' a boolean that indicates if we should save the child image meta data into temporary files (instead of overwriting the persistent meta data files). 'test' a boolean that indicates we shouldn't save any child image meta data, instead we should just test to see if the meta data is changing. 'stage' indicates which stage of execution we should be performing on a child image.R~RHN( RRRRtt_LinkedImageChild__syncmdRRR RRRAR>R(RRVRR~RHRRIR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_op_setup_syncmd. sc/Cs|rG|j|dtd|d| s+dSttjdd|_dS|j|d|d|d| sldS|jj|j tj d|ddddd t d dd dd |d t d|dtdgddd|dgdt j dt jd| d| d| d| d| dt jdS(s6Prepare to sync a child image. This involves updating the linked image metadata in the child and then possibly recursing into the child to actually update packages. For descriptions of parameters please see the descriptions in api.py`gen_plan_*RRHRNR~Rt backup_betbackup_be_namet be_activateRRRtli_parent_syncRt li_target_alltli_target_listtnew_beRtoriginstparsable_versiontquietRt reject_patsRRtverbose(t(_LinkedImageChild__child_op_setup_syncmdR>R RRRRAR@tsetupR7RRtRtclient_output_parsable_versiontclient_output_quiettclient_output_verbose(RRRRRRRRRRRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_syncb sF     c 1Cs|j|dtd|d| s%dS|dkr:g}n|jj|jtjddd|ddd dd td dd |d tdddddtddd|dgd|dtj dtj d|d| d| d| d| dtj dS(s Prepare to update a child image.RR~RNt act_timeoutiRR^R_R`RR<tignore_missingt li_erecurseRRaRdRRetpargsRfRgRRhRRRi( RjRtRR@RkR7RRRRlRmRn( RRRRRR<RRRRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_update s>      c -Cs|j|dtd|d| s%dS|jj|jtjd|ddddd dd td dd dd ddtddd|dgd|dtj dtj d|d|d| d| d| dtj dS(s*Prepare to install a pkg in a child image.RR~RNRRpiR^R_R`RRrRRaRdRReRsRfRgRRhRRRi( RjRtR@RkR7RRRRRlRmRn( RRRRRRRRRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_install s6    c%Cs|j|dtd|d|s%dS|jj|jtjddddddd td dd dd dd tddd|d|dtj dtj d|d|dtdtj dS(s*Prepare to install a pkg in a child image.RR~RNRpiR^R_R`RRrRRaRdRRsRfRgRRqRi( RjRtR@RkR7RRRRRlRmRn(RRRRRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_uninstall s.    c -Cs/|j|dtd|d| s%dS| o.| s8t| rPtj} | }ntj} |}g|jD]\}}d||f^ql}|jj|j | d|ddd dd dd td dd ddddtddd|dgd|dt j dt j d|d|d| d| d| dt jdS(s*Prepare to install a pkg in a child image.RR~RNs%s=%sRRpiR^R_R`RRrRRaRdRReRsRfRgRRhRRRi(RjRtRRRRtitemsR@RkR7RRRlRmRn(RRRRRRRRRRRRRGR t varcet_dictRUtbtvarcets((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_change_varcets# sD    /  cCsS|jj|jtjdtd|d|dtdgd|dtjdtj d S( s Prepare to detach a child image.R<RRRbRcRRgRiN( R@RkR7RRRtR>RRmRn(RRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_detachS s  cCs6|j|dtsdS|jj|jtjdS(s7Prepare to a check if a child's publishers are in sync.R~N(RjRtR@RkR7RR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_pubcheckb sc CsT|j|dtsdS|jj|jtjdtdtdgdtdtdS(sUPrepare to a child image to see if it's in sync with its constraints.R~NRaRbRct omit_headersRg(RjRtR@RkR7RRR>(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt__child_setup_audito s cCs#|jjd|_d|_dS(s8Public interface to abort an operation on a child image.N(R@tabortRRARB(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR s  cKs|jdkst|jdks*t||_|tjkrU|j||n.|tjkrw|j||n |tj kr|j ||n|tj kr|j |||||n|tj kr|j||||n|tjkr|j||||no|tjkr<|j||||nG|tjksZ|tjkrs|j||||ntd|dS(sbPublic interface to setup an operation that we'd like to perform on a child image.s!Unsupported package client op: %sN(RARRRBRRt$_LinkedImageChild__child_setup_auditRt%_LinkedImageChild__child_setup_detachRt'_LinkedImageChild__child_setup_pubcheckRt#_LinkedImageChild__child_setup_syncRt%_LinkedImageChild__child_setup_updateRt&_LinkedImageChild__child_setup_installRt(_LinkedImageChild__child_setup_uninstallRRt-_LinkedImageChild__child_setup_change_varcetst RuntimeError(RRRRRRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR s6          cCs$|jdk rtS|jjdS(s8Public interface to start an operation on a child image.N(RARRtR@tstart(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR scCs |jdk rtS|jjS(sSPublic interface to query if an operation on a child image is done.N(RARRtR@tis_done(R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR sc Cs|j}d|_|jdk r@|j}d|_|ddfS|jjsUt|jj\}}}}|dk rtj}n|dk s|tj tj gkrt j d|j d|d|||||f}t||d}|||fS|tj kr<|dkstt|dd}|||fStjdksR| rqt|dd}|||fSd}ytj|}WnWtk r}t j d|j d||||f}t||d}|||fSXt|j |dRRRURSRTR\RtRRRjRR3RRRRRRRRRRRRRRR(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR} sJ & ,   5 F , % 0   $ G cCs2g|jdtD]}t||jg^qS(sZReturn publisher information for the specified image. Publisher information is returned in a sorted list of lists of the format: , Where: is a string is a boolean The tuples are sorted by publisher rank. t inc_disabled(tget_sorted_publishersR>RFtsticky(R{R|((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR) scCst|j|jj}|dk rx|jD]z\}}||krRq4n|r||ksjt|t|g8}n|r4||kst|t|gO}q4q4Wnt|S(s<Figure out the current (or planned) list of packages in img.N(RRERFRIRt plan_descRRf(R{RRtsrctdst((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR< s  cCst|d|}|jj}|d k rE|jd k rE|j}ntg|D]}|j|f^qO}t}|j|j}x|D]}x|j ||j gD]}|j dks|j ddkrqn|j |} | sqntg| D]} | d^qttgkr/qn| ||t|d| r>dStj||tj }tj |d}t j |ddd|}|j Wn:tk r} |rtj| ntj| nX|S(s4Load JSON encoded linked image metadata from a file.R.trRsutf-8t object_hookN(RRKRLRMt PkgDecoderRRxRRtO_RDONLYRRtloadRRRR( RRR.RDRRRRRGR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR s  RcBseZdZdZRS(s<Utility class used when json encoding linked image metadata.cCst|tjjtjjjjfr1t|St|t j rM|j St|t t frlt|Stjj||S(sRequired routine that overrides the default base class version. This routine must serialize 'obj' when attempting to save 'obj' json format.(R_RKRRRLRMtcommonRRFtpkgplantPkgPlanRRRRfRRt JSONEncodertdefault(RRP((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRs   (R;R<R=R(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR scCsi}x|jD]\}}t|tkrC|jd}nt|tkrg|jd}nt|tkr|jdkrt}q|jdkrt}qn|||(tdcttrvdctR R!((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR!s  cCs;tg|jD]$\}}||kr||f^qS(s'Remove a set of keys from a dictionary.(RR(RRR R!((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR7sc Cs|o | st|s|o"| s,t|s8|o;| sEt|dksit|tksit|r|dkstd|}n4|r|dkstd|}n|r|dkstd|}n|r|dkstd|}n| r+|dkstddj| }n| r|dksCtd}xv| D]+\} } |d| | d | d f7}qPWn@| r|dkstd dj| }n|dkst|r|jr|j}n|jj}n|r |j}|j }nd }|r)d t|}nd}|rT|rTdt||f}n|rgd|}nt d|||fdS(sOops. We hit a runtime error. Die with a nice informative message. Note that runtime errors should never happen and usually indicate bugs (or possibly corrupted linked image metadata), so they are not localized (just like asserts are not localized).s!Invalid linked content policy: %ss&Invalid linked image update policy: %ssInvalid linked image type: %ss$Invalid linked property value: %s=%ss&Missing required linked properties: %ss, s4Multiple plugins reported different path transforms:s %s = %s -> %siis*Found saved temporal linked properties: %ssLinked image error: sLinked image (%s) error: ts Linked image (%s) path: %ss Linked image path: %ss%s: %s%sN( RRRRFRRR R}R.R7R(RRBR4RRjtbad_cptbad_iupRRRRtsaved_temporal_propsRt transformt err_prefixt err_suffix((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR?s` $           cCs=ytj||SWn"tk r8}tj|nXdS(s7Simple wrapper for accessing files in the current root.N(RxR~RRR(RR.R((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRscCs=ytjd|SWn"tk r8}tj|nXdS(s7Simple wrapper for accessing files in the current root.R N(Rxtar_isdirRRR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt path_isdirscCs@ytjd||SWn"tk r;}tj|nXdS(s7Simple wrapper for accessing files in the current root.R N(RxRRRR(RRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt path_mkdirscCsCytjd|d|SWn"tk r>}tj|nXdS(s7Simple wrapper for accessing files in the current root.R RN(RxRERRR(RRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR scCsftjj|s"td||jtjtj}|tkrKtS|j|drbtSt S(s3Check if 'path_transform' can be applied to 'path'.spath is not absolute: %si( RRR7RRRRRtR}R>(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pytpath_transform_applicables" cCs\tjj|s"td||jtjtj}|d|df}t||S(s5Check if 'path_transform' has been applied to 'path'.spath is not absolute: %sii(RRR7RRRR(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyR:s"cCstjj|s"td||jtjtj}|tkrK|S|\}}t||slttjj||t |S(s%Apply the 'path_transform' to 'path'.spath is not absolute: %s( RRR7RRRRRRR'(RRtoroottnroot((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRs"  cCs!|d|df}t||S(s)Unapply the 'path_transform' from 'path'.ii(R(RR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRscCstjj|s"td|tjj|sDtd||jtjtj}|jtjtj}d}|ddd}|ddd}xAttt|t|D]}||||krPqqW||dddjtjtj}||dddjtjtj}|d|dkoYdknsdt|d|dkodknst||krt S||fS(sYGiven an two paths create a transform that can be used to translate between them.sopath is not absolute: %ssnpath is not absolute: %siNiR ( RRR7RRRtrangetminR'R(topathtnpathRt opath_revt npath_revRR((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyRs"""(**** (bR=t collectionsRRR&RRt simplejsonRt pkg.actionsRKt pkg.altroottaltrootRxt pkg.catalogtpkg.client.api_errorsRLt api_errorsRtpkg.client.bootenvRztpkg.client.linkedimagetpkg.client.pkgdefsRtpkg.client.pkgplanRtpkg.client.pkgremotetpkg.client.progressRt pkg.facettpkg.fmritpkg.miscRtpkg.pkgsubprocesst pkg.versiont pkg.clientRtloggerR-R,R+RRRRRRRRRfR@RRXRRRt __DATA_DIRRRRRRRRt namedtupleR RR"R%R)tobjectR*RARRcRRRRRRtR R>RRRRRRRRRR RR:RRR(((sC/usr/lib/python2.7/vendor-packages/pkg/client/linkedimage/common.pyt)s                       UD        A