o nnh](@sddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z ddl mZmZdddZddZd d Zd d ZdddZddZddZddZddZdS)) annotationsN)PY2b)to_bytesto_textcCsl|rtjdsttd||fSttd||fStjds-ttd|Sttd|S)z This function will check if the service name supplied is enabled in any of the sysv runlevels :arg name: name of the service to test for :kw runlevel: runlevel to check (default: None) z /etc/rc0.d/z/etc/init.d/rc%s.d/S??%sz/etc/rc%s.d/S??%sz/etc/init.d/rc?.d/S??%sz/etc/rc?.d/S??%s)ospathisdirboolglob)namerunlevelrG/usr/local/lib/python3.10/dist-packages/ansible/module_utils/service.pysysv_is_enabled,s  rcCs|dr |}|Sd|}|S)z This function will return the expected path for an init script corresponding to the service name supplied. :arg name: name or path of the service to test for /z/etc/init.d/%s) startswith)r resultrrrget_sysv_script>s rcCstjt|S)z This function will return True or False depending on the existence of an init script corresponding to the service name supplied. :arg name: name of the service to test for )rrexistsr)r rrr sysv_existsMsrc Csfd}tdkr d}nd}|dd}|||g\}}}|dkr1|D] }||vr0d}|Sq%|S)zX Last resort to find a service by trying to match pattern to programs in memory FSunOS-efauxwwpsTr)platformsystem get_bin_path run_command splitlines) modulepatternfoundflagspsbinrcpsoutpserrlinerrrget_psWs   r)cCs |s|jd||fddSdS)a{ This function will return an error or exit gracefully depending on check mode status and if the service is missing or not. :arg module: is an AnsibleModule object, used for it's utility methods :arg found: boolean indicating if services were found or not :arg service: name of service :kw msg: extra info to append to error/success msg when missing z+Could not find the requested service %s: %smsgN) fail_json)r r"servicer,rrrfail_if_missingls r/cCst}|dkrWttjtj}tdD] }||kr t||q|tdvr,t|t}|dkr9tdt }|dkrEt dt dt}|dkrWtd|S)zk This function performs the double fork process to detach from the parent process and execute. rz*Unable to detach session while daemonizingr) rforkopendevnullO_RDWRrangedup2close_exitsetsid Exceptionchdir)pidfdnumsidrrr fork_processzs(       rAc sd}d}z tt}Wn.ty|jdtdYnty;}z|jt|tdWYd}~nd}~ww|dkr t dt |t sbt rYt t||d}n t t||d}g}|D] }|t||dqftj|dtjtjfd d d }|j|jg} |jtd |jtd i} | rt| g| d \} } } | | | s|durt | D]"}|| vrt||}|r| |t||d7<q| |qnn| s|tj|jt| |jt| |jgtj d}t!d t||dt d t"ddS|dkr|jdddSt d t#|dtd } tdggdg\} } } d| vrVtd|}|sNn |t||d7}q+t$t||dS)a Execute a command while detaching as a daemon, returns rc, stdout, and stderr. :arg module: is an AnsibleModule object, used for it's utility methods :arg cmd: is a list or string representing the command and options to run This is complex because daemonization is hard for people. What we do is daemonize a part of this module, the daemon runs the command, picks up the return code and output, and returns it to the main process. isurrogate_or_strictz"Error while attempting to fork: %s)r, exceptionNr)errorsFcstdS)N)rr8rpiperrszdaemonize..)shellstdoutstderr preexec_fnr*rE)protocolr1zSUnable to fork, no exception thrown, probably due to lack of resources, check logs.r+)%rrGrAOSErrorr- traceback format_excr;rr8 isinstancelistrshlexsplitrappend subprocessPopenPIPErJrKrselectpollreadfilenoremovewaitpickledumps returncodeHIGHEST_PROTOCOLwriter9waitpidloads)r cmdchunkrDr=excrun_cmdcpfdsoutputrfdwfdefdoutdata return_datarrFr daemonizesn   "      ,    rtcCsdtdkr d}nd}|dd}|d||f\}}}|dkr0|dD] }||vr/dSq&d S) NrrrrTz%s %sr F)rrrrrT)r r!psflagsr$r%rqerrr(rrrcheck_pss  rxcCs|drAdD] }tj|rdSqz#tdd}|}|dkWdWS1s/wYWdSty@YdSwdS) z Find out if the machine supports systemd or not :arg module: is an AnsibleModule object, used for it's utility methods Returns True if the system supports systemd, False if not. systemctl)z/run/systemd/system/z/dev/.run/systemd/z/dev/.systemd/Tz /proc/1/commrsystemdNF)rrrrr3readlinestripIOError)r canary init_procinitrrris_systemd_manageds    $ r)N)r*) __future__rr rr_rrYrSrVrOansible.module_utils.sixrr+ansible.module_utils.common.text.convertersrrrrrr)r/rArtrxrrrrrs(   *_