
    Vh!                    ~    d dl mZ dZd dlZd dlmZmZ d dlmZm	Z	m
Z
 d dlmZ d dlmZmZ d dlmZ  G d	 d
e      Zy)    )annotationsa  
author: Matt Clay (@mattclay) <matt@mystile.com>
name: lxd
short_description: Run tasks in LXD instances using C(lxc) CLI
description:
  - Run commands or put/fetch files to an existing instance using C(lxc) CLI.
options:
  remote_addr:
    description:
      - Instance (container/VM) identifier.
      - Since community.general 8.0.0, a FQDN can be provided; in that case, the first component (the part before C(.)) is
        used as the instance identifier.
    type: string
    default: inventory_hostname
    vars:
      - name: inventory_hostname
      - name: ansible_host
      - name: ansible_lxd_host
  executable:
    description:
      - Shell to use for execution inside instance.
    type: string
    default: /bin/sh
    vars:
      - name: ansible_executable
      - name: ansible_lxd_executable
  lxd_become_method:
    description:
      - Become command used to switch to a non-root user.
      - Is only used when O(remote_user) is not V(root).
    type: str
    default: /bin/su
    vars:
      - name: lxd_become_method
    version_added: 10.4.0
  remote:
    description:
      - Name of the LXD remote to use.
    type: string
    default: local
    vars:
      - name: ansible_lxd_remote
    version_added: 2.0.0
  remote_user:
    description:
      - User to login/authenticate as.
      - Can be set from the CLI via the C(--user) or C(-u) options.
    type: string
    default: root
    vars:
      - name: ansible_user
    env:
      - name: ANSIBLE_REMOTE_USER
    ini:
      - section: defaults
        key: remote_user
    keyword:
      - name: remote_user
    version_added: 10.4.0
  project:
    description:
      - Name of the LXD project to use.
    type: string
    vars:
      - name: ansible_lxd_project
    version_added: 2.0.0
N)PopenPIPE)AnsibleErrorAnsibleConnectionFailureAnsibleFileNotFound)get_bin_path)to_bytesto_text)ConnectionBasec                  t     e Zd ZdZdZdZ fdZd Z fdZddZ	d fd	Z
dd	Z fd
Z fdZ fdZ xZS )
Connectionz lxd based connections zcommunity.general.lxdTc                    t        t        | 
  ||g|i | 	 t        d      | _        y # t
        $ r t        d      w xY w)Nlxczlxc command not found in PATH)superr   __init__r	   _lxc_cmd
ValueErrorr   )selfplay_context	new_stdinargskwargs	__class__s        l/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/connection/lxd.pyr   zConnection.__init__\   sM    j$(yR4R6R	@(/DM 	@>??	@s	   , Ac                J    | j                  d      j                  dd      d   S )z/ translate remote_addr to lxd (short) hostname remote_addr.   r   )
get_optionsplit)r   s    r   _hostzConnection._hostd   s#    }-33C;A>>    c                    t         t        |           | j                  sE| j                  j                  d| j                  d       | j                                d| _        yy)z$connect to lxd (nothing to do here) z#ESTABLISH LXD CONNECTION FOR USER: remote_userhostTN)r   r   _connect
_connected_displayvvvr    r"   r   r   s    r   r(   zConnection._connecth   sW    j$(*MM CDOOTaDbCcdkokukukwx"DO r#   c                b   | j                   g}| j                  d      r"|j                  d| j                  d      g       |j                  d| j                  d       d| j                          dg       | j                  d      dk7  r| j                  j                  d	| j                  d       d
| j                  d       | j                                |j                  | j                  d      | j                  d      dg       |j                  | j                  d      d|g       |S )z,build the command to execute on the lxd hostproject	--projectexecremote:z--r%   rootz INFO: Running as non-root user: z?,                 trying to run 'lxc exec' with become method: lxd_become_methodr&   z-c
executable)r   r    extendr"   r*   r+   )r   cmdexec_cmds      r   _build_commandzConnection._build_commandp   s    MM???9%OO[$//)*DEFDOOH$=#>a

~!NPTUV??=)V3MM24??=3Q2R S>>BooNa>b=ceZZ\  
 OO!45t}7UW[\ 	6cBCr#   c                2   t         t        |   |||       | j                  j	                  d| | j                                | j                  |      }| j                  j                  d| | j                                |D cg c]  }t        |d       }}t        |dd      }t        |t        t        t              }|j                  |      \  }}t        |      }t        |      }| j                  j                  d	| d
| | j                                d|v rt        d| j                                |j                         dk(  s|j                         dk(  rt        d| j                                |j                  ||fS c c}w )z# execute a command on the lxd host )in_datasudoablezEXEC r&   surrogate_or_stricterrorspassthru)r?   	nonstringstdinstdoutstderrzEXEC lxc output:  zis not runningzinstance not running: zError: Instance not foundzerror: not foundzinstance not found: )r   r   exec_commandr*   r+   r"   r9   vvvvvr
   r   r   communicater   r   strip
returncode)
r   r7   r;   r<   	local_cmdiprocessrD   rE   r   s
            r   rG   zConnection.exec_command   sk   j$,S'H,UE#-djjl;'',	eI;/djjlCHQR1Xa(=>R	R7+@JW	d4H ,,W5/xqA

Uv%*-CDJJL>+RSS<<>88FLLNN`<`*-A$**,+PQQ!!6611# Ss   	Fc                V   | j                  d      \  }}}|dk7  r t        d| j                  d       d|       |j                         }| j                  d      \  }}}|dk7  r t        d| j                  d       d|       |j                         }t	        |      t	        |      fS )z=Get the user and group ID of 'remote_user' from the instance.z
/bin/id -ur   z"Failed to get remote uid for user r%   z: z
/bin/id -gz"Failed to get remote gid for user )rG   r   r    rJ   int)r   rcuid_outerruidgid_outgids          r   _get_remote_uid_gidzConnection._get_remote_uid_gid   s      ,,\:GS74T__]5S4TTVWZV[\  mmo,,\:GS74T__]5S4TTVWZV[\  mmo3xS!!r#   c                   t         t        |   ||       | j                  j	                  d| d| | j                                t        j                  j                  t        |d            st        d|       | j                  g}| j                  d      r"|j                  d| j                  d      g       | j                  d	      d
k7  rd| j                         \  }}|j                  dddt        |      dt        |      || j                  d       d| j                          d| g       n:|j                  dd|| j                  d       d| j                          d| g       | j                  j!                  d| | j                                |D cg c]  }t        |d       }}t#        |t$        t$        t$              }|j'                          yc c}w )z put a file from local to lxd zPUT  TO r&   r=   r>   zinput path is not a file: r.   r/   r%   r3   filepushz--uidz--gidr1   r2   /rB   N)r   r   put_filer*   r+   r"   ospathisfiler
   r   r   r    r6   rW   strrH   r   r   rI   )	r   in_pathout_pathrL   rT   rV   rM   rN   r   s	           r   r]   zConnection.put_file   s   j$((;D	hZ8tzz|Lww~~hw7LMN%(B7)&LMM]]O	??9%k4??9+EFG??=)V3//1HCHHx014::<.(L	 x014::<.(L	 	d9+.TZZ\BHQR1Xa(=>R	R	d4H Ss   #G%c           	        t         t        |   ||       | j                  j	                  d| d| | j                                | j                  g}| j                  d      r"|j                  d| j                  d      g       |j                  dd| j                  d       d	| j                          d
| |g       |D cg c]  }t        |d       }}t        |t        t        t              }|j                          yc c}w )z  fetch a file from lxd to local zFETCH rY   r&   r.   r/   rZ   pullr1   r2   r\   r=   r>   rB   N)r   r   
fetch_filer*   r+   r"   r   r    r6   r
   r   r   rI   )r   rb   rc   rL   rM   rN   r   s         r   rf   zConnection.fetch_file   s    j$*7H=F7)4z:N]]O	??9%k4??9+EFGFx()4::<.'C
 	 IRR1Xa(=>R	R	d4H Ss   Dc                8    t         t        |           d| _        y)z+ close the connection (nothing to do here) FN)r   r   closer)   r,   s    r   rh   zConnection.close   s    j$%'r#   )returnra   )NT)ri   ztuple[int, int])__name__
__module____qualname____doc__	transporthas_pipeliningr   r"   r(   r9   rG   rW   r]   rf   rh   __classcell__)r   s   @r   r   r   V   sD    !'IN@?#028"&*X(   r#   r   )
__future__r   DOCUMENTATIONr^   
subprocessr   r   ansible.errorsr   r   r   #ansible.module_utils.common.processr	   +ansible.module_utils.common.text.convertersr
   r   ansible.plugins.connectionr   r    r#   r   <module>ry      s8    #BH 
 " V V < I 5e  e r#   