
    f                      @   d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	m
Z
mZ  ej                  e      ZdZdedefd	Zdefd
Zdee   fdZdedefdZdefdZdefdZdee   fdZdZdededefdZ G d de	j6                        Zee	j:                  ffgZd Zy)zA Datasource to support the Windows Subsystem for Linux platform.     N)PurePath)Listcast)sourcessubputilz/usr/bin/wslpathpathreturnc                 r    t        j                   t        d| g      \  }}t        |j                               S )a@  
    Translates a path inside the current WSL instance's filesystem to a
    Windows accessible path.

    Example:
    # Running under an instance named "CoolInstance"
    root = wslpath2win("/") # root == "//wsl.localhost/CoolInstance/"

    :param path: string representing a Linux path, whether existing or not.
    z-amr   WSLPATH_CMDr   rstripr	   out_s      A/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceWSL.pywsl_path_2_winr      s.     YYUD12FCCJJL!!    c                  0    t        d      } | j                  S )zL
    Returns the name of the current WSL instance as seen from outside.
    /)r   name)root_net_paths    r   instance_namer   #   s     #3'Mr   c                      d} d}g }t        j                         j                         D ]'  }|d   | k(  s||d   v s|j                  |d          ) |S )z
    Return a list of mount points of the Windows drives inside the current
    WSL instance, if drives are mounted, or an empty list otherwise
    9pzaname=drvfsfstypeopts
mountpoint)r   mountsvaluesappend)FS_TYPEOPTIONS_CONTAINmountedmnts       r   mounted_win_drivesr&   +   s`    
 G#OG{{}##% .x=G#3v;(FNN3|,-. Nr   c                 r    t        j                   t        d| g      \  }}t        |j                               S )a_  
    Returns a translation of a Windows path to a Linux path that can be
    accessed inside the current instance filesystem.

    It requires the Windows drive mounting feature to be enabled and the
    disk drive must be muonted for this to succeed.

    Example:
    # Assuming Windows drives are mounted under /mnt/ and "S:" doesn't exist:
    p = winpath2wsl("C:\ProgramData") # p == "/mnt/c/ProgramData/"
    n = winpath2wsl("S:\CoolFolder") # Exception! S: is not mounted.

    :param path: string representing a Windows path. The root drive must exist,
    although the path is not required to.
    z-aur   r   s      r   win_path_2_wslr(   ;   s.      YYUD12FCCJJL!!r   c                     t               } | st        d      d}| D ]N  }||z  }t        j                  |t        j                        s-t
        j                  d|       t        |      c S  t        ddj                  |       z        )z?
    Returns the Linux path to the Windows host's cmd.exe.
    zWindows drives are not mounted.z%s/Windows/System32/cmd.exezFound cmd.exe at <%s>z,Couldn't find cmd.exe in any mount point: %sz, )	r&   IOErrorosaccessX_OKLOGdebugr   join)r   	candidater%   cmds       r   cmd_executabler3   O   s    
  !F788 .I #oyybgg&		)3/} 669JJ r   c                  ~   t               } t        j                  d| j                         ddg      \  }}|j                         }|st        j                  d      t        |      }t        j                  j                  |d      }t        j                  j                  |      st        d|z        t        |      S )z
    Returns the Windows user profile directory translated as a Linux path
    accessible inside the current WSL instance.
    z/initz/Czecho %USERPROFILE%z4No output from cmd.exe to show the user profile dir.z.cloud-initz%s directory doesn't exist.)r3   r   as_posixr   ProcessExecutionErrorr(   r+   r	   r0   isdirFileNotFoundErrorr   )r2   homer   win_profile_dirseed_dirs        r   cloud_init_data_dirr<   g   s    
 
C ii#,,.$8LMNGD!;;=D((B
 	
 %T*Oww||O];H77==" = HIIHr   c                 b    t        j                         \  }}}|r|n|}d| z  |d|dd|z  dgS )z
    Return a list of candidate file names that may contain user-data
    in some supported format, ordered by precedence.
    z%s.user-data-z
.user-dataz%s-all.user-datazdefault.user-data)r   get_linux_distro)r   distribution_id
version_idversion_codenameversions        r   candidate_user_data_file_namesrD      sK    
 594I4I4K1OZ!1&j,<G 	&,g6_,	 	r   ziid-datasource-wslcloudinitdirr   c                 p   dt         i}t        j                  j                  | j	                         d|z        }	 t        j                  t        j                  |            }|rd|vr(d| d| }t        j                  |       t        |      |S # t        $ r t        j                  d|       Y Qw xY w)z`
    Returns the relevant metadata loaded from cloudinit dir based on the
    instance name
    instance-idz%s.meta-dataz<No instance metadata found at %s. Using default instance-id.z Metadata at z5 does not contain instance-id key. Instead received: )DEFAULT_INSTANCE_IDr+   r	   r0   r5   r   	load_yamlload_binary_filer8   r.   r/   error
ValueError)rE   r   metadatametadata_pathmsgs        r   load_instance_metadatarP      s    
 23HGGLL-!?M
>>$"7"7"FG }H4 M? +""*- 	 			#oO  
		J	

s   (B B54B5c                   8    e Zd ZdZdedefdZdefdZdefdZy)DataSourceWSLWSLr;   r
   c                    t        j                  |      D ci c]'  }|j                  j                         |j                  ) }}|st        d|z        t        | j                        D cg c]  }|j                          }}|D ]$  }||j                         v st        ||         c S  t        d|z        c c}w c c}w )z
        Finds the most precendent of the candidate files that may contain
        user-data, if any, or None otherwise.
        z%s directory is emptyz6%s doesn't contain any of the expected user-data files)
r+   scandirr   casefoldr	   r*   rD   r   keysr   )selfr;   efexisting_filesffolded_namesfilenames          r   find_user_data_filez!DataSourceWSL.find_user_data_file   s     35**X2F
,.BGG'
 
 1H<== 4D4F4FG
 JJL
 
 % 	:H>..00x 899	: DxO
 	


s   ,B=-Cc                    | j                         }|sy	 t        t               | j                        }||j	                  d      k(  S # t
        t        f$ r)}t        j                  dt        |             Y d }~yd }~ww xY w)NFrG   z2Unable to check_instance_id from metadata file: %s)
get_instance_idrP   r<   r   getr*   rL   r.   warningstr)rX   sys_cfgcurrentrM   errs        r   check_instance_idzDataSourceWSL.check_instance_id   s{     &&(	-#%t'9'9H hll=999$ 	KKDC 	s   1A A?A::A?c                    d | _         t               }t               | _        	 t        || j                        | _        | j                  |      }t        t        t        j                  |j                                     | _        y# t        t        f$ r)}t        j                  dt        |             Y d }~yd }~ww xY w)NTz"Unable to setup WSL datasource: %sF)vendordata_rawr<   r   rP   rM   r^   r   rc   r   rJ   r5   userdata_rawrL   r*   r.   rK   )rX   r;   filerf   s       r   	_get_datazDataSourceWSL._get_data   s    "&(*_	2$,,DM ++H5D $T**4==?;!D G$ 	II:CHE	s   A"B B=B88B=N)	__name__
__module____qualname__dsnamer   r^   boolrg   rl    r   r   rR   rR      s2    F
H 
 
<D (4 r   rR   c                 6    t        j                  | t              S )N)r   list_from_dependsdatasources)dependss    r   get_datasource_listrw     s    $$Wk::r   ) __doc__loggingr+   pathlibr   typingr   r   	cloudinitr   r   r   	getLoggerrm   r.   r   rc   r   r   r&   r(   r3   r<   rD   rH   dictrP   
DataSourcerR   DEP_FILESYSTEMru   rw   rr   r   r   <module>r      s    H  	   ) )g! " " "s DI  " " "( 0X 4T#Y ( +  # $ 8FG&& FV W++-.;r   