
    VhO                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
d dlZd dlmZ d dlmZ d dlmZmZ  G d	 d
e      Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona  
module: snap
short_description: Manages snaps
description:
  - Manages snaps packages.
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  name:
    description:
      - Name of the snaps to be installed.
      - Any named snap accepted by the C(snap) command is valid.
      - O(dangerous=true) may be necessary when installing C(.snap) files. See O(dangerous) for more details.
    required: true
    type: list
    elements: str
  state:
    description:
      - Desired state of the package.
      - When O(state=present) the module will use C(snap install) if the snap is not installed, and C(snap refresh) if it
        is installed but from a different channel.
    default: present
    choices: [absent, present, enabled, disabled]
    type: str
  classic:
    description:
      - Install a snap that has classic confinement.
      - This option corresponds to the C(--classic) argument of the C(snap install) command.
      - This level of confinement is permissive, granting full system access, similar to that of traditionally packaged applications
        that do not use sandboxing mechanisms. This option can only be specified when the task involves a single snap.
      - See U(https://snapcraft.io/docs/snap-confinement) for more details about classic confinement and confinement levels.
    type: bool
    required: false
    default: false
  channel:
    description:
      - Define which release of a snap is installed and tracked for updates. This option can only be specified if there is
        a single snap in the task.
      - If not passed, the C(snap) command will default to V(stable).
      - If the value passed does not contain the C(track), it will default to C(latest). For example, if V(edge) is passed,
        the module will assume the channel to be V(latest/edge).
      - See U(https://snapcraft.io/docs/channels) for more details about snap channels.
    type: str
    required: false
  options:
    description:
      - Set options with pattern C(key=value) or C(snap:key=value). If a snap name is given, the option will be applied to
        that snap only. If the snap name is omitted, the options will be applied to all snaps listed in O(name). Options will
        only be applied to active snaps.
      - Options will only be applied when C(state) is set to V(present). This is done after the necessary installation or
        refresh (upgrade/downgrade) of all the snaps listed in O(name).
      - See U(https://snapcraft.io/docs/configuration-in-snaps) for more details about snap configuration options.
    required: false
    type: list
    elements: str
    version_added: 4.4.0
  dangerous:
    description:
      - Install the snap in dangerous mode, without validating its assertions and signatures.
      - This is useful when installing local snaps that are either unsigned or have signatures that have not been acknowledged.
      - See U(https://snapcraft.io/docs/install-modes) for more details about installation modes.
    type: bool
    required: false
    default: false
    version_added: 7.2.0
notes:
  - Privileged operations, such as installing and configuring snaps, require root priviledges. This is only the case if the
    user has not logged in to the Snap Store.
author:
  - Victor Carceler (@vcarceler) <vcarceler@iespuigcastellar.xeill.net>
  - Stanislas Lange (@angristan) <angristan@pm.me>

seealso:
  - module: community.general.snap_alias
a  
# Install "foo" and "bar" snap
- name: Install foo
  community.general.snap:
    name:
      - foo
      - bar

# Install "foo" snap with options par1=A and par2=B
- name: Install "foo" with options
  community.general.snap:
    name:
      - foo
    options:
      - par1=A
      - par2=B

# Install "foo" and "bar" snaps with common option com=A and specific options fooPar=X and barPar=Y
- name: Install "foo" and "bar" with options
  community.general.snap:
    name:
      - foo
      - bar
    options:
      - com=A
      - foo:fooPar=X
      - bar:barPar=Y

# Remove "foo" snap
- name: Remove foo
  community.general.snap:
    name: foo
    state: absent

# Install a snap with classic confinement
- name: Install "foo" with option --classic
  community.general.snap:
    name: foo
    classic: true

# Install a snap with from a specific channel
- name: Install "foo" with option --channel=latest/edge
  community.general.snap:
    name: foo
    channel: latest/edge
a  
classic:
  description: Whether or not the snaps were installed with the classic confinement.
  type: bool
  returned: When snaps are installed
channel:
  description: The channel the snaps were installed from.
  type: str
  returned: When snaps are installed
cmd:
  description: The command that was executed on the host.
  type: str
  returned: When changed is true
snaps_installed:
  description: The list of actually installed snaps.
  type: list
  returned: When any snaps have been installed
snaps_removed:
  description: The list of actually removed snaps.
  type: list
  returned: When any snaps have been removed
options_changed:
  description: The list of options set/changed in format C(snap:key=value).
  type: list
  returned: When any options have been changed/set
  version_added: 4.4.0
version:
  description: Versions of snap components as reported by C(snap version).
  type: dict
  returned: always
  version_added: 10.3.0
N)	to_native)StateModuleHelper)snap_runnerget_versionc                      e Zd ZdZdZdZ ej                  d      Z ej                  d      Z	 ej                  d      Z
 e eddd	
       eddg d       edd       ed       edd       edd      dd	      ZdZed        Zd Zd Zd'dZd(dZd Zd Zd Zd Zd Zd)d Zd! Zd" Zd# Zd$ Zd% Zd& Zy)*Snapr         z(?:\S+\s+){5}(?P<notes>\S+)z6(?P<snap_prefix>\S+:)?(?P<key>\S+)\s*=\s*(?P<value>.+)z-^(?P<name>\S+)\s+\S+\s+\S+\s+(?P<channel>\S+)liststrT)typeelementsrequiredpresent)absentr   enableddisabled)r   defaultchoicesboolF)r   r   )r   )r   r   )namestateclassicchanneloptions	dangerous)argument_specsupports_check_modec                 $    | D ]  }|dk7  s	|c S  y)Nr    )aelems     j/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/snap.py_first_non_zerozSnap._first_non_zero   s"     	Dqy	     c           	      J   t        | j                        | _        t        | j                        | j                  _        | j                  j                  dg | j                  dk\         | j                  j                  dg | j                  dk\         | j                  j                  dd | j                  dk\         | j                  j                  dg | j                  dk\         | j                  j                  dk(  rB| j                  j                  d| j                  | j                  j                               d}nd	}| j                  j                  d
|d       | j                  j                  d| j                  | j                  | j                  j                     | j                  j                        dd       | j                  j                  dt        t        | j                  j                  | j                  j                              dd       y )Nsnapinfo_run_info   outputstatus_run_info
status_outrun_infor   
snap_namesr   
status_varFsnap_statusT)r-   changesnap_status_map)r   modulerunnerr	   varsversionset	verbosityr   names_from_snapsr   r3   r2   r   dictzip)selfr2   s     r&   __init_module__zSnap.__init_module__   s   !$++.'4		 			)2t~~7JL		'T^^q5HJ		lD$..A2EG		j"dnn.AC99??i'IIMM,(=(=diinn(MN%JJ		lJu=		mT%5%5dii		@T@T6UW[W`W`WhWh%irw  AE  	F		'c$))..$))BWBW.X)Ybgptur(   c                     | j                  | j                  | j                  j                     | j                  j                        | j                  _         | j                  j                  d| j                  _        y y )Nstable)r3   r8   r2   r   r?   s    r&   __quit_module__zSnap.__quit_module__   s\     $ 0 0499;O;O1PRVR[R[RcRc d		99$ (DII %r(   c                    g }g }g }g }g }	|rdn| j                   j                  }
| j                  |dgz         5 }|r|j                  |
|      \  }}}|j	                  ||z          |j	                  |       |j	                  |j                                |j	                  |j                                |	j	                  |j                         n|D ]  }|j                  |
|      \  }}}|j	                  ||gz          |j	                  |       |j	                  |j                                |j	                  |j                                |	j	                  |j                          d d d        dj                  |D cg c]  }t        |       c}      | j                  |      dj                  |      dj                  |      |	fS # 1 sw Y   cxY wc c}w )Nrefreshr   )r   r   z; 
)
r8   r   r7   runappendstripr0   joinr   r'   )r?   commandsactionable_namesbundlerF   results_cmd
results_rcresults_outresults_errresults_run_infor   ctxrcouterrr   xs                    r&   _run_multiple_commandszSnap._run_multiple_commands   s   
$	$))//[[VH,- 	:"wwU9IwJC""8.>#>?!!"%""399;/""399;/ ''5, :D#&77T7#BLBS&&x4&'89%%b)&&syy{3&&syy{3$++CLL9:	:$ II[9y|9:  ,IIk"IIk"
 	
#	: 	:$ :s   D6GGGNc                 J   i }t        |t              s| j                  d       |j                         D ]l  \  }}||n|dz   |z   }t        |t        t
        t        t        j                  f      rt	        |      ||<   K|j                  | j                  ||             n |S )Nz{Non-dict non-leaf element encountered while parsing option map. The output format of 'snap set' may have changed. Aborting!.)json_subtreeprefix)
isinstancer=   do_raiseitemsr   floatr   numbersIntegralupdateconvert_json_subtree_to_map)r?   r\   r]   
option_mapkeyvaluefull_keys          r&   re   z Snap.convert_json_subtree_to_map  s    
,-MM X Y ',,. 	iJC$ns&3,2DH%#udG4D4D!EF'*5z
8$!!$"B"BPU^f"B"gh	i r(   c                 N    t        j                  |      }| j                  |      S N)jsonloadsre   )r?   json_stringjson_objects      r&   convert_json_to_mapzSnap.convert_json_to_map$  s!    jj-//<<r(   c           	      f   | j                  d      5 }|j                  |      \  }}}d d d        dk7  ri S j                         }d|d   v ri S 	 | j                  |      }|S # 1 sw Y   =xY w# t        $ r6}| j                  dj                  |t        |      |             Y d }~y d }~ww xY w)Nzget namer   r   zhas no configurationzUParsing option map returned by 'snap get {0}' triggers exception '{1}', output:
'{2}'msg)r7   rH   
splitlinesrp   	Exceptionr_   formatr   )	r?   	snap_namerT   rU   rV   rW   resultrf   es	            r&   retrieve_option_mapzSnap.retrieve_option_map(  s    [[$ 	377	72LBS	3 7I!!VAY.I	M11#6J	3 	3  	MMMlsst}  @C  DE  @F  HK  L  M M	Ms#   A%A1 %A.1	B0:,B++B0c                 z    d fd fd}g }ra j                  d|      5 }	 |j                        } j                  j                  j	                  |j
                         	 d d d        |S |S #  j                  j                  j	                  |j
                         w xY w# 1 sw Y   |S xY w)Nc                     |j                  d      D cg c]  }|j                  d      s| }}|d   j                         d   }|gS c c}w )NrG   zname:r   r   )split
startswith)rU   rV   rW   lineresr   s         r&   process_onez*Snap.names_from_snaps.<locals>.process_one<  sI    $'IIdOPDtw7O4PCPq6<<>!$D6M Qs
   A
A
c                 n    |j                  d      }g }|D ]  }|j                   | |d              |S )Nz
--- )r~   extend)rU   rV   rW   outputsr   soutr   s         r&   process_manyz+Snap.names_from_snaps.<locals>.process_manyA  sA     ii(GC 6

;r4456Jr(   c           
         t        	      dk(  r|}}n|}}d|v r_j                  dj                  |j                  d      D cg c]&  }|j	                  d      r|j                         d   ( c}              || ||      S c c}w )Nr   zwarning: no snap foundzSnaps not found: {0}.rG   )lenr_   rw   r~   r   )
rU   rV   rW   check_errorprocess_rX   r   r   r?   snapss
         r&   processz&Snap.names_from_snaps.<locals>.processK  s    5zQ!&!'';65<<GJyyQU>iBCABNfAg ?@ggim >i j k BS))>is   +Bz	info name)output_processrr   )r7   rH   r8   r*   rI   r0   )r?   r   r   namesrT   r   r   s   ``   @@r&   r<   zSnap.names_from_snaps;  s    	
		* [A ESEGGG/EII//66s||D	E
 u II//66s||D	E
 s"   B0A< /B0<1B--B00B:c                    d }| j                  d      5 }|j                  d      \  }}}d d d        j                  d      dd  }|D 	cg c]  }	| j                  j	                  |	       }}	|D 
cg c]'  }
|
s|
j                  d      |
j                  d      f) }}
|| j                  _        j                  | j                  _	        |D cg c]  } ||||       c}S # 1 sw Y   xY wc c}	w c c}
w c c}w )	Nc                     |D cg c]  \  }}|| k(  s| }}}|st         j                  S |r(|d   |dj                  |      fvrt         j                  S t         j                  S c c}}w )Nr   z
latest/{0})r   NOT_INSTALLEDrw   CHANNEL_MISMATCH	INSTALLED)r   r   	installedncmatchs         r&   _status_checkz'Snap.snap_status.<locals>._status_checkc  sg    #,:41aT	Q:E:)))58G\5H5H5Q+RR,,,~~% ;s
   A'A'_listT)check_rcrG   r   r   r   )
r7   rH   r~   _Snap__list_rer   groupr8   r/   r0   r.   )r?   rx   r   r   rT   rU   rV   rW   list_outrX   mr   s               r&   r3   zSnap.snap_statusb  s    	& [[! 	2S77D71LBS	299T?12&5=>DNN((+>>CKQaqQWWV_aggi&89QQ'		$'LL		!=FGa(3GG	2 	2 ?Q Hs#   C&"C24C7<$C7C<&C/c                 r   | j                  d      5 }|j                  |      \  }}}d d d        dk7  ry j                         d   }| j                  j	                  |      }|s"| j                  dj                  ||             |j                  d      }d|j                  d	      vS # 1 sw Y   xY w)
Nz
_list namerr   r   r   z+Unable to parse 'snap list {0}' output:
{1}rs   notesr   ,)	r7   rH   ru   _Snap__disable_rer   r_   rw   r   r~   )	r?   rx   rT   rU   rV   rW   ry   r   r   s	            r&   is_snap_enabledzSnap.is_snap_enabledv  s    [[& 	3#77	72LBS	37!!$!!''/MMLSST]_bcMdG$S!111	3 	3s   B--B6c                    d| _         || j                  _        | j                  ry g d}t	        | j                  j
                        xs | j                  j                  dk7  }t        |      dkD  }|r-|r+| j                  ||d|      \  | j                  _	        }}}}	n)| j                  |||      \  | j                  _	        }}}}	|	| j                  _
        |dk(  ry t        j                  d	      }
|
j                  |      }|r$|j                  d
      }dj                  |      }n&dj                  | j                  j                        }| j!                  |       y )NT)r   r   r   r   rB   r   F)rN   rF   rF   r   z]^error: This revision of snap "(?P<package_name>\w+)" was published using classic confinementpackage_namez?Couldn't install {name} because it requires classic confinementrr   zoOoops! Snap installation failed while executing '{cmd}', please examine logs and error output for more details.cmdrs   )changedr8   snaps_installed
check_moder   r   r   r   rY   r   r0   recompiler   r   rw   r_   )r?   actionable_snapsrF   paramshas_one_pkg_paramshas_multiple_snapsrU   rV   rW   r0   classic_snap_patternr   err_pkgrt   s                 r&   _presentzSnap._present  sQ   $4		!??=!$))"3"34U		8I8IX8U !12Q6"4484O4OPVXhqv  AH4O  5I1DIIM2sC484O4OPVXhry4O4z1DIIM2sC%		7!zz +V  W$**3/kk.1GSZZ`gZhC3396diimm63L #r(   c                 4   | j                   j                  dd       | j                   j                  dd       | j                   j                  D cg c]/  }| j                   j                  |   t        j
                  k(  s.|1 }}|r| j                  |d       | j                   j                  D cg c]/  }| j                   j                  |   t        j                  k(  s.|1 }}|r| j                  |       | j                          y c c}w c c}w )Nr   Tr,   r   r   )	r8   set_metar   r5   r   r   r   r   set_options)r?   snapactionable_refreshactionable_installs       r&   state_presentzSnap.state_present  s    		9T2		9T2/3yy~~ztAZAZ[_A`dhdydyAydzzMM,dM;/3yy~~wtAZAZ[_A`dhdvdvAvdwwMM,- { xs   /DD6/D&Dc                    | j                   j                  y | j                   j                  D cg c]/  }| j                   j                  |   t        j
                  k7  s.|1 }}g }|D ]  }| j                  |      }g }| j                   j                  D ]  }| j                  j                  |      }|s#dj                  |      }	| j                  |	       |j                  d      }
|
r|
d d nd }|;|| j                   j                  vr#dj                  |      }	| j                  |	       |	|||k(  s|j                  d      }|j                  d      j                         }||vs||v s||   |k7  s|d	z   |z   }||n|d
z   |z   }|j                  |       |j                  |         |sSd| _        | j                  rh| j!                  d      5 }|j#                  ||      \  }}}d d d        dk7  sdv r#dj                  |      }	| j                  |	       dj                  dj%                  |      ||      }	| j                  |	        |r|| j                   _        y y c c}w # 1 sw Y   xY w)N)rx   z)Cannot parse set option '{option_string}')option_stringsnap_prefixr   zSSnap option '{option_string}' refers to snap which is not in the list of snap namesrg   rh   =:Tz_set name options)r   r   r   zhas no "configure" hookz4Snap '{snap}' does not have any configurable options)r   z?Cannot set options '{options}' for snap '{snap}': error={error} )r   r   error)r8   r   r   r5   r   r   r{   _Snap__set_param_rer   rw   r_   r   rJ   rI   r   r   r7   rH   rK   options_changed)r?   sr   overall_options_changedrx   rf   r   r   r   rt   r   selected_snap_namerg   rh   option_without_prefixoption_with_prefixrT   rU   rV   rW   s                       r&   r   zSnap.set_options  s   99$'+yy~~l!9R9RST9UY]YkYk9kAll"$) *	+I11I1FJ O!%!2!2 K++11-@ELL[hLiCMM#&#kk-89D["%5$"%16HPTPYPYP^P^6^ovv  FSv  TCMM#&%-)2GIYkLk++e,C!KK0668E*,z0AjQToY^F^03c	E0A->P>\]bknqbq  uB  cB*'../DE/667IJ-K0 #%89 XS'*wwIw'WCXQw4;"X"_"_en"_"oC MM#._ff$'HH_$=IUX g Zc*U*	+X #(?DII% #_ mHX Xs   /I= I=#JJ	c                    | j                   j                  D cg c]  } ||      s| }}|sy d| _        || j                   |<   | j                  ry | j	                  ||      \  | j                   _        }}}}	|	| j                   _        |dk(  ry dj                  | j                   j
                        }
| j                  |
       y c c}w )NTr   zlOoops! Snap operation failed while executing '{cmd}', please examine logs and error output for more details.r   rs   )	r8   r   r   r   rY   r   r0   rw   r_   )r?   actionable_funcactionable_varr   r   r   rU   rV   rW   r0   rt   s              r&   _generic_state_actionzSnap._generic_state_action  s    '+yy~~L!9KALL$4		.!??040K0KFTd0e-		r3X%		7//5v$))--v/H 	# Ms
   C
C
c                 6      j                   fddg d       y )Nc                 X    j                   j                  |    t        j                  k7  S rk   )r8   r5   r   r   r   r?   s    r&   <lambda>z#Snap.state_absent.<locals>.<lambda>  s!    TYY-F-Fq-ITM_M_-_ r(   snaps_removedr   r   r   r   rC   s   `r&   state_absentzSnap.state_absent  s    ""#_ap  sR  	Sr(   c                 6      j                   fddg d       y )Nc                 (    j                  |        S rk   )r   r   s    r&   r   z$Snap.state_enabled.<locals>.<lambda>  s    1E1Ea1H-H r(   snaps_enabledr   r   rC   s   `r&   state_enabledzSnap.state_enabled  s    ""#H/[z{r(   c                 B    | j                  | j                  dg d       y )Nsnaps_disabledr   )r   r   rC   s    r&   state_disabledzSnap.state_disabled  s    ""4#7#79IKjkr(   )TFrk   )F) __name__
__module____qualname__r   r   r   r   r   r   r   r   r=   r6   use_old_vardictstaticmethodr'   r@   rD   rY   re   rp   r{   r<   r3   r   r   r   r   r   r   r   r   r#   r(   r&   r   r      s   MI2::<=LRZZ YZN

KLIfutDuiAmn7'%8659
 !
F O v()
 
D"=M&%NH(
2>4@l S|lr(   r   c                  ,    t         j                          y rk   )r   executer#   r(   r&   mainr     s    LLNr(   __main__)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr   rl   rb   +ansible.module_utils.common.text.convertersr   Hansible_collections.community.general.plugins.module_utils.module_helperr   ?ansible_collections.community.general.plugins.module_utils.snapr   r	   r   r   r   r#   r(   r&   <module>r      sk    A @Ob-^
B 
   A f dAl AlH
 zF r(   