2424"""
2525
2626import logging
27+ import time
2728from urllib .parse import parse_qs , urlparse
2829
2930import pytest
@@ -40,6 +41,28 @@ def delete_telemetry_tag(aws_session, instance_id):
4041 aws_session .ec2 .delete_tags (Resources = [instance_id ], Tags = [{"Key" : TELEMETRY_TAG_KEY }])
4142
4243
44+ def set_imds_hop_limit (aws_session , instance_id , hop_limit , timeout = 120 ):
45+ """Set the IMDSv2 hop limit and wait until it is live.
46+
47+ modify_instance_metadata_options is asynchronous (InstanceMetadataOptions.State
48+ goes pending -> applied); launching a container before it applies races the
49+ telemetry script's one-shot IMDS probe and makes the test flaky.
50+ """
51+ aws_session .ec2 .modify_instance_metadata_options (
52+ InstanceId = instance_id , HttpPutResponseHopLimit = hop_limit
53+ )
54+ deadline = time .time () + timeout
55+ while time .time () < deadline :
56+ instance = aws_session .ec2 .describe_instances (InstanceIds = [instance_id ])["Reservations" ][0 ][
57+ "Instances"
58+ ][0 ]
59+ options = instance ["InstanceMetadataOptions" ]
60+ if options ["State" ] == "applied" and options ["HttpPutResponseHopLimit" ] == hop_limit :
61+ return
62+ time .sleep (5 )
63+ raise TimeoutError (f"IMDS hop_limit={ hop_limit } not applied within { timeout } s" )
64+
65+
4366def telemetry_file_exists (conn , container ):
4467 result = conn .run (f"docker exec { container } test -f /tmp/test_request.txt" , warn = True )
4568 return result .return_code == 0
@@ -122,9 +145,7 @@ def test_imds_hop_limit(conn, aws_session, telemetry_container, ec2_instance):
122145
123146 # hop_limit=1: container can't get IMDSv2 token through Docker bridge
124147 delete_telemetry_tag (aws_session , instance_id )
125- aws_session .ec2 .modify_instance_metadata_options (
126- InstanceId = instance_id , HttpPutResponseHopLimit = 1
127- )
148+ set_imds_hop_limit (aws_session , instance_id , 1 )
128149 container_name = telemetry_container ("telemetry-hop1" , env = {"TEST_MODE" : "1" })
129150
130151 assert not telemetry_file_exists (conn , container_name ), (
@@ -135,9 +156,7 @@ def test_imds_hop_limit(conn, aws_session, telemetry_container, ec2_instance):
135156 assert TELEMETRY_TAG_KEY not in tags , "Tag should not exist with hop_limit=1"
136157
137158 # hop_limit=2: container can get IMDSv2 token
138- aws_session .ec2 .modify_instance_metadata_options (
139- InstanceId = instance_id , HttpPutResponseHopLimit = 2
140- )
159+ set_imds_hop_limit (aws_session , instance_id , 2 )
141160 container_name = telemetry_container ("telemetry-hop2" , env = {"TEST_MODE" : "1" })
142161
143162 assert telemetry_file_exists (conn , container_name ), "Telemetry should fire with hop_limit=2"
0 commit comments