
    Vh                         d dl mZ dZd dlZd dlmZ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)    )annotationsu   
author: Stéphane Graber (@stgraber)
name: incus
short_description: Run tasks in Incus instances using the Incus CLI
description:
  - Run commands or put/fetch files to an existing Incus instance using Incus CLI.
version_added: "8.2.0"
options:
  remote_addr:
    description:
      - The instance identifier.
    type: string
    default: inventory_hostname
    vars:
      - name: inventory_hostname
      - name: ansible_host
      - name: ansible_incus_host
  executable:
    description:
      - The shell to use for execution inside the instance.
    type: string
    default: /bin/sh
    vars:
      - name: ansible_executable
      - name: ansible_incus_executable
  incus_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: incus_become_method
    version_added: 10.4.0
  remote:
    description:
      - The name of the Incus remote to use (per C(incus remote list)).
      - Remotes are used to access multiple servers from a single client.
    type: string
    default: local
    vars:
      - name: ansible_incus_remote
  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:
      - The name of the Incus project to use (per C(incus project list)).
      - Projects are used to divide the instances running on a server.
    type: string
    default: default
    vars:
      - name: ansible_incus_project
N)call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 fdZddZd Z	d fd	Z
dd	Z fd
Z fdZ fdZ xZS )
Connectionz Incus based connections incusTc                    t        t        | 
  ||g|i | t        d      | _        | j                  st        d      y )Nr   zincus command not found in PATH)superr   __init__r
   
_incus_cmdr   )selfplay_context	new_stdinargskwargs	__class__s        n/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/connection/incus.pyr   zConnection.__init__]   sB    j$(yR4R6R&w/@AA     c                    t         t        |           | j                  sE| j                  j                  d| j                  d       | j                                d| _        yy)z&connect to Incus (nothing to do here) z%ESTABLISH Incus CONNECTION FOR USER: remote_userhostTN)r   r   _connect
_connected_displayvvv
get_option	_instancer   r   s    r   r!   zConnection._connecte   sY    j$(*MM EdooVcFdEef#'>>#3  5"DO r   c                   | j                   d| j                  d      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 incus host	--projectprojectexecremote:z--r   rootz INFO: Running as non-root user: zA,                 trying to run 'incus exec' with become method: incus_become_methodr   z-c
executable)r   r%   r&   r#   r$   extend)r   cmdexec_cmds      r   _build_commandzConnection._build_commandn   s     OO3x()4>>+;*<= ??=)V3MM24??=3Q2R S@@DPe@f?gi^^%  
 OO!679WY]^ 	6cBCr   c                H    | j                  d      j                  d      d   S )Nremote_addr.r   )r%   split)r   s    r   r&   zConnection._instance   s#     }-33C8;;r   c                   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        |      }|d	k(  rt        d
| j                                |dk(  rt        d| j                                |j                  ||fS c c}w )z% execute a command on the Incus host )in_datasudoablezEXEC r   surrogate_or_stricterrorspassthru)r>   	nonstring)stdinstdoutstderrz Error: Instance is not running.
zinstance not running: zError: Instance not found
zinstance not found: )r   r   exec_commandr#   r$   r&   r4   vvvvvr   r   r   communicater   r   
returncode)
r   r2   r:   r;   	local_cmdiprocessrB   rC   r   s
            r   rD   zConnection.exec_command   s:   j$,S'H,UE#-#~~/ 	 	1 '',	eI;/dnn6FGHQR1Xa(=>R	R7+@JW	d4H ,,W588*-CDNNDTCU+VWW22*-A$..BRAS+TUU!!6611 Ss   	E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 )rD   r   r%   strip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                L   t         t        |   ||       | j                  j	                  d| d| | j                                t        j                  j                  t        |d            st        d|       | j                  d      dk7  rr| j                         \  }}| j                  d	| j                  d
      dddt        |      dt        |      d|| j                  d       d| j                          d| g}nH| j                  d	| j                  d
      ddd|| j                  d       d| j                          d| g}| j                  j                  d| | j                                |D cg c]  }t        |d       }}t!        |       yc c}w )z  put a file from local to Incus zPUT  TO r   r<   r=   zinput path is not a file: r   r.   r)   r*   filepushz--uidz--gid--quietr,   r-   /N)r   r   put_filer#   r$   r&   ospathisfiler   r	   r%   rT   r   strrE   r   )r   in_pathout_pathrQ   rS   rH   rI   r   s          r   r[   zConnection.put_file   s   j$((;D	hZ8#~~/ 	 	1 ww~~hw7LMN%(B7)&LMM??=)V3//1HC	*CC??8,-Qt~~/?.@(LI  	*??8,-Qt~~/?.@(L	I 	d9+.T^^5EFHQR1Xa(=>R	RY Ss   ?F!c                t   t         t        |   ||       | j                  j	                  d| d| | j                                | j                  d| j                  d      ddd| j                  d	       d
| j                          d| |g}|D cg c]  }t        |d       }}t        |       yc c}w )z" fetch a file from Incus to local zFETCH rV   r   r)   r*   rW   pullrY   r,   r-   rZ   r<   r=   N)
r   r   
fetch_filer#   r$   r&   r   r%   r   r   )r   r`   ra   rH   rI   r   s        r   rd   zConnection.fetch_file   s    j$*7H=F7)4z:#~~/ 	 	1 OO3FIx()4>>+;*<AgYG	 IRR1Xa(=>R	RY Ss   B5c                8    t         t        |           d| _        y)z+ close the connection (nothing to do here) FN)r   r   closer"   r'   s    r   rf   zConnection.close   s    j$%'r   )returnr_   )NT)rg   ztuple[int, int])__name__
__module____qualname____doc__	transporthas_pipeliningr   r!   r4   r&   rD   rT   r[   rd   rf   __classcell__)r   s   @r   r   r   W   sD    #INB#0<
26"&*X$   r   r   )
__future__r   DOCUMENTATIONr\   
subprocessr   r   r   ansible.errorsr   r   r	   #ansible.module_utils.common.processr
   ansible.module_utils._textr   r   ansible.plugins.connectionr   r    r   r   <module>rw      s;    #BH 
 ( ( V V < 8 5d  d r   