|
30 | 30 | MMDS_VERSIONS = ["V2", "V1"] |
31 | 31 |
|
32 | 32 |
|
33 | | -def _validate_mmds_snapshot( |
34 | | - basevm, |
35 | | - microvm_factory, |
36 | | - version, |
37 | | - imds_compat, |
38 | | - fc_binary_path=None, |
39 | | - jailer_binary_path=None, |
40 | | -): |
41 | | - """Test MMDS behaviour across snap-restore.""" |
42 | | - ipv4_address = "169.254.169.250" |
43 | | - |
44 | | - # Configure MMDS version with custom IPv4 address. |
45 | | - configure_mmds( |
46 | | - basevm, |
47 | | - version=version, |
48 | | - iface_ids=["eth0"], |
49 | | - ipv4_address=ipv4_address, |
50 | | - imds_compat=imds_compat, |
51 | | - ) |
52 | | - |
53 | | - expected_mmds_config = { |
54 | | - "version": version, |
55 | | - "ipv4_address": ipv4_address, |
56 | | - "network_interfaces": ["eth0"], |
57 | | - "imds_compat": False if imds_compat is None else imds_compat, |
58 | | - } |
59 | | - response = basevm.api.vm_config.get() |
60 | | - assert response.json()["mmds-config"] == expected_mmds_config |
61 | | - |
62 | | - data_store = {"latest": {"meta-data": {"ami-id": "ami-12345678"}}} |
63 | | - populate_data_store(basevm, data_store) |
64 | | - expected_response = "latest/" if imds_compat else data_store |
65 | | - |
66 | | - basevm.start() |
67 | | - ssh_connection = basevm.ssh |
68 | | - run_guest_cmd(ssh_connection, f"ip route add {ipv4_address} dev eth0", "") |
69 | | - |
70 | | - # Both V1 and V2 support token generation. |
71 | | - token = generate_mmds_session_token(ssh_connection, ipv4_address, token_ttl=60) |
72 | | - |
73 | | - # Fetch metadata. |
74 | | - cmd = generate_mmds_get_request( |
75 | | - ipv4_address, |
76 | | - token=token, |
77 | | - ) |
78 | | - run_guest_cmd(ssh_connection, cmd, expected_response, use_json=not imds_compat) |
79 | | - |
80 | | - # Create snapshot. |
81 | | - snapshot = basevm.snapshot_full() |
82 | | - |
83 | | - # Resume microVM and ensure session token is still valid on the base. |
84 | | - response = basevm.resume() |
85 | | - |
86 | | - # Fetch metadata again using the same token. |
87 | | - run_guest_cmd(ssh_connection, cmd, expected_response, use_json=not imds_compat) |
88 | | - |
89 | | - # Kill base microVM. |
90 | | - basevm.kill() |
91 | | - |
92 | | - # Load microVM clone from snapshot. |
93 | | - kwargs = {} |
94 | | - if fc_binary_path: |
95 | | - kwargs["fc_binary_path"] = fc_binary_path |
96 | | - if jailer_binary_path: |
97 | | - kwargs["jailer_binary_path"] = jailer_binary_path |
98 | | - microvm = microvm_factory.build(**kwargs) |
99 | | - microvm.spawn() |
100 | | - microvm.restore_from_snapshot(snapshot, resume=True) |
101 | | - |
102 | | - ssh_connection = microvm.ssh |
103 | | - |
104 | | - # Check the reported MMDS config. |
105 | | - response = microvm.api.vm_config.get() |
106 | | - assert response.json()["mmds-config"] == expected_mmds_config |
107 | | - |
108 | | - # Since V1 should accept GET request even with invalid token, don't regenerate a token for V1. |
109 | | - if version == "V2": |
110 | | - # Attempting to reuse the token across a restore must fail in V2. |
111 | | - cmd = generate_mmds_get_request(ipv4_address, token=token) |
112 | | - run_guest_cmd(ssh_connection, cmd, "MMDS token not valid.") |
113 | | - |
114 | | - # Re-generate token. |
115 | | - token = generate_mmds_session_token(ssh_connection, ipv4_address, token_ttl=60) |
116 | | - |
117 | | - # Data store is empty after a restore. |
118 | | - cmd = generate_mmds_get_request(ipv4_address, token=token) |
119 | | - run_guest_cmd( |
120 | | - ssh_connection, |
121 | | - cmd, |
122 | | - ( |
123 | | - "Cannot retrieve value. The value has an unsupported type." |
124 | | - if imds_compat |
125 | | - else "null" |
126 | | - ), |
127 | | - ) |
128 | | - |
129 | | - # Now populate the store. |
130 | | - populate_data_store(microvm, data_store) |
131 | | - |
132 | | - # Fetch metadata. |
133 | | - run_guest_cmd(ssh_connection, cmd, expected_response, use_json=not imds_compat) |
134 | | - |
135 | | - |
136 | 33 | @pytest.mark.parametrize("version", MMDS_VERSIONS) |
137 | 34 | @pytest.mark.parametrize("imds_compat", [True, False]) |
138 | 35 | def test_mmds_token(uvm_plain, version, imds_compat): |
@@ -627,18 +524,95 @@ def test_mmds_snapshot(uvm_nano, microvm_factory, version, imds_compat): |
627 | 524 | Ensures that the version is persisted or initialised with the default if |
628 | 525 | the firecracker version does not support it. |
629 | 526 | """ |
| 527 | + basevm = uvm_nano |
| 528 | + basevm.add_net_iface() |
| 529 | + ipv4_address = "169.254.169.250" |
630 | 530 |
|
631 | | - current_release = working_version_as_artifact() |
632 | | - uvm_nano.add_net_iface() |
633 | | - _validate_mmds_snapshot( |
634 | | - uvm_nano, |
635 | | - microvm_factory, |
636 | | - version, |
637 | | - imds_compat, |
638 | | - fc_binary_path=current_release.path, |
639 | | - jailer_binary_path=current_release.jailer, |
| 531 | + # Configure MMDS version with custom IPv4 address. |
| 532 | + configure_mmds( |
| 533 | + basevm, |
| 534 | + version=version, |
| 535 | + iface_ids=["eth0"], |
| 536 | + ipv4_address=ipv4_address, |
| 537 | + imds_compat=imds_compat, |
640 | 538 | ) |
641 | 539 |
|
| 540 | + expected_mmds_config = { |
| 541 | + "version": version, |
| 542 | + "ipv4_address": ipv4_address, |
| 543 | + "network_interfaces": ["eth0"], |
| 544 | + "imds_compat": False if imds_compat is None else imds_compat, |
| 545 | + } |
| 546 | + response = basevm.api.vm_config.get() |
| 547 | + assert response.json()["mmds-config"] == expected_mmds_config |
| 548 | + |
| 549 | + data_store = {"latest": {"meta-data": {"ami-id": "ami-12345678"}}} |
| 550 | + populate_data_store(basevm, data_store) |
| 551 | + expected_response = "latest/" if imds_compat else data_store |
| 552 | + |
| 553 | + basevm.start() |
| 554 | + ssh_connection = basevm.ssh |
| 555 | + run_guest_cmd(ssh_connection, f"ip route add {ipv4_address} dev eth0", "") |
| 556 | + |
| 557 | + # Both V1 and V2 support token generation. |
| 558 | + token = generate_mmds_session_token(ssh_connection, ipv4_address, token_ttl=60) |
| 559 | + |
| 560 | + # Fetch metadata. |
| 561 | + cmd = generate_mmds_get_request( |
| 562 | + ipv4_address, |
| 563 | + token=token, |
| 564 | + ) |
| 565 | + run_guest_cmd(ssh_connection, cmd, expected_response, use_json=not imds_compat) |
| 566 | + |
| 567 | + # Create snapshot. |
| 568 | + snapshot = basevm.snapshot_full() |
| 569 | + |
| 570 | + # Resume microVM and ensure session token is still valid on the base. |
| 571 | + response = basevm.resume() |
| 572 | + |
| 573 | + # Fetch metadata again using the same token. |
| 574 | + run_guest_cmd(ssh_connection, cmd, expected_response, use_json=not imds_compat) |
| 575 | + |
| 576 | + # Kill base microVM. |
| 577 | + basevm.kill() |
| 578 | + |
| 579 | + # Load microVM clone from snapshot. |
| 580 | + microvm = microvm_factory.build() |
| 581 | + microvm.spawn() |
| 582 | + microvm.restore_from_snapshot(snapshot, resume=True) |
| 583 | + |
| 584 | + ssh_connection = microvm.ssh |
| 585 | + |
| 586 | + # Check the reported MMDS config. |
| 587 | + response = microvm.api.vm_config.get() |
| 588 | + assert response.json()["mmds-config"] == expected_mmds_config |
| 589 | + |
| 590 | + if version == "V2": |
| 591 | + # Attempting to reuse the token across a restore must fail in V2. |
| 592 | + cmd = generate_mmds_get_request(ipv4_address, token=token) |
| 593 | + run_guest_cmd(ssh_connection, cmd, "MMDS token not valid.") |
| 594 | + |
| 595 | + # Re-generate token. |
| 596 | + token = generate_mmds_session_token(ssh_connection, ipv4_address, token_ttl=60) |
| 597 | + |
| 598 | + # Data store is empty after a restore. |
| 599 | + cmd = generate_mmds_get_request(ipv4_address, token=token) |
| 600 | + run_guest_cmd( |
| 601 | + ssh_connection, |
| 602 | + cmd, |
| 603 | + ( |
| 604 | + "Cannot retrieve value. The value has an unsupported type." |
| 605 | + if imds_compat |
| 606 | + else "null" |
| 607 | + ), |
| 608 | + ) |
| 609 | + |
| 610 | + # Now populate the store. |
| 611 | + populate_data_store(microvm, data_store) |
| 612 | + |
| 613 | + # Fetch metadata. |
| 614 | + run_guest_cmd(ssh_connection, cmd, expected_response, use_json=not imds_compat) |
| 615 | + |
642 | 616 |
|
643 | 617 | def test_mmds_v2_negative(uvm_plain): |
644 | 618 | """ |
|
0 commit comments