grthtrhthjhtyjytjytkergtrhtrjytjerhrfh4:24 29/09/2026a ·( fØQã@sÞdZddlZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl mZmZmZddlmZmZmZmZdd lmZmZdd lmZmZdd lmZd ZGd d„deƒZdd„ZedkrÚeƒdS)aš Implements the RTSRoot class. This file is part of RTSLib. Copyright (c) 2011-2013 by Datera, Inc Copyright (c) 2011-2014 by Red Hat, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. éNé)ÚCFSNode)ÚTarget)Ú FabricModule)Ú so_mappingÚbs_cacheÚ StorageObject)Ú RTSLibErrorÚRTSLibALUANotSupportedÚmodprobeÚmount_configfs)Ú dict_removeÚset_attributes)ÚfreadÚfwrite)ÚALUATargetPortGroupz/etc/target/saveconfig.jsoncs€eZdZdZdZdZ‡fdd„Zdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Z‡fd&d'„ZdCd*d+„ZdDd,d-„ZdEd.d/„ZdFd1d2„Zd3d4„Zeed5d6�Zee d7d6�Zee d8d6�Z ee d9d6�Z!ee d:d6�Z"eed;d6�Z#eedd6�Z&eed?d6�Z'eed@d6�Z(ee dAd6�Z)eedBd6�Z*‡Z+S)GÚRTSRoota` This is an interface to the root of the configFS object tree. Is allows one to start browsing Target and StorageObjects, as well as helper methods to return arbitrary objects from the configFS tree. >>> import rtslib.root as root >>> rtsroot = root.RTSRoot() >>> rtsroot.path '/sys/kernel/config/target' >>> rtsroot.exists True >>> rtsroot.targets # doctest: +ELLIPSIS [...] >>> rtsroot.tpgs # doctest: +ELLIPSIS [...] >>> rtsroot.storage_objects # doctest: +ELLIPSIS [...] >>> rtsroot.network_portals # doctest: +ELLIPSIS [...] z /var/targetz /etc/targetcsztt|ƒ ¡z tƒWn ty8tdƒtƒYn0z| d¡Wn$tyltdƒ| d¡Yn0| ¡dS)zz Instantiate an RTSRoot object. Basically checks for configfs setup and base kernel modules (tcm) ZconfigfsÚanyZtarget_core_modN)ÚsuperrÚ__init__r r r Z_create_in_cfs_ineÚ _set_dbroot©Úself©Ú __class__©ú//usr/lib/python3.9/site-packages/rtslib/root.pyrFs    zRTSRoot.__init__ccs*| ¡|jD]}|jD] }|VqqdS©N)Ú _check_selfÚfabric_modulesÚtargets)rZ fabric_moduleÚtargetrrrÚ _list_targetsZs  zRTSRoot._list_targetsccs | ¡t ¡D] }|VqdSr)rrÚall)rÚsorrrÚ_list_storage_objects`s zRTSRoot._list_storage_objectsccs*| ¡|jD]}|jD] }|VqqdSr)rÚstorage_objectsÚ alua_tpgs)rr$ÚarrrÚ_list_alua_tpgses  zRTSRoot._list_alua_tpgsccs*| ¡|jD]}|jD] }|VqqdSr)rr Útpgs)rÚtZtpgrrrÚ _list_tpgsks  zRTSRoot._list_tpgsccs*| ¡|jD]}|jD] }|VqqdSr)rr*Ú node_acls)rr+Znode_aclrrrÚ_list_node_aclsqs  zRTSRoot._list_node_aclsccs*| ¡|jD]}|jD] }|VqqdSr)rr*Únode_acl_groups)rr+ÚnagrrrÚ_list_node_acl_groupsws  zRTSRoot._list_node_acl_groupsccs*| ¡|jD]}|jD] }|VqqdSr)rr-Ú mapped_luns)rÚnaZmlunrrrÚ_list_mapped_luns}s  zRTSRoot._list_mapped_lunsccs*| ¡|jD]}|jD] }|VqqdSr)rr/Úmapped_lun_groups)rr0ZmlgrrrÚ_list_mapped_lun_groupsƒs  zRTSRoot._list_mapped_lun_groupsccs*| ¡|jD]}|jD] }|VqqdSr)rr*Únetwork_portals)rr+ÚprrrÚ_list_network_portals‰s  zRTSRoot._list_network_portalsccs*| ¡|jD]}|jD] }|VqqdSr)rr*Úluns)rr+ÚlunrrrÚ _list_luns�s  zRTSRoot._list_lunsccs&| ¡|jD]}|jr|jVqdSr)rr-Zsession)rr3rrrÚ_list_sessions•s zRTSRoot._list_sessionsccs | ¡t ¡D] }|VqdSr)rrr#)rÚmodrrrÚ_list_fabric_modules›s zRTSRoot._list_fabric_modulescCsdS)NZrtslibrrrrrÚ__str__ szRTSRoot.__str__cCsª|jd}tj |¡s"|j|_dSt|ƒ|_|j|jkr¦zt||jdƒWnNtj |j¡sttd  |j¡ƒ‚n"ddl m }|d  |j¡ƒYdSYn0t|ƒ|_dS)Nz/dbrootÚ z?Cannot set dbroot to {}. Please check if this directory exists.r)ÚwarnzECannot set dbroot to {}. Target devices have already been registered.) ÚpathÚosÚexistsÚ_default_dbrootÚ_dbrootrrÚisdirr ÚformatÚwarningsrB)rZ dbroot_pathrBrrrr£s&    ÿ ÿ zRTSRoot._set_dbrootcCs|jSr)rGrrrrÚ _get_dbrootºszRTSRoot._get_dbrootc Cs´| ¡}zóz RTSRoot.dump..r&cSsg|] }| ¡‘qSrrf)rgr+rrrrhrir cSs$g|]}| d¡r|jr| ¡‘qS)Údiscovery_auth)Ú has_featureZdiscovery_enable_authrR©rgrbrrrrhs þr)rrrRr&r r)rÚdrrrrRs z RTSRoot.dumpNFcCsº|s tdƒ‚|jD]*}|s|r,|r|j|kr| ¡|rq>qdd„|jDƒD] }| ¡qN|jD]*}|sn|r||rb|j|krb| ¡|rbqŽqb|s¶|s¶t d|j ¡D]}t   |¡q¦dS)z6 Remove entire current configuration. z-As a precaution, confirm=True needs to be setcss|]}| d¡r|VqdS)rjN)rkrlrrrÚ 3riz)RTSRoot.clear_existing..z %s/core/*_*N) r r ÚwwnÚdeleterZclear_discovery_auth_settingsr&rPÚglobZ configfs_dirrDÚrmdir)rr!rQÚconfirmr+Úfmr$Zhba_dirrrrÚclear_existings"   zRTSRoot.clear_existingc s°|r|j||dd�n°t|jƒs*t|jƒrÆt|jƒr‚| dg¡D]@}|jD]4}|d|jkrJ|d|jkrJtd|j|jfƒ‚qJq@t|jƒrÆ| dg¡D],}|jD] } |d| jkr¢td | jƒ‚q¢q˜g‰|rØd d „‰n ‡fd d „‰t | dg¡ƒD�]n\} ‰dˆv�rˆd | ƒqô|�s"|�r2|rôˆd|krôzt ˆd} Wn6t �yxˆdˆdƒ|�rpY�qfYqôYn0ˆ  ¡} t | dƒz| fi| ¤Ž} Wn\t�yú}zBˆdˆd|fƒ|�rÚWYd}~�qfWYd}~qôWYd}~n d}~00‡‡fdd„}t| ˆ di¡|ƒˆ di¡D].}zt | |ˆ¡Wnt�yTYn0�q*|rô�qfqôt | dg¡ƒD]T\} }d|v�r˜ˆd| ƒ�qv|jD](}|d|jk�rž| |ˆ¡�qv�qž�qvt | dg¡ƒD]Î\} }d|v�rþˆd| ƒ�qÜ|�s |�r|�rÜ|d|k�rÜd|v�rHˆd|dƒ|�rÜ�q¬�qÜ|ddd„|jDƒv�r‚ˆd|dƒ|�rÜ�q¬�qÜt|dƒ}t ||ˆ¡|�rÜ�q¬�q܈S)a Takes a dict generated by dump() and reconfigures the target to match. Returns list of non-fatal errors that were encountered. Will refuse to restore over an existing configuration unless clear_existing is True. T)rsr&rPrNz)storageobject '%s:%s' exist not restoringr roz'target with wwn %s exist, not restoringcSs t|ƒ‚dSr)r ©Zerr_strrrrÚerr_funcdsz!RTSRoot.restore..err_funccsˆ |d¡dS)Nz , skipped)r^rv)Úerrorsrrrwgsz''name' not defined in storage object %dz3'plugin' not defined or invalid in storageobject %s)rEÚ attributesrNZ buffered_moder'z%Could not create StorageObject %s: %sNcsˆdˆdˆd|fƒS)NzStorage Object %s/%s: %srNrPr)Úx)rwr$rrÚ so_err_funcˆsz$RTSRoot.restore..so_err_funcryr'rz%'name' not defined in fabricmodule %dz'wwn' not defined in target %dÚfabricz target %s missing 'fabric' fieldcss|] }|jVqdSr)rPrlrrrrn±riz"RTSRoot.restore..zUnknown fabric '%s')rurr&r r\rPrNr ror[rÚKeyErrorÚcopyr Ú ExceptionrrZsetupr rrr)rÚconfigr!rQruÚabort_on_errorZ config_soZ loaded_soZ config_tgZ loaded_tgÚindexZso_clsÚkwargsZso_objrdr{Zalua_tpgrtZfm_objr+r)rwrxr$rÚrestoreHs¢   ÿ ÿ   ÿ       "           zRTSRoot.restorec Cs:|st}|r| ||¡}n| ¡}|d}tjtjB}d|A}zt |¡Wnty^Yn0t  |¡}z t  |tj tj Btj B|¡}Wnty¨td|ƒ‚Yn0t |d¡�N} |  tj|ddd�¡|  d¡|  ¡t |  ¡¡|  ¡Wd ƒn1�s 0Yt ||¡t  |¡t |¡d S) z€ Write the configuration in json format to a file. Save file defaults to '/etc/target/saveconfig.json'. z.tempiÿrMÚwTé)Z sort_keysÚindentrAN)Údefault_save_filererRÚstatÚS_IRUSRÚS_IWUSRrDr]ÚOSErrorÚumaskrSÚO_WRONLYÚO_CREATÚO_EXCLrZÚfdopenÚwriterTÚdumpsÚflushÚfsyncÚfilenoÚcloseÚshutilr~) rr`r_rcZtmp_fileÚmoder�Zumask_originalZfdescrbrrrÚ save_to_fileÁs4      (  zRTSRoot.save_to_fileTcCsX|st}t|dƒ�2}t | ¡¡}|j|||||d�WdƒS1sJ0YdS)a  Restore the configuration from a file in json format. Restore file defaults to '/etc/target/saveconfig.json'. Returns a list of non-fatal errors. If abort_on_error is set, it will raise the exception instead of continuing. rL)rur�N)rˆrSrTrUrVr„)rZ restore_filerur!rQr�rbr€rrrÚrestore_from_fileîs   þzRTSRoot.restore_from_filecCs t ¡dS)zE Invalidate any caches used throughout the hierarchy N)rÚclearrrrrÚinvalidate_cachesszRTSRoot.invalidate_cacheszGet the list of Target objects.)Údocz-Get the list of all the existing TPG objects.z1Get the list of all the existing NodeACL objects.z6Get the list of all the existing NodeACLGroup objects.z3Get the list of all the existing MappedLUN objects.z8Get the list of all the existing MappedLUNGroup objects.z*Get the list of all the existing sessions.z8Get the list of all the existing Network Portal objects.z1Get the list of all the existing Storage objects.z)Get the list of all existing LUN objects.z)Get the list of all FabricModule objects.z%Get the list of all ALUA TPG objects.zGet the target database root)NNF)NNFF)NN)NTNNF),Ú__name__Ú __module__Ú __qualname__Ú__doc__rFZ_preferred_dbrootrr"r%r)r,r.r1r4r6r9r<r=r?r@rrKrerRrur„ršr›r�Úpropertyr r*r-r/r2r5Zsessionsr7r&r:rr'ZdbrootÚ __classcell__rrrrr'sŒ T  )ÿ y -þ ÿÿÿÿÿÿÿÿÿÿÿÿÿrcCsddl}| ¡dS)zRun the doctests.rN)ÚdoctestZtestmod)r¥rrrÚ_test!sr¦Ú__main__) r¢rDr‰rTrqrXr˜Znoderr!rr|rZtcmrrrZutilsr r r r r rrrZaluarrˆrr¦rŸrrrrÚs,    }