
    Vh                         d dl mZmZmZ eZdZd dl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 d dlmZ d dlmZ d d	lmZmZ d d
lmZ  e       Z G d de      Zy)    )absolute_importdivisionprint_functiona  
---
author:
    - Michael Scherer (@mscherer) <misc@zarb.org>
name: libvirt_lxc
short_description: Run tasks in lxc containers via libvirt
description:
    - Run commands or put/fetch files to an existing lxc container using libvirt.
options:
  remote_addr:
    description:
        - Container identifier.
    default: The set user as per docker's configuration
    vars:
        - name: ansible_host
        - name: ansible_libvirt_lxc_host
  libvirt_lxc_noseclabel:
    description:
        - "This setting causes libvirt to connect to LXC containers by passing ``--noseclabel`` parameter to ``virsh`` command."
        - This is necessary when running on systems which do not have SELinux.
    default: False
    version_added: '1.4.0'
    type: boolean
    ini:
        - section: selinux
          key: 'libvirt_lxc_noseclabel'
    env:
        - name: ANSIBLE_LIBVIRT_LXC_NOSECLABEL
    vars:
        - name: ansible_libvirt_lxc_noseclabel
N)	constants)AnsibleError)shlex_quote)get_bin_path)to_bytes)ConnectionBaseBUFSIZE)Displayc                        e Zd ZdZdZdZdZdZ fdZd Z	d Z
 fd	Zej                  fd
Zd fd	Zd Z fdZ fdZ fdZ xZS )
Connectionz Local lxc based connections zcommunity.general.libvirt_lxcTrootFc                     t        t        | 
  ||g|i | | j                  j                  | _        | j                  d      | _        | j                  | j
                         y )Nvirsh)	superr   __init___play_contextremote_addrlxc_search_executabler   _check_domain)selfplay_context	new_stdinargskwargs	__class__s        t/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/libvirt/plugins/connection/libvirt_lxc.pyr   zConnection.__init__F   sU    j$(yR4R6R%%11,,W5
488$    c                 P    	 t        |      S # t        $ r t        d      |z  w xY w)Nz%s command not found in PATH)r	   
ValueErrorr   )r   
executables     r    r   zConnection._search_executableN   s5    	L
++ 	L=>KK	Ls   
 %c           
          t        j                  | j                  ddddt        |      gt         j                  t         j                        }|j                          |j                  rt        d|z        y )N-q-clxc:///dominfo)stdoutstderrz"%s is not a lxc defined in libvirt)
subprocessPopenr   r
   PIPEcommunicate
returncoder   )r   domainps      r    r   zConnection._check_domainT   s_    djj$iHU[L\]$.OOJOOM	<<CfLMM r!   c                     t         t        |           | j                  s)t        j                  d| j                         d| _        yy)z( connect to the lxc; nothing to do here zTHIS IS A LOCAL LXC DIRhostTN)r   r   _connect
_connecteddisplayvvvr   r   r   s    r    r6   zConnection._connect[   s8    j$(*KK1KA"DO r!   c                    t         j                  r!t         j                  j                         d   nd}| j                  ddddg}| j	                  d      r|dgz  }|| j
                  d	|d|gz  }t        j                  d
|| j
                         |D cg c]  }t        |d       }}t        j                  |d|t        j                  t        j                        }|S c c}w )a/   run a command on the chroot.  This is only needed for implementing
        put_file() get_file() so that we don't have to read the whole file
        into memory.

        compared to exec_command() it looses some niceties like being able to
        return the process's exit code immediately.
        r   z/bin/shr&   r'   r(   zlxc-enter-namespacelibvirt_lxc_noseclabelz--noseclabelz--zEXEC r4   surrogate_or_stricterrorsF)shellstdinr*   r+   )CDEFAULT_EXECUTABLEsplitr   
get_optionr   r8   r9   r
   r,   r-   r.   )r   cmdrA   r$   	local_cmdir2   s          r    _buffered_exec_commandz!Connection._buffered_exec_commandb   s     9:8L8LQ))//1!4R[
ZZtY8MN	??34.))Idhhj$<<	,488<HQR1Xa(=>R	RYe5$.OOJOOM 	 Ss   C&c                     t         t        |   |||       | j                  |      }|j	                  |      \  }}|j
                  ||fS )z run a command on the chroot )in_datasudoable)r   r   exec_commandrI   r/   r0   )r   rF   rK   rL   r2   r*   r+   r   s          r    rM   zConnection.exec_commandy   sL    j$,S'H,U'',w/ff--r!   c                    |j                  t        j                  j                        s8t        j                  j	                  t        j                  j                  |      }t        j                  j                  |      S )a   Make sure that we put files into a standard path

            If a path is relative, then we need to choose where to put it.
            ssh chooses $HOME but we aren't guaranteed that a home dir will
            exist in any given chroot.  So for now we're choosing "/" instead.
            This also happens to be the former default.

            Can revisit using $HOME instead if it's a problem
        )
startswithospathsepjoinnormpath)r   remote_paths     r    _prefix_login_pathzConnection._prefix_login_path   sK     %%bggkk2'',,rww{{K@Kww,,r!   c                    t         t        |   ||       t        j	                  d|d|| j
                         t        | j                  |            }	 t        t        |d      d      5 }t        j                  |j                               j                  sd}nd}	 | j                  d	|d
t        ||      }	 |j%                         \  }}|j,                  dk7  rt#        d|d|d|d|      	 ddd       y# t         $ r t#        d      w xY w# t&        $ r& t)        j*                          t#        d|d|      w xY w# 1 sw Y   yxY w# t.        $ r t#        d|z        w xY w)z# transfer a file from local to lxc zPUT  TO r4   r=   r>   rbz count=0 zdd of= bs=)rA   3chroot connection requires dd command in the chrootfailed to transfer file  to r   :

Nz$file or module does not exist at: %s)r   r   put_filer8   r9   r   r   rV   openr
   rP   fstatfilenost_sizerI   r   OSErrorr   r/   	Exception	traceback	print_excr0   IOError)	r   in_pathout_pathin_filecountr2   r*   r+   r   s	           r    ra   zConnection.put_file   su   j$((;gx8txxHt66x@A	Qhw/DEtL zPWxx 0199&EE^33(T[]b4ckr3sAa%&]]_NFF <<1$&V]_gioqw'xyy %z z  ^&'\]]^ ! a'')&WV^'_``az z   	QEOPP	QsT   E /3E#DD&E=E DE/EEEE E E4c                    t         t        |   ||       t        j	                  d|d|| j
                         t        | j                  |            }	 | j                  d|dt              }t        t        |d      d	      5 }	 |j                  j                  t              }|r3|j!                  |       |j                  j                  t              }|r3|j)                         \  }}|j*                  dk7  rt        d
|d|d|d|      	 ddd       y# t        $ r t        d      w xY w# t"        $ r& t%        j&                          t        d
|d|      w xY w# 1 sw Y   yxY w)z  fetch a file from lxc to local zFETCH rX   r4   zdd if=r[   r\   r=   r>   zwb+r]   r^   r   r_   r`   N)r   r   
fetch_filer8   r9   r   r   rV   rI   r   rf   r   rb   r
   r*   readwriterg   rh   ri   r/   r0   )	r   rk   rl   r2   out_filechunkr*   r+   r   s	           r    rp   zConnection.fetch_file   sX   j$*7H=:Jd55g>?	V++,QRA (8,ABEJ 	vh]g.NN5)HHMM'2E  ]]_NFF||q "RY[cekms#tuu !	v 	v  	VTUU	V  ]##%"RZ#[\\]	v 	vs1   D# 
E-AD; 9E-#D8;/E**E--E6c                 8    t         t        |           d| _        y)z. terminate the connection; nothing to do here FN)r   r   closer7   r:   s    r    rv   zConnection.close   s    j$%'r!   )NF)__name__
__module____qualname____doc__	transporthas_pipeliningdefault_userhas_ttyr   r   r   r6   r,   r.   rI   rM   rV   ra   rp   rv   __classcell__)r   s   @r    r   r   ;   s`    '/IN LG%LN# 1; ..-Q4v0   r!   r   )
__future__r   r   r   type__metaclass__DOCUMENTATIONrP   os.pathr,   rh   ansibler   rB   ansible.errorsr   ansible.module_utils.six.movesr   #ansible.module_utils.common.processr	   ansible.module_utils._textr
   ansible.plugins.connectionr   r   ansible.utils.displayr   r8   r    r!   r    <module>r      sS    C B@ 
    " ' 6 < / > )
)J  J r!   