
    VhC                         d dl mZmZmZ eZd dlmZ d dlZd dl	Z	d Z
 G d de      Z G d de      Z G d	 d
e      Z G d de      Z G d de      Z G d de      Zy)    )absolute_importdivisionprint_function)to_bytesNc           
          t        j                  dd|       }t        j                  ddt        j                  ddd|z               }t        |      dkD  r|S dS )z
    Normalizes btrfs subvolume paths to ensure exactly one leading slash, no trailing slashes and no consecutive slashes.
    In addition, if the path is prefixed with a leading <FS_TREE>, this value is removed.
    z
^<FS_TREE> z/+$z/+/r   )resublen)pathfstree_strippedresults      p/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/module_utils/btrfs.pynormalize_subvolume_pathr      sO    
 ff]B5OVVFBuc33H IJF[1_6-#-    c                       e Zd Zy)BtrfsModuleExceptionN)__name__
__module____qualname__ r   r   r   r      s    r   r   c                   R    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zy)BtrfsCommandsz?
    Provides access to a subset of the Btrfs command line
    c                 V    || _         | j                   j                  dd      | _        y )NbtrfsTrequired)_BtrfsCommands__moduleget_bin_path_BtrfsCommands__btrfsselfmodules     r   __init__zBtrfsCommands.__init__!   s$    }}11'D1Ir   c                    d| j                   z  }| j                  j                  |d      }|d   j                         D cg c]  }|j	                          }}g }d }|D ]k  }|j                  d      r#| j                  |      }|j                  |       7|j                  d      sI|d   j                  | j                  |             m |S c c}w )Nz%s filesystem show -dTcheck_rc   Labeldeviddevices)	r!   r   run_command
splitlinesstrip
startswith _BtrfsCommands__parse_filesystemappend'_BtrfsCommands__parse_filesystem_device)r#   commandr   xstdoutfilesystemscurrentlines           r   filesystem_showzBtrfsCommands.filesystem_show%   s    )T\\:**7T*B%+AY%9%9%;<!'')<< 	PDw'11$7""7+)	"))$*H*H*NO	P  =s   Cc           	          t        j                  ddt        j                  dd|            }t        j                  dd|      }i }|dk7  r|j                  d      nd |d<   ||d<   g |d	<   g |d
<   g |d<   d |d<   |S )Nz\s*uuid:.*$r   z
^Label:\s*z^.*uuid:\s*none'labeluuidr,   mountpoints
subvolumesdefault_subvolid)r
   r   r/   )r#   r9   r>   id
filesystems        r   __parse_filesystemz BtrfsCommands.__parse_filesystem3   s    ~r266-T+JKVVNB-
276/ekk#.t
7
6 "
9$&
=!#%
< )-
%&r   c                 0    t        j                  dd|      S )Nz	^.*path\sr   )r
   r   )r#   r9   s     r   __parse_filesystem_devicez'BtrfsCommands.__parse_filesystem_device@   s    vvlB--r   c                 `   | j                   d|}| j                  j                  |d      }|d   j                         D cg c]  }|j	                  d       }}dd ddg}t        |      d	kD  r1|j                  |d	d  D cg c]  }| j                  |       c}       |S c c}w c c}w )
Nz subvolume list -tap Tr'   r)   	   r	   rC   parentr      )r!   r   r-   r.   splitr   extend+_BtrfsCommands__parse_subvolume_list_record)r#   filesystem_pathr4   r   r5   r6   rA   s          r   subvolumes_listzBtrfsCommands.subvolumes_listC   s    15O**7T*B)/)=)=)?@A!''$-@@$<=
v;?fUVUWjYtAA!DYZ	 A Zs   B&B+c                 V    t        |d         t        |d         t        |d         dS )Nr   rM   rJ   rK   )intr   )r#   items     r   __parse_subvolume_list_recordz+BtrfsCommands.__parse_subvolume_list_recordL   s.    d1g,$q'l,T!W5
 	
r   c                     | j                   ddt        |      g}| j                  j                  |d      }t	        |d   j                         j                         d         S )N	subvolumezget-defaultTr'   r)   )r!   r   r   r-   rT   r/   rN   )r#   rQ   r4   r   s       r   subvolume_get_defaultz#BtrfsCommands.subvolume_get_defaultS   sV    <<mXo=VW**7T*B6!9??$**,Q/00r   c                     | j                   ddt        |      t        |      g}| j                  j	                  |d      }y )NrX   zset-defaultTr'   )r!   strr   r   r-   )r#   rQ   subvolume_idr4   r   s        r   subvolume_set_defaultz#BtrfsCommands.subvolume_set_defaultY   s;    <<mS=NPXYhPij**7T*Br   c                 p    | j                   ddt        |      g}| j                  j                  |d      }y )NrX   createTr'   r!   r   r   r-   r#   subvolume_pathr4   r   s       r   subvolume_createzBtrfsCommands.subvolume_create]   2    <<h8PQ**7T*Br   c                     | j                   ddt        |      t        |      g}| j                  j                  |d      }y )NrX   snapshotTr'   r`   )r#   snapshot_sourcesnapshot_destinationr4   r   s        r   subvolume_snapshotz BtrfsCommands.subvolume_snapshota   s;    <<j(?:SU]^rUst**7T*Br   c                 p    | j                   ddt        |      g}| j                  j                  |d      }y )NrX   deleteTr'   r`   ra   s       r   subvolume_deletezBtrfsCommands.subvolume_deletee   rd   r   N)r   r   r   __doc__r%   r:   r1   r3   rR   rP   rY   r]   rc   ri   rl   r   r   r   r   r      sC    J.
1CCCCr   r   c                   F    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)BtrfsInfoProviderzP
    Utility providing details of the currently available btrfs filesystems
    c                 v    || _         t        |      | _        | j                   j                  dd      | _        y )NfindmntTr   )_BtrfsInfoProvider__moduler   _BtrfsInfoProvider__btrfs_apir     _BtrfsInfoProvider__findmnt_pathr"   s     r   r%   zBtrfsInfoProvider.__init__p   s2    (0"mm88T8Rr   c                    | j                   j                         }| j                         }|D ][  }| j                  ||d         }||d<   t	        |      dkD  s,|d   d   }| j                  |      |d<   | j                  |      |d<   ] |S )Nr,   r@   r   
mountpointrA   rB   )rs   r:   $_BtrfsInfoProvider__find_mountpoints2_BtrfsInfoProvider__filter_mountpoints_for_devicesr   get_subvolumesget_default_subvolume_id)r#   r7   r@   rD   device_mountpointsrv   s         r   get_filesystemsz!BtrfsInfoProvider.get_filesystemsu   s    &&668--/% 		[J!%!F!F{T^_hTi!j(:J}%%&* 02<@
+/+>+>z+J
<(151N1Nz1Z
-.		[ r   c                 F    | j                         }| j                  ||      S N)rw   rx   )r#   filesystem_devicesr@   s      r   get_mountpointsz!BtrfsInfoProvider.get_mountpoints   s$    --/44[BTUUr   c                 8    | j                   j                  |      S r~   )rs   rR   r#   rQ   s     r   ry   z BtrfsInfoProvider.get_subvolumes   s    //@@r   c                 8    | j                   j                  |      S r~   )rs   rY   r   s     r   rz   z*BtrfsInfoProvider.get_default_subvolume_id   s    55oFFr   c                 <    |D cg c]  }|d   |v s| c}S c c}w )Ndevicer   )r#   r@   r,   ms       r    __filter_mountpoints_for_devicesz2BtrfsInfoProvider.__filter_mountpoints_for_devices   s!    &Ca1X;'+ACCCs   c                     d| j                   z  }| j                  j                  |      }g }|d   dk(  r<|d   j                         }|D ]$  }| j	                  |      }|j                  |       & |S )Nz%s -t btrfs -nvPr   r)   )rt   rr   r-   r.   *_BtrfsInfoProvider__parse_mountpoint_pairsr2   )r#   r4   r   r@   linesr9   rv   s          r   __find_mountpointsz$BtrfsInfoProvider.__find_mountpoints   s}    $t':'::**73!9>1I((*E /!::4@
"":./ r   c                     t        j                  d      }|j                  |      }|.|j                         }|d   |d   | j	                  |d         dS t        d|z        )Nzl^TARGET="(?P<target>.*)"\s+SOURCE="(?P<source>.*)"\s+FSTYPE="(?P<fstype>.*)"\s+OPTIONS="(?P<options>.*)"\s*$targetsourceoptions)rv   r   subvolidz-Failed to parse findmnt result for line: '%s')r
   compilesearch	groupdict*_BtrfsInfoProvider__extract_mount_subvolidr   )r#   r9   patternmatchgroupss        r   __parse_mountpoint_pairsz*BtrfsInfoProvider.__parse_mountpoint_pairs   sz    **  M  Nt$__&F %X. * 99&:KL  ''VY]']^^r   c                     |j                  d      D ],  }|j                  d      st        |t        d      d        c S  t	        d|z        )N,z	subvolid=z6Failed to find subvolid for mountpoint in options '%s')rN   r0   rT   r   r   )r#   mount_optionsoptions      r   __extract_mount_subvolidz*BtrfsInfoProvider.__extract_mount_subvolid   sV    #))#. 	6F  -6#k"2"3455	6 ##[^k#kllr   N)r   r   r   rm   r%   r|   r   ry   rz   rx   rw   r   r   r   r   r   ro   ro   j   s;    S
 VAGD	_mr   ro   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zed        Zed        Zed        Zed        Zed        Zy)BtrfsSubvolumezY
    Wrapper class providing convenience methods for inspection of a btrfs subvolume
    c                      || _         || _        y r~   )_BtrfsSubvolume__filesystem_BtrfsSubvolume__subvolume_id)r#   rD   r\   s      r   r%   zBtrfsSubvolume.__init__   s    &*r   c                     | j                   S r~   )r   r#   s    r   get_filesystemzBtrfsSubvolume.get_filesystem   s       r   c                 J    | j                         }|d uxr t        |      dkD  S Nr   )r   r   r#   r@   s     r   
is_mountedzBtrfsSubvolume.is_mounted   s*    **,$&?3{+;a+??r   c                      d| j                   k(  S )NrJ   r   r   s    r   is_filesystem_rootz!BtrfsSubvolume.is_filesystem_root   s    D''''r   c                 H    | j                   j                  | j                  k(  S r~   )r   rB   r   r   s    r   is_filesystem_defaultz$BtrfsSubvolume.is_filesystem_default   s      11T5H5HHHr   c                 *   | j                         }|t        |      dkD  r|d   S | j                  b| j                  j	                  | j                        }|j                         }|*|t        j                  j                  z   | j                  z   S y y r   )
r   r   rL   r   get_subvolume_by_idget_mounted_pathosr   sepname)r#   r@   rL   parent_paths       r   r   zBtrfsSubvolume.get_mounted_path   s    **,"s;'7!';q>![[$&&::4;;GF 113K&"RWW[[0499<< ' r   c                 L    | j                   j                  | j                        S r~   )r   get_mountpoints_by_subvolume_idr   r   s    r   r   zBtrfsSubvolume.get_mountpoints   s      @@ATATUUr   c                     | j                   }|j                  |      r%|t        |      d }t        j                  dd|      S t        d|d|d      )z
        Get the relative path from this subvolume to the named child subvolume.
        The provided parameter is expected to be normalized as by normalize_subvolume_path.
        Nz^/*r   zPath 'z' doesn't start with 'r=   )r   r0   r   r
   r   r   )r#   absolute_child_pathr   relatives       r   get_child_relative_pathz&BtrfsSubvolume.get_child_relative_path   sP    
 yy))$/*3t9:6H66&"h//&Nacg'hiir   c                 X    | j                   }|| j                  j                  |      S d S r~   )rL   r   r   )r#   	parent_ids     r   get_parent_subvolumez#BtrfsSubvolume.get_parent_subvolume   s-    KK	CLCXt  44Y?b^bbr   c                 L    | j                   j                  | j                        S r~   )r   get_subvolume_childrenr   r   s    r   get_child_subvolumesz#BtrfsSubvolume.get_child_subvolumes   s      778K8KLLr   c                 L    | j                   j                  | j                        S r~   )r   get_subvolume_info_for_idr   r   s    r   __infozBtrfsSubvolume.__info   s      ::4;N;NOOr   c                     | j                   S r~   r   r   s    r   rC   zBtrfsSubvolume.id   s    """r   c                 T    | j                   j                  d      j                         S )Nr	   )r   rN   popr   s    r   r   zBtrfsSubvolume.name   s    yys#''))r   c                      | j                   d   S Nr   _BtrfsSubvolume__infor   s    r   r   zBtrfsSubvolume.path   s    {{6""r   c                      | j                   d   S )NrL   r   r   s    r   rL   zBtrfsSubvolume.parent   s    {{8$$r   N)r   r   r   rm   r%   r   r   r   r   r   r   r   r   r   propertyr   rC   r   r   rL   r   r   r   r   r      s    +!@(I
V
jcM P P # # * * # # % %r   r   c                       e Zd ZdZd Zed        Zed        Zed        Zed        Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)BtrfsFilesystemzZ
    Wrapper class providing convenience methods for inspection of a btrfs filesystem
    c                     || _         |d   | _        |d   | _        |d   | _        d|v r|d   nd | _        | j                  d|v r|d   ng        | j                  d|v r
|d          y g        y )Nr?   r>   r,   rB   r@   rA   )_BtrfsFilesystem__provider_BtrfsFilesystem__uuid_BtrfsFilesystem__label_BtrfsFilesystem__devices"_BtrfsFilesystem__default_subvolid$_BtrfsFilesystem__update_mountpoints#_BtrfsFilesystem__update_subvolumes)r#   infoproviderr$   s       r   r%   zBtrfsFilesystem.__init__  s    " 6lG}i ?QTX>X$'9":^b!!$9N$}"5TVW  |t7Kl!3TQSTr   c                     | j                   S r~   )r   r   s    r   r?   zBtrfsFilesystem.uuid  s    {{r   c                     | j                   S r~   )r   r   s    r   r>   zBtrfsFilesystem.label  s    ||r   c                     | j                   S r~   )r   r   s    r   rB   z BtrfsFilesystem.default_subvolid  s    &&&r   c                 ,    t        | j                        S r~   )listr   r   s    r   r,   zBtrfsFilesystem.devices  s    DNN##r   c                 d    | j                          | j                          | j                          y r~   )refresh_mountpointsrefresh_subvolumesrefresh_default_subvolumer   s    r   refreshzBtrfsFilesystem.refresh#  s&      "!&&(r   c                     | j                   j                  t        | j                              }| j	                  |       y r~   )r   r   r   r   r   r   s     r   r   z#BtrfsFilesystem.refresh_mountpoints(  s-    oo55d4>>6JK!!+.r   c                     t               | _        |D ]G  }|d   }|d   }|| j                  vrg | j                  |<   | j                  |   j                  |       I y )Nr   rv   )dict_BtrfsFilesystem__mountpointsr2   )r#   r@   ir   rv   s        r   __update_mountpointsz$BtrfsFilesystem.__update_mountpoints,  sd    !V 	<A}H<Jt111/1""8,x(//
;	<r   c                     | j                         }|-| j                  j                  |      }| j                  |       y y r~   )get_any_mountpointr   ry   r   )r#   rQ   rA   s      r   r   z"BtrfsFilesystem.refresh_subvolumes5  s=    113&77HJ$$Z0 'r   c                 T    t               | _        |D ]  }|| j                  |d   <    y )NrC   )r   _BtrfsFilesystem__subvolumes)r#   rA   rX   s      r   __update_subvolumesz#BtrfsFilesystem.__update_subvolumes;  s/     F# 	;I1:Dio.	;r   c                 j    | j                         }|!| j                  j                  |      | _        y y r~   )r   r   rz   r   r   s     r   r   z)BtrfsFilesystem.refresh_default_subvolumeA  s2    113&&*oo&N&N&_D# 'r   c                     || j                   v S r~   )r   )r#   r   s     r   contains_devicezBtrfsFilesystem.contains_deviceF  s    ''r   c                 (    | j                  |      d uS r~   )get_subvolume_by_name)r#   rX   s     r   contains_subvolumez"BtrfsFilesystem.contains_subvolumeI  s    )))4D@@r   c                 :    || j                   v rt        | |      S d S r~   )r   r   r#   r\   s     r   r   z#BtrfsFilesystem.get_subvolume_by_idL  s"    5ATEVEV5V~dL1`\``r   c                 @    || j                   v r| j                   |   S d S r~   )r   r   s     r   r   z)BtrfsFilesystem.get_subvolume_info_for_idO  s&    2>$BSBS2St  .]Y]]r   c                 t    | j                   j                         D ]  }|d   |k(  st        | |d         c S  y )Nr   rC   r   valuesr   )r#   rX   subvolume_infos      r   r   z%BtrfsFilesystem.get_subvolume_by_nameR  sF    "//668 	BNf%2%dN4,@AA	B r   c                 l    | j                   j                         D ]  }t        |      dkD  s|d   c S  y r   )r   r   r   )r#   subvol_mountpointss     r   r   z"BtrfsFilesystem.get_any_mountpointX  s?    "&"4"4";";"= 	-%&*)!,,	- r   c                     | j                   j                         D ]&  \  }}t        |      dkD  s| j                  |      c S  y r   )r   itemsr   r   )r#   r   r   s      r   get_any_mounted_subvolumez)BtrfsFilesystem.get_any_mounted_subvolume_  sJ    ,0,>,>,D,D,F 	:(H(%&*//99	: r   c                 @    || j                   v r| j                   |   S g S r~   )r   r   s     r   r   z/BtrfsFilesystem.get_mountpoints_by_subvolume_ide  s&    3?4CUCU3Ut!!,/][]]r   c                     | j                         }t        |      dkD  r<||v rt        | ||   d         S t        j                  dd|      }t        |      dkD  r<t        | d      S )zMReturn the identified subvolume if existing, else the closest matching parentr)   rC   z/[^/]+$r   rJ   )(_BtrfsFilesystem__get_subvolumes_by_pathr   r   r
   r   )r#   rX   subvolumes_by_paths      r   get_nearest_subvolumez%BtrfsFilesystem.get_nearest_subvolumeh  sm    !::<)nq ..%d,>y,I$,OPPFF:r9=		 )nq  dA&&r   c                    | j                  |      }|j                  |k(  r|j                         }||j                         t	        d|z        |j                         t
        j                  j                  z   |j                  |      z   S )z>Find a path to the target subvolume through a mounted ancestorz=Failed to find a path '%s' through a mounted parent subvolume)r  r   r   r   r   r   r   r   )r#   subvolume_namenearests      r   get_mountpath_as_childz&BtrfsFilesystem.get_mountpath_as_childs  s~    ,,^<<<>)224G?g668@&'fiw'wxx++-;g>]>]^l>mmmr   c                     | j                   j                         D cg c]  }|d   |k(  st        | |d          c}S c c}w )NrL   rC   r   )r#   r\   r5   s      r   r   z&BtrfsFilesystem.get_subvolume_children}  s?    7;7H7H7O7O7Qq!UVW_U`dpUptQtW-qqqs   ??c                 \    i }| j                   j                         D ]  }|d   }|||<    |S r   )r   r   )r#   r   sr   s       r   __get_subvolumes_by_pathz(BtrfsFilesystem.__get_subvolumes_by_path  s>    ""))+ 	AV9DF4L	 r   c                 R    | j                   d uxr t        | j                         dkD  S r   )r   r   r   s    r   r   zBtrfsFilesystem.is_mounted  s(    !!-M#d6H6H2IA2MMr   c           	      $   g }| j                   | j                   j                         ng }|D ]2  }|d   }|j                  ||d   |d   | j                  |      d       4 | j                  | j
                  | j                  | j                  |dS )NrC   r   rL   )rC   r   rL   r@   )default_subvolumer,   r>   r?   rA   )r   r   r2   r   r   r   r   r   )r#   rA   sourcesrX   rC   s        r   get_summaryzBtrfsFilesystem.get_summary  s    
040A0A0M$##**,SU  	I4B!&)#H-#CCBG	 	 "&!8!8~~\\KK$
 	
r   N)r   r   r   rm   r%   r   r?   r>   rB   r,   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r   r  r   r  r   r   r   r   r      s    U     ' ' $ $)
/<1;`
(Aa^^	'nrN
r   r   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	BtrfsFilesystemsProviderz?
    Provides methods to query available btrfs filesystems
    c                 @    || _         t        |      | _        d | _        y r~   )!_BtrfsFilesystemsProvider__modulero   #_BtrfsFilesystemsProvider__provider&_BtrfsFilesystemsProvider__filesystemsr"   s     r   r%   z!BtrfsFilesystemsProvider.__init__  s    +F3!r   c                 b   |d   %t         j                  j                  |d         |d<   | j                          | j                  j                         D cg c]  }| j                  ||      s| }}t        |      dk(  r|d   S t        dt        |      |d   |d   |d   fz        c c}w )Nr   r)   r   zAFound %d filesystems matching criteria uuid=%s label=%s device=%sr?   r>   )	r   r   realpath%_BtrfsFilesystemsProvider__check_initr  r   6_BtrfsFilesystemsProvider__filesystem_matches_criteriar   r   )r#   criteriafmatchings       r   get_matching_filesystemz0BtrfsFilesystemsProvider.get_matching_filesystem  s    H)!#!1!1(82D!EHX#1188:n!d>`>`abdl>mAnnx=AA;&'jH !"	n (  	 os   B,/B,c                     |d   d u xs |j                   |d   k(  xr: |d   d u xs |j                  |d   k(  xr |d   d u xs |j                  |d         S )Nr?   r>   r   )r?   r>   r   )r#   rD   r  s      r   __filesystem_matches_criteriaz6BtrfsFilesystemsProvider.__filesystem_matches_criteria  sy    &!T)PZ__@P-P _'"d*Sj.>.>(7BS.S_(#t+]z/I/I(S[J\/]	`r   c                     t         j                  j                  |      }| j                          | j                  j                         D ]  }|j                  |      s|c S  y r~   )r   r   r  r  r  r   r   )r#   r   real_devicefss       r   get_filesystem_for_devicez2BtrfsFilesystemsProvider.get_filesystem_for_device  sX    gg&&v.$$++- 	B!!+.		 r   c                 h    | j                          t        | j                  j                               S r~   )r  r   r  r   r   s    r   r|   z(BtrfsFilesystemsProvider.get_filesystems  s(    D&&--/00r   c                     | j                   bt               | _         | j                  j                         D ]5  }|d   }t	        || j                  | j
                        | j                   |<   7 y y )Nr?   )r  r   r  r|   r   r  )r#   r  r?   s      r   __check_initz%BtrfsFilesystemsProvider.__check_init  se    %!%D__446 ^y+:1doot}}+]""4(^ &r   N)
r   r   r   rm   r%   r   r  r&  r|   r  r   r   r   r  r    s'    "
 `
1^r   r  )
__future__r   r   r   type__metaclass__+ansible.module_utils.common.text.convertersr   r
   r   r   	Exceptionr   objectr   ro   r   r   r  r   r   r   <module>r0     s{   
 C B @ 	 	.	9 	LCF LC^Em EmPK%V K%\\
f \
~1^v 1^r   