99# or in the "LICENSE.txt" file accompanying this file.
1010# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied.
1111# See the License for the specific language governing permissions and limitations under the License.
12+ import contextlib
13+ import fcntl
1214import json
1315import logging
1416import os as operating_system
@@ -241,14 +243,26 @@ def _check_error_cases(remote_command_executor, dcv_authenticator_port):
241243 logging .info (f"Completed checks for authentication failure on { remote_command_executor .target } " )
242244
243245
246+ @contextlib .contextmanager
247+ def _temporary_known_host (hostname , host_keys_file , env ):
248+ """Add SSH host keys for hostname, yield, then remove them. Serialized via file lock across processes."""
249+ lock_file = host_keys_file + ".lock"
250+ with open (lock_file , "w" ) as lf :
251+ fcntl .flock (lf , fcntl .LOCK_EX )
252+ try :
253+ add_keys_to_known_hosts (hostname , host_keys_file )
254+ yield
255+ finally :
256+ remove_keys_from_known_hosts (hostname , host_keys_file , env = env )
257+
258+
244259def _test_show_url (cluster , region , dcv_port , access_from , use_login_node = False ): # noqa: C901
245260 """Test dcv-connect with --show-url."""
246261 env = operating_system .environ .copy ()
247262 env ["AWS_DEFAULT_REGION" ] = region
248263
249264 node_ip = cluster .get_login_node_public_ip () if use_login_node else cluster .head_node_ip
250265
251- # add ssh key to jenkins user known hosts file to avoid ssh keychecking prompt
252266 # Ensure known_hosts path exists to avoid `cat` command returning non-zero exit when testing in ADC region.
253267 host_keys_file = operating_system .path .expanduser ("~/.ssh/known_hosts" )
254268 host_keys_path = Path (host_keys_file )
@@ -260,18 +274,18 @@ def _test_show_url(cluster, region, dcv_port, access_from, use_login_node=False)
260274 except Exception as e :
261275 logging .warning (f"Failed to prepare known_hosts file { host_keys_file } : { e } " )
262276
263- add_keys_to_known_hosts (node_ip , host_keys_file )
264-
265277 dcv_connect_args = ["pcluster" , "dcv-connect" , "--cluster-name" , cluster .name , "--show-url" ]
266278
267279 if use_login_node :
268280 dcv_connect_args .extend (["--login-node-ip" , node_ip ])
269281
270- try :
271- result = run_pcluster_command (dcv_connect_args , env = env )
272- finally :
273- # remove ssh key from jenkins user known hosts file
274- remove_keys_from_known_hosts (node_ip , host_keys_file , env = env )
282+ with _temporary_known_host (node_ip , host_keys_file , env ):
283+ try :
284+ result = run_pcluster_command (dcv_connect_args , env = env )
285+ except subprocess .CalledProcessError as e :
286+ raise AssertionError (
287+ f"Command { e .cmd } failed (exit { e .returncode } ).\n stderr: { e .stderr } \n stdout: { e .stdout } "
288+ ) from e
275289
276290 assert_that (result .stdout ).matches (
277291 r"Please use the following one-time URL in your browser within 30 seconds:\n"
0 commit comments