
    :"ri_                     X   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlZd dlZd dlmZ  ej                          j"                  Zedk(  rd Znd Zd ZddZddZ G d	 d
e      Z G d d      Z G d de      Z G d de      Z G d de      Zy)    N)serverversionWindowsc                 2    | j                  d      r| S | dz   S )Nz.exe)endswithnames    W/var/www/fortnox.pascalinesoft.com/venv/lib/python3.12/site-packages/asyncpg/cluster.pyplatform_exer
      s    == Kf}    c                     | S N r   s    r	   r
   r
   #   s    r   c                  8   t        j                   t         j                  t         j                        } 	 | j                  d       | j	                         d   | j                          S # t        $ r Y | j                          y w xY w# | j                          w xY w)N)	127.0.0.1r      )socketAF_INETSOCK_STREAMbindgetsocknameclose	Exception)socks    r	   find_available_portr   '   ss    ==););<D		"#!!$ 	

  

 	

s#   #A( (	B1B BB Bc                 F   dj                  t        j                  t        j                  d            }|t        j                         }|t        j                         }| d} t        j                  j                  |||z   | z         }t        j                  |d       |S )N    )ki  )joinrandomchoicesstringascii_lowercasetempfile
gettempdirgettempprefixospathmkdir)suffixprefixdirr   fns        r	   _world_readable_mkdtempr.   2   s    776>>&"8"8A>?D
{!!#~'')~	c6D=61	2BHHRIr   c                     t         dk(  r,t        j                  j                  d      rt	        | ||      S t        j                  | ||      S )Nr   GITHUB_ACTIONS)_systemr'   environgetr.   r$   mkdtempr*   r+   r,   s      r	   _mkdtempr6   ?   s@    )

/? @ 'vvs;;44r   c                       e Zd Zy)ClusterErrorN)__name__
__module____qualname__r   r   r	   r8   r8   I   s    r   r8   c                       e Zd ZdddZd Zd Zd Zd Zd!dZd	 Z	d"i d
dZ
d Zd"dZd Zd Zd Zd ZddddZd ZdddddZd Zd Zd Zd Zd"dZd Zd Zd Zd  Zy)#ClusterNpg_config_pathc                    || _         || _        t        j                  j	                  d      xs t        j                  j	                  d      | _        d | _        d | _        d | _        d | _	        d | _
        y )NPGINSTALLATIONPGBIN)	_data_dir_pg_config_pathr'   r2   r3   _pg_bin_dir_pg_ctl_daemon_pid_daemon_process_connection_addr_connection_spec_override)selfdata_dirr?   s      r	   __init__zCluster.__init__N   sh    !-JJNN+, 'zz~~g& 	 # $)-&r   c                     | j                   S r   )_pg_versionrK   s    r	   get_pg_versionzCluster.get_pg_version[   s    r   c                      y)NTr   rP   s    r	   
is_managedzCluster.is_managed^   s    r   c                     | j                   S r   )rC   rP   s    r	   get_data_dirzCluster.get_data_dira   s    ~~r   c                 8   | j                   | j                          t        j                  | j                   dd| j                  gt        j
                  t        j
                        }|j                  |j                  }}|j                  dk(  sHt        j                  j                  | j                        rt        j                  | j                        sy|j                  dk(  ry|j                  dk(  rt        j                  d	|j                               }|s(t!        d
j#                  |j                                     t%        |j'                  d            | _        | j+                  d      S t!        dj#                  |j                  |            )Nstatus-Dstdoutstderr   not-initialized   stoppedr   z.*PID\s?:\s+(\d+).*z(could not parse pg_ctl status output: {}r   timeoutz)pg_ctl status exited with status {:d}: {})rF   	_init_env
subprocessrunrC   PIPErZ   r[   
returncoder'   r(   existslistdirrematchdecoder8   formatintgrouprG   _test_connection)rK   processrZ   r[   rs        r	   
get_statuszCluster.get_statusd   s9   <<NN..\\8T4>>:??:??< !!#277>>$..+IJJt~~.$1$1$/AA">EE)* *  #1771:D(((33;BB&&01 1r   c                    K   | j                         }|j                  |       t        j                  dd|i| d {   S 7 w)Nloopr   )get_connection_specupdateasyncpgconnect)rK   rt   kwargs	conn_infos       r	   rx   zCluster.connect   s?     ,,.	 __<$<)<<<<s   <AAAc                    | j                         dk7  r$t        dj                  | j                              t	        |      }d|vrd|d<   |rI|j                         D cg c]  \  }}dj                  ||       }}}dgdj                  |      gz   }ng }t        j                  | j                  d	       t        j                  | j                  d
d| j                  g|z   t        j                  t        j                  | j                        }|j                  }|j                  dk7  r3t        dj                  |j                  |j!                                     |j!                         S c c}}w )Initialize cluster.r]   ,cluster in {!r} has already been initializedencodingzUTF-8--{}={}-o T)exist_okinitrX   rZ   r[   cwdr   z'pg_ctl init exited with status {:d}:
{})rr   r8   rl   rC   dictitemsr   r'   makedirsrc   rd   rF   re   STDOUTrZ   rf   rk   )rK   settingsr   vsettings_args
extra_argsrp   outputs           r	   r   zCluster.init   sN   ?? 11>EENN$% % >X%#*HZ )1)9;!%A '--a3 ;M ;388M#:";;JJ
DNNT2..\\648:E??$$	
 ":AA&&9: : }}+;s   !E2server_settingsc                   | j                         }|dk(  ry|dk(  r$t        dj                  | j                              |j	                  dd      }|dk(  r
t               }|j                         D cg c]  \  }}dj                  ||       }}}|j                  dj                  |             |j                  d	      }	|	|j                  d
      }	|	t        dk7  rt        j                         }	|j                  d      }
|
rkt        j                  j                  | j                  d      }t        j                   |
|       t        j"                  |d       |j!                         }||d<   |	| j$                  dk  rd
}nd	}|	||<   |j                         D ](  \  }}|j'                  ddj                  ||      g       * t        dk(  rPt        j(                  d      ret*        j,                  }t/        ddj                  | j0                  dd| j                  ddj                  |      g      t*        j2                         nt4        j6                  }t5        j8                  | j0                  dd| j                  ddj                  |      g|t4        j:                  | j                        }|j<                  dk7  r|j2                  r*dj                  |j2                  j?                               }nd}t        dj                  |j<                  |            t        j(                  d      rt*        j,                  }nt4        j6                  }t5        j@                  | jB                  d| j                  g||t4        j:                  | j                        | _"        | jD                  jF                  | _$        | jK                  |       yc c}}w )zStart the cluster.runningNr]   z(cluster in {!r} has not been initializedportdynamicr   z	--port={}unix_socket_directoriesunix_socket_directoryr   ssl_key_filez
srvkey.pemi  )	   r^   z-c{}={}ASYNCPG_DEBUG_SERVERzasyncpg.cluster: Runningr   startrX   r   filer   r   z:
{}r   z&pg_ctl start exited with status {:d}{}r`   )&rr   r8   rl   rC   popr   r   appendr3   r1   r$   r%   r'   r(   r   shutilcopychmodrO   extendgetenvsysrZ   printrF   r[   rc   DEVNULLrd   r   rf   rk   Popen	_postgresrH   pidrG   ro   )rK   waitr   optsrW   r   r   r   r   sockdirssl_keykeyfilesockdir_optrZ   rp   r[   s                   r	   r   zCluster.start   sS   "Y((:AANN$% % xx%9&(D9=FAi&&q!,F
F+,,T23!%%&?@?%))*ABG?w)3))+G!%%n5ggll4>><@GKK)HHWe$-224O.5ON+&(57+2OK(#))+ 	<DAqtW^^Aq%9:;	< i
 yy/0.HHgtT^^chhz2   $++ nnwdnnsxx
+-!((NNG !!Q&>>$^^GNN,A,A,CDFF"<CC**F45 5 yy/0#++   ^^T4>>GJG!%,,	    $3377Dd+_ Gs   4Oc                    | j                         }|dk7  rt        d      t        j                  | j                  dd| j
                  gt        j                  t        j                  | j
                        }|j                  }|j                  dk7  r3t        dj                  |j                  |j                                     y)	zReload server configuration.r   z%cannot reload: cluster is not runningreloadrX   r   r   'pg_ctl stop exited with status {:d}: {}N)rr   r8   rc   rd   rF   rC   re   r[   rf   rl   rk   )rK   rW   rp   r[   s       r	   r   zCluster.reload  s    "YFGG..\\8T4>>:????	
 "9@@&&9: : #r   c           
         t        j                  | j                  dd| j                  dt	        |      ddgt         j
                  t         j
                  | j                        }|j                  }|j                  dk7  r3t        dj                  |j                  |j                                     | j                  2| j                  j                  | j                  j                          y y y )	NstoprX   z-tz-mfastr   r   r   )rc   rd   rF   rC   strre   r[   rf   r8   rl   rk   rH   kill)rK   r   rp   r[   s       r	   r   zCluster.stop  s    ..\\64s4y6????
 "9@@&&9: :   ,$$//7  %%' 8 -r   c                     | j                         }|dk(  s|dk(  r t        j                  | j                         y t	        dj                  |            )Nr_   r]   zcannot destroy {} cluster)rr   r   rmtreerC   r8   rl   rK   rW   s     r	   destroyzCluster.destroy.  sE    "Y&,="=MM$..):AA&IJJr   c                     | j                   | j                         | _         | j                   O| j                  r7| j                   j                         }|j	                  | j                         |S | j                   S y r   )rI   _connection_addr_from_pidfilerJ   r   rv   )rK   argss     r	   _get_connection_speczCluster._get_connection_spec5  sp      ($($F$F$HD!  ,--,,113D::;,,, -r   c                 b    | j                         }|dk7  rt        d      | j                         S )Nr   zcluster is not running)rr   r8   r   r   s     r	   ru   zCluster.get_connection_specA  s1    "Y788((**r   c                     || _         y r   )rJ   rK   ry   s     r	   override_connection_specz Cluster.override_connection_specH  s
    )/&r   )oidxidc                   | j                         }|dk(  rt        d      |dk(  rt        d      g }||j                  dt        |      g       ||j                  dt        |      g       |sy |j	                  | j
                         	 | j                  d      }t        j                  |g|z   t        j                  t        j                  	      }|j                  }|j                  d
k7  r3t        dj                  |j                  |j                                     y # t        $ r | j                  d      }Y w xY w)Nr]   z4cannot modify WAL status: cluster is not initializedr   z,cannot modify WAL status: cluster is runningr   z-xpg_resetwalpg_resetxlogrY   r   z'pg_resetwal exited with status {:d}: {})rr   r8   r   r   r   rC   _find_pg_binaryrc   rd   re   r[   rf   rl   rk   )rK   r   r   rW   r   	reset_walrp   r[   s           r	   r   zCluster.reset_walK  s=   "&&FH H Y>@ @ ?KKs3x()?KKs3x()DNN#	=,,];I ..K$??:??< "9@@&&9: : #  	=,,^<I	=s   D& &EEc                 6   | j                         }|dk(  rt        d      t        j                  j	                  | j
                  d      }	 t        |d      5  	 ddd       y# 1 sw Y   yxY w# t        $ r }t        dj                  |            |d}~ww xY w)z$Remove all records from pg_hba.conf.r]   5cannot modify HBA records: cluster is not initializedpg_hba.confwNcannot modify HBA records: {})	rr   r8   r'   r(   r   rC   openIOErrorrl   )rK   rW   pg_hbaes       r	   	reset_hbazCluster.reset_hbao  s    "&&GI I dnnm<	Bfc"    	B/66q9;@AB	Bs6   A/ A#A/ #A,(A/ ,A/ /	B8BBhosttypeaddressauth_optionsc                   | j                         }|dk(  rt        d      |dvrt        dj                  |            t        j
                  j                  | j                  d      }dj                  |||      }	|dk7  r0|t        d	j                  |            |	d
j                  |      z  }	|	d
j                  |      z  }	||	ddj                  d |D              z   z  }		 t        |d      5 }
t        |	|
       ddd       y# 1 sw Y   yxY w# t        $ r }t        dj                  |            |d}~ww xY w)zAdd a record to pg_hba.conf.r]   r   >   r   localhostssl	hostnosslzinvalid HBA record type: {!r}r   z{} {} {}r   Nz#{!r} entry requires a valid addressz {}r   c              3   F   K   | ]  \  }}d j                  ||        yw)r   N)rl   ).0r   r   s      r	   	<genexpr>z(Cluster.add_hba_entry.<locals>.<genexpr>  s$      %?)-Aq!$%?s   !ar   r   )rr   r8   
ValueErrorrl   r'   r(   r   rC   r   r   r   )rK   r   databaseuserr   auth_methodr   rW   r   recordfr   s               r	   add_hba_entryzCluster.add_hba_entry  sZ    "&&GI I @@<CCDIJJdnnm<""4487? 9@@FH H %,,w//%,,{++#cCHH %?1=%? ? ? ?F	Bfc" &af1%& & & 	B/66q9;@AB	Bs6   &D 2D	 D 	DD D 	D>D99D>c                    | j                          t        dk7  r| j                  dddd       | j                  ddddd       | j                  dd	ddd       | j                         }|d
k(  r| j	                          y y )Nr   r   alltrustr   r   r   r   r   127.0.0.1/32r   r   r   r   r   ::1/128r   )r   r1   r   rr   r   r   s     r	   trust_local_connectionszCluster.trust_local_connections  s    iGe$)w  @$)'. 	 	0 		$)'. 	 	0 "YKKM r   c                     t         dk7  r| j                  dd|d       | j                  ddd|d       | j                  dd	d|d       | j                         }|d
k(  r| j                          y y )Nr   r   replicationr   r   r   r   r   r   r   )r1   r   rr   r   )rK   r   rW   s      r	   trust_local_replication_byz"Cluster.trust_local_replication_by  s    iGm$(g  ?$1'. 	 	0 		$1'. 	 	0 "YKKM r   c                 P   | j                   sY| j                  | j                        }| j                  |      }|j	                  d      | _         | j                   st        d      | j                  d      | _        | j                  d      | _        | j                         | _
        y )Nbindirz1pg_config output did not provide the BINDIR valuepg_ctlpostgres)rE   _find_pg_configrD   _run_pg_configr3   r8   r   rF   r   _get_pg_versionrO   )rK   	pg_configpg_config_datas      r	   rb   zCluster._init_env  s    ,,T-A-ABI!00;N-11(;D##"GI I ++H5--j9//1r   c                 l   t         j                  j                  | j                  d      }	 t	        |d      5 }|j                         }d d d        j                         }t        |      dk  ry t        |d         }| j                  r|| j                  k7  ry |d   }|d   }|d   }|rR|d   dk7  rGt         j                  j                  t         j                  j                  | j                  |            }|}	n|}	|	d	k(  rd
}	n|	dk(  rd}	n|	dk(  rd}	|	|dS # 1 sw Y   xY w# t        $ r Y y w xY w)Nzpostmaster.pidrt   r   r^   r\      /*	localhostz0.0.0.0r   z::z::1)r   r   )r'   r(   r   rC   r   readFileNotFoundError
splitlineslenrm   rG   normpath)
rK   pidfiler   piddatalinespmpidportnumr   hostaddrhost_strs
             r	   r   z%Cluster._connection_addr_from_pidfile  s:   '',,t~~/?@	gt$ #&&(#
 ""$u:>E!H)9)9 9 ((8qzS ''**GGLL9;HHs?"H""HH 
 	
K# #  		s(   D' D	D' D$ D' '	D32D3c                    d | _         t        j                         }	 t        |      D ]  }| j                   (| j	                         }|t        j                  d       7	 |j                  t        j                  dddd|d| j                         }|j                  |j                                 n |j                          y# t        t        j                  t        j                  t        j                  f$ r t        j                  d       Y t        j                  $ r Y  tw xY w# |j                          w xY w)Nr   r   r  )r   r   ra   rt   r   r   )rI   asyncionew_event_loopranger   timesleeprun_until_completerw   rx   r   OSErrorTimeoutErrorCannotConnectNowErrorPostgresConnectionErrorPostgresError)rK   ra   rt   i	conn_speccons         r	   ro   zCluster._test_connection  s(    $%%'	7^ ((0 $ 9 9 ;I (

1 11 A-701A +/*?*?ABC  ++CIIK836 JJL!  !5!555779  JJqM,,  	 JJLs=   AD-  3C"D- AD*D- D*&D- )D**D- -D?c                    t        j                  |t         j                  t         j                        }|j                  |j                  }}|j
                  dk7  r%t        dj                  |j
                  |            i }|j                         D ]X  }|j                  d      j                  d      \  }}}	|s*|	j                         ||j                         j                         <   Z |S )NrY   r   z%pg_config exited with status {:d}: {}utf-8=)rc   rd   re   rZ   r[   rf   r8   rl   r  rk   	partitionstriplower)
rK   r?   rp   rZ   r[   configliner   eqr   s
             r	   r   zCluster._run_pg_config!  s    ..:??:??L "FMM""F , - - F))+ :;;w/99#>2q01	F1779??,-:
 Mr   c                    |t         j                  j                  d      xs t         j                  j                  d      }|r*t        t         j                  j                  |d            }nt         j                  j                  d      j                  t         j                        }|D ]L  }t        t         j                  j                  |d            }t         j                  j                  |      sL n d }|st        d      t         j                  j                  |      st        dj                  |            |S )NrA   rB   r   PATHz#could not find pg_config executablez{!r} is not an executable)r'   r2   r3   r
   r(   r   splitpathseprg   r8   isfilerl   )rK   r?   
pg_installpathenvr(   s        r	   r   zCluster._find_pg_config3  s   !

/0 +::>>'*  !-GGLL[9"; **..066rzzB# *D%1T;7&9Nww~~n5	* &*NDEEww~~n-:AA   ! ! r   c                    t        t        j                  j                  | j                  |            }t        j                  j                  |      s,t        dj                  |      dj                  |      z         |S )Nzcould not find {} executable: z${!r} does not exist or is not a file)r
   r'   r(   r   rE   r-  r8   rl   )rK   binarybpaths      r	   r   zCluster._find_pg_binaryO  si    RWW\\$*:*:FCDww~~e$077?6==eDEF F r   c                    t        j                  | j                  dgt         j                  t         j                        }|j                  |j
                  }}|j                  dk7  r%t        dj                  |j                  |            |j                  d      j                  d      }d}|j                  |      st        dj                  |            |t        |      d  }t        j                  |      S )	Nz	--versionrY   r   z.postgres --version exited with status {:d}: {}r!  z 
zpostgres (PostgreSQL) z,could not determine server version from {!r})rc   rd   r   re   rZ   r[   rf   r8   rl   rk   r$  
startswithr  r   split_server_version_string)rK   rp   rZ   r[   version_stringr+   s         r	   r   zCluster._get_pg_versionY  s    ..^^[)??:??< !"@GG&&01 1  w/55e<)((0>EE"$% % (F588HHr   r   <   )r9   r:   r;   rM   rQ   rS   rU   rr   rx   r   r   r   r   r   r   ru   r   r   r   r   r   r   rb   r   ro   r   r   r   r   r   r   r	   r=   r=   M   s    37 . 16=
!F], ],~:(((K
-+0  $ ":HB  %+D04!BF 2,
\#J$8Ir   r=   c                   *     e Zd Zddddd fd
Z xZS )TempClusterNdata_dir_suffixdata_dir_prefixdata_dir_parentr?   c                b    t        |||      | _        t        |   | j                  |       y )Nr5   r>   )r6   rC   superrM   )rK   r<  r=  r>  r?   	__class__s        r	   rM   zTempCluster.__init__p  s1     ")8&57 	Gr   )r9   r:   r;   rM   __classcell__rA  s   @r	   r:  r:  o  s    !%t!%dH Hr   r:  c                   L     e Zd Zddddd fd
Z fdZd Zdi d fdZ xZS )	HotStandbyClusterNr;  c                H    || _         || _        t        |   ||||       y )Nr;  )_master
_repl_userr@  rM   )rK   masterreplication_userr<  r=  r>  r?   rA  s          r	   rM   zHotStandbyCluster.__init__z  s1     *+++)	 	 	+r   c                 N    t         |           | j                  d      | _        y )Npg_basebackup)r@  rb   r   _pg_basebackup)rK   rA  s    r	   rb   zHotStandbyCluster._init_env  s!    "22?Cr   c                 @   | j                         dk7  r$t        dj                  | j                              t	        j
                  | j                  d| j                  d   d| j                  d   d| j                  d| j                  g	t        j                  t        j                  	      }|j                  }|j                  d
k7  r3t        dj                  |j                  |j                                     | j                  dk  rt        t         j"                  j%                  | j                  d      d      5 }|j'                  t)        j*                  dj                  | j                  d   | j                  d   | j                                     ddd       |j                         S t        t         j"                  j%                  | j                  d      d      }|j-                          |j                         S # 1 sw Y   |j                         S xY w)r|   r]   r}   z-hr   z-pr   rX   z-UrY   r   z.pg_basebackup init exited with status {:d}:
{}   r   zrecovery.confr   z                    standby_mode = 'on'
                    primary_conninfo = 'host={host} port={port} user={user}'
                r   r   r   Nzstandby.signal)rr   r8   rl   rC   rc   rd   rM  rG  rH  re   r   rZ   rf   rk   rO   r   r'   r(   r   writetextwrapdedentr   )rK   r   rp   r   r   s        r	   r   zHotStandbyCluster.init  s   ?? 11>EENN$% % ..  $V(<4<<'t~~4??$ ??:+<+<	> "AHH&&9: : g%bggll4>>?CSI ,Q ) Ff-f-  *+ ,, }} RWW\\$..2BCSIAGGI}}, }}s   >AHHr   c                    | j                   dk\  rK|j                         }dj                  | j                  d   | j                  d   | j                        |d<   t        |   d||d| y )	NrO  z%"host={host} port={port} user={user}"r   r   rQ  primary_conninfo)r   r   r   )rO   r   rl   rG  rH  r@  r   )rK   r   r   r   rA  s       r	   r   zHotStandbyCluster.start  st    w&-224O7>>f-f- ?  ./ 	I4IDIr   r7  )r9   r:   r;   rM   rb   r   r   rB  rC  s   @r	   rE  rE  y  s4     "&t!%d
+D!FJ J Jr   rE  c                   V    e Zd Zd Zd Zd Zd Zd ZddZddZ	d Z
d	 Zd
ddddZy)RunningClusterc                     || _         y r   )r  r   s     r	   rM   zRunningCluster.__init__  s	    r   c                      y)NFr   rP   s    r	   rS   zRunningCluster.is_managed  s    r   c                 ,    t        | j                        S r   )r   r  rP   s    r	   ru   z"RunningCluster.get_connection_spec  s    DNN##r   c                      y)Nr   r   rP   s    r	   rr   zRunningCluster.get_status  s    r   c                      y r   r   )rK   r   s     r	   r   zRunningCluster.init      r   c                      y r   r   )rK   r   r   s      r	   r   zRunningCluster.start  r^  r   c                      y r   r   )rK   r   s     r	   r   zRunningCluster.stop  r^  r   c                      y r   r   rP   s    r	   r   zRunningCluster.destroy  r^  r   c                     t        d      Nz.cannot modify HBA records of unmanaged clusterr8   rP   s    r	   r   zRunningCluster.reset_hba  s    KLLr   r   Nr   c                    t        d      rc  rd  )rK   r   r   r   r   r   r   s          r	   r   zRunningCluster.add_hba_entry  s    KLLr   r7  )r9   r:   r;   rM   rS   ru   rr   r   r   r   r   r   r   r   r   r	   rX  rX    s@     $M %+D04Mr   rX  )NNN)r  r'   os.pathplatformr    ri   r   r   r"   rc   r   r$   rS  r  rw   r   unamesystemr1   r
   r   r.   r6   r   r8   r=   r:  rE  rX  r   r   r	   <module>rj     s     	    	     
     ! (..

!
!
i

5	9 	_I _IDH' H?J ?JDMW Mr   