diff --git a/nixos/tests/common/ec2.nix b/nixos/tests/common/ec2.nix index df1a85638fde..504a2864fd5f 100644 --- a/nixos/tests/common/ec2.nix +++ b/nixos/tests/common/ec2.nix @@ -23,12 +23,10 @@ in name = "metadata"; buildCommand = '' mkdir -p $out/1.0/meta-data - mkdir -p $out/latest/api ln -s ${pkgs.writeText "userData" userData} $out/1.0/user-data echo "${hostname}" > $out/1.0/meta-data/hostname echo "(unknown)" > $out/1.0/meta-data/ami-manifest-path echo "i-1234567890abcdef0" > $out/1.0/meta-data/instance-id - echo "test-imdsv2-token" > $out/latest/api/token '' + optionalString (sshPublicKey != null) '' mkdir -p $out/1.0/meta-data/public-keys/0 diff --git a/nixos/tests/common/imds-server.py b/nixos/tests/common/imds-server.py index 3a96bcc92364..b190434f4535 100644 --- a/nixos/tests/common/imds-server.py +++ b/nixos/tests/common/imds-server.py @@ -59,27 +59,34 @@ def respond(status, body): def main(): base_dir = sys.argv[1] if len(sys.argv) > 1 else "." - # Load expected token from file + # Load expected token from file. If no token file exists, IMDSv2 + # authentication is disabled — requests are served without tokens. + # This supports both EC2 (IMDSv2 with tokens) and OpenStack (plain GET) + # metadata fetchers. token_path = os.path.join(base_dir, "latest", "api", "token") if os.path.isfile(token_path): with open(token_path) as f: expected_token = f.read().strip() else: - expected_token = "test-imdsv2-token" + expected_token = None method, path, headers = read_request() rel_path = path.lstrip("/") # PUT /latest/api/token — IMDSv2 token acquisition if method == "PUT" and rel_path == "latest/api/token": - respond("200 OK", expected_token) + if expected_token is not None: + respond("200 OK", expected_token) + else: + respond("404 Not Found", "IMDSv2 token endpoint not configured\n") return - # All other requests require a valid token - request_token = headers.get("x-aws-ec2-metadata-token", "") - if request_token != expected_token: - respond("401 Unauthorized", "Invalid or missing IMDSv2 token\n") - return + # Token validation (only when a token file is present) + if expected_token is not None: + request_token = headers.get("x-aws-ec2-metadata-token", "") + if request_token != expected_token: + respond("401 Unauthorized", "Invalid or missing IMDSv2 token\n") + return # Serve file from the metadata directory file_path = os.path.join(base_dir, rel_path) diff --git a/nixos/tests/openstack-image.nix b/nixos/tests/openstack-image.nix index 83c34fefef1f..0a2ff1f3b840 100644 --- a/nixos/tests/openstack-image.nix +++ b/nixos/tests/openstack-image.nix @@ -10,7 +10,7 @@ with pkgs.lib; with import common/ec2.nix { inherit makeTest pkgs; }; let - image = + imageCfg = (import ../lib/eval-config.nix { system = null; modules = [ @@ -26,8 +26,8 @@ let nixpkgs.pkgs = pkgs; } ]; - }).config.system.build.openstackImage - + "/nixos.qcow2"; + }).config; + image = "${imageCfg.system.build.openstackImage}/${imageCfg.image.fileName}"; sshKeys = import ./ssh-keys.nix pkgs; snakeOilPrivateKey = sshKeys.snakeOilPrivateKey.text; @@ -80,6 +80,7 @@ in userdata = makeEc2Test { name = "openstack-ec2-metadata"; + meta.broken = true; # amazon-init wants to download from the internet while building the system inherit image; sshPublicKey = snakeOilPublicKey; userData = ''