@@ -124,24 +124,22 @@ class _KeepAliveContext:
124124
125125 __slots__ = ("__ssh" , "__keepalive_status" , "__enforce" )
126126
127- def __init__ (self , ssh : "SSHClientBase" , enforce : bool = True ) -> None :
127+ def __init__ (self , ssh : "SSHClientBase" , enforce : int ) -> None :
128128 """Context manager for keepalive management.
129129
130130 :param ssh: connection instance
131131 :type ssh: SSHClientBase
132- :param enforce: keepalive mode for context manager
133- :type enforce: bool
134- :param enforce: Keep connection alive after context manager exit
132+ :param enforce: keepalive period for context manager
133+ :type enforce: int
135134 """
136135 self .__ssh : "SSHClientBase" = ssh
137- self .__keepalive_status : bool = ssh .keepalive_mode
138- self .__enforce : typing . Optional [ bool ] = enforce
136+ self .__keepalive_status : int = ssh .keepalive_mode
137+ self .__enforce : int = enforce
139138
140139 def __enter__ (self ) -> None :
141140 self .__ssh .__enter__ ()
142141 self .__keepalive_status = self .__ssh .keepalive_mode
143- if self .__enforce is not None :
144- self .__ssh .keepalive_mode = self .__enforce
142+ self .__ssh .keepalive_mode = self .__enforce
145143
146144 def __exit__ (self , exc_type : typing .Any , exc_val : typing .Any , exc_tb : typing .Any ) -> None :
147145 # Exit before releasing!
@@ -189,7 +187,7 @@ def __init__(
189187 ] = None ,
190188 ssh_auth_map : typing .Optional [typing .Union [typing .Dict [str , ssh_auth .SSHAuth ], ssh_auth .SSHAuthMapping ]] = None ,
191189 sock : typing .Optional [typing .Union [paramiko .ProxyCommand , paramiko .Channel , socket .socket ]] = None ,
192- keepalive : bool = True ,
190+ keepalive : typing . Union [ int , bool ] = 1 ,
193191 ) -> None :
194192 """Main SSH Client helper.
195193
@@ -220,8 +218,8 @@ def __init__(
220218 :type ssh_auth_map: typing.Optional[typing.Union[typing.Dict[str, ssh_auth.SSHAuth], ssh_auth.SSHAuthMapping]]
221219 :param sock: socket for connection. Useful for ssh proxies support
222220 :type sock: typing.Optional[typing.Union[paramiko.ProxyCommand, paramiko.Channel, socket.socket]]
223- :param keepalive: keepalive mode
224- :type keepalive: bool
221+ :param keepalive: keepalive period
222+ :type keepalive: typing.Union[int, bool]
225223
226224 .. note:: auth has priority over username/password/private_keys
227225 .. note::
@@ -234,6 +232,7 @@ def __init__(
234232 .. versionchanged:: 6.0.0 added optional ssh_auth_map for ssh proxy cases with authentication on each step
235233 .. versionchanged:: 6.0.0 added optional sock for manual proxy chain handling
236234 .. versionchanged:: 6.0.0 keepalive exposed to constructor
235+ .. versionchanged:: 6.0.0 keepalive became int, now used in ssh transport as period of keepalive requests
237236 .. versionchanged:: 6.0.0 private_keys is deprecated
238237 """
239238 if private_keys is not None :
@@ -262,7 +261,7 @@ def __init__(
262261 self .__auth_mapping [self .hostname ] = self .__auth_mapping [host ]
263262
264263 self .__sudo_mode = False
265- self .__keepalive_mode : bool = keepalive
264+ self .__keepalive_mode : int = int ( keepalive )
266265 self .__verbose : bool = verbose
267266 self .__sock = sock
268267
@@ -402,12 +401,7 @@ def __connect(self) -> None:
402401 self .__ssh = paramiko .SSHClient ()
403402 self .__ssh .set_missing_host_key_policy (paramiko .AutoAddPolicy ())
404403 self .auth .connect (
405- client = self .__ssh ,
406- hostname = self .hostname ,
407- port = self .port ,
408- log = self .__verbose ,
409- sock = sock ,
410- compress = bool (self .ssh_config [self .hostname ].compression ),
404+ client = self .__ssh , hostname = self .hostname , port = self .port , log = self .__verbose , sock = sock ,
411405 )
412406 else :
413407 self .__ssh = self .__get_client ()
@@ -434,12 +428,9 @@ def __get_client(self) -> paramiko.SSHClient:
434428 hostname = config .hostname ,
435429 port = config .port or 22 ,
436430 sock = paramiko .ProxyCommand (config .proxycommand ),
437- compress = bool (config .compression ),
438431 )
439432 else :
440- auth .connect (
441- last_ssh_client , hostname = config .hostname , port = config .port or 22 , compress = bool (config .compression )
442- )
433+ auth .connect (last_ssh_client , hostname = config .hostname , port = config .port or 22 )
443434
444435 for config , auth in self .__conn_chain [1 :]: # start has another logic, so do it out of cycle
445436 ssh = paramiko .SSHClient ()
@@ -449,9 +440,7 @@ def __get_client(self) -> paramiko.SSHClient:
449440 sock = last_ssh_client .get_transport ().open_channel (
450441 kind = "direct-tcpip" , dest_addr = (config .hostname , config .port or 22 ), src_addr = (config .proxyjump , 0 ),
451442 )
452- auth .connect (
453- ssh , hostname = config .hostname , port = config .port or 22 , sock = sock , compress = bool (config .compression )
454- )
443+ auth .connect (ssh , hostname = config .hostname , port = config .port or 22 , sock = sock )
455444 last_ssh_client = ssh
456445 continue
457446
@@ -541,23 +530,25 @@ def sudo_mode(self, mode: bool) -> None:
541530 self .__sudo_mode = bool (mode )
542531
543532 @property
544- def keepalive_mode (self ) -> bool :
545- """Persistent keepalive mode for connection object.
533+ def keepalive_mode (self ) -> int :
534+ """Keepalive period for connection object.
546535
547- :rtype: bool
536+ :rtype: int
537+ If 0 - close connection on exit from context manager.
548538 """
549539 return self .__keepalive_mode
550540
551541 @keepalive_mode .setter
552- def keepalive_mode (self , mode : bool ) -> None :
553- """Persistent keepalive mode change for connection object.
542+ def keepalive_mode (self , period : typing . Union [ int , bool ] ) -> None :
543+ """Keepalive period change for connection object.
554544
555- :param mode: keepalive mode enable/disable
556- :type mode: bool
545+ :param period: keepalive period change
546+ :type period: typing.Union[int, bool]
547+ If 0 - close connection on exit from context manager.
557548 """
558- self .__keepalive_mode = bool ( mode )
549+ self .__keepalive_mode = int ( period )
559550 transport : paramiko .Transport = self .__ssh .get_transport ()
560- transport .set_keepalive (1 if mode else 0 )
551+ transport .set_keepalive (int ( period ) )
561552
562553 def reconnect (self ) -> None :
563554 """Reconnect SSH session."""
@@ -571,22 +562,22 @@ def sudo(self, enforce: typing.Optional[bool] = None) -> "typing.ContextManager[
571562 :param enforce: Enforce sudo enabled or disabled. By default: None
572563 :type enforce: typing.Optional[bool]
573564 :return: context manager with selected sudo state inside
574- :rtype: typing.ContextManager
565+ :rtype: typing.ContextManager[None]
575566 """
576567 return _SudoContext (ssh = self , enforce = enforce )
577568
578- def keepalive (self , enforce : bool = True ) -> "typing.ContextManager[None]" :
579- """Call contextmanager with keepalive mode change.
569+ def keepalive (self , enforce : typing . Union [ int , bool ] = 1 ) -> "typing.ContextManager[None]" :
570+ """Call contextmanager with keepalive period change.
580571
581- :param enforce: Enforce keepalive enabled or disabled .
582- :type enforce: bool
572+ :param enforce: Enforce keepalive period .
573+ :type enforce: typing.Union[int, bool]
583574 :return: context manager with selected keepalive state inside
584- :rtype: typing.ContextManager
575+ :rtype: typing.ContextManager[None]
585576
586577 .. Note:: Enter and exit ssh context manager is produced as well.
587578 .. versionadded:: 1.2.1
588579 """
589- return _KeepAliveContext (ssh = self , enforce = enforce )
580+ return _KeepAliveContext (ssh = self , enforce = int ( enforce ) )
590581
591582 def _prepare_command (self , cmd : str , chroot_path : typing .Optional [str ] = None ) -> str :
592583 """Prepare command: cower chroot and other cases.
@@ -811,7 +802,7 @@ def proxy_to(
811802 None ,
812803 ] = None ,
813804 ssh_auth_map : typing .Optional [typing .Union [typing .Dict [str , ssh_auth .SSHAuth ], ssh_auth .SSHAuthMapping ]] = None ,
814- keepalive : bool = True ,
805+ keepalive : typing . Union [ int , bool ] = 1 ,
815806 ) -> "SSHClientBase" :
816807 """Start new SSH connection using current as proxy.
817808
@@ -838,8 +829,8 @@ def proxy_to(
838829 ]
839830 :param ssh_auth_map: SSH authentication information mapped to host names. Useful for complex SSH Proxy cases.
840831 :type ssh_auth_map: typing.Optional[typing.Union[typing.Dict[str, ssh_auth.SSHAuth], ssh_auth.SSHAuthMapping]]
841- :param keepalive: keepalive mode
842- :type keepalive: bool
832+ :param keepalive: keepalive period
833+ :type keepalive: typing.Union[int, bool]
843834 :return: new ssh client instance using current as a proxy
844835 :rtype: SSHClientBase
845836
@@ -866,7 +857,7 @@ def proxy_to(
866857 ssh_config = ssh_config ,
867858 sock = sock ,
868859 ssh_auth_map = ssh_auth_map if ssh_auth_map is not None else self .__auth_mapping ,
869- keepalive = keepalive ,
860+ keepalive = int ( keepalive ) ,
870861 )
871862
872863 def execute_through_host (
0 commit comments