|
10 | 10 | import contextlib |
11 | 11 | import importlib.util |
12 | 12 | import logging |
| 13 | +import re |
13 | 14 | import time |
14 | 15 | from typing import Any, Dict, List, Optional |
15 | 16 |
|
@@ -155,6 +156,37 @@ def _create_command( |
155 | 156 |
|
156 | 157 | return script |
157 | 158 |
|
| 159 | + async def _read_max_sessions(self) -> int: |
| 160 | + """ |
| 161 | + Read the SSH MaxSessions value and return it. |
| 162 | + """ |
| 163 | + max_sessions = 10 |
| 164 | + |
| 165 | + # pyrefly: ignore[missing-attribute] |
| 166 | + ret = await self._conn.run( |
| 167 | + "grep -i '^MaxSessions' /etc/ssh/sshd_config", |
| 168 | + timeout=5, |
| 169 | + ) |
| 170 | + if ret.returncode == 0: |
| 171 | + match = re.search(r"^MaxSessions (?P<value>\d+)", ret.stdout) |
| 172 | + if match: |
| 173 | + max_sessions = int(match.group("value")) |
| 174 | + return max_sessions |
| 175 | + |
| 176 | + # pyrefly: ignore[missing-attribute] |
| 177 | + ret = await self._conn.run( |
| 178 | + "sudo sshd -T | grep maxsessions", |
| 179 | + timeout=5, |
| 180 | + ) |
| 181 | + if ret.returncode == 0: |
| 182 | + match = re.search(r"^maxsessions (?P<value>\d+)", ret.stdout) |
| 183 | + if match: |
| 184 | + max_sessions = int(match.group("value")) |
| 185 | + |
| 186 | + self._logger.info("Maximum SSH sessions: %d", max_sessions) |
| 187 | + |
| 188 | + return max_sessions |
| 189 | + |
158 | 190 | def setup(self, **kwargs: Dict[str, Any]) -> None: |
159 | 191 | if not importlib.util.find_spec("asyncssh"): |
160 | 192 | raise CommunicationError("'asyncssh' library is not available") |
@@ -226,17 +258,8 @@ async def communicate(self, iobuffer: Optional[IOBuffer] = None) -> None: |
226 | 258 | known_hosts=self._known_hosts, |
227 | 259 | ) |
228 | 260 |
|
229 | | - # pyrefly: ignore[missing-attribute] |
230 | | - # read maximum number of sessions and limit `run_command` |
231 | | - # concurrent calls to that by using a semaphore |
232 | | - ret = await self._conn.run( |
233 | | - r'sed -n "s/^MaxSessions\s*\([[:digit:]]*\)/\1/p" ' |
234 | | - "/etc/ssh/sshd_config" |
235 | | - ) |
236 | | - |
237 | | - max_sessions = ret.stdout or 10 |
| 261 | + max_sessions = await self._read_max_sessions() |
238 | 262 |
|
239 | | - self._logger.info("Maximum SSH sessions: %d", max_sessions) |
240 | 263 | self._session_sem = asyncio.Semaphore(max_sessions) |
241 | 264 | except (asyncssh.Error, ConnectionError) as err: |
242 | 265 | if not self._stop: |
|
0 commit comments