
    VhF                     N   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mZmZ d dlmZ d dlmZ d d	lmZ  G d
 d      Z G d 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 G d de      Zd Zedk(  r e        yy)    )absolute_importdivisionprint_functiona  
module: launchd
author:
  - Martin Migasiewicz (@martinm82)
short_description: Manage macOS services
version_added: 1.0.0
description:
  - Manage launchd services on target macOS hosts.
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  name:
    description:
      - Name of the service.
    type: str
    required: true
  plist:
    description:
      - Name of the V(.plist) file for the service.
      - Defaults to V({name}.plist).
    type: str
    version_added: 10.1.0
  state:
    description:
      - V(started)/V(stopped) are idempotent actions that will not run commands unless necessary.
      - Launchd does not support V(restarted) nor V(reloaded) natively. These will trigger a stop/start (restarted) or an
        unload/load (reloaded).
      - V(restarted) unloads and loads the service before start to ensure that the latest job definition (plist) is used.
      - V(reloaded) unloads and loads the service to ensure that the latest job definition (plist) is used. Whether a service
        is started or stopped depends on the content of the definition file.
    type: str
    choices: [reloaded, restarted, started, stopped, unloaded]
  enabled:
    description:
      - Whether the service should start on boot.
      - B(At least one of state and enabled are required).
    type: bool
  force_stop:
    description:
      - Whether the service should not be restarted automatically by launchd.
      - Services might have the 'KeepAlive' attribute set to true in a launchd configuration. In case this is set to true,
        stopping a service will cause that launchd starts the service again.
      - Set this option to V(true) to let this module change the C(KeepAlive) attribute to V(false).
    type: bool
    default: false
notes:
  - A user must privileged to manage services using this module.
requirements:
  - A system managed by launchd
  - The plistlib Python library
a  
- name: Make sure spotify webhelper is started
  community.general.launchd:
    name: com.spotify.webhelper
    state: started

- name: Deploy custom memcached job definition
  template:
    src: org.memcached.plist.j2
    dest: /Library/LaunchDaemons/org.memcached.plist

- name: Run memcached
  community.general.launchd:
    name: org.memcached
    state: started

- name: Stop memcached
  community.general.launchd:
    name: org.memcached
    state: stopped

- name: Stop memcached
  community.general.launchd:
    name: org.memcached
    state: stopped
    force_stop: true

- name: Restart memcached
  community.general.launchd:
    name: org.memcached
    state: restarted

- name: Unload memcached
  community.general.launchd:
    name: org.memcached
    state: unloaded

- name: restart sshd
  community.general.launchd:
    name: com.openssh.sshd
    plist: ssh.plist
    state: restarted
z
status:
  description: Metadata about service status.
  returned: always
  type: dict
  sample:
    {
      "current_pid": "-",
      "current_state": "stopped",
      "previous_pid": "82636",
      "previous_state": "running"
    }
N)ABCMetaabstractmethod)sleep)AnsibleModule)	to_nativec                   0    e Zd ZdZdZdZdZdZed        Z	y)ServiceStater               c           
          t         j                  dt         j                  dt         j                  dt         j                  dt         j
                  di}||    S )Nunknownloadedstoppedstartedunloaded)r   UNKNOWNLOADEDSTOPPEDSTARTEDUNLOADED)statestringss     m/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/launchd.py	to_stringzServiceState.to_string   sN       )  )  )!!:
 u~    N)
__name__
__module____qualname__r   r   r   r   r   staticmethodr    r    r   r   r      s-    GFGGH r    r   c                   P    e Zd ZddZed        Zd Zd ZddZd Z	d Z
d	 Zd
 Zy)PlistNc                    d| _         || _        ||| _        n
d|z  | _        t        || j                        j	                         \  }}}}t        t        d      | _        | j                  | j                        | _	        | j                  Hd| j                  d| j                  }||t        j                  k(  r|dz  }|j                  |       | j                  |       y )NFz%s.plist	readPlistzUnable to find the plist file z for service z+ and it was not found among active servicesmsg)_Plist__changed_Plist__service_Plist__filenameLaunchCtlListrunhasattrplistlibold_plistlib_Plist__find_service_plist_Plist__filer   r   	fail_json_Plist__update)selfmoduleservicefilenamer   piddummyr+   s           r   __init__zPlist.__init__   s     &DO(72DO#0#H#L#L#N sE5 $Hk://@;;C {u(=(==DD%fr    c                    t         j                  j                  t        j                  d      d      ddddg}|D ]>  }	 t        j                  |      }| |v st         j                  j                  ||       c S  y# t
        $ r Y Mw xY w)z.Finds the plist file associated with a serviceHOMEzLibrary/LaunchAgentsz/Library/LaunchAgentsz/Library/LaunchDaemonsz/System/Library/LaunchAgentsz/System/Library/LaunchDaemonsN)ospathjoingetenvlistdirOSError)r;   launchd_pathsrB   filess       r   __find_service_plistzPlist.__find_service_plist   s    
 GGLL6*,BC#$*+
 " 	4D

4( 5 ww||D(33	4   s   A==	B	B	c                 H    | j                  |       | j                  |       y N)_Plist__handle_param_enabled_Plist__handle_param_force_stop)r8   r9   s     r   __updatezPlist.__update   s    ##F+&&v.r    c           	      h   i }| j                   rt        j                  | j                        S 	 t	        | j                  d      5 }t        j
                  |      }d d d        |S # 1 sw Y   |S xY w# t        $ r6}|j                  d| j                  dt        |             Y d }~|S d }~ww xY w)NrbzFailed to read plist file  due to r*   )	r3   r2   r)   r5   openload	Exceptionr6   r
   r8   r9   service_plistplist_fpes        r   __read_plist_filezPlist.__read_plist_file   s    %%dkk22	Odkk4( 8H (h 78
 8
   	O37;;	!"N O O	Os5   A2 A%A2 %A/*A2 /A2 2	B1;+B,,B1c           	      l   |si }| j                   r!t        j                  || j                         y 	 t	        | j                  d      5 }t        j
                  ||       d d d        y # 1 sw Y   y xY w# t        $ r5}|j                  d| j                  dt        |             Y d }~y d }~ww xY w)NwbzFailed to write to plist file  rQ   r*   )	r3   r2   
writePlistr5   rR   dumprT   r6   r
   rU   s        r   __write_plist_filezPlist.__write_plist_file   s    Mt{{;	Pdkk4( 7HmX67 7 7 	P48KK1"O P P	Ps5   A5 	A) A5 )A2.A5 2A5 5	B3>+B..B3c                     |j                   d   | j                  |      }|j                   d   ^|j                  dd      }|j                   d   |k7  r9|j                   d   |d<   |j                  s| j	                  ||       d| _        y y y y y )Nenabled	RunAtLoadFTparams_Plist__read_plist_fileget
check_mode_Plist__write_plist_filer,   )r8   r9   rV   r`   s       r   __handle_param_enabledzPlist.__handle_param_enabled   s    ==#/ 226:M }}Y'3'++K?==+w617y1IM+. ",,//F)- -	 7 4 0r    c                 "   |j                   d   | j                  |      }|j                   d   _|j                  dd      }|j                   d   r=|r:|j                   d    |d<   |j                  s| j	                  ||       d| _        y y y y y y )N
force_stop	KeepAliveFTrb   )r8   r9   rV   
keep_alives       r   __handle_param_force_stopzPlist.__handle_param_force_stop   s    ==&2 226:M }}\*6*..{EB
==.:5;]]<5P1PM+. ",,//F)- -	 4>. 7 3r    c                     | j                   S rK   )r,   r8   s    r   
is_changedzPlist.is_changed  s    ~~r    c                     | j                   S rK   )r5   ro   s    r   get_filezPlist.get_file  s    {{r    rK   )r!   r"   r#   r>   r$   r4   r7   rd   rg   rL   rM   rp   rr   r%   r    r   r'   r'      s?    .  */P.$. r    r'   c                   `    e Zd ZeZdZd Zd Zed        Z	d Z
d Zd Zd Zd	 Zd
 Zd Zd Zy)LaunchCtlTask   c                 p    || _         || _        || _        | j                   j                  dd      | _        y )N	launchctlT)_module_service_plistget_bin_path_launch)r8   r9   r:   plists       r   r>   zLaunchCtlTask.__init__  s/    ||00dCr    c                 B    | j                          | j                         S )zwRuns a launchd command like 'load', 'unload', 'start', 'stop', etc.
        and returns the new state and pid.
        )
runCommand	get_statero   s    r   r0   zLaunchCtlTask.run  s     	~~r    c                      y rK   r%   ro   s    r   r   zLaunchCtlTask.runCommand#  s    r    c                    | j                  d      \  }}}|dk7  r)| j                  j                  d| j                  z         t        j
                  }d}d }|j                         D ]  }|j                         s|j                  d      \  }}	}
|
j                         | j                  k(  sG|}|	}|	dvrt        j                  }n&|dk7  rt        j                  }nt        j                  } n ||||fS )Nlistr   zFailed to get status of %sr*   -	)0z-2z-3z-9z-15)
_launchctlrx   r6   r|   r   r   
splitlinesstripsplitry   r   r   r   )r8   rcouterrr   service_pidstatus_codeliner<   last_exit_codelabels              r   r   zLaunchCtlTask.get_state'  s    v.C7LL""0DLLA # C %%NN$ 	Dzz|-1ZZ-=*^U;;=DMM1"%K"0K &-KK !- 4 4 !- 4 4 !- 4 43	4 {K55r    c                 `    | j                  d      \  }}}t        | j                         |||fS )Nstartr   r   WAITING_TIMEr8   r   r   r   s       r   r   zLaunchCtlTask.startL  s0    w/Cd C~r    c                 `    | j                  d      \  }}}t        | j                         |||fS )Nstopr   r   s       r   r   zLaunchCtlTask.stopR  s0    v.Cd C~r    c                 B    | j                          | j                         S rK   )r   r   ro   s    r   restartzLaunchCtlTask.restartX  s    		zz|r    c                 B    | j                          | j                         S rK   )unloadrS   ro   s    r   reloadzLaunchCtlTask.reload]  s    yy{r    c                 $    | j                  d      S )NrS   r   ro   s    r   rS   zLaunchCtlTask.loadb  s    v&&r    c                 $    | j                  d      S )Nr   r   ro   s    r   r   zLaunchCtlTask.unloade  s    x((r    c           	      r   |dv r| j                   j                         n|dv r| j                  nd}| j                  j	                  | j
                  d|d|      \  }}}|dk7  rMd|d| j                  d| j                   j                         d	|d
	}| j                  j                  |       |||fS )N)rS   r   )r   r     r   z
Unable to z 'z' (z): ''r*   )rz   rr   ry   rx   run_commandr|   r6   )r8   commandservice_or_plistr   r   r   r+   s          r   r   zLaunchCtlTask._launchctlh  s    5< A 64;;//14;?P4P4==VX 	 ||//,,1ABDC 7(<(<(>ECLL""s"+C~r    N)r!   r"   r#   r   __metaclass__r   r>   r0   r   r   r   r   r   r   r   rS   r   r   r%   r    r   rt   rt     sT    MLD   #6J

')r    rt   c                   $     e Zd Z fdZd Z xZS )LaunchCtlStartc                 0    t         t        |   |||       y rK   )superr   r>   r8   r9   r:   r}   	__class__s       r   r>   zLaunchCtlStart.__init__x  s    nd,VWeDr    c                 "   | j                         \  }}}}|t        j                  t        j                  fv r!| j	                          | j                          y |t        j                  k(  r<| j                  j                         r!| j	                          | j                          y y |t        j                  k(  r!| j                          | j                          y |t        j                  k(  r!| j	                          | j                          y y rK   )r   r   r   r   r   r   r   rz   rp   r   rS   r   r8   r   r=   s      r   r   zLaunchCtlStart.runCommand{  s    %)^^%5"ueU\))<+>+>??KKMJJLl*** {{%%'

 ( l+++IIKJJLl*** KKMJJL	 +r    r!   r"   r#   r>   r   __classcell__r   s   @r   r   r   w  s    Er    r   c                   $     e Zd Z fdZd Z xZS )LaunchCtlStopc                 0    t         t        |   |||       y rK   )r   r   r>   r   s       r   r>   zLaunchCtlStop.__init__  s    mT+FGUCr    c                    | j                         \  }}}}|t        j                  k(  r<| j                  j	                         r!| j                          | j                          y y |t        j                  t        j                  fv r;| j                  j	                         r| j                          | j                          y |t        j                  k(  r!| j                          | j                          y y rK   )
r   r   r   rz   rp   r   r   r   r   r   r   s      r   r   zLaunchCtlStop.runCommand  s    %)^^%5"ueUL((( {{%%'		 ( |++\-@-@AA{{%%'IIKl*** KKMIIK	 +r    r   r   s   @r   r   r     s    Dr    r   c                   $     e Zd Z fdZd Z xZS )LaunchCtlReloadc                 0    t         t        |   |||       y rK   )r   r   r>   r   s       r   r>   zLaunchCtlReload.__init__      ot-fguEr    c                     | j                         \  }}}}|t        j                  k(  r| j                          y | j	                          y rK   )r   r   r   rS   r   r   s      r   r   zLaunchCtlReload.runCommand  s9    %)^^%5"ueUL))) IIKKKMr    r   r   s   @r   r   r     s    Fr    r   c                   $     e Zd Z fdZd Z xZS )LaunchCtlUnloadc                 0    t         t        |   |||       y rK   )r   r   r>   r   s       r   r>   zLaunchCtlUnload.__init__  r   r    c                 N    | j                         \  }}}}| j                          y rK   )r   r   r   s      r   r   zLaunchCtlUnload.runCommand  s     %)^^%5"ueUr    r   r   s   @r   r   r     s    Fr    r   c                   (     e Zd Z fdZ fdZ xZS )LaunchCtlRestartc                 0    t         t        |   |||       y rK   )r   r   r>   r   s       r   r>   zLaunchCtlRestart.__init__  s    .vwFr    c                 J    t         t        |           | j                          y rK   )r   r   r   r   )r8   r   s    r   r   zLaunchCtlRestart.runCommand  s    02

r    r   r   s   @r   r   r     s    G r    r   c                   $     e Zd Z fdZd Z xZS )r/   c                 0    t         t        |   ||d        y rK   )r   r/   r>   )r8   r9   r:   r   s      r   r>   zLaunchCtlList.__init__  s    mT+FGTBr    c                      y rK   r%   ro   s    r   r   zLaunchCtlList.runCommand  s     	r    r   r   s   @r   r/   r/     s    Cr    r/   c                     t        t        t        dd      t        d      t        dg d      t        d      t        dd	      
      dddgg      } | j                  d   }| j                  d   }| j                  d   }d}dx}}|di d}t        | ||      }|j	                         |d<   t        | |      j                         \  }	}
}}t        j                  |	      |d   d<   |
|d   d<   t        | ||      t        | ||      t        | ||      t        | ||      t        | ||      d}d}| j                  s||   j                         \  }	}
}}t        j                  |	      |d   d<   |
|d   d<   ||d   d<   ||d   d<   |d   d   |d   d   k7  s|d   d   |d   d   k7  rd|d<   | j                  r|d   d   |k7  rd|d<    | j                  di | y )NstrT)typerequired)r   )reloaded	restartedr   r   r   )r   choicesboolF)r   default)namer}   r   r`   rj   r   r`   )argument_specsupports_check_moderequired_one_ofr   r}   r   r   )r   changedstatusr   r   previous_stateprevious_pid)r   r   r   r   r   r   current_statecurrent_pidr   errorr%   )r	   dictrc   r'   rp   r/   r0   r   r   r   r   r   r   r   rf   	exit_json)r9   r:   plist_filenameactionr   r   r   resultr}   r   r<   r=   tasksr   s                 r   mainr     s>   540E"E+fgf%7
 !i 
F mmF#G]]7+N]]7#F	
BNC#F &'>2E((*F9  -VW=AACE3u)5)?)?)FF8%&'*F8^$ "&'59 %8%fgu=#FGU;#FGU;E K',V}'8'8':$sK(4(>(>u(EF8_%&)F8]#&1F8]# #F8Wx)VH-=>N-OO8]+vh/?/OO y(O,6 $F9Fvr    __main__) 
__future__r   r   r   r   r   DOCUMENTATIONEXAMPLESRETURNrA   r2   abcr   r   timer   ansible.module_utils.basicr	   +ansible.module_utils.common.text.convertersr
   r   r'   objectrt   r   r   r   r   r   r/   r   r!   r%   r    r   <module>r      s    A @7r*X
 
  '  4 A &u upbF bJ] 6M 6m m  M =@ zF r    