PSc@s)ddlZddlmZddlmZddlmZddlmZddl m Z yddl Z Wne e fk rn XddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl!Z!ddl"Z"e#e_$e#e_%ddl&Z&ddl'Z'ddl(Z(ddl)j*Z*ddl+j,Z-ddl.j/Z/ddl0j1Z1ddl2j3Z3ddl4j5Z5ddl6Z(ddl7j8Z8ddl9j:j;Z<ddl=j:j>Z>ddl?j:j@ZAddlBZ(ddlCmDZDmEZEmFZFdeGfd YZHd eGfd YZId eIfd YZJddZKdeJfdYZLdefdYZMdefdYZNdeGfdYZOdS(iN(t HandlerTool(t serve_file(t formatdate(t SimplePlugin(t_HTTPErrorTemplate(tQueryt ParseErrortBooleanQueryExceptiontDummycBseZdZRS(s.Dummy object used for dispatch method mapping.(t__name__t __module__t__doc__(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRXst_DepotcBseZdZRS(s4Private, abstract, base class for all Depot classes.(R R R (((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyR ]st DepotHTTPcBseZdZddddddddd d d d d ddddgZdddddddd ddg ZdddddgZdCZdCZdCdZ dZ e dZ dZ dCdZdZdZejdZejjddDgdZdZied6e_d Zied6e_d!Zied6e_d"Zied6e_d#Zied6e_e d$Zd%Zied6ed&6dEdFdGdHgd.6e_d/Z ied6e _d0Z!ie"d16d2d36ed6e!_ejjddIdJdKgd4Z#ejjddLdMdNgd5Z$ejjddOdPdQgd6Z%ejjddRdSdTgd7Z&ejjddUdVdWgd8Z'd9Z(ie"d16d2d36ed&6dXdYdZgd.6e(_d:Z)ejjdd[d\d]gd;Z*ejjdd^gd<Z+ejjdde,j-fgd=Z.ejjdde,j-fgd>Z/d?Z0ejjdde,j-fgd@Z1ejjdd_gdBZ2RS(`sThe DepotHTTP object is intended to be used as a cherrypy application object and represents the set of operations that a pkg.depotd server provides to HTTP-based clients.tversionstsearchtcatalogtinfotmanifesttfilelisttfiletopentappendtclosetabandontaddtp5it publishertindextstatustadmincCs>tjj|_||_||_d|_d|_||_|j dd}|j dd}|rt j j |st j j ||}n||_t j j |jd|_nd|_d|_|j dd}|s tj}tjtj|dtn||_tj||j|js?|j rw|j|_|jj dd s|jj dqn$|j!r|j"|_n |j#|_i}xn|j dd D]Z}d |kr|j$d d \} } n |} d } |j%| g|| j&| qWi|_'xt(j)|t(j*D]\} } t+j,d| } | s[q1n| j-d } | j-d} | |jkrq1n| |kr| || ks1d || krq1n|j.| t/| sq1nt| j0d<| |j'kr|j'| j&t/| nt1}t2|| |t/| g|j'| t6j;|_?|j?j<dS(sInitialize and map the valid operations for the depot. While doing so, ensure that the operations have been explicitly "exposed" for external usage. request_pub_func, if set is a function that gets called with cherrypy.request.path_info that returns the publisher used for a given request. itpkgt content_roottpkg_roottwebt writable_roott ignore_errorsRtprefixt disable_opst/it*s (.*)_(\d+)itexposedt.t_serror_page.defaulttsignal_handlertgracefulN(@RtnrlocktNRLockt_locktcfgtrepotflist_requeststflist_file_requeststrequest_pub_funct get_propertytostpathtisabstjoinR tweb_roottNonettempfiletmkdtemptatexittregistertshutiltrmtreetTruettmp_roottfacetinitt write_configtmirrortroottREPO_OPS_MIRRORtops_listtremovet read_onlytREPO_OPS_READONLYtREPO_OPS_DEFAULTtrsplitt setdefaultRtvopstinspectt getmemberstismethodtretmatchtgrouptsupportstintt__dict__Rtsetattrt publisherstreplacetgetattrtcherrypytconfigtupdatetdefault_error_pagethasattrtenginet subscribetrefreshtBackgroundTaskPlugint_DepotHTTP__bgtask(tselfR2tdconfR5R R!RDR&tentrytoptvertnametfunctmtopattrtpubtpubattr((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt__init__s                     "    cCsEy|jj|jjWn$tjk r@tjddnXdS(sQueues a background task to update search indexes. This method is a protected helper function for depot consumers.s<Skipping indexing; another operation is already in progress.tINDEXN(RitputR2t refresh_indextQueuetFullR`tlog(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt_queue_refresh_indexs  cKs>tj}x*dD]"}||jkr|j|=qqWt|S(sThis function is registered as the default error page for CherryPy errors. This sets the response headers to be uncacheable, and then returns a HTTP response that is identical to the default CherryPy message format.s Cache-ControltPragma(s Cache-ControlR}(R`tresponsetheadersR(tkwargsR~tkey((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRc s   cCsz|jr|jtjjSy&tjjjdjdd}Wntk rVdSX||jkrv|dkrv|SdS(sPrivate helper function to retrieve the publisher prefix for the current operation from the request path. Returns None if a publisher prefix was not found in the request path. The publisher is assumed to be the first component of the path_info string if it doesn't match the operation's name. This does mean that a publisher can't be named the same as an operation, but that isn't viewed as an unreasonable limitation. R'itfeedN( R5R`trequestt path_infotstriptsplitt IndexErrorR<RO(Rjtreq_pub((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt _get_req_pub.s  c CsU|j}|s-|jjjdd}nd }|ry|jj|}Wntk rd}qX|j}|r|j}qn|d krd}n|d krt ||f}nt j j } |dks|dks|dkr| t ||f}t ||f}n | |}t j j } d|| dsN(R:(RRmtvers((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pys si,i,(t _DepotHTTP__set_response_expiresRtVERSIONR:RRt iteritems(RjRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt versions_0s  c s4tj}d|jd<|jdddy|d}Wntk rPd }nXtt|dtdtj dd d d g}y"|j j |d |j Wnxt jk r}tjtjt|nHt jk r}tjd t|tjtjt|nXfd }|S(sTBased on the request path, return a list of token type / FMRI pairs.stext/plain; charset=utf-8s Content-typeRiQitcase_sensitivet return_typet num_to_returnt start_pointRssRequest failed: %sc 3sxtD]\}}x|D]\}}}|\}}}tj|j}t|tjjrd|jj|j ||j |fVq d|||j |jj|j fVq Wq WdS(Ns %s %s %s %s ( t enumeratetactionstfromstrtrstript isinstancet attributetAttributeActiontattrstgettkey_attrRo( titresRRtvalstfmri_strtfvtlineta(tres_list(s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytoutputs N(R`R~RRRR<RRtFalsetRETURN_ACTIONSR2RRtsrepot RepositorySearchUnavailableErrorRRtSERVICE_UNAVAILABLEtRepositoryErrorR{R(RjRR~ttokentquery_args_lstRR((Rs6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytsearch_0s*     sresponse.streamcsg}y|dg}Wntk r*nX|s@|j}n.|jrntjtjd||fn|stjtjny"|jj|d|jWnt t fk r}tjtjt |nxt j k r}tjtjt |nHt jk rX}tjdt |tjtjt |nXtdkry0dj}tj|gdgWqtk rtjtj_dSXntj}d|jd<|jd d d fd }|S( sgBased on the request path, return a list of packages that match the specified criteria.isargs:%s, params:%sRssRequest failed: %siNstext/plain; charset=utf-8s Content-typeRiQc3sttjdVxtD]\}}x|D]\}}}|tjkr|\}}}d|||tj||jfVq2|tjkr2|}d|||fVq2q2WqWdS(Nis%s %s %s %s %s s %s %s %s ( RRtVALIDATION_STRINGRRturllibtquoteRtRETURN_PACKAGES(RRRRRRRR(R(s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRXs   (RtvaluesR`RRRR2RRRRRRRRRR{RRtnextt itertoolstchaint StopIterationt NO_CONTENTR~RRR(RjtargsRt query_str_lstRttmpR~R((Rs6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytsearch_1!sF         cs tj}yjjdj}WnHtjk rr}tjdt|tj t j t|nXtj }d|j d|j|Stjtjd|dS(syOutputs the contents of the file, named by the SHA hash name in the request path, directly to the client.tGETtPOSTtPUTs%s is not allowedN(sPOSTsPUT(R`RtmethodRt_DepotHTTP__upload_fileRRtMETHOD_NOT_ALLOWED(RjRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytfile_1[s      srequest.process_request_bodyisresponse.timeoutcGs3tj}tj}|jjdd}y|d}Wntk rNd}nX|sstjtj t dny+t j ||}|j j||}WnKt jtjfk r}tjd|tjtj t|nX|jr|j r|j|jnd|jd<||jd[/]/admin/0?cmd=refresh-index Available commands are: rebuild Discard search data and package catalogs and rebuild both. rebuild-indexes Discard search data and rebuild. rebuild-packages Discard package catalogs and rebuild. refresh Update search and package data. refresh-indexes Update search data. (Add packages found in the repository to their related search indexes.) refresh-packages Update package data. (Add packages found in the repository to their related catalog.) tcmdRtrebuildRst build_catalogt build_indexsrebuild-indexessrebuild-packagesRgRxsrefresh-indexessrefresh-packagess&Unknown or unsupported operation: '%s's:Another operation is already in progress; try again later.N(RRiRwR2R'RRCRt add_contentRxR`RRRRyRzR(RjRRR&((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytadmin_0s<             cGsytj|dd}Wntk r3d}nXy|jj|Wn1tjk r{}tj t j t |nXdS(syAborts an in-flight transaction for the Transaction ID specified in the request path. Returns no output.iRN( RRRR<R2RRRR`RRRR(RjRRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt abandon_09s  c Gsvytj|dd}Wntk r3d }nXy|d}Wntk r[d }nX|tjkrtjtj t d|ntj }t d|j jD}x|D]}||jdr||jdry<tj||}t|tstn|||gs t[t]s9The specified Action attribute value, '%s', is not valid.sContent-Lengthspkg.sizesRequest failed: %sN( RRRR<RttypesR`RRRR+RtdictRtitemsR/tendswithtastt literal_evalRtlistRRZRtrfileRt ActionErrorR{R2RRR( RjRRt entry_typeRRRR1tdatatsizetactionR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytadd_0OsR       &    cGsytj|dd}Wntk r6d}nXtj}tj}t|jj dd}|dkrtj t j t dn|j}y|jj|||Wn1tjk r}tj t j t|nXd|jd<|jS(sAdds a file to an in-flight transaction for the Transaction ID specified in the request path. The content is expected to be in the request body. Returns no output.iRsContent-Lengthsfile/1 must be sent a file.t0N(RRRR<R`RR~RZRRRRRR+R;R2tadd_fileRRRtbody(RjRRRR~R?R>R((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt __upload_files$        cGsy|d}Wntk r'd}nXya|dkr\|jj|jjd|jn,d|}tj|tjt j |Wn)t j k rtjt j dnXdS(sProvides an administrative interface for search indexing. Returns no output if successful; otherwise the response body will contain the failure details. iRRgRssUnknown index subcommand: %ss:Another operation is already in progress; try again later.N(RRiRwR2RxRR`R{RRRRyRzR(RjRR&terr((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytindex_0s       c Gsry|jj}Wn?tk rQ}tjd|tjtjt|nXg|D] }|^qY}t |dkr|ddkr|d|kr|dcd7Wtjd t#|jd S(s Initialize.tnastyt nasty_levelt nasty_sleepg?sNASTY Depot StartedsNASTY nasty=%d, nasty_sleep=%dstools.nasty_before.onstools.nasty_before.nasty_depoti iisNASTY Depot Error List: %sN($R RuRERFR2RGtrequested_filestrequested_catalogstrequested_manifestsRZR6RRt NASTY_CYCLEt nasty_cyclet maxroll_adjR`R{RRRt nasty_beforeRCRRtREQUEST_TIMEOUTt BAD_GATEWAYtGATEWAY_TIMEOUTRRRterrlistRtrangeRR(RjR2RkterrorstxtnR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRu's:                 cCs|jj|jd|j|_d|jtj|jtj|j|_|jdkrqt j dn|j|jdkrt j dn|jj dS(NiisNASTY nastiness at minisNASTY nastiness at max( R0RRRtNASTY_MULTIPLIERtmathtsintpiRR`R{R(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRgs   idcCs<t||j}tjd|}||jkr8tStS(s7Randomly returns true when the server should misbehave.i(RZRRRRRCR(RjRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRs cCs|jddS(sNastiness sometimes.Ri(R(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt need_nasty_2scCs|jddS(sNastiness less often.Ri(R(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt need_nasty_3scCs|jddS(sNastiness very rarely.Ri N(R(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt need_nasty_4scCs6tj|j}tjd|tj|dS(s&Raise an http error from self.errlist.sNASTY: Random HTTP error: %dN(RRRR`R{R(Rjtcode((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRscCs(tjd|jtj|jdS(sSleep for a few seconds.sNASTY: sleep for %d secsN(R`R{RRtsleep(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRscGsyt|d}Wn)ttfk r?tjtjnX|dksX|dkrmtjtjntjd|||_dS(Niids%Nastiness set to %d by client request( RZRRR`RRRR{R(RjRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRs stools.nasty_before.onRs Content-Typestext/plain; charset=utf-8c Gs|jrZtjdtj}tj|_tjddddddg|j d %s/%ds css8|].\}}d|djd|DfVqdS(s%s %sRcss|]}t|VqdS(N(R(RR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pys sN(R:(RRmR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pys s(RR`R{R~Rt UNAUTHORIZEDRRRRRRRRRRRRRZt normalvariateRR:( RjRR~RRmRtverlenRtoldv((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRsR                  stools.nasty_before.maxrollcGstjtjdS(sProvide a full version of the catalog, as appropriate, to the requesting client. Incremental catalogs are not supported for v0 catalog clients.N(R`RRR(RjR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRs sresponse.streamc Gsy|jj}Wn?tk rQ}tjd|tjtjt|nXg|D] }|^qY}|stjtj t dnt |dkr|ddkr|d|kr|dcd7N} || t| || d}qW||_n|j||_|jS(shA method that imitates the functionality of serve_file(), but behaves in a nasty manner.s Content-TypeRKiisContent-Lengths NASTY serve_file: truncated filesapplication/datas!NASTY serve_file: prepend garbagesNASTY!sNASTY serve_file: flip bitsiii(RR`R~RR7tstattst_sizeRtEnvironmentErrorRRRRRRRRCR]RDRR{RRZtabstgaussRtmaxtordRtchr(RjRt content_typet already_nastyR~tfsttfilesztnfileRDtncorruptRtptchartbit((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRCsV               "'$ (s Content-Typestext/plain; charset=utf-8(s Content-Typesapplication/data(sPragmasno-cache(s Cache-Controlsno-cache, must-revalidate(sExpiresi(R R R RRRuRRRRRRRR`RRRRRRRRRCRRRRRRR(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRsR @        A   =  w  / &  t DNSSD_PlugincBs2eZdZdZdZdZdZRS(s/Allow a depot to configure DNS-SD through mDNS.cCstj||dtkr;d|_d|_dSdtj|_|j|_d|_ |d|_ d|_ t |_|dr|d rd }nd }d tj|j f}tj||d d d f|_dS(s|Bus is the cherrypy engine and gconf is a dictionary containing the CherryPy configuration. t pybonjourcSsdS(N(R<(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytscSsdS(N(R<(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRsNspkg(5) mirror on %ss _pkg5._tcpsserver.socket_portsserver.ssl_certificatesserver.ssl_private_keythttpsthttps%s:%sR(RRutglobalststarttexitRt gethostnameRot wanted_nametregtypetportR<tsd_hdlRtreg_oktgetfqdnturlparset urlunsplitturl(Rjtbustgconftprototnetloc((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRus"          cCsq|tjkr/|jjdtj|nt|_||_|j|jkrm|jjd|jndS(sCallback invoked by service register function. Arguments are determined by the pybonjour framework, and must not be changed. s Error in DNS-SD registration: %ss"DNS-SD service name changed to: %sN( RtkDNSServiceErr_NoErrorRR{t BonjourErrorRCRRoR(RjRtflagst error_codeRoRtdomain((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytreg_cbs    c Csi|jjdtj}|j|d            cCsF|jjd|jr)|jjnd|_|jjddS(NsDNS-SD plugin exiteds+Service unregistration for DNS-SD complete.(RR{RRR<(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRs   (R R R RuRRR(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRs    'RhcBsDeZdZdZdZdZdZde_dZRS(sThis class allows background task execution for the depot server. It is designed in such a way as to only allow a few tasks to be queued for execution at a time. cCs/tj||tjd|_d|_dS(Ni (RRuRyt_BackgroundTaskPlugin__qR<t_BackgroundTaskPlugin__thread(RjR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRuscOs>|jjdkr!tjn|jj|||fdS(sfSchedule the given task for background execution if queue isn't full. i N(Rtunfinished_tasksRyRzt put_nowait(RjttaskRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRwscCsx|jryoy"|jjdd\}}}Wntjk rJwnX|||t|jdrz|jjnWq|jjd|dt qXqWdS(s0Run any background task scheduled for execution.ttimeoutg?t task_dones1Failure encountered executing background task %r.RN( t_BackgroundTaskPlugin__runningRRRytEmptyRdRRR{RC(RjRRR((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytruns "  cCs>t|_|js:tjd|j|_|jjndS(s!Start the background task plugin.ttargetN(RCRRt threadingtThreadRR(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyR s  iBcCs/t|_|jr+|jjd|_ndS(s Stop the background task plugin.N(RRRR:R<(Rj((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pytstop s   ( R R R RuRwRRtpriorityR (((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyRhs    t DepotConfigcBseZdZiejdejdejddddgejdejdddd d d d d gejdejddddgejddddgejdejdddddddgejdddddddgddejdejddddgddej dej dejdej dej d de j d!ie j d6ejd"ddddgejd#dd$d%d&d'gdd%ejd(ddddgej d)ejd*dddggejd+ejd,ejd-dd.ejd/dd0ejd1dd2ej d3dd4gejd5ejd6gejd7ej d8ej d9dd:ggd;6Z d=ejd=d<ZRS(>s+Returns an object representing a configuration interface for a a pkg(5) depot server. The class of the object returned will depend upon the specified configuration target (which is used as to retrieve and store configuration data). 'target' is the optional location to retrieve existing configuration data or store the configuration data when requested. The location can be None, the pathname of a file, or an SMF FMRI. If a pathname is provided, and does not exist, it will be created if needed. 'overrides' is a dictionary of property values indexed by section name and property name. If provided, it will override any values read from an existing file or any defaults initially assigned. 'version' is an integer value specifying the set of configuration data to use for the operation. If not provided, the version will be based on the target if supported. If a version cannot be determined, the newest version will be assumed. Rtaddresstcfg_filetallowedRs R tdebugRs hash=sha256shash=sha1+sha256shash=sha512_256shash=sha1+sha512_256R&t image_roots t inst_roott ll_mirrort log_accesststderrtstdouttnonet log_errorsRRHR!R'Rt proxy_basetreadonlytsocket_timeouttsort_file_max_sizet value_mapt ssl_cert_filet ssl_dialogstbuiltintsmfs t ssl_key_filetthreadsR#tpkg_buitfeed_descriptiont feed_iconsweb/_themes/pkg-block-icon.pngt feed_logosweb/_themes/pkg-block-logo.pngt feed_namespackage repository feedt feed_windowit pkg_securetssl_key_passphraseRRRi#icCsx|s%tjd|jd|d|S|jdrVtj|d|jd|d|Stj|d|jd|d|S(Nt definitionst overridesRssvc:(R1tConfigt_DepotConfig__defsR/Rt FileConfig(tclsR R/R((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyt__new__{ s  N(R R R R1tPropertySectiontPropListt PropDefinedtPropertytPropBooltPropIntt PropPubURItindexertSORT_FILE_MAX_SIZER1R<Rt EmptyDictR4(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyR( sh                           "(PR`tcherrypy._cptoolsRtcherrypy.lib.staticRt email.utilsRtcherrypy.process.pluginsRtcherrypy._cperrorRRtOSErrort ImportErrorRR?R8RQRRRSRRR7RRVRAt simplejsonRRR R=R RRR<tpwdtgrpRRyRt pkg.actionsRt pkg.configRaR1tpkg.fmriRt pkg.indexerR<t pkg.manifestRtpkg.miscRt pkg.nrlocktpkg.p5iRtpkg.server.catalogtserverRRtpkg.server.faceREtpkg.server.repositoryRRt pkg.versiontpkg.server.query_parserRRRtobjectRR R RRRRhR(((s6/usr/lib/python2.7/vendor-packages/pkg/server/depot.pyts|                             #p^?