diff --git a/.buildkite/common.py b/.buildkite/common.py
index 196435bb2e0..a8913d5d6ef 100644
--- a/.buildkite/common.py
+++ b/.buildkite/common.py
@@ -13,14 +13,14 @@
import subprocess
from pathlib import Path
-DEFAULT_INSTANCES = {
- "c5n.metal": "x86_64", # Intel Skylake
- "m5n.metal": "x86_64", # Intel Cascade Lake
- "m6i.metal": "x86_64", # Intel Icelake
- "m6a.metal": "x86_64", # AMD Milan
- "m6g.metal": "aarch64", # Graviton2
- "m7g.metal": "aarch64", # Graviton3
-}
+DEFAULT_INSTANCES = [
+ "c5n.metal", # Intel Skylake
+ "m5n.metal", # Intel Cascade Lake
+ "m6i.metal", # Intel Icelake
+ "m6a.metal", # AMD Milan
+ "m6g.metal", # Graviton2
+ "m7g.metal", # Graviton3
+]
DEFAULT_PLATFORMS = [
("al2", "linux_5.10"),
@@ -28,6 +28,11 @@
]
+def get_arch_for_instance(instance):
+ """Return instance architecture"""
+ return "x86_64" if instance[2] != "g" else "aarch64"
+
+
def overlay_dict(base: dict, update: dict):
"""Overlay a dict over a base one"""
base = base.copy()
@@ -145,7 +150,7 @@ def __call__(self, parser, namespace, value, option_string=None):
"--instances",
required=False,
nargs="+",
- default=DEFAULT_INSTANCES.keys(),
+ default=DEFAULT_INSTANCES,
)
COMMON_PARSER.add_argument(
"--platforms",
@@ -288,7 +293,7 @@ def _adapt_group(self, group):
step["command"] = prepend + step["command"]
if self.shared_build is not None:
step["depends_on"] = self.build_key(
- DEFAULT_INSTANCES[step["agents"]["instance"]]
+ get_arch_for_instance(step["agents"]["instance"])
)
return group
@@ -323,7 +328,7 @@ def build_group_per_arch(self, label, *args, **kwargs):
if set_key:
for step in grp["steps"]:
step["key"] = self.build_key(
- DEFAULT_INSTANCES[step["agents"]["instance"]]
+ get_arch_for_instance(step["agents"]["instance"])
)
return self.add_step(grp, depends_on_build=depends_on_build)
diff --git a/.buildkite/pipeline_cpu_template.py b/.buildkite/pipeline_cpu_template.py
index 2de782320c1..c8c5f75fa09 100755
--- a/.buildkite/pipeline_cpu_template.py
+++ b/.buildkite/pipeline_cpu_template.py
@@ -23,7 +23,7 @@ class BkStep(str, Enum):
cpu_template_test = {
"rdmsr": {
BkStep.COMMAND: [
- "tools/devtool -y test --no-build -- -m nonci -n4 --dist worksteal integration_tests/functional/test_cpu_features.py -k 'test_cpu_rdmsr' "
+ "tools/devtool -y test --no-build -- -m nonci -n4 --dist worksteal integration_tests/functional/test_cpu_features_x86_64.py -k 'test_cpu_rdmsr' "
],
BkStep.LABEL: "📖 rdmsr",
"instances": ["c5n.metal", "m5n.metal", "m6a.metal", "m6i.metal"],
@@ -34,13 +34,13 @@ class BkStep(str, Enum):
"tools/devtool -y test --no-build -- -m no_block_pr integration_tests/functional/test_cpu_template_helper.py -k test_guest_cpu_config_change",
],
BkStep.LABEL: "🖐️ fingerprint",
- "instances": DEFAULT_INSTANCES.keys(),
+ "instances": DEFAULT_INSTANCES,
"platforms": DEFAULT_PLATFORMS,
},
"cpuid_wrmsr": {
"snapshot": {
BkStep.COMMAND: [
- "tools/devtool -y test --no-build -- -m nonci -n4 --dist worksteal integration_tests/functional/test_cpu_features.py -k 'test_cpu_wrmsr_snapshot or test_cpu_cpuid_snapshot'",
+ "tools/devtool -y test --no-build -- -m nonci -n4 --dist worksteal integration_tests/functional/test_cpu_features_x86_64.py -k 'test_cpu_wrmsr_snapshot or test_cpu_cpuid_snapshot'",
"mkdir -pv tests/snapshot_artifacts_upload/{instance}_{os}_{kv}",
"sudo mv tests/snapshot_artifacts/* tests/snapshot_artifacts_upload/{instance}_{os}_{kv}",
],
@@ -52,7 +52,7 @@ class BkStep(str, Enum):
BkStep.COMMAND: [
"buildkite-agent artifact download tests/snapshot_artifacts_upload/{instance}_{os}_{kv}/**/* .",
"mv tests/snapshot_artifacts_upload/{instance}_{os}_{kv} tests/snapshot_artifacts",
- "tools/devtool -y test --no-build -- -m nonci -n4 --dist worksteal integration_tests/functional/test_cpu_features.py -k 'test_cpu_wrmsr_restore or test_cpu_cpuid_restore'",
+ "tools/devtool -y test --no-build -- -m nonci -n4 --dist worksteal integration_tests/functional/test_cpu_features_x86_64.py -k 'test_cpu_wrmsr_restore or test_cpu_cpuid_restore'",
],
BkStep.LABEL: "📸 load snapshot artifacts created on {instance} {snapshot_os} {snapshot_kv} to {restore_instance} {restore_os} {restore_kv}",
BkStep.TIMEOUT: 30,
diff --git a/.buildkite/pipeline_cross.py b/.buildkite/pipeline_cross.py
index ceb89d27f3d..d7cd261a3d0 100755
--- a/.buildkite/pipeline_cross.py
+++ b/.buildkite/pipeline_cross.py
@@ -21,10 +21,12 @@
instances_x86_64 = ["c5n.metal", "m5n.metal", "m6i.metal", "m6a.metal"]
instances_aarch64 = ["m7g.metal"]
commands = [
- "./tools/devtool -y sh ./tools/create_snapshot_artifact/main.py",
- "mkdir -pv snapshots/{instance}_{kv}",
- "sudo chown -Rc $USER: snapshot_artifacts",
- "mv -v snapshot_artifacts/* snapshots/{instance}_{kv}",
+ "./tools/devtool -y test --no-build -- -m nonci -n4 integration_tests/functional/test_snapshot_phase1.py",
+ # punch holes in mem snapshot tiles and tar them so they are preserved in S3
+ "find test_results/test_snapshot_phase1 -type f -name mem |xargs -P4 -t -n1 fallocate -d",
+ "mv -v test_results/test_snapshot_phase1 snapshot_artifacts",
+ "mkdir -pv snapshots",
+ "tar cSvf snapshots/{instance}_{kv}.tar snapshot_artifacts",
]
pipeline.build_group(
"📸 create snapshots",
@@ -80,10 +82,10 @@
k_val = pytest_keyword_for_instance.get(dst_instance, "")
step = {
"command": [
- f"buildkite-agent artifact download snapshots/{src_instance}_{src_kv}/* .",
- f"mv -v snapshots/{src_instance}_{src_kv} snapshot_artifacts",
+ f"buildkite-agent artifact download snapshots/{src_instance}_{src_kv}.tar .",
+ f"tar xSvf snapshots/{src_instance}_{src_kv}.tar",
*pipeline.devtool_test(
- pytest_opts=f"-m nonci {k_val} integration_tests/functional/test_snapshot_restore_cross_kernel.py",
+ pytest_opts=f"-m nonci -n4 {k_val} integration_tests/functional/test_snapshot_restore_cross_kernel.py",
),
],
"label": f"🎬 {src_instance} {src_kv} ➡️ {dst_instance} {dst_kv}",
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 1d6da74ba72..e05f0c2ae15 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -15,16 +15,20 @@ Certificate of Origin and signing off your commits, please check
## PR Checklist
+- [ ] I have read and understand [CONTRIBUTING.md][3].
+- [ ] I have run `tools/devtool checkstyle` to verify that the PR passes the
+ automated style checks.
+- [ ] I have described what is done in these changes, why they are needed, and
+ how they are solving the problem in a clear and encompassing way.
+- [ ] I have updated any relevant documentation (both in code and in the docs)
+ in the PR.
+- [ ] I have mentioned all user-facing changes in `CHANGELOG.md`.
- [ ] If a specific issue led to this PR, this PR closes the issue.
-- [ ] The description of changes is clear and encompassing.
-- [ ] Any required documentation changes (code and docs) are included in this
- PR.
-- [ ] API changes follow the [Runbook for Firecracker API changes][2].
-- [ ] User-facing changes are mentioned in `CHANGELOG.md`.
-- [ ] All added/changed functionality is tested.
-- [ ] New `TODO`s link to an issue.
-- [ ] Commits meet
- [contribution quality standards](https://github.com/firecracker-microvm/firecracker/blob/main/CONTRIBUTING.md#contribution-quality-standards).
+- [ ] When making API changes, I have followed the
+ [Runbook for Firecracker API changes][2].
+- [ ] I have tested all new and changed functionalities in unit tests and/or
+ integration tests.
+- [ ] I have linked an issue to every new `TODO`.
______________________________________________________________________
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0ab56b4db0..6e7be8f518f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,33 @@ and this project adheres to
### Added
+### Changed
+
+- [#4913](https://github.com/firecracker-microvm/firecracker/pull/4913): Removed
+ unnecessary fields (`max_connections` and `max_pending_resets`) from the
+ snapshot format, bumping the snapshot version to 5.0.0. Users need to
+ regenerate snapshots.
+
+### Deprecated
+
+### Removed
+
+### Fixed
+
+- [#4921](https://github.com/firecracker-microvm/firecracker/pull/4921): Fixed
+ swagger `CpuConfig` definition to include missing aarch64-specific fields.
+
+## \[1.10.1\]
+
+### Changed
+
+- [#4907](https://github.com/firecracker-microvm/firecracker/pull/4907): Bumped
+ the snapshot version to 4.0.0, so users need to regenerate snapshots.
+
+## \[1.10.0\]
+
+### Added
+
- [#4834](https://github.com/firecracker-microvm/firecracker/pull/4834): Add
`VIRTIO_NET_F_RX_MRGBUF` support to the `virtio-net` device. When this feature
is negotiated, guest `virtio-net` driver can perform more efficient memory
@@ -33,10 +60,6 @@ and this project adheres to
### Changed
-- [#4875](https://github.com/firecracker-microvm/firecracker/pull/4875):
- Increase default queue size for the `virtio-net` device from 256 to 512. This
- decreases wait time between guest and vmm threads for network packets
- processing and allows for more throughput.
- [#4844](https://github.com/firecracker-microvm/firecracker/pull/4844): Upgrade
`virtio-net` device to use `readv` syscall to avoid unnecessary memory copies
on RX path, increasing the RX performance.
diff --git a/Cargo.lock b/Cargo.lock
index cf18c4387dc..b3ad7e16b54 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7,9 +7,9 @@ name = "acpi_tables"
version = "0.1.0"
dependencies = [
"displaydoc",
- "thiserror",
- "vm-memory 0.16.0",
- "zerocopy 0.8.7",
+ "thiserror 2.0.3",
+ "vm-memory",
+ "zerocopy 0.8.10",
]
[[package]]
@@ -64,9 +64,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstream"
-version = "0.6.17"
+version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338"
+checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -79,9 +79,9 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.9"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56"
+checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
@@ -125,11 +125,11 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "aws-lc-fips-sys"
-version = "0.12.13"
+version = "0.12.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf12b67bc9c5168f68655aadb2a12081689a58f1d9b1484705e4d1810ed6e4ac"
+checksum = "8671005a9c1e80bd3dc9aee84c5bfd594d32a3d645fdb56d5d9d5e26daa4c315"
dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.5",
"cc",
"cmake",
"dunce",
@@ -140,9 +140,9 @@ dependencies = [
[[package]]
name = "aws-lc-rs"
-version = "1.10.0"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdd82dba44d209fddb11c190e0a94b78651f95299598e472215667417a03ff1d"
+checksum = "fe7c2840b66236045acd2607d5866e274380afd87ef99d6226e961e2cb47df45"
dependencies = [
"aws-lc-fips-sys",
"aws-lc-sys",
@@ -154,11 +154,11 @@ dependencies = [
[[package]]
name = "aws-lc-sys"
-version = "0.22.0"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df7a4168111d7eb622a31b214057b8509c0a7e1794f44c546d742330dc793972"
+checksum = "ad3a619a9de81e1d7de1f1186dcba4506ed661a0e483d84410fdef0ee87b2f96"
dependencies = [
- "bindgen 0.69.4",
+ "bindgen 0.69.5",
"cc",
"cmake",
"dunce",
@@ -204,9 +204,9 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.69.4"
+version = "0.69.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
+checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
dependencies = [
"bitflags 2.6.0",
"cexpr",
@@ -261,9 +261,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
-version = "1.1.31"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
+checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
dependencies = [
"jobserver",
"libc",
@@ -341,9 +341,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.20"
+version = "4.5.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
+checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
dependencies = [
"clap_builder",
"clap_derive",
@@ -360,9 +360,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.20"
+version = "4.5.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
+checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
dependencies = [
"anstream",
"anstyle",
@@ -384,9 +384,9 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.7.2"
+version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
+checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
[[package]]
name = "clippy-tracing"
@@ -418,7 +418,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "cpu-template-helper"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
dependencies = [
"clap",
"displaydoc",
@@ -426,16 +426,16 @@ dependencies = [
"log-instrument",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 2.0.3",
"vmm",
"vmm-sys-util",
]
[[package]]
name = "cpufeatures"
-version = "0.2.14"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
+checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
dependencies = [
"libc",
]
@@ -606,7 +606,7 @@ dependencies = [
[[package]]
name = "firecracker"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
dependencies = [
"bincode",
"cargo_toml",
@@ -620,7 +620,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
- "thiserror",
+ "thiserror 2.0.3",
"timerfd",
"userfaultfd",
"utils",
@@ -707,9 +707,9 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.15.0"
+version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
+checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
[[package]]
name = "heck"
@@ -800,13 +800,13 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "jailer"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
dependencies = [
"libc",
"log-instrument",
"nix 0.29.0",
"regex",
- "thiserror",
+ "thiserror 2.0.3",
"utils",
"vmm-sys-util",
]
@@ -857,9 +857,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.161"
+version = "0.2.164"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
+checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
[[package]]
name = "libloading"
@@ -883,7 +883,7 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870c3814345f050991f99869417779f6062542bcf4ed81db7a1b926ad1306638"
dependencies = [
- "vm-memory 0.16.0",
+ "vm-memory",
]
[[package]]
@@ -1140,12 +1140,12 @@ dependencies = [
[[package]]
name = "rebase-snap"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
dependencies = [
"displaydoc",
"libc",
"log-instrument",
- "thiserror",
+ "thiserror 2.0.3",
"utils",
"vmm-sys-util",
]
@@ -1164,9 +1164,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.8"
+version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
@@ -1187,9 +1187,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
-version = "0.38.38"
+version = "0.38.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
+checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
dependencies = [
"bitflags 2.6.0",
"errno",
@@ -1215,7 +1215,7 @@ dependencies = [
[[package]]
name = "seccompiler"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
dependencies = [
"bincode",
"displaydoc",
@@ -1223,7 +1223,7 @@ dependencies = [
"log-instrument",
"serde",
"serde_json",
- "thiserror",
+ "thiserror 2.0.3",
"utils",
"vmm-sys-util",
]
@@ -1239,18 +1239,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.214"
+version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
+checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.214"
+version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
+checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [
"proc-macro2",
"quote",
@@ -1259,9 +1259,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.132"
+version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
+checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
dependencies = [
"itoa",
"memchr",
@@ -1295,7 +1295,7 @@ dependencies = [
[[package]]
name = "snapshot-editor"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
dependencies = [
"clap",
"clap-num",
@@ -1303,7 +1303,7 @@ dependencies = [
"libc",
"log-instrument",
"semver",
- "thiserror",
+ "thiserror 2.0.3",
"utils",
"vmm",
"vmm-sys-util",
@@ -1323,9 +1323,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.85"
+version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
+checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
@@ -1334,18 +1334,38 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.65"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
+dependencies = [
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"
+dependencies = [
+ "thiserror-impl 2.0.3",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
+checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
- "thiserror-impl",
+ "proc-macro2",
+ "quote",
+ "syn",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.65"
+version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
+checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"
dependencies = [
"proc-macro2",
"quote",
@@ -1455,7 +1475,7 @@ dependencies = [
"cfg-if",
"libc",
"nix 0.27.1",
- "thiserror",
+ "thiserror 1.0.69",
"userfaultfd-sys",
]
@@ -1486,8 +1506,8 @@ dependencies = [
"log-instrument",
"serde",
"serde_json",
- "thiserror",
- "vm-memory 0.16.0",
+ "thiserror 2.0.3",
+ "vm-memory",
"vmm-sys-util",
]
@@ -1521,14 +1541,14 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "vhost"
-version = "0.12.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79e9f0c62b0e4d5adbb7a9dc138b6003bdf823f196a927daf7ca0ae93cafd8ce"
+checksum = "bce0aad4d8776cb64f1ac591e908a561c50ba6adac4416296efee590b155623f"
dependencies = [
"bitflags 2.6.0",
"libc",
"uuid",
- "vm-memory 0.15.0",
+ "vm-memory",
"vmm-sys-util",
]
@@ -1539,7 +1559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e4ce718bd4e8d74b1747363e27f715a6b1bd6971597cb21425dadbf4e712241"
dependencies = [
"libc",
- "thiserror",
+ "thiserror 1.0.69",
]
[[package]]
@@ -1550,23 +1570,12 @@ checksum = "7e21282841a059bb62627ce8441c491f09603622cd5a21c43bfedc85a2952f23"
[[package]]
name = "vm-memory"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a320fc11792e063174402ff444aa3c80363cbf1e31c47b5ef74124406c334ce6"
-dependencies = [
- "libc",
- "thiserror",
- "winapi",
-]
-
-[[package]]
-name = "vm-memory"
-version = "0.16.0"
+version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2919f87420b6998a131eb7c78843890295e91a3f8f786ccc925c8d387b75121"
+checksum = "f1720e7240cdc739f935456eb77f370d7e9b2a3909204da1e2b47bef1137a013"
dependencies = [
"libc",
- "thiserror",
+ "thiserror 1.0.69",
"winapi",
]
@@ -1611,17 +1620,17 @@ dependencies = [
"serde",
"serde_json",
"slab",
- "thiserror",
+ "thiserror 2.0.3",
"timerfd",
"userfaultfd",
"utils",
"vhost",
"vm-allocator",
"vm-fdt",
- "vm-memory 0.16.0",
+ "vm-memory",
"vm-superio",
"vmm-sys-util",
- "zerocopy 0.8.7",
+ "zerocopy 0.8.10",
]
[[package]]
@@ -1798,11 +1807,11 @@ dependencies = [
[[package]]
name = "zerocopy"
-version = "0.8.7"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb3da5f7220f919a6c7af7c856435a68ee1582fd7a77aa72936257d8335bd6f6"
+checksum = "a13a42ed30c63171d820889b2981318736915150575b8d2d6dbee7edd68336ca"
dependencies = [
- "zerocopy-derive 0.8.7",
+ "zerocopy-derive 0.8.10",
]
[[package]]
@@ -1818,9 +1827,9 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
-version = "0.8.7"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e5f54f3cc93cd80745404626681b4b9fca9a867bad5a8424b618eb0db1ae6ea"
+checksum = "593e7c96176495043fcb9e87cf7659f4d18679b5bab6b92bdef359c76a7795dd"
dependencies = [
"proc-macro2",
"quote",
diff --git a/README.md b/README.md
index dde5c21e794..f98079fc81c 100644
--- a/README.md
+++ b/README.md
@@ -132,7 +132,7 @@ We test all combinations of:
| Instance | Host OS & Kernel | Guest Rootfs | Guest Kernel |
| :-------- | :---------------- | :----------- | :----------- |
-| c5n.metal | al2 linux_5.10 | ubuntu 22.04 | linux_5.10 |
+| c5n.metal | al2 linux_5.10 | ubuntu 24.04 | linux_5.10 |
| m5n.metal | al2023 linux_6.1 | | linux_6.1 |
| m6i.metal | | | |
| m6a.metal | | | |
diff --git a/docs/RELEASE_POLICY.md b/docs/RELEASE_POLICY.md
index 07cfe70c9b7..fe2f881d6b6 100644
--- a/docs/RELEASE_POLICY.md
+++ b/docs/RELEASE_POLICY.md
@@ -90,9 +90,10 @@ v3.1 will be patched since were the last two Firecracker releases and less than
| Release | Release Date | Latest Patch | Min. end of support | Official end of Support |
| ------: | -----------: | -----------: | ------------------: | :------------------------------ |
+| v1.10 | 2024-11-07 | v1.10.1 | 2025-05-07 | Supported |
| v1.9 | 2024-09-02 | v1.9.1 | 2025-03-02 | Supported |
| v1.8 | 2024-07-10 | v1.8.0 | 2025-01-10 | Supported |
-| v1.7 | 2024-03-18 | v1.7.0 | 2024-09-18 | Supported |
+| v1.7 | 2024-03-18 | v1.7.0 | 2024-09-18 | 2024-09-18 (end of 6mo support) |
| v1.6 | 2023-12-20 | v1.6.0 | 2024-06-20 | 2024-07-10 (v1.8 released) |
| v1.5 | 2023-10-09 | v1.5.1 | 2024-04-09 | 2024-04-09 (end of 6mo support) |
| v1.4 | 2023-07-20 | v1.4.1 | 2024-01-20 | 2024-01-20 (end of 6mo support) |
diff --git a/docs/getting-started.md b/docs/getting-started.md
index cb9a7fee9ee..644d31e78a8 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -9,7 +9,7 @@ You can check if your system meets the requirements by running
`firecracker/tools/devtool checkenv`.
An opinionated way to run Firecracker is to launch an
-[EC2](https://aws.amazon.com/ec2/) `c5.metal` instance with Ubuntu 22.04.
+[EC2](https://aws.amazon.com/ec2/) `c5.metal` instance with Ubuntu 24.04.
Firecracker requires [the KVM Linux kernel module](https://www.linux-kvm.org/)
to perform its virtualization and emulation tasks.
@@ -95,24 +95,26 @@ For simplicity, this guide will not use the [`jailer`](../src/jailer/).
To successfully start a microVM, you will need an uncompressed Linux kernel
binary, and an ext4 file system image (to use as rootfs). This guide uses a 5.10
-kernel image with a Ubuntu 22.04 rootfs from our CI:
+kernel image with a Ubuntu 24.04 rootfs from our CI:
```bash
ARCH="$(uname -m)"
-latest=$(wget "http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/v1.10/x86_64/vmlinux-5.10&list-type=2" -O - 2>/dev/null | grep "(?<=)(firecracker-ci/v1.10/x86_64/vmlinux-5\.10\.[0-9]{3})(?=)" -o -P)
+latest=$(wget "http://spec.ccfc.min.s3.amazonaws.com/?prefix=firecracker-ci/v1.10/$ARCH/vmlinux-5.10&list-type=2" -O - 2>/dev/null | grep -oP "(?<=)(firecracker-ci/v1.10/$ARCH/vmlinux-5\.10\.[0-9]{1,3})(?=)")
# Download a linux kernel binary
wget "https://s3.amazonaws.com/spec.ccfc.min/${latest}"
# Download a rootfs
-wget "https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.10/${ARCH}/ubuntu-22.04.ext4"
-
-# Download the ssh key for the rootfs
-wget "https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.10/${ARCH}/ubuntu-22.04.id_rsa"
-
-# Set user read permission on the ssh key
-chmod 400 ./ubuntu-22.04.id_rsa
+wget -O ubuntu-24.04.squashfs.upstream "https://s3.amazonaws.com/spec.ccfc.min/firecracker-ci/v1.10/${ARCH}/ubuntu-24.04.squashfs"
+
+# Create an ssh key for the rootfs
+unsquashfs ubuntu-24.04.squashfs.upstream
+ssh-keygen -f id_rsa -N ""
+cp -v id_rsa.pub squashfs-root/root/.ssh/authorized_keys
+mv -v id_rsa ./ubuntu-24.04.id_rsa
+# re-squash
+mksquashfs squashfs-root ubuntu-24.04.squashfs -all-root -noappend -comp zstd
```
### Getting a Firecracker Binary
@@ -238,7 +240,7 @@ sudo curl -X PUT --unix-socket "${API_SOCKET}" \
}" \
"http://localhost/boot-source"
-ROOTFS="./ubuntu-22.04.ext4"
+ROOTFS="./ubuntu-24.04.ext4"
# Set rootfs
sudo curl -X PUT --unix-socket "${API_SOCKET}" \
@@ -280,13 +282,13 @@ sudo curl -X PUT --unix-socket "${API_SOCKET}" \
sleep 2s
# Setup internet access in the guest
-ssh -i ./ubuntu-22.04.id_rsa root@172.16.0.2 "ip route add default via 172.16.0.1 dev eth0"
+ssh -i ./ubuntu-24.04.id_rsa root@172.16.0.2 "ip route add default via 172.16.0.1 dev eth0"
# Setup DNS resolution in the guest
-ssh -i ./ubuntu-22.04.id_rsa root@172.16.0.2 "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
+ssh -i ./ubuntu-24.04.id_rsa root@172.16.0.2 "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"
# SSH into the microVM
-ssh -i ./ubuntu-22.04.id_rsa root@172.16.0.2
+ssh -i ./ubuntu-24.04.id_rsa root@172.16.0.2
# Use `root` for both the login and password.
# Run `reboot` to exit.
diff --git a/docs/network-setup.md b/docs/network-setup.md
index ad77bd3e7e9..fb2c1ca0977 100644
--- a/docs/network-setup.md
+++ b/docs/network-setup.md
@@ -1,49 +1,108 @@
# Getting Started Firecracker Network Setup
-This is a very simple quick-start guide to getting a Firecracker guest connected
-to the network. If you're using Firecracker in production, or even want to run
-multiple guests, you'll need to adapt this setup.
+This is a simple quick-start guide to getting one or more Firecracker microVMs
+connected to the Internet via the host. If you run a production setup, you
+should consider modifying this setup to accommodate your specific needs.
-**Note** Currently firecracker supports only TUN/TAP network backend with no
+**Note:** Currently, Firecracker supports only a TUN/TAP network backend with no
multi queue support.
-The simple steps in this guide assume that your internet-facing interface is
-`eth0`, you have nothing else using `tap0` and no other `iptables` rules. Check
-out the *Advanced:* sections if that doesn't work for you.
+The steps in this guide assume `eth0` to be your Internet-facing network
+interface on the host. If `eth0` isn't your main network interface, you should
+change the value to the correct one in the commands below. IPv4 is also assumed
+to be used, so you will need to adapt the instructions accordingly to support
+IPv6.
+
+Each microVM requires a host network interface (like `eth0`) and a Linux `tap`
+device (like `tap0`) used by Firecracker, but the differences in configuration
+stem from routing: how packets from the `tap` get to the network interface
+(egress) and vice-versa (ingress). There are three main approaches of how to
+configure routing for a microVM.
+
+1. **NAT-based**, which is presented in the main part of this guide. It is
+ simple but doesn't expose your microVM to the local network (LAN).
+1. **Bridge-based**, which exposes your microVM to the local network. Learn more
+ about in the _Advanced: Bridge-based routing_ section of this guide.
+1. **Namespaced NAT**, which sacrifices performance in comparison to the other
+ approaches but is desired in the scenario when two clones of the same microVM
+ are running at the same time. To learn more about it, check out the
+ [Network Connectivity for Clones](./snapshotting/network-for-clones.md)
+ guide.
+
+To run multiple microVMs while using NAT-based routing, check out the _Advanced:
+Multiple guests_ section. The same principles can be applied to other routing
+methods with a bit more effort.
+
+For the choice of firewall, `nft` is recommended for use on production Linux
+systems, but, for the sake of compatibility, this guide provides a choice
+between either `nft` or the `iptables-nft` translation layer. The latter is
+[no longer recommended](https://access.redhat.com/solutions/6739041) but may be
+more familiar to readers.
+
+## On the Host
+
+The first step on the host for any microVM is to create a Linux `tap` device,
+which Firecracker will use for networking.
+
+For this setup, only two IP addresses will be necessary - one for the `tap`
+device and one for the guest itself, through which you will, for example, `ssh`
+into the guest. So, we'll choose the smallest IPv4 subnet needed for 2
+addresses: `/30`. For this VM, let's use the `172.16.0.1` `tap` IP and the
+`172.16.0.2` guest IP.
-## On The Host
+```bash
+# Create the tap device.
+sudo ip tuntap add tap0 mode tap
+# Assign it the tap IP and start up the device.
+sudo ip addr add 172.16.0.1/30 dev tap0
+sudo ip link set tap0 up
+```
-The first step on the host is to create a `tap` device:
+**Note:** The IP of the TAP device should be chosen such that it's not in the
+same subnet as the IP address of the host.
+
+We'll need to enable IPv4 forwarding on the system.
```bash
-sudo ip tuntap add tap0 mode tap
+echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
```
-Then you have a few options for routing traffic out of the tap device, through
-your host's network interface. One option is NAT, set up like this:
+### Configuration via `nft`
+
+We'll need an nftables table for our routing needs, and 2 chains inside that
+table: one for NAT on `postrouting` stage, and another one for filtering on
+`forward` stage:
```bash
-sudo ip addr add 172.16.0.1/24 dev tap0
-sudo ip link set tap0 up
-sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
-sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
-sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-sudo iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT
+sudo nft add table firecracker
+sudo nft 'add chain firecracker postrouting { type nat hook postrouting priority srcnat; policy accept; }'
+sudo nft 'add chain firecracker filter { type filter hook forward priority filter; policy accept; }'
```
-*Note:* The IP of the TAP device should be chosen such that it's not in the same
-subnet as the IP address of the host.
+The first rule we'll need will masquerade packets from the guest IP as if they
+came from the host's IP, by changing the source IP address of these packets:
-*Advanced:* If you are running multiple Firecracker MicroVMs in parallel, or
-have something else on your system using `tap0` then you need to create a `tap`
-for each one, with a unique name.
+```bash
+sudo nft add rule firecracker postrouting ip saddr 172.16.0.2 oifname eth0 counter masquerade
+```
-*Advanced:* You also need to do the `iptables` set up for each new `tap`. If you
-have `iptables` rules you care about on your host, you may want to save those
-rules before starting.
+The second rule we'll need will accept packets from the tap IP (the guest will
+use the tap IP as its gateway and will therefore route its own packets through
+the tap IP) and direct them to the host network interface:
```bash
-sudo iptables-save > iptables.rules.old
+sudo nft add rule firecracker filter iifname tap0 oifname eth0 accept
+```
+
+### Configuration via `iptables-nft`
+
+Tables and chains are managed by `iptables-nft` automatically, but we'll need
+three rules to perform the NAT steps:
+
+```bash
+sudo iptables-nft -t nat -A POSTROUTING -o eth0 -s 172.16.0.2 -j MASQUERADE
+sudo iptables-nft -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+sudo iptables-nft -A FORWARD -i tap0 -o eth0 -j ACCEPT
```
## Setting Up Firecracker
@@ -85,14 +144,20 @@ configuration file like this:
```
Alternatively, if you are using firectl, add
---tap-device=tap0/06:00:AC:10:00:02\` to your command line.
+`--tap-device=tap0/06:00:AC:10:00:02\` to your command line.
## In The Guest
-Once you have booted the guest, bring up networking within the guest:
+Once you have booted the guest, it will have its networking interface with the
+name specified by `iface_id` in the Firecracker configuration.
+
+You'll now need to assign the guest its IP, activate the guest's networking
+interface and set up the `tap` IP as the guest's gateway address, so that
+packets are routed through the `tap` device, where they are then picked up by
+the setup on the host prepared before:
```bash
-ip addr add 172.16.0.2/24 dev eth0
+ip addr add 172.16.0.2/30 dev eth0
ip link set eth0 up
ip route add default via 172.16.0.1 dev eth0
```
@@ -107,23 +172,183 @@ your environment. For testing, you can add a public DNS server to
nameserver 8.8.8.8
```
-## \[Advanced\] Setting Up a Bridge Interface
+**Note:** Sometimes, it's undesirable to have `iproute2` (providing the `ip`
+command) installed on your guest OS, or you simply want to have these steps be
+performed automatically. To do this, check out the _Advanced: Guest network
+configuration using kernel command line_ section.
+
+## Cleaning up
+
+The first step to cleaning up is to delete the tap device on the host:
+
+```bash
+sudo ip link del tap0
+```
+
+### Cleanup using `nft`
+
+You'll want to delete the two nftables rules for NAT routing from the
+`postrouting` and `filter` chains. To do this with nftables, you'll need to look
+up the _handles_ (identifiers) of these rules by running:
+
+```bash
+sudo nft -a list ruleset
+```
+
+Now, find the `# handle` comments relating to the two rules and delete them. For
+example, if the handle to the masquerade rule is 1 and the one to the forwarding
+rule is 2:
+
+```bash
+sudo nft delete rule firecracker postrouting handle 1
+sudo nft delete rule firecracker filter handle 2
+```
+
+Run the following steps only **if you have no more guests** running on the host:
+
+Set IPv4 forwarding back to disabled:
+
+```bash
+echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward
+```
+
+If you're using `nft`, delete the `firecracker` table to revert your nftables
+configuration fully back to its initial state:
+
+```bash
+sudo nft delete table firecracker
+```
+
+### Cleanup using `iptables-nft`
+
+Of the configured `iptables-nft` rules, two should be deleted if you have guests
+remaining in your configuration:
+
+```bash
+sudo iptables-nft -t nat -D POSTROUTING -o eth0 -s 172.16.0.2 -j MASQUERADE
+sudo iptables-nft -D FORWARD -i tap0 -o eth0 -j ACCEPT
+```
+
+**If you have no more guests** running on the host, then similarly set IPv4
+forwarding back to disabled:
+
+```bash
+echo 0 | sudo tee /proc/sys/net/ipv4/ip_forward
+```
+
+And delete the remaining `conntrack` rule that applies to all guests:
+
+```bash
+sudo iptables-nft -D FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
+```
+
+If nothing else is using `iptables-nft` on the system, you may even want to
+delete the entire system ruleset like so:
+
+```bash
+sudo iptables-nft -F
+sudo iptables-nft -t nat -F
+```
+
+## Advanced: Multiple guests
+
+To configure multiple guests, we will only need to repeat some of the steps in
+this setup for each of the microVMs:
+
+1. Each microVM has its own subnet and the two IP addresses inside of it: the
+ `tap` IP and the guest IP.
+1. Each microVM has its own two nftables rules for masquerading and forwarding,
+ while the same table and two chains can be shared between the microVMs.
+1. Each microVM has its own routing configuration inside the guest itself
+ (achieved through `iproute2` or the method described in the _Advanced: Guest
+ network configuration at kernel level_ section).
+
+To give a more concrete example, **let's add a second microVM** to the one
+you've already configured:
+
+Let's assume we allocate /30 subnets in the 172.16.0.0/16 range sequentially to
+give out as few addresses as needed.
+
+The next /30 subnet in the 172.16.0.0/16 range will give us these two IPs:
+172.16.0.5 as the `tap` IP and 172.16.0.6 as the guest IP.
+
+Our new `tap` device will, sequentially, have the name `tap1`:
+
+```bash
+sudo ip tuntap add tap1 mode tap
+sudo ip addr add 172.16.0.5/30 dev tap1
+sudo ip link set tap1 up
+```
+
+Now, let's add the new two `nft` rules, also with the new values:
+
+```bash
+sudo nft add rule firecracker postrouting ip saddr 172.16.0.6 oifname eth0 counter masquerade
+sudo nft add rule firecracker filter iifname tap1 oifname eth0 accept
+```
+
+If using `iptables-nft`, add the rules like so:
+
+```bash
+sudo iptables-nft -t nat -A POSTROUTING -o eth0 -s 172.16.0.6 -j MASQUERADE
+sudo iptables-nft -A FORWARD -i tap1 -o eth0 -j ACCEPT
+```
+
+Modify your Firecracker configuration with the `host_dev_name` now being `tap1`
+instead of `tap0`, boot up the guest and perform the routing inside of it like
+so, changing the guest IP and `tap` IP:
+
+```bash
+ip addr add 172.16.0.6/30 dev eth0
+ip link set eth0 up
+ip route add default via 172.16.0.5 dev eth0
+```
+
+Or, you can use the setup from _Advanced: Guest network configuration at kernel
+level_ by simply changing the G and T variables, i.e. the guest IP and `tap` IP.
+
+**Note:** if you'd like to calculate the guest and `tap` IPs using the
+sequential subnet allocation method that has been used here, you can use the
+following formulas specific to IPv4 addresses:
+
+`tap` IP = `172.16.[(A*O+1)/256].[(A*O+1)%256]`.
+
+Guest IP = `172.16.[(A*O+2)/256].[(A*O+2)%256]`.
+
+Round down the division and replace `A` with the amount of IP addresses inside
+your subnet (for a /30 subnet, that will be 4 addresses, for example) and
+replace `O` with the sequential number of your microVM, starting at 0. You can
+replace `172.16` with any other values that fit between between 1 and 255 as
+usual with an IPv4 address.
+
+For example, let's calculate the addresses of the 1000-th microVM with a /30
+subnet in the `172.16.0.0/16` range:
+
+`tap` IP = `172.16.[(4*999+1)/256].[(4*999+1)%256]` = `172.16.15.157`.
+
+Guest IP = `172.16.[(4*999+2)/256].[(4*999+2)%256]` = `172.16.15.158`.
+
+This allocation setup has been used successfully in the `firecracker-demo`
+project for launching several thousand microVMs on the same host:
+[relevant lines](https://github.com/firecracker-microvm/firecracker-demo/blob/63717c6e7fbd277bdec8e26a5533d53544a760bb/start-firecracker.sh#L45).
+
+## Advanced: Bridge-based routing
### On The Host
-1. Create a bridge interface
+1. Create a bridge interface:
```bash
sudo ip link add name br0 type bridge
```
-1. Add tap interface [created above](#on-the-host) to the bridge
+1. Add the `tap` device [created above](#on-the-host) to the bridge:
```bash
sudo ip link set dev tap0 master br0
```
-1. Define an IP address in your network for the bridge.
+1. Define an IP address in your network for the bridge:
For example, if your gateway were on `192.168.1.1` and you wanted to use this
for getting dynamic IPs, you would want to give the bridge an unused IP
@@ -133,24 +358,30 @@ nameserver 8.8.8.8
sudo ip address add 192.168.1.7/24 dev br0
```
-1. Add firewall rules to allow traffic to be routed to the guest
+1. Add a firewall rule to allow traffic to be routed to the guest:
```bash
sudo iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
```
+1. Once you're cleaning up the configuration, make sure to delete the bridge:
+
+ ```bash
+ sudo ip link del br0
+ ```
+
### On The Guest
1. Define an unused IP address in the bridge's subnet e.g., `192.168.1.169/24`.
- _Note: Alternatively, you could rely on DHCP for getting a dynamic IP address
- from your gateway._
+ **Note**: Alternatively, you could rely on DHCP for getting a dynamic IP
+ address from your gateway.
```bash
ip addr add 192.168.1.169/24 dev eth0
```
-1. Set the interface up.
+1. Enable the network interface:
```bash
ip link set eth0 up
@@ -177,43 +408,38 @@ nameserver 8.8.8.8
192.168.1.1 via 192.168.1.7 dev eth0
```
-1. Add your nameserver to `resolve.conf`
+1. Add your nameserver to `/etc/resolve.conf`
```bash
# cat /etc/resolv.conf
nameserver 192.168.1.1
```
-## Cleaning up
+## Advanced: Guest network configuration using kernel command line
-The first step to cleaning up is deleting the tap device:
+The Linux kernel supports an `ip` CLI arguments that can be passed to it when
+booting. Boot arguments in Firecracker are configured in the `boot_args`
+property of the boot source (`boot-source` object in the JSON configuration or
+the equivalent endpoint in the API server).
-```bash
-sudo ip link del tap0
-```
+The value of the `ip` CLI argument for our setup will be the of this format:
+`G::T:GM::GI:off`. G is the guest IP (without the subnet), T is the `tap` IP
+(without the subnet), GM is the "long" mask IP of the guest CIDR and GI is the
+name of the guest network interface.
-If you don't have anything else using `iptables` on your machine, clean up those
-rules:
-
-```bash
-sudo iptables -F
-sudo sh -c "echo 0 > /proc/sys/net/ipv4/ip_forward" # usually the default
-```
+Substituting our values, we get:
+`ip=172.16.0.2::172.16.0.1:255.255.255.252::eth0:off`. Insert this at the end of
+your boot arguments for your microVM, and the guest Linux kernel will
+automatically perform the routing configuration done in the _In the Guest_
+section without needing `iproute2` installed in the guest.
-If you have an existing iptables setup, you'll want to be more careful about
-cleaning up.
+As soon as you boot the guest, it will already be connected to the network
+(assuming you correctly performing the other steps).
-*Advanced:* If you saved your iptables rules in the first step, then you can
-restore them like this:
+**Note**: you can also use the `ip` argument to configure a primary DNS server
+and, optionally, a second DNS server without needing to touch
+`/etc/resolv.conf`. As an example:
-```bash
-if [ -f iptables.rules.old ]; then
- sudo iptables-restore < iptables.rules.old
-fi
-```
-
-*Advanced:* If you created a bridge interface, delete it using the following:
-
-```bash
-sudo ip link del br0
-```
+`ip=172.16.0.2::172.16.0.1:255.255.255.252::eth0:off:8.8.8.8:1.1.1.1` configures
+`8.8.8.8` as the primary DNS server and `1.1.1.1` as the secondary DNS server,
+as well as the rest of the guest-side routing.
diff --git a/docs/snapshotting/snapshot-support.md b/docs/snapshotting/snapshot-support.md
index a9e0bc8dc4c..75ffd306e25 100644
--- a/docs/snapshotting/snapshot-support.md
+++ b/docs/snapshotting/snapshot-support.md
@@ -642,8 +642,8 @@ booting, to avoid this issue.
We have a mechanism in place to experiment with snapshot compatibility across
supported host kernel versions by generating snapshot artifacts through
-[this tool](../../tools/create_snapshot_artifact) and checking devices'
-functionality using
+[this test](../../tests/integration_tests/functional/test_snapshot_phase1.py)
+and checking devices' functionality using
[this test](../../tests/integration_tests/functional/test_snapshot_restore_cross_kernel.py).
The test restores the snapshot and ensures that all the devices set-up (network
devices, disk, vsock, balloon and MMDS) are operational post-load.
diff --git a/resources/guest_configs/ci.config b/resources/guest_configs/ci.config
new file mode 100644
index 00000000000..7bbf1fb1f56
--- /dev/null
+++ b/resources/guest_configs/ci.config
@@ -0,0 +1,7 @@
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SQUASHFS_ZSTD=y
+# aarch64 only TBD split into a separate file
+CONFIG_DEVMEM=y
+# CONFIG_ARM64_ERRATUM_3194386 is not set
diff --git a/resources/guest_configs/debug.config b/resources/guest_configs/debug.config
new file mode 100644
index 00000000000..6ff73f2162b
--- /dev/null
+++ b/resources/guest_configs/debug.config
@@ -0,0 +1,5 @@
+CONFIG_FRAME_POINTER=y
+# CONFIG_KGDB=y
+# CONFIG_KGDB_SERIAL_CONSOLE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
diff --git a/resources/guest_configs/ftrace.config b/resources/guest_configs/ftrace.config
new file mode 100644
index 00000000000..b180c7f232a
--- /dev/null
+++ b/resources/guest_configs/ftrace.config
@@ -0,0 +1,11 @@
+CONFIG_FTRACE=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_FUNCTION_GRAPH_TRACER=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_SCHED_TRACER=y
+CONFIG_STACK_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_FTRACE_MCOUNT_RECORD=y
+CONFIG_FTRACE_SYSCALLS=y
diff --git a/resources/guest_configs/patches/0001-fix-Adjust-config-options-for-what-is-needed-by-our-.patch b/resources/guest_configs/patches/0001-fix-Adjust-config-options-for-what-is-needed-by-our-.patch
deleted file mode 100644
index ed1f683dce1..00000000000
--- a/resources/guest_configs/patches/0001-fix-Adjust-config-options-for-what-is-needed-by-our-.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 85e406b23c086c446ccfd6f8c83670800cc4de3a Mon Sep 17 00:00:00 2001
-From: Patrick Roy
-Date: Tue, 30 Jul 2024 13:59:04 +0100
-Subject: [PATCH] fix: Adjust config options for what is needed by our tests
-
-Additionally, set `CONFIG_MSDOS_PARTITION=y` for our PARTUUID tests,
-`CONFIG_DEVMEM=y` on aarch64/5.10 (for various integration tests that
-rely on /dev/mem), and CONFIG_IKCONFIG=y and CONFIG_IKCONFIG_PROC=y for
-the spectre-meltdown-checker.sh tests to work on AMD.
-
-Signed-off-by: Patrick Roy
----
- .../guest_configs/microvm-kernel-ci-aarch64-5.10.config | 7 ++++---
- .../microvm-kernel-ci-x86_64-5.10-no-acpi.config | 5 +++--
- .../guest_configs/microvm-kernel-ci-x86_64-5.10.config | 5 +++--
- 3 files changed, 10 insertions(+), 7 deletions(-)
-
-diff --git a/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config b/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-index ac44904c..0555055c 100644
---- a/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-+++ b/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-@@ -110,7 +110,8 @@ CONFIG_RCU_STALL_COMMON=y
- CONFIG_RCU_NEED_SEGCBLIST=y
- # end of RCU Subsystem
-
--# CONFIG_IKCONFIG is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
- # CONFIG_IKHEADERS is not set
- CONFIG_LOG_BUF_SHIFT=17
- CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-@@ -752,7 +753,7 @@ CONFIG_PARTITION_ADVANCED=y
- # CONFIG_AMIGA_PARTITION is not set
- # CONFIG_ATARI_PARTITION is not set
- # CONFIG_MAC_PARTITION is not set
--# CONFIG_MSDOS_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
- # CONFIG_LDM_PARTITION is not set
- # CONFIG_SGI_PARTITION is not set
- # CONFIG_ULTRIX_PARTITION is not set
-@@ -1726,7 +1727,7 @@ CONFIG_HW_RANDOM_VIRTIO=y
- # CONFIG_HW_RANDOM_CCTRNG is not set
- # CONFIG_HW_RANDOM_XIPHERA is not set
- # CONFIG_HW_RANDOM_GRAVITON is not set
--# CONFIG_DEVMEM is not set
-+CONFIG_DEVMEM=y
- # CONFIG_RAW_DRIVER is not set
- # CONFIG_TCG_TPM is not set
- # CONFIG_XILLYBUS is not set
-diff --git a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config
-index b87fb3e4..a27c1f84 100644
---- a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config
-+++ b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config
-@@ -134,7 +134,8 @@ CONFIG_RCU_NEED_SEGCBLIST=y
- # end of RCU Subsystem
-
- CONFIG_BUILD_BIN2C=y
--# CONFIG_IKCONFIG is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
- # CONFIG_IKHEADERS is not set
- CONFIG_LOG_BUF_SHIFT=17
- CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-@@ -702,7 +703,7 @@ CONFIG_PARTITION_ADVANCED=y
- # CONFIG_AMIGA_PARTITION is not set
- # CONFIG_ATARI_PARTITION is not set
- # CONFIG_MAC_PARTITION is not set
--# CONFIG_MSDOS_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
- # CONFIG_LDM_PARTITION is not set
- # CONFIG_SGI_PARTITION is not set
- # CONFIG_ULTRIX_PARTITION is not set
-diff --git a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config
-index 09461c17..af9ec662 100644
---- a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config
-+++ b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config
-@@ -127,7 +127,8 @@ CONFIG_RCU_NEED_SEGCBLIST=y
- # end of RCU Subsystem
-
- CONFIG_BUILD_BIN2C=y
--# CONFIG_IKCONFIG is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
- # CONFIG_IKHEADERS is not set
- CONFIG_LOG_BUF_SHIFT=17
- CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-@@ -739,7 +740,7 @@ CONFIG_PARTITION_ADVANCED=y
- # CONFIG_AMIGA_PARTITION is not set
- # CONFIG_ATARI_PARTITION is not set
- # CONFIG_MAC_PARTITION is not set
--# CONFIG_MSDOS_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
- # CONFIG_LDM_PARTITION is not set
- # CONFIG_SGI_PARTITION is not set
- # CONFIG_ULTRIX_PARTITION is not set
---
-2.34.1
-
diff --git a/resources/guest_configs/patches/0002-ci-adjust-6.1-guest-kernel-configs-for-our-CI.patch b/resources/guest_configs/patches/0002-ci-adjust-6.1-guest-kernel-configs-for-our-CI.patch
deleted file mode 100644
index 06604fd104a..00000000000
--- a/resources/guest_configs/patches/0002-ci-adjust-6.1-guest-kernel-configs-for-our-CI.patch
+++ /dev/null
@@ -1,76 +0,0 @@
-From 911b916fdc53acfc7229302b029fd615f1e670cf Mon Sep 17 00:00:00 2001
-From: Babis Chalios
-Date: Fri, 23 Aug 2024 12:54:26 +0200
-Subject: [PATCH 2/2] ci: adjust 6.1 guest kernel configs for our CI
-
-Set CONFIG_MSDOS_PARTITION=y for our PARTUUID tests,
-CONFIG_DEVMEM=y on aarch64 for various integration tests that rely on
-/dev/mem being there and CONFIG_IKCONFIG=y, CONFIG_IKCONFIG_PROC=y for
-the spectre-meltdown-checker.sh tests to work on AMD.
-
-Signed-off-by: Babis Chalios
----
- .../guest_configs/microvm-kernel-ci-aarch64-6.1.config | 7 ++++---
- .../guest_configs/microvm-kernel-ci-x86_64-6.1.config | 7 ++++---
- 2 files changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config b/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-index 26b87a65..5c0334f4 100644
---- a/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-+++ b/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-@@ -140,7 +140,8 @@ CONFIG_RCU_STALL_COMMON=y
- CONFIG_RCU_NEED_SEGCBLIST=y
- # end of RCU Subsystem
-
--# CONFIG_IKCONFIG is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
- # CONFIG_IKHEADERS is not set
- CONFIG_LOG_BUF_SHIFT=17
- CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
-@@ -753,7 +754,7 @@ CONFIG_PARTITION_ADVANCED=y
- # CONFIG_AMIGA_PARTITION is not set
- # CONFIG_ATARI_PARTITION is not set
- # CONFIG_MAC_PARTITION is not set
--# CONFIG_MSDOS_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
- # CONFIG_LDM_PARTITION is not set
- # CONFIG_SGI_PARTITION is not set
- # CONFIG_ULTRIX_PARTITION is not set
-@@ -1823,7 +1824,7 @@ CONFIG_HW_RANDOM_VIRTIO=y
- # CONFIG_HW_RANDOM_XIPHERA is not set
- CONFIG_HW_RANDOM_ARM_SMCCC_TRNG=y
- # CONFIG_HW_RANDOM_GRAVITON is not set
--# CONFIG_DEVMEM is not set
-+CONFIG_DEVMEM=y
- # CONFIG_TCG_TPM is not set
- # CONFIG_XILLYBUS is not set
- CONFIG_RANDOM_TRUST_CPU=y
-diff --git a/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config b/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config
-index 967e3203..8a2769c0 100644
---- a/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config
-+++ b/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config
-@@ -162,8 +162,9 @@ CONFIG_RCU_STALL_COMMON=y
- CONFIG_RCU_NEED_SEGCBLIST=y
- # end of RCU Subsystem
-
--# CONFIG_IKCONFIG is not set
--# CONFIG_IKHEADERS is not set
-+CONFIG_IKCONFIG=y
-+CONFIG_IKCONFIG_PROC=y
-+# CONFIG_IKHEADERS=y
- CONFIG_LOG_BUF_SHIFT=17
- CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
- CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
-@@ -769,7 +770,7 @@ CONFIG_PARTITION_ADVANCED=y
- # CONFIG_AMIGA_PARTITION is not set
- # CONFIG_ATARI_PARTITION is not set
- # CONFIG_MAC_PARTITION is not set
--# CONFIG_MSDOS_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
- # CONFIG_LDM_PARTITION is not set
- # CONFIG_SGI_PARTITION is not set
- # CONFIG_ULTRIX_PARTITION is not set
---
-2.34.1
-
diff --git a/resources/guest_configs/patches/0003-enable-ftrace.patch b/resources/guest_configs/patches/0003-enable-ftrace.patch
deleted file mode 100644
index a836a6fb3a7..00000000000
--- a/resources/guest_configs/patches/0003-enable-ftrace.patch
+++ /dev/null
@@ -1,115 +0,0 @@
-diff --git a/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config b/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-index ac44904c1..2a6f2310f 100644
---- a/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-+++ b/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-@@ -3089,7 +3089,17 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
- CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
- CONFIG_HAVE_C_RECORDMCOUNT=y
- CONFIG_TRACING_SUPPORT=y
--# CONFIG_FTRACE is not set
-+CONFIG_FTRACE=y
-+CONFIG_FUNCTION_TRACER=y
-+CONFIG_FUNCTION_GRAPH_TRACER=y
-+CONFIG_IRQSOFF_TRACER=y
-+CONFIG_PREEMPT_TRACER=y
-+CONFIG_SCHED_TRACER=y
-+CONFIG_STACK_TRACER=y
-+CONFIG_BLK_DEV_IO_TRACE=y
-+CONFIG_FUNCTION_PROFILER=y
-+CONFIG_FTRACE_MCOUNT_RECORD=y
-+CONFIG_FTRACE_SYSCALLS=y
- # CONFIG_SAMPLES is not set
- CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
- # CONFIG_STRICT_DEVMEM is not set
-diff --git a/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config b/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-index 26b87a658..f0f765298 100644
---- a/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-+++ b/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-@@ -3309,7 +3309,17 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
- CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
- CONFIG_HAVE_C_RECORDMCOUNT=y
- CONFIG_TRACING_SUPPORT=y
--# CONFIG_FTRACE is not set
-+CONFIG_FTRACE=y
-+CONFIG_FUNCTION_TRACER=y
-+CONFIG_FUNCTION_GRAPH_TRACER=y
-+CONFIG_IRQSOFF_TRACER=y
-+CONFIG_PREEMPT_TRACER=y
-+CONFIG_SCHED_TRACER=y
-+CONFIG_STACK_TRACER=y
-+CONFIG_BLK_DEV_IO_TRACE=y
-+CONFIG_FUNCTION_PROFILER=y
-+CONFIG_FTRACE_MCOUNT_RECORD=y
-+CONFIG_FTRACE_SYSCALLS=y
- # CONFIG_SAMPLES is not set
- # CONFIG_STRICT_DEVMEM is not set
-
-diff --git a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config
-index b87fb3e44..fc45dda19 100644
---- a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config
-+++ b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10-no-acpi.config
-@@ -2905,7 +2905,17 @@ CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
- CONFIG_HAVE_FENTRY=y
- CONFIG_HAVE_C_RECORDMCOUNT=y
- CONFIG_TRACING_SUPPORT=y
--# CONFIG_FTRACE is not set
-+CONFIG_FTRACE=y
-+CONFIG_FUNCTION_TRACER=y
-+CONFIG_FUNCTION_GRAPH_TRACER=y
-+CONFIG_IRQSOFF_TRACER=y
-+CONFIG_PREEMPT_TRACER=y
-+CONFIG_SCHED_TRACER=y
-+CONFIG_STACK_TRACER=y
-+CONFIG_BLK_DEV_IO_TRACE=y
-+CONFIG_FUNCTION_PROFILER=y
-+CONFIG_FTRACE_MCOUNT_RECORD=y
-+CONFIG_FTRACE_SYSCALLS=y
- # CONFIG_SAMPLES is not set
- CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
- CONFIG_STRICT_DEVMEM=y
-diff --git a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config
-index 09461c178..6d85bce2c 100644
---- a/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config
-+++ b/resources/guest_configs/microvm-kernel-ci-x86_64-5.10.config
-@@ -2987,7 +2987,17 @@ CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
- CONFIG_HAVE_FENTRY=y
- CONFIG_HAVE_C_RECORDMCOUNT=y
- CONFIG_TRACING_SUPPORT=y
--# CONFIG_FTRACE is not set
-+CONFIG_FTRACE=y
-+CONFIG_FUNCTION_TRACER=y
-+CONFIG_FUNCTION_GRAPH_TRACER=y
-+CONFIG_IRQSOFF_TRACER=y
-+CONFIG_PREEMPT_TRACER=y
-+CONFIG_SCHED_TRACER=y
-+CONFIG_STACK_TRACER=y
-+CONFIG_BLK_DEV_IO_TRACE=y
-+CONFIG_FUNCTION_PROFILER=y
-+CONFIG_FTRACE_MCOUNT_RECORD=y
-+CONFIG_FTRACE_SYSCALLS=y
- # CONFIG_SAMPLES is not set
- CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
- CONFIG_STRICT_DEVMEM=y
-diff --git a/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config b/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config
-index 967e32031..d11ef968a 100644
---- a/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config
-+++ b/resources/guest_configs/microvm-kernel-ci-x86_64-6.1.config
-@@ -3185,7 +3185,17 @@ CONFIG_HAVE_OBJTOOL_MCOUNT=y
- CONFIG_HAVE_C_RECORDMCOUNT=y
- CONFIG_HAVE_BUILDTIME_MCOUNT_SORT=y
- CONFIG_TRACING_SUPPORT=y
--# CONFIG_FTRACE is not set
-+CONFIG_FTRACE=y
-+CONFIG_FUNCTION_TRACER=y
-+CONFIG_FUNCTION_GRAPH_TRACER=y
-+CONFIG_IRQSOFF_TRACER=y
-+CONFIG_PREEMPT_TRACER=y
-+CONFIG_SCHED_TRACER=y
-+CONFIG_STACK_TRACER=y
-+CONFIG_BLK_DEV_IO_TRACE=y
-+CONFIG_FUNCTION_PROFILER=y
-+CONFIG_FTRACE_MCOUNT_RECORD=y
-+CONFIG_FTRACE_SYSCALLS=y
- # CONFIG_SAMPLES is not set
- CONFIG_HAVE_SAMPLE_FTRACE_DIRECT=y
- CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI=y
diff --git a/resources/guest_configs/patches/0004-disable-CONFIG_ARM64_ERRATUM_3194386-for-aarch64.patch b/resources/guest_configs/patches/0004-disable-CONFIG_ARM64_ERRATUM_3194386-for-aarch64.patch
deleted file mode 100644
index f3f16925e41..00000000000
--- a/resources/guest_configs/patches/0004-disable-CONFIG_ARM64_ERRATUM_3194386-for-aarch64.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-diff --git a/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config b/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-index ac44904c1..9f912a70b 100644
---- a/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-+++ b/resources/guest_configs/microvm-kernel-ci-aarch64-5.10.config
-@@ -341,6 +341,7 @@ CONFIG_ARM64_ERRATUM_1463225=y
- CONFIG_ARM64_ERRATUM_1542419=y
- CONFIG_ARM64_ERRATUM_1508412=y
- CONFIG_ARM64_ERRATUM_2457168=y
-+# CONFIG_ARM64_ERRATUM_3194386 is not set
- CONFIG_CAVIUM_ERRATUM_22375=y
- CONFIG_CAVIUM_ERRATUM_23144=y
- CONFIG_CAVIUM_ERRATUM_23154=y
-diff --git a/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config b/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-index 26b87a658..29fe130f2 100644
---- a/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-+++ b/resources/guest_configs/microvm-kernel-ci-aarch64-6.1.config
-@@ -362,6 +362,7 @@ CONFIG_ARM64_ERRATUM_2441009=y
- CONFIG_ARM64_ERRATUM_2457168=y
- CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD=y
- CONFIG_ARM64_ERRATUM_2966298=y
-+# CONFIG_ARM64_ERRATUM_3194386 is not set
- CONFIG_CAVIUM_ERRATUM_22375=y
- CONFIG_CAVIUM_ERRATUM_23144=y
- CONFIG_CAVIUM_ERRATUM_23154=y
diff --git a/resources/rebuild.sh b/resources/rebuild.sh
index 9f6850d0555..90bac7addb7 100755
--- a/resources/rebuild.sh
+++ b/resources/rebuild.sh
@@ -20,25 +20,6 @@ function install_dependencies {
apt install -y bc flex bison gcc make libelf-dev libssl-dev squashfs-tools busybox-static tree cpio curl patch docker.io
}
-function dir2ext4img {
- # ext4
- # https://unix.stackexchange.com/questions/503211/how-can-an-image-file-be-created-for-a-directory
- local DIR=$1
- local IMG=$2
- # Default size for the resulting rootfs image is 300M
- local SIZE=${3:-300M}
- local TMP_MNT=$(mktemp -d)
- truncate -s "$SIZE" "$IMG"
- mkfs.ext4 -F "$IMG"
- mount "$IMG" "$TMP_MNT"
- tar c -C $DIR . |tar x -C "$TMP_MNT"
- # cleanup
- # Use the -l flag for lazy unmounting since sometimes umount fails
- # with "device busy" and simply calling `sync` doesn't help
- umount -l "$TMP_MNT"
- rmdir $TMP_MNT
-}
-
function prepare_docker {
nohup /usr/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 &
@@ -67,7 +48,7 @@ function build_rootfs {
cp -rvf overlay/* $rootfs
- # curl -O https://cloud-images.ubuntu.com/minimal/releases/jammy/release/ubuntu-22.04-minimal-cloudimg-amd64-root.tar.xz
+ # curl -O https://cloud-images.ubuntu.com/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64-root.tar.xz
#
# TBD use systemd-nspawn instead of Docker
# sudo tar xaf ubuntu-22.04-minimal-cloudimg-amd64-root.tar.xz -C $rootfs
@@ -89,26 +70,13 @@ EOF
# TBD what abt /etc/hosts?
echo | tee $rootfs/etc/resolv.conf
- # Generate key for ssh access from host
- if [ ! -s id_rsa ]; then
- ssh-keygen -f id_rsa -N ""
- fi
- install -d -m 0600 "$rootfs/root/.ssh/"
- cp id_rsa.pub "$rootfs/root/.ssh/authorized_keys"
- id_rsa=$OUTPUT_DIR/$ROOTFS_NAME.id_rsa
- cp id_rsa $id_rsa
-
- # -comp zstd but guest kernel does not support
rootfs_img="$OUTPUT_DIR/$ROOTFS_NAME.squashfs"
mv $rootfs/root/manifest $OUTPUT_DIR/$ROOTFS_NAME.manifest
- mksquashfs $rootfs $rootfs_img -all-root -noappend
- rootfs_ext4=$OUTPUT_DIR/$ROOTFS_NAME.ext4
- dir2ext4img $rootfs $rootfs_ext4
+ mksquashfs $rootfs $rootfs_img -all-root -noappend -comp zstd
rm -rf $rootfs
for bin in fast_page_fault_helper fillmem init readmem; do
rm $PWD/overlay/usr/local/bin/$bin
done
- rm -f id_rsa{,.pub}
rm -f nohup.out
}
@@ -155,12 +123,6 @@ function clone_amazon_linux_repo {
[ -d linux ] || git clone https://github.com/amazonlinux/linux linux
}
-function apply_kernel_patches_for_ci {
- for p in $PWD/guest_configs/patches/* ; do
- patch -p2 < $p
- done
-}
-
# prints the git tag corresponding to the newest and best matching the provided kernel version $1
# this means that if a microvm kernel exists, the tag returned will be of the form
#
@@ -200,8 +162,9 @@ function build_al_kernel {
echo "FATAL: Unsupported architecture!"
exit 1
fi
- cp "$KERNEL_CFG" .config
-
+ # Concatenate all config files into one. olddefconfig will then resolve
+ # as needed. Later values override earlier ones.
+ cat "$@" >.config
make olddefconfig
make -j $(nproc) $target
LATEST_VERSION=$(cat include/config/kernel.release)
@@ -226,16 +189,30 @@ function prepare_and_build_rootfs {
compile_and_install $BIN/devmemread.c $BIN/devmemread
fi
- build_rootfs ubuntu-22.04 jammy
+ build_rootfs ubuntu-24.04 noble
build_initramfs
}
+function vmlinux_split_debuginfo {
+ VMLINUX="$1"
+ DEBUGINFO="$VMLINUX.debug"
+ VMLINUX_ORIG="$VMLINUX"
+ if [ $ARCH = "aarch64" ]; then
+ # in aarch64, the debug info is in vmlinux
+ VMLINUX_ORIG=linux/vmlinux
+ fi
+ objcopy --only-keep-debug $VMLINUX_ORIG $DEBUGINFO
+ objcopy --preserve-dates --strip-debug --add-gnu-debuglink=$DEBUGINFO $VMLINUX
+ # gdb does not support compressed files, but compress them because they are huge
+ gzip -v $DEBUGINFO
+}
+
function build_al_kernels {
if [[ $# = 0 ]]; then
local KERNEL_VERSION="all"
elif [[ $# -ne 1 ]]; then
die "Too many arguments in '$(basename $0) kernels' command. Please use \`$0 help\` for help."
- else
+ else
KERNEL_VERSION=$1
if [[ "$KERNEL_VERSION" != @(5.10|5.10-no-acpi|6.1) ]]; then
die "Unsupported kernel version: '$KERNEL_VERSION'. Please use \`$0 help\` for help."
@@ -244,22 +221,31 @@ function build_al_kernels {
clone_amazon_linux_repo
- # Apply kernel patches on top of AL configuration
- apply_kernel_patches_for_ci
+ CI_CONFIG="$PWD/guest_configs/ci.config"
if [[ "$KERNEL_VERSION" == @(all|5.10) ]]; then
- build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10.config
+ build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10.config "$CI_CONFIG"
fi
if [[ $ARCH == "x86_64" && "$KERNEL_VERSION" == @(all|5.10-no-acpi) ]]; then
- build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10-no-acpi.config
+ build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10-no-acpi.config "$CI_CONFIG"
fi
if [[ "$KERNEL_VERSION" == @(all|6.1) ]]; then
- build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config 5.10
+ build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config "$CI_CONFIG"
fi
- # Undo kernel patches on top of AL configuration
- git restore $PWD/guest_configs
- rm -rf $PWD/guest_configs/*.orig
+ # Build debug kernels
+ FTRACE_CONFIG="$PWD/guest_configs/ftrace.config"
+ DEBUG_CONFIG="$PWD/guest_configs/debug.config"
+ OUTPUT_DIR=$OUTPUT_DIR/debug
+ mkdir -pv $OUTPUT_DIR
+ if [[ "$KERNEL_VERSION" == @(all|5.10) ]]; then
+ build_al_kernel "$PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10.config" "$CI_CONFIG" "$FTRACE_CONFIG" "$DEBUG_CONFIG"
+ vmlinux_split_debuginfo $OUTPUT_DIR/vmlinux-5.10.*
+ fi
+ if [[ "$KERNEL_VERSION" == @(all|6.1) ]]; then
+ build_al_kernel "$PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config" "$CI_CONFIG" "$FTRACE_CONFIG" "$DEBUG_CONFIG"
+ vmlinux_split_debuginfo $OUTPUT_DIR/vmlinux-6.1.*
+ fi
}
function print_help {
@@ -267,25 +253,25 @@ function print_help {
Firecracker CI artifacts build script
Usage: $(basename $0) [] []
-
+
Available commands:
-
+
all (default)
Build CI rootfs and default guest kernels using configurations from
resources/guest_configs.
This will patch the guest configurations with all the patches under
resources/guest_configs/patches.
This is the default command, if no command is chosen.
-
+
rootfs
Builds only the CI rootfs.
-
+
kernels [version]
Builds our the currently supported CI kernels.
-
+
version: Optionally choose a kernel version to build. Supported
versions are: 5.10, 5.10-no-acpi or 6.1.
-
+
help
Displays the help message and exits.
EOF
@@ -310,7 +296,7 @@ function main {
fi
set -x
-
+
install_dependencies
# Create the directory in which we will store the kernels and rootfs
diff --git a/src/acpi-tables/Cargo.toml b/src/acpi-tables/Cargo.toml
index abf511c0c06..15137400180 100644
--- a/src/acpi-tables/Cargo.toml
+++ b/src/acpi-tables/Cargo.toml
@@ -8,9 +8,9 @@ license = "Apache-2.0"
[dependencies]
displaydoc = "0.2.5"
-thiserror = "1.0.65"
-vm-memory = { version = "0.16.0", features = ["backend-mmap", "backend-bitmap"] }
-zerocopy = { version = "0.8.7", features = ["derive"] }
+thiserror = "2.0.3"
+vm-memory = { version = "0.16.1", features = ["backend-mmap", "backend-bitmap"] }
+zerocopy = { version = "0.8.10", features = ["derive"] }
[lib]
bench = false
diff --git a/src/clippy-tracing/Cargo.toml b/src/clippy-tracing/Cargo.toml
index 4dcd08e42eb..91e03a2afb8 100644
--- a/src/clippy-tracing/Cargo.toml
+++ b/src/clippy-tracing/Cargo.toml
@@ -10,7 +10,7 @@ name = "clippy-tracing"
bench = false
[dependencies]
-clap = { version = "4.5.20", features = ["derive"] }
+clap = { version = "4.5.21", features = ["derive"] }
itertools = "0.13.0"
proc-macro2 = { version = "1.0.89", features = ["span-locations"] }
quote = "1.0.37"
diff --git a/src/cpu-template-helper/Cargo.toml b/src/cpu-template-helper/Cargo.toml
index 4e5a746647e..6654bb090c4 100644
--- a/src/cpu-template-helper/Cargo.toml
+++ b/src/cpu-template-helper/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "cpu-template-helper"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
authors = ["Amazon Firecracker team "]
edition = "2021"
license = "Apache-2.0"
@@ -10,13 +10,13 @@ name = "cpu-template-helper"
bench = false
[dependencies]
-clap = { version = "4.5.20", features = ["derive", "string"] }
+clap = { version = "4.5.21", features = ["derive", "string"] }
displaydoc = "0.2.5"
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
-serde = { version = "1.0.214", features = ["derive"] }
-serde_json = "1.0.132"
-thiserror = "1.0.65"
+serde = { version = "1.0.215", features = ["derive"] }
+serde_json = "1.0.133"
+thiserror = "2.0.3"
vmm = { path = "../vmm" }
vmm-sys-util = "0.12.1"
diff --git a/src/firecracker/Cargo.toml b/src/firecracker/Cargo.toml
index 9efd00098d0..8d0889c23dd 100644
--- a/src/firecracker/Cargo.toml
+++ b/src/firecracker/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "firecracker"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
authors = ["Amazon Firecracker team "]
edition = "2021"
build = "build.rs"
@@ -18,15 +18,15 @@ bench = false
[dependencies]
displaydoc = "0.2.5"
event-manager = "0.4.0"
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
micro_http = { git = "https://github.com/firecracker-microvm/micro-http" }
seccompiler = { path = "../seccompiler" }
-serde = { version = "1.0.214", features = ["derive"] }
+serde = { version = "1.0.215", features = ["derive"] }
serde_derive = "1.0.136"
-serde_json = "1.0.132"
-thiserror = "1.0.65"
+serde_json = "1.0.133"
+thiserror = "2.0.3"
timerfd = "1.6.0"
utils = { path = "../utils" }
vmm = { path = "../vmm" }
@@ -34,18 +34,18 @@ vmm-sys-util = { version = "0.12.1", features = ["with-serde"] }
[dev-dependencies]
cargo_toml = "0.20.5"
-libc = "0.2.161"
+libc = "0.2.164"
regex = { version = "1.11.1", default-features = false, features = ["std", "unicode-perl"] }
# Dev-Dependencies for uffd examples
-serde = { version = "1.0.214", features = ["derive"] }
+serde = { version = "1.0.215", features = ["derive"] }
userfaultfd = "0.8.1"
[build-dependencies]
bincode = "1.2.1"
seccompiler = { path = "../seccompiler" }
-serde = { version = "1.0.214" }
-serde_json = "1.0.132"
+serde = { version = "1.0.215" }
+serde_json = "1.0.133"
[features]
tracing = ["log-instrument", "seccompiler/tracing", "utils/tracing", "vmm/tracing"]
diff --git a/src/firecracker/src/api_server/parsed_request.rs b/src/firecracker/src/api_server/parsed_request.rs
index 125463d1d05..10405c156ec 100644
--- a/src/firecracker/src/api_server/parsed_request.rs
+++ b/src/firecracker/src/api_server/parsed_request.rs
@@ -276,7 +276,7 @@ pub(crate) enum RequestError {
#[error("API Resource IDs can only contain alphanumeric characters and underscores.")]
InvalidID,
// The HTTP method & request path combination is not valid.
- #[error("Invalid request method and/or path: {} {0}.", .1.to_str())]
+ #[error("Invalid request method and/or path: {} {}.", .1.to_str(), .0)]
InvalidPathMethod(String, Method),
// An error occurred when deserializing the json body of a request.
#[error("An error occurred when deserializing the json body of a request: {0}.")]
diff --git a/src/firecracker/swagger/firecracker.yaml b/src/firecracker/swagger/firecracker.yaml
index 869e8758fdf..20bad48bf64 100644
--- a/src/firecracker/swagger/firecracker.yaml
+++ b/src/firecracker/swagger/firecracker.yaml
@@ -5,7 +5,7 @@ info:
The API is accessible through HTTP calls on specific URLs
carrying JSON modeled data.
The transport medium is a Unix Domain Socket.
- version: 1.10.0-dev
+ version: 1.11.0-dev
termsOfService: ""
contact:
email: "compute-capsule@amazon.com"
@@ -840,7 +840,7 @@ definitions:
default: "None"
CpuConfig:
- type: string
+ type: object
description:
The CPU configuration template defines a set of bit maps as modifiers of flags accessed by register
to be disabled/enabled for the microvm.
@@ -854,6 +854,12 @@ definitions:
reg_modifiers:
type: object
description: A collection of registers to be modified. (aarch64)
+ vcpu_features:
+ type: object
+ description: A collection of vcpu features to be modified. (aarch64)
+ kvm_capabilities:
+ type: object
+ description: A collection of kvm capabilities to be modified. (aarch64)
Drive:
type: object
diff --git a/src/jailer/Cargo.toml b/src/jailer/Cargo.toml
index 02a2c40fed5..55b50efb785 100644
--- a/src/jailer/Cargo.toml
+++ b/src/jailer/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "jailer"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
authors = ["Amazon Firecracker team "]
edition = "2021"
description = "Process for starting Firecracker in production scenarios; applies a cgroup/namespace isolation barrier and then drops privileges."
@@ -12,11 +12,11 @@ name = "jailer"
bench = false
[dependencies]
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
nix = { version = "0.29.0", default-features = false, features = ["dir"] }
regex = { version = "1.11.1", default-features = false, features = ["std"] }
-thiserror = "1.0.65"
+thiserror = "2.0.3"
vmm-sys-util = "0.12.1"
utils = { path = "../utils" }
diff --git a/src/rebase-snap/Cargo.toml b/src/rebase-snap/Cargo.toml
index 227dd50a128..c944f5f346d 100644
--- a/src/rebase-snap/Cargo.toml
+++ b/src/rebase-snap/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "rebase-snap"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
authors = ["Amazon Firecracker team "]
edition = "2021"
license = "Apache-2.0"
@@ -11,9 +11,9 @@ bench = false
[dependencies]
displaydoc = "0.2.5"
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
-thiserror = "1.0.65"
+thiserror = "2.0.3"
vmm-sys-util = "0.12.1"
utils = { path = "../utils" }
diff --git a/src/seccompiler/Cargo.toml b/src/seccompiler/Cargo.toml
index a00febe4b63..1916a085b51 100644
--- a/src/seccompiler/Cargo.toml
+++ b/src/seccompiler/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "seccompiler"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
authors = ["Amazon Firecracker team "]
edition = "2021"
description = "Program that compiles multi-threaded seccomp-bpf filters expressed as JSON into raw BPF programs, serializing them and outputting them to a file."
@@ -18,11 +18,11 @@ bench = false
[dependencies]
bincode = "1.2.1"
displaydoc = "0.2.5"
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
-serde = { version = "1.0.214", features = ["derive"] }
-serde_json = "1.0.132"
-thiserror = "1.0.65"
+serde = { version = "1.0.215", features = ["derive"] }
+serde_json = "1.0.133"
+thiserror = "2.0.3"
utils = { path = "../utils" }
diff --git a/src/snapshot-editor/Cargo.toml b/src/snapshot-editor/Cargo.toml
index b7832164fc9..022342d896f 100644
--- a/src/snapshot-editor/Cargo.toml
+++ b/src/snapshot-editor/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "snapshot-editor"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
authors = ["Amazon Firecracker team "]
edition = "2021"
license = "Apache-2.0"
@@ -10,14 +10,14 @@ name = "snapshot-editor"
bench = false
[dependencies]
-clap = { version = "4.5.20", features = ["derive", "string"] }
+clap = { version = "4.5.21", features = ["derive", "string"] }
displaydoc = "0.2.5"
fc_utils = { package = "utils", path = "../utils" }
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
semver = "1.0.23"
-thiserror = "1.0.65"
+thiserror = "2.0.3"
vmm = { path = "../vmm" }
vmm-sys-util = "0.12.1"
diff --git a/src/utils/Cargo.toml b/src/utils/Cargo.toml
index aa0fd23e4fd..2514ee05b0b 100644
--- a/src/utils/Cargo.toml
+++ b/src/utils/Cargo.toml
@@ -11,15 +11,15 @@ bench = false
[dependencies]
derive_more = { version = "1.0.0", default-features = false, features = ["from"] }
displaydoc = "0.2.5"
-libc = "0.2.161"
+libc = "0.2.164"
log-instrument = { path = "../log-instrument", optional = true }
-serde = { version = "1.0.214", features = ["derive"] }
-thiserror = "1.0.65"
-vm-memory = { version = "0.16.0", features = ["backend-mmap", "backend-bitmap"] }
+serde = { version = "1.0.215", features = ["derive"] }
+thiserror = "2.0.3"
+vm-memory = { version = "0.16.1", features = ["backend-mmap", "backend-bitmap"] }
vmm-sys-util = "0.12.1"
[dev-dependencies]
-serde_json = "1.0.132"
+serde_json = "1.0.133"
[features]
tracing = ["log-instrument"]
diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml
index a55cf721e43..070cae5088f 100644
--- a/src/vmm/Cargo.toml
+++ b/src/vmm/Cargo.toml
@@ -12,7 +12,7 @@ bench = false
acpi_tables = { path = "../acpi-tables" }
aes-gcm = { version = "0.10.1", default-features = false, features = ["aes"] }
arrayvec = { version = "0.7.6", optional = true }
-aws-lc-rs = { version = "1.10.0", features = ["bindgen"] }
+aws-lc-rs = { version = "1.11.0", features = ["bindgen"] }
base64 = "0.22.1"
bincode = "1.2.1"
bitflags = "2.6.0"
@@ -25,7 +25,7 @@ gdbstub_arch = { version = "0.3.1", optional = true }
kvm-bindings = { version = "0.10.0", features = ["fam-wrappers", "serde"] }
kvm-ioctls = "0.19.0"
lazy_static = "1.5.0"
-libc = "0.2.161"
+libc = "0.2.164"
linux-loader = "0.13.0"
log = { version = "0.4.22", features = ["std", "serde"] }
log-instrument = { path = "../log-instrument", optional = true }
@@ -34,19 +34,19 @@ micro_http = { git = "https://github.com/firecracker-microvm/micro-http" }
seccompiler = { path = "../seccompiler" }
semver = { version = "1.0.23", features = ["serde"] }
-serde = { version = "1.0.214", features = ["derive", "rc"] }
-serde_json = "1.0.132"
+serde = { version = "1.0.215", features = ["derive", "rc"] }
+serde_json = "1.0.133"
slab = "0.4.7"
-thiserror = "1.0.65"
+thiserror = "2.0.3"
timerfd = "1.5.0"
userfaultfd = "0.8.1"
utils = { path = "../utils" }
-vhost = { version = "0.12.1", features = ["vhost-user-frontend"] }
+vhost = { version = "0.13.0", features = ["vhost-user-frontend"] }
vm-allocator = "0.1.0"
-vm-memory = { version = "0.16.0", features = ["backend-mmap", "backend-bitmap"] }
+vm-memory = { version = "0.16.1", features = ["backend-mmap", "backend-bitmap"] }
vm-superio = "0.8.0"
vmm-sys-util = { version = "0.12.1", features = ["with-serde"] }
-zerocopy = { version = "0.8.7" }
+zerocopy = { version = "0.8.10" }
[target.'cfg(target_arch = "aarch64")'.dependencies]
vm-fdt = "0.3.0"
diff --git a/src/vmm/src/devices/virtio/device.rs b/src/vmm/src/devices/virtio/device.rs
index b5af6862af9..5adf4873dc6 100644
--- a/src/vmm/src/devices/virtio/device.rs
+++ b/src/vmm/src/devices/virtio/device.rs
@@ -156,7 +156,7 @@ pub trait VirtioDevice: AsAny + Send {
let avail_features = self.avail_features();
let unrequested_features = v & !avail_features;
if unrequested_features != 0 {
- warn!("Received acknowledge request for unknown feature: {:x}", v);
+ warn!("Received acknowledge request for unknown feature: {:#x}", v);
// Don't count these features as acked.
v &= !unrequested_features;
}
diff --git a/src/vmm/src/devices/virtio/iovec.rs b/src/vmm/src/devices/virtio/iovec.rs
index 4cbbc512186..2161d7273ef 100644
--- a/src/vmm/src/devices/virtio/iovec.rs
+++ b/src/vmm/src/devices/virtio/iovec.rs
@@ -482,10 +482,12 @@ mod tests {
use super::IoVecBuffer;
// Redefine `IoVecBufferMut` with specific length. Otherwise
// Rust will not know what to do.
- type IoVecBufferMut = super::IoVecBufferMut<256>;
+ type IoVecBufferMutDefault = super::IoVecBufferMut;
use crate::devices::virtio::iov_deque::IovDeque;
- use crate::devices::virtio::queue::{Queue, VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE};
+ use crate::devices::virtio::queue::{
+ Queue, FIRECRACKER_MAX_QUEUE_SIZE, VIRTQ_DESC_F_NEXT, VIRTQ_DESC_F_WRITE,
+ };
use crate::devices::virtio::test_utils::VirtQueue;
use crate::test_utils::multi_region_mem;
use crate::vstate::memory::{Bytes, GuestAddress, GuestMemoryMmap};
@@ -614,12 +616,12 @@ mod tests {
let (mut q, _) = read_only_chain(&mem);
let head = q.pop().unwrap();
// SAFETY: This descriptor chain is only loaded into one buffer
- unsafe { IoVecBufferMut::from_descriptor_chain(&mem, head).unwrap_err() };
+ unsafe { IoVecBufferMutDefault::from_descriptor_chain(&mem, head).unwrap_err() };
let (mut q, _) = write_only_chain(&mem);
let head = q.pop().unwrap();
// SAFETY: This descriptor chain is only loaded into one buffer
- unsafe { IoVecBufferMut::from_descriptor_chain(&mem, head).unwrap() };
+ unsafe { IoVecBufferMutDefault::from_descriptor_chain(&mem, head).unwrap() };
}
#[test]
@@ -640,7 +642,8 @@ mod tests {
let head = q.pop().unwrap();
// SAFETY: This descriptor chain is only loaded once in this test
- let mut iovec = unsafe { IoVecBufferMut::from_descriptor_chain(&mem, head).unwrap() };
+ let mut iovec =
+ unsafe { IoVecBufferMutDefault::from_descriptor_chain(&mem, head).unwrap() };
assert_eq!(iovec.len(), 4 * 64);
// We are creating a new queue where we can get descriptors from. Probably, this is not
@@ -717,7 +720,8 @@ mod tests {
let head = q.pop().unwrap();
// SAFETY: This descriptor chain is only loaded into one buffer
- let mut iovec = unsafe { IoVecBufferMut::from_descriptor_chain(&mem, head).unwrap() };
+ let mut iovec =
+ unsafe { IoVecBufferMutDefault::from_descriptor_chain(&mem, head).unwrap() };
let buf = vec![0u8, 1, 2, 3, 4];
// One test vector for each part of the chain
@@ -814,8 +818,8 @@ mod verification {
use crate::devices::virtio::iov_deque::IovDeque;
// Redefine `IoVecBufferMut` and `IovDeque` with specific length. Otherwise
// Rust will not know what to do.
- type IoVecBufferMut256 = super::IoVecBufferMut<256>;
- type IovDeque256 = IovDeque<256>;
+ type IoVecBufferMutDefault = super::IoVecBufferMut;
+ type IovDequeDefault = IovDeque;
use crate::arch::PAGE_SIZE;
use crate::devices::virtio::queue::FIRECRACKER_MAX_QUEUE_SIZE;
@@ -860,10 +864,10 @@ mod verification {
);
let offset = (deque.start + deque.len) as usize;
- let mirror = if offset >= FIRECRACKER_MAX_QUEUE_SIZE as usize {
- offset - FIRECRACKER_MAX_QUEUE_SIZE as usize
+ let mirror = if offset >= L as usize {
+ offset - L as usize
} else {
- offset + FIRECRACKER_MAX_QUEUE_SIZE as usize
+ offset + L as usize
};
// SAFETY: self.iov is a valid pointer and `self.start + self.len` is within range (we
@@ -904,7 +908,7 @@ mod verification {
}
}
- fn create_iov_deque() -> IovDeque256 {
+ fn create_iov_deque() -> IovDequeDefault {
// SAFETY: safe because the layout has non-zero size
let mem = unsafe {
std::alloc::alloc(std::alloc::Layout::from_size_align_unchecked(
@@ -912,14 +916,14 @@ mod verification {
PAGE_SIZE,
))
};
- IovDeque256 {
+ IovDequeDefault {
iov: mem.cast(),
start: kani::any_where(|&start| start < FIRECRACKER_MAX_QUEUE_SIZE),
len: 0,
}
}
- fn create_iovecs_mut(mem: *mut u8, size: usize, nr_descs: usize) -> (IovDeque256, u32) {
+ fn create_iovecs_mut(mem: *mut u8, size: usize, nr_descs: usize) -> (IovDequeDefault, u32) {
let mut vecs = create_iov_deque();
let mut len = 0u32;
for _ in 0..nr_descs {
@@ -939,7 +943,7 @@ mod verification {
(vecs, len)
}
- impl IoVecBufferMut256 {
+ impl IoVecBufferMutDefault {
fn any_of_length(nr_descs: usize) -> Self {
// We only write into `IoVecBufferMut` objects, so we can simply create a guest memory
// object initialized to zeroes, trying to be nice to Kani.
@@ -1029,12 +1033,10 @@ mod verification {
#[kani::proof]
#[kani::unwind(5)]
#[kani::solver(cadical)]
- // The `IovDeque` is defined as type alias in the kani module. Because of this
- // we need to specify original type here for stub to work.
#[kani::stub(IovDeque::push_back, stubs::push_back)]
fn verify_write_to_iovec() {
for nr_descs in 0..MAX_DESC_LENGTH {
- let mut iov_mut = IoVecBufferMut256::any_of_length(nr_descs);
+ let mut iov_mut = IoVecBufferMutDefault::any_of_length(nr_descs);
let mut buf = kani::vec::any_vec::();
let offset: u32 = kani::any();
diff --git a/src/vmm/src/devices/virtio/mmio.rs b/src/vmm/src/devices/virtio/mmio.rs
index 463d11ca2e2..f734058c5b1 100644
--- a/src/vmm/src/devices/virtio/mmio.rs
+++ b/src/vmm/src/devices/virtio/mmio.rs
@@ -138,7 +138,7 @@ impl MmioTransport {
self.with_queue_mut(f);
} else {
warn!(
- "update virtio queue in invalid state 0x{:x}",
+ "update virtio queue in invalid state {:#x}",
self.device_status
);
}
@@ -227,7 +227,7 @@ impl MmioTransport {
}
_ => {
warn!(
- "invalid virtio driver status transition: 0x{:x} -> 0x{:x}",
+ "invalid virtio driver status transition: {:#x} -> {:#x}",
self.device_status, status
);
}
@@ -282,7 +282,7 @@ impl MmioTransport {
0x70 => self.device_status,
0xfc => self.config_generation,
_ => {
- warn!("unknown virtio mmio register read: 0x{:x}", offset);
+ warn!("unknown virtio mmio register read: {:#x}", offset);
return;
}
};
@@ -290,11 +290,7 @@ impl MmioTransport {
}
0x100..=0xfff => self.locked_device().read_config(offset - 0x100, data),
_ => {
- warn!(
- "invalid virtio mmio read: 0x{:x}:0x{:x}",
- offset,
- data.len()
- );
+ warn!("invalid virtio mmio read: {:#x}:{:#x}", offset, data.len());
}
};
}
@@ -324,7 +320,7 @@ impl MmioTransport {
.ack_features_by_page(self.acked_features_select, v);
} else {
warn!(
- "ack virtio features in invalid state 0x{:x}",
+ "ack virtio features in invalid state {:#x}",
self.device_status
);
}
@@ -346,7 +342,7 @@ impl MmioTransport {
0xa0 => self.update_queue_field(|q| lo(&mut q.used_ring_address, v)),
0xa4 => self.update_queue_field(|q| hi(&mut q.used_ring_address, v)),
_ => {
- warn!("unknown virtio mmio register write: 0x{:x}", offset);
+ warn!("unknown virtio mmio register write: {:#x}", offset);
}
}
}
@@ -361,11 +357,7 @@ impl MmioTransport {
}
}
_ => {
- warn!(
- "invalid virtio mmio write: 0x{:x}:0x{:x}",
- offset,
- data.len()
- );
+ warn!("invalid virtio mmio write: {:#x}:{:#x}", offset, data.len());
}
}
}
diff --git a/src/vmm/src/devices/virtio/net/device.rs b/src/vmm/src/devices/virtio/net/device.rs
index 6c69bd171a7..818fed86a30 100755
--- a/src/vmm/src/devices/virtio/net/device.rs
+++ b/src/vmm/src/devices/virtio/net/device.rs
@@ -31,7 +31,7 @@ use crate::devices::virtio::net::tap::Tap;
use crate::devices::virtio::net::{
gen, NetError, NetQueue, MAX_BUFFER_SIZE, NET_QUEUE_SIZES, RX_INDEX, TX_INDEX,
};
-use crate::devices::virtio::queue::{DescriptorChain, Queue, FIRECRACKER_MAX_QUEUE_SIZE};
+use crate::devices::virtio::queue::{DescriptorChain, Queue};
use crate::devices::virtio::{ActivateError, TYPE_NET};
use crate::devices::{report_net_event_fail, DeviceError};
use crate::dumbo::pdu::arp::ETH_IPV4_FRAME_LEN;
@@ -119,7 +119,7 @@ impl RxBuffers {
Ok(Self {
min_buffer_size: 0,
iovec: IoVecBufferMut::new()?,
- parsed_descriptors: VecDeque::with_capacity(FIRECRACKER_MAX_QUEUE_SIZE.into()),
+ parsed_descriptors: VecDeque::with_capacity(NET_QUEUE_MAX_SIZE.into()),
used_descriptors: 0,
used_bytes: 0,
})
@@ -2153,7 +2153,7 @@ pub mod tests {
// Test RX bandwidth rate limiting
{
// create bandwidth rate limiter that allows 2000 bytes/s with bucket size 1000 bytes
- let mut rl = RateLimiter::new(1000, 0, 500, 0, 0, 0).unwrap();
+ let mut rl = RateLimiter::new(1000, 0, 1000, 0, 0, 0).unwrap();
// set up RX
assert!(th.net().rx_buffer.used_descriptors == 0);
@@ -2195,9 +2195,9 @@ pub mod tests {
assert_eq!(th.net().metrics.rx_rate_limiter_throttled.count(), 2);
}
- // wait for 500ms to give the rate-limiter timer a chance to replenish
- // wait for an extra 500ms to make sure the timerfd event makes its way from the kernel
- thread::sleep(Duration::from_millis(1000));
+ // wait for 1000ms to give the rate-limiter timer a chance to replenish
+ // wait for an extra 1000ms to make sure the timerfd event makes its way from the kernel
+ thread::sleep(Duration::from_millis(2000));
// following RX procedure should succeed because bandwidth should now be available
{
@@ -2276,7 +2276,7 @@ pub mod tests {
// Test RX ops rate limiting
{
// create ops rate limiter that allows 2 ops/s with bucket size 1 ops
- let mut rl = RateLimiter::new(0, 0, 0, 1, 0, 500).unwrap();
+ let mut rl = RateLimiter::new(0, 0, 0, 1, 0, 1000).unwrap();
// set up RX
assert!(th.net().rx_buffer.used_descriptors == 0);
@@ -2319,9 +2319,9 @@ pub mod tests {
assert_eq!(th.rxq.used.idx.get(), 0);
}
- // wait for 500ms to give the rate-limiter timer a chance to replenish
- // wait for an extra 500ms to make sure the timerfd event makes its way from the kernel
- thread::sleep(Duration::from_millis(1000));
+ // wait for 1000ms to give the rate-limiter timer a chance to replenish
+ // wait for an extra 1000ms to make sure the timerfd event makes its way from the kernel
+ thread::sleep(Duration::from_millis(2000));
// following RX procedure should succeed because ops should now be available
{
diff --git a/src/vmm/src/devices/virtio/net/mod.rs b/src/vmm/src/devices/virtio/net/mod.rs
index 197f2069d47..4bc5b896601 100644
--- a/src/vmm/src/devices/virtio/net/mod.rs
+++ b/src/vmm/src/devices/virtio/net/mod.rs
@@ -6,7 +6,7 @@
use std::io;
/// Maximum size of the queue for network device.
-pub const NET_QUEUE_MAX_SIZE: u16 = 512;
+pub const NET_QUEUE_MAX_SIZE: u16 = 256;
/// Maximum size of the frame buffers handled by this device.
pub const MAX_BUFFER_SIZE: usize = 65562;
/// The number of queues of the network device.
diff --git a/src/vmm/src/devices/virtio/vsock/device.rs b/src/vmm/src/devices/virtio/vsock/device.rs
index bf438aca99f..eb7c144c4be 100644
--- a/src/vmm/src/devices/virtio/vsock/device.rs
+++ b/src/vmm/src/devices/virtio/vsock/device.rs
@@ -322,7 +322,7 @@ where
fn write_config(&mut self, offset: u64, data: &[u8]) {
METRICS.cfg_fails.inc();
warn!(
- "vsock: guest driver attempted to write device config (offset={:x}, len={:x})",
+ "vsock: guest driver attempted to write device config (offset={:#x}, len={:#x})",
offset,
data.len()
);
diff --git a/src/vmm/src/gdb/target.rs b/src/vmm/src/gdb/target.rs
index fc2da289e8a..b8230342b27 100644
--- a/src/vmm/src/gdb/target.rs
+++ b/src/vmm/src/gdb/target.rs
@@ -390,7 +390,7 @@ impl MultiThreadBase for FirecrackerTarget {
while !data.is_empty() {
let gpa = arch::translate_gva(&vcpu_state.vcpu_fd, gva, &vmm).map_err(|e| {
- error!("Error {e:?} translating gva on read address: {gva:X}");
+ error!("Error {e:?} translating gva on read address: {gva:#X}");
})?;
// Compute the amount space left in the page after the gpa
@@ -424,7 +424,7 @@ impl MultiThreadBase for FirecrackerTarget {
while !data.is_empty() {
let gpa = arch::translate_gva(&vcpu_state.vcpu_fd, gva, &vmm).map_err(|e| {
- error!("Error {e:?} translating gva on read address: {gva:X}");
+ error!("Error {e:?} translating gva on read address: {gva:#X}");
})?;
// Compute the amount space left in the page after the gpa
@@ -436,7 +436,7 @@ impl MultiThreadBase for FirecrackerTarget {
vmm.guest_memory()
.write(&data[..write_len], GuestAddress(gpa))
.map_err(|e| {
- error!("Error {e:?} writing memory at {gpa:X}");
+ error!("Error {e:?} writing memory at {gpa:#X}");
})?;
data = &data[write_len..];
diff --git a/src/vmm/src/mmds/ns.rs b/src/vmm/src/mmds/ns.rs
index 09d73b21e99..8075df8cb91 100644
--- a/src/vmm/src/mmds/ns.rs
+++ b/src/vmm/src/mmds/ns.rs
@@ -81,8 +81,6 @@ impl MmdsNetworkStack {
mac_addr: MacAddr,
ipv4_addr: Ipv4Addr,
tcp_port: u16,
- max_connections: NonZeroUsize,
- max_pending_resets: NonZeroUsize,
mmds: Arc>,
) -> Self {
MmdsNetworkStack {
@@ -93,8 +91,8 @@ impl MmdsNetworkStack {
tcp_handler: TcpIPv4Handler::new(
ipv4_addr,
tcp_port,
- max_connections,
- max_pending_resets,
+ NonZeroUsize::new(DEFAULT_MAX_CONNECTIONS).unwrap(),
+ NonZeroUsize::new(DEFAULT_MAX_PENDING_RESETS).unwrap(),
),
mmds,
}
@@ -105,14 +103,7 @@ impl MmdsNetworkStack {
let ipv4_addr = mmds_ipv4_addr.unwrap_or_else(|| Ipv4Addr::from(DEFAULT_IPV4_ADDR));
// The unwrap()s are safe because the given literals are greater than 0.
- Self::new(
- mac_addr,
- ipv4_addr,
- DEFAULT_TCP_PORT,
- NonZeroUsize::new(DEFAULT_MAX_CONNECTIONS).unwrap(),
- NonZeroUsize::new(DEFAULT_MAX_PENDING_RESETS).unwrap(),
- mmds,
- )
+ Self::new(mac_addr, ipv4_addr, DEFAULT_TCP_PORT, mmds)
}
pub fn set_ipv4_addr(&mut self, ipv4_addr: Ipv4Addr) {
@@ -562,14 +553,8 @@ mod tests {
let ip = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
let other_ip = Ipv4Addr::new(5, 6, 7, 8);
let mac = MacAddr::from_bytes_unchecked(&[0; 6]);
- let mut ns = MmdsNetworkStack::new(
- mac,
- ip,
- DEFAULT_TCP_PORT,
- NonZeroUsize::new(DEFAULT_MAX_CONNECTIONS).unwrap(),
- NonZeroUsize::new(DEFAULT_MAX_PENDING_RESETS).unwrap(),
- Arc::new(Mutex::new(Mmds::default())),
- );
+ let mut ns =
+ MmdsNetworkStack::new_with_defaults(Some(ip), Arc::new(Mutex::new(Mmds::default())));
let mut eth =
EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_ARP).unwrap();
@@ -589,14 +574,8 @@ mod tests {
let ip = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
let other_ip = Ipv4Addr::new(5, 6, 7, 8);
let mac = MacAddr::from_bytes_unchecked(&[0; 6]);
- let ns = MmdsNetworkStack::new(
- mac,
- ip,
- DEFAULT_TCP_PORT,
- NonZeroUsize::new(DEFAULT_MAX_CONNECTIONS).unwrap(),
- NonZeroUsize::new(DEFAULT_MAX_PENDING_RESETS).unwrap(),
- Arc::new(Mutex::new(Mmds::default())),
- );
+ let ns =
+ MmdsNetworkStack::new_with_defaults(Some(ip), Arc::new(Mutex::new(Mmds::default())));
let mut eth =
EthernetFrame::write_incomplete(buf.as_mut(), mac, mac, ETHERTYPE_IPV4).unwrap();
@@ -615,14 +594,8 @@ mod tests {
let ip = Ipv4Addr::from(DEFAULT_IPV4_ADDR);
let other_ip = Ipv4Addr::new(5, 6, 7, 8);
let mac = MacAddr::from_bytes_unchecked(&[0; 6]);
- let mut ns = MmdsNetworkStack::new(
- mac,
- ip,
- DEFAULT_TCP_PORT,
- NonZeroUsize::new(DEFAULT_MAX_CONNECTIONS).unwrap(),
- NonZeroUsize::new(DEFAULT_MAX_PENDING_RESETS).unwrap(),
- Arc::new(Mutex::new(Mmds::default())),
- );
+ let mut ns =
+ MmdsNetworkStack::new_with_defaults(Some(ip), Arc::new(Mutex::new(Mmds::default())));
// try IPv4 with detour_arp
let mut eth =
diff --git a/src/vmm/src/mmds/persist.rs b/src/vmm/src/mmds/persist.rs
index dc0113f8a5c..82feff79bc8 100644
--- a/src/vmm/src/mmds/persist.rs
+++ b/src/vmm/src/mmds/persist.rs
@@ -4,7 +4,6 @@
//! Defines the structures needed for saving/restoring MmdsNetworkStack.
use std::net::Ipv4Addr;
-use std::num::NonZeroUsize;
use std::sync::{Arc, Mutex};
use serde::{Deserialize, Serialize};
@@ -20,8 +19,6 @@ pub struct MmdsNetworkStackState {
mac_addr: [u8; MAC_ADDR_LEN as usize],
ipv4_addr: u32,
tcp_port: u16,
- max_connections: NonZeroUsize,
- max_pending_resets: NonZeroUsize,
}
impl Persist<'_> for MmdsNetworkStack {
@@ -37,8 +34,6 @@ impl Persist<'_> for MmdsNetworkStack {
mac_addr,
ipv4_addr: self.ipv4_addr.into(),
tcp_port: self.tcp_handler.local_port(),
- max_connections: self.tcp_handler.max_connections(),
- max_pending_resets: self.tcp_handler.max_pending_resets(),
}
}
@@ -50,8 +45,6 @@ impl Persist<'_> for MmdsNetworkStack {
MacAddr::from_bytes_unchecked(&state.mac_addr),
Ipv4Addr::from(state.ipv4_addr),
state.tcp_port,
- state.max_connections,
- state.max_pending_resets,
mmds,
))
}
@@ -83,13 +76,5 @@ mod tests {
restored_ns.tcp_handler.local_port(),
ns.tcp_handler.local_port()
);
- assert_eq!(
- restored_ns.tcp_handler.max_connections(),
- ns.tcp_handler.max_connections()
- );
- assert_eq!(
- restored_ns.tcp_handler.max_pending_resets(),
- ns.tcp_handler.max_pending_resets()
- );
}
}
diff --git a/src/vmm/src/persist.rs b/src/vmm/src/persist.rs
index 560d9d7c6b7..5b01ed49c75 100644
--- a/src/vmm/src/persist.rs
+++ b/src/vmm/src/persist.rs
@@ -157,7 +157,7 @@ pub enum CreateSnapshotError {
}
/// Snapshot version
-pub const SNAPSHOT_VERSION: Version = Version::new(3, 0, 0);
+pub const SNAPSHOT_VERSION: Version = Version::new(5, 0, 0);
/// Creates a Microvm snapshot.
pub fn create_snapshot(
diff --git a/src/vmm/src/vstate/vcpu/x86_64.rs b/src/vmm/src/vstate/vcpu/x86_64.rs
index 6fee3933435..a1bb22d1bb7 100644
--- a/src/vmm/src/vstate/vcpu/x86_64.rs
+++ b/src/vmm/src/vstate/vcpu/x86_64.rs
@@ -61,7 +61,7 @@ pub enum KvmVcpuError {
VcpuGetLapic(kvm_ioctls::Error),
/// Failed to get KVM vcpu mp state: {0}
VcpuGetMpState(kvm_ioctls::Error),
- /// Failed to get KVM vcpu msr: 0x{0:x}
+ /// Failed to get KVM vcpu msr: {0:#x}
VcpuGetMsr(u32),
/// Failed to get KVM vcpu msrs: {0}
VcpuGetMsrs(kvm_ioctls::Error),
@@ -321,7 +321,7 @@ impl KvmVcpu {
.filter(|msr| msr.index == MSR_IA32_TSC_DEADLINE && msr.data == 0)
.for_each(|msr| {
warn!(
- "MSR_IA32_TSC_DEADLINE is 0, replacing with {:x}.",
+ "MSR_IA32_TSC_DEADLINE is 0, replacing with {:#x}.",
tsc_value
);
msr.data = tsc_value;
diff --git a/src/vmm/src/vstate/vm.rs b/src/vmm/src/vstate/vm.rs
index 0f72abcf68f..3d24dc6f9ac 100644
--- a/src/vmm/src/vstate/vm.rs
+++ b/src/vmm/src/vstate/vm.rs
@@ -34,7 +34,7 @@ use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap, GuestMemoryRe
pub enum VmError {
/// The host kernel reports an invalid KVM API version: {0}
ApiVersion(i32),
- /// Missing KVM capabilities: {0:x?}
+ /// Missing KVM capabilities: {0:#x?}
Capabilities(u32),
/** Error creating KVM object: {0} Make sure the user launching the firecracker process is \
configured on the /dev/kvm file's ACL. */
diff --git a/tests/README.md b/tests/README.md
index 4fee1baee30..ea46ff56786 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -303,9 +303,9 @@ that are pre-initialized with specific guest kernels and rootfs:
- `uvm_plain_any` is parametrized by the guest kernels
[supported](../docs/kernel-policy.md) by Firecracker and a read-only Ubuntu
- 22.04 squashfs as rootfs,
+ 24.04 squashfs as rootfs,
- `uvm_plain` yields a Firecracker process pre-initialized with a 5.10 kernel
- and the same Ubuntu 22.04 squashfs.
+ and the same Ubuntu 24.04 squashfs.
Generally, tests should use the former if you are testing some interaction
between the guest and Firecracker, while the latter should be used if
diff --git a/tests/conftest.py b/tests/conftest.py
index c77fee09039..8f4c2e51ff5 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -307,14 +307,20 @@ def custom_cpu_template(request, record_property):
@pytest.fixture(
- params=list(static_cpu_templates_params()) + list(custom_cpu_templates_params())
+ params=[
+ pytest.param(None, id="NO_CPU_TMPL"),
+ *static_cpu_templates_params(),
+ *custom_cpu_templates_params(),
+ ],
)
def cpu_template_any(request, record_property):
- """This fixture combines static and custom CPU templates"""
- if "name" in request.param:
- record_property("custom_cpu_template", request.param["name"])
- else:
- record_property("static_cpu_template", request.param)
+ """This fixture combines no template, static and custom CPU templates"""
+ cpu_template_name = request.param
+ if request.param is None:
+ cpu_template_name = "None"
+ elif "name" in request.param:
+ cpu_template_name = request.param["name"]
+ record_property("cpu_template", cpu_template_name)
return request.param
@@ -382,27 +388,24 @@ def rootfs_fxt(request, record_property):
)
# Fixtures for all Ubuntu rootfs, and specific versions
-rootfs = pytest.fixture(rootfs_fxt, params=rootfs_params("*.squashfs"))
-rootfs_ubuntu_22 = pytest.fixture(
- rootfs_fxt, params=rootfs_params("ubuntu-22*.squashfs")
-)
+rootfs = pytest.fixture(rootfs_fxt, params=rootfs_params("ubuntu-24*.squashfs"))
rootfs_rw = pytest.fixture(rootfs_fxt, params=rootfs_params("*.ext4"))
@pytest.fixture
-def uvm_plain(microvm_factory, guest_kernel_linux_5_10, rootfs_ubuntu_22):
+def uvm_plain(microvm_factory, guest_kernel_linux_5_10, rootfs):
"""Create a vanilla VM, non-parametrized
kernel: 5.10
- rootfs: Ubuntu 22.04
+ rootfs: Ubuntu 24.04
"""
- return microvm_factory.build(guest_kernel_linux_5_10, rootfs_ubuntu_22)
+ return microvm_factory.build(guest_kernel_linux_5_10, rootfs)
@pytest.fixture
def uvm_plain_rw(microvm_factory, guest_kernel_linux_5_10, rootfs_rw):
"""Create a vanilla VM, non-parametrized
kernel: 5.10
- rootfs: Ubuntu 22.04
+ rootfs: Ubuntu 24.04
"""
return microvm_factory.build(guest_kernel_linux_5_10, rootfs_rw)
@@ -424,12 +427,24 @@ def artifact_dir():
@pytest.fixture
-def uvm_plain_any(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def uvm_plain_any(microvm_factory, guest_kernel, rootfs):
"""All guest kernels
kernel: all
- rootfs: Ubuntu 22.04
+ rootfs: Ubuntu 24.04
"""
- return microvm_factory.build(guest_kernel, rootfs_ubuntu_22)
+ return microvm_factory.build(guest_kernel, rootfs)
+
+
+guest_kernel_6_1_debug = pytest.fixture(
+ guest_kernel_fxt,
+ params=kernel_params("vmlinux-6.1*", artifact_dir=defs.ARTIFACT_DIR / "debug"),
+)
+
+
+@pytest.fixture
+def uvm_plain_debug(microvm_factory, guest_kernel_6_1_debug, rootfs_rw):
+ """VM running a kernel with debug/trace Kconfig options"""
+ return microvm_factory.build(guest_kernel_6_1_debug, rootfs_rw)
@pytest.fixture
diff --git a/tests/data/static_cpu_templates/aarch64_with_sve_and_pac.json b/tests/data/static_cpu_templates/aarch64_with_sve_and_pac.json
index b155d81dc34..29e47be4a92 100644
--- a/tests/data/static_cpu_templates/aarch64_with_sve_and_pac.json
+++ b/tests/data/static_cpu_templates/aarch64_with_sve_and_pac.json
@@ -1,4 +1,4 @@
{
"kvm_capabilities": ["170", "171", "172"],
- "vcpu_features": [{ "index": 0, "bitmap": "0b1110000" }]
+ "vcpu_features": [{ "index": 0, "bitmap": "0b111xxxx" }]
}
diff --git a/tests/framework/artifacts.py b/tests/framework/artifacts.py
index f4e05a88c94..77584f02129 100644
--- a/tests/framework/artifacts.py
+++ b/tests/framework/artifacts.py
@@ -32,12 +32,12 @@ def select_supported_kernels():
return supported_kernels
-def kernels(glob) -> Iterator:
+def kernels(glob, artifact_dir: Path = ARTIFACT_DIR) -> Iterator:
"""Return supported kernels as kernels supported by the current combination of kernel and
instance type.
"""
supported_kernels = select_supported_kernels()
- for kernel in sorted(ARTIFACT_DIR.rglob(glob)):
+ for kernel in sorted(artifact_dir.glob(glob)):
for kernel_regex in supported_kernels:
if re.fullmatch(kernel_regex, kernel.name):
yield kernel
@@ -49,9 +49,11 @@ def disks(glob) -> Iterator:
yield from sorted(ARTIFACT_DIR.glob(glob))
-def kernel_params(glob="vmlinux-*", select=kernels) -> Iterator:
+def kernel_params(
+ glob="vmlinux-*", select=kernels, artifact_dir=ARTIFACT_DIR
+) -> Iterator:
"""Return supported kernels"""
- for kernel in select(glob):
+ for kernel in select(glob, artifact_dir):
yield pytest.param(kernel, id=kernel.name)
diff --git a/tests/framework/microvm_helpers.py b/tests/framework/microvm_helpers.py
index 4239eb2489f..f29ae84a9a0 100644
--- a/tests/framework/microvm_helpers.py
+++ b/tests/framework/microvm_helpers.py
@@ -222,3 +222,26 @@ def run_in_netns(cmd):
# add a route on the host for the clone address
run(f"ip route add {ingress_ipv4} via {veth_guest_ip}")
+
+ def trace_cmd_guest(self, fns, cmd, port=4321):
+ """Run trace-cmd on the guest, but transfer the data directly to the host."""
+ docker_apt_install("trace-cmd")
+ print("host> trace-cmd listen")
+ _proc = subprocess.Popen(
+ [
+ "ip",
+ "netns",
+ "exec",
+ self.vm.netns.id,
+ "trace-cmd",
+ "listen",
+ "-p",
+ str(port),
+ ]
+ )
+ print("guest> trace-cmd record")
+ host_ip = self.vm.iface["eth0"]["iface"].host_ip
+ _guest_ps = self.vm.ssh.run(
+ f"trace-cmd record -N {host_ip}:{port} -p function {" ".join(fns)} {cmd}"
+ )
+ return list(Path(".").glob("trace.*.dat"))
diff --git a/tests/framework/utils_cpu_templates.py b/tests/framework/utils_cpu_templates.py
index 5badd7c640a..e57ecfe72c7 100644
--- a/tests/framework/utils_cpu_templates.py
+++ b/tests/framework/utils_cpu_templates.py
@@ -29,7 +29,7 @@ def get_supported_cpu_templates():
match get_cpu_vendor(), global_props.cpu_codename:
# T2CL template is only supported on Cascade Lake and newer CPUs.
case CpuVendor.INTEL, CpuModel.INTEL_SKYLAKE:
- return sorted(set(INTEL_TEMPLATES) - set(["T2CL"]))
+ return sorted(set(INTEL_TEMPLATES) - {"T2CL"})
case CpuVendor.INTEL, _:
return INTEL_TEMPLATES
case CpuVendor.AMD, _:
@@ -42,18 +42,12 @@ def get_supported_cpu_templates():
SUPPORTED_CPU_TEMPLATES = get_supported_cpu_templates()
-# Custom CPU templates for Aarch64 for testing
-AARCH64_CUSTOM_CPU_TEMPLATES_G2 = ["v1n1"]
-AARCH64_CUSTOM_CPU_TEMPLATES_G3 = [
- "aarch64_with_sve_and_pac",
- "v1n1",
-]
-
def get_supported_custom_cpu_templates():
"""
Return the list of custom CPU templates supported by the platform.
"""
+ # pylint:disable=too-many-return-statements
host_linux = global_props.host_linux_version_tpl
match get_cpu_vendor(), global_props.cpu_codename:
@@ -65,9 +59,11 @@ def get_supported_custom_cpu_templates():
case CpuVendor.AMD, _:
return AMD_TEMPLATES
case CpuVendor.ARM, CpuModel.ARM_NEOVERSE_N1 if host_linux >= (6, 1):
- return AARCH64_CUSTOM_CPU_TEMPLATES_G2
+ return ["v1n1"]
case CpuVendor.ARM, CpuModel.ARM_NEOVERSE_V1 if host_linux >= (6, 1):
- return AARCH64_CUSTOM_CPU_TEMPLATES_G3
+ return ["v1n1", "aarch64_with_sve_and_pac"]
+ case CpuVendor.ARM, CpuModel.ARM_NEOVERSE_V1:
+ return ["aarch64_with_sve_and_pac"]
case _:
return []
diff --git a/tests/framework/utils_cpuid.py b/tests/framework/utils_cpuid.py
index 65e953f43ac..4303e3ba967 100644
--- a/tests/framework/utils_cpuid.py
+++ b/tests/framework/utils_cpuid.py
@@ -10,6 +10,8 @@
from framework.utils import check_output
from framework.utils_imdsv2 import imdsv2_get
+CPU_FEATURES_CMD = r"lscpu |grep -oP '^Flags:\s+\K.+'"
+
class CpuVendor(Enum):
"""CPU vendors enum."""
diff --git a/tests/framework/utils_drive.py b/tests/framework/utils_drive.py
index 2e67ff41f39..7bb623d73e0 100644
--- a/tests/framework/utils_drive.py
+++ b/tests/framework/utils_drive.py
@@ -23,17 +23,15 @@ class VhostUserBlkBackendType(Enum):
CROSVM = "Crosvm"
-def partuuid_and_disk_path(rootfs_ubuntu_22, disk_path):
+def partuuid_and_disk_path(rootfs, disk_path):
"""
We create a new file with specified path, get its partuuid and use it as a rootfs.
"""
- initial_size = rootfs_ubuntu_22.stat().st_size + 50 * MB
+ initial_size = rootfs.stat().st_size + 50 * MB
disk_path.touch()
os.truncate(disk_path, initial_size)
check_output(f"echo type=83 | sfdisk --no-tell-kernel {str(disk_path)}", shell=True)
- check_output(
- f"dd bs=1M seek=1 if={str(rootfs_ubuntu_22)} of={disk_path}", shell=True
- )
+ check_output(f"dd bs=1M seek=1 if={str(rootfs)} of={disk_path}", shell=True)
ptuuid = check_output(
f"blkid -s PTUUID -o value {disk_path}", shell=True, encoding="ascii"
).strip()
diff --git a/tests/host_tools/network.py b/tests/host_tools/network.py
index e1c53020fd0..7877b914d28 100644
--- a/tests/host_tools/network.py
+++ b/tests/host_tools/network.py
@@ -5,6 +5,7 @@
import ipaddress
import random
import string
+import subprocess
from dataclasses import dataclass, field
from pathlib import Path
@@ -67,9 +68,14 @@ def __init__(self, netns, ssh_key: Path, host, user, *, on_error=None):
self._on_error = on_error
+ @property
+ def user_host(self):
+ """remote address for in SSH format @"""
+ return f"{self.user}@{self.host}"
+
def remote_path(self, path):
"""Convert a path to remote"""
- return f"{self.user}@{self.host}:{path}"
+ return f"{self.user_host}:{path}"
def _scp(self, path1, path2, options):
"""Copy files to/from the VM using scp."""
@@ -111,21 +117,12 @@ def run(self, cmd_string, timeout=None, *, check=False, debug=False):
If `debug` is set, pass `-vvv` to `ssh`. Note that this will clobber stderr.
"""
- command = [
- "ssh",
- *self.options,
- f"{self.user}@{self.host}",
- cmd_string,
- ]
+ command = ["ssh", *self.options, self.user_host, cmd_string]
if debug:
command.insert(1, "-vvv")
- return self._exec(
- command,
- timeout,
- check=check,
- )
+ return self._exec(command, timeout, check=check)
def check_output(self, cmd_string, timeout=None, *, debug=False):
"""Same as `run`, but raises an exception on non-zero return code of remote command"""
@@ -144,6 +141,27 @@ def _exec(self, cmd, timeout=None, check=False):
raise
+ # pylint:disable=invalid-name
+ def Popen(
+ self,
+ cmd: str,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ **kwargs,
+ ) -> subprocess.Popen:
+ """Execute the command in the guest and return a Popen object.
+
+ pop = uvm.ssh.Popen("while true; do echo $(date -Is) $RANDOM; sleep 1; done")
+ pop.stdout.read(16)
+ """
+ cmd = ["ssh", *self.options, self.user_host, cmd]
+ if self.netns is not None:
+ cmd = ["ip", "netns", "exec", self.netns] + cmd
+ return subprocess.Popen(
+ cmd, stdin=stdin, stdout=stdout, stderr=stderr, **kwargs
+ )
+
def mac_from_ip(ip_address):
"""Create a MAC address based on the provided IP.
diff --git a/tests/integration_tests/functional/test_api.py b/tests/integration_tests/functional/test_api.py
index 5aebe7b5265..27366529c39 100644
--- a/tests/integration_tests/functional/test_api.py
+++ b/tests/integration_tests/functional/test_api.py
@@ -895,7 +895,7 @@ def _drive_patch(test_microvm):
"is_root_device": True,
"cache_type": "Unsafe",
"is_read_only": True,
- "path_on_host": "/ubuntu-22.04.squashfs",
+ "path_on_host": "/" + test_microvm.rootfs_file.name,
"rate_limiter": None,
"io_engine": "Sync",
"socket": None,
@@ -1226,7 +1226,7 @@ def test_get_full_config(uvm_plain):
"is_root_device": True,
"cache_type": "Unsafe",
"is_read_only": True,
- "path_on_host": "/ubuntu-22.04.squashfs",
+ "path_on_host": "/" + test_microvm.rootfs_file.name,
"rate_limiter": None,
"io_engine": "Sync",
"socket": None,
diff --git a/tests/integration_tests/functional/test_cpu_features_aarch64.py b/tests/integration_tests/functional/test_cpu_features_aarch64.py
index a1066da21a5..8357f54b568 100644
--- a/tests/integration_tests/functional/test_cpu_features_aarch64.py
+++ b/tests/integration_tests/functional/test_cpu_features_aarch64.py
@@ -2,13 +2,16 @@
# SPDX-License-Identifier: Apache-2.0
"""Tests for the CPU features for aarch64."""
+import os
import platform
import re
import pytest
import framework.utils_cpuid as cpuid_utils
-from framework.utils_cpuid import CpuModel
+from framework import utils
+from framework.properties import global_props
+from framework.utils_cpuid import CPU_FEATURES_CMD, CpuModel
PLATFORM = platform.machine()
@@ -48,7 +51,7 @@ def _check_cpu_features_arm(test_microvm, guest_kv, template_name=None):
case CpuModel.ARM_NEOVERSE_V1, _, None:
expected_cpu_features = DEFAULT_G3_FEATURES_5_10
- _, stdout, _ = test_microvm.ssh.check_output(r"lscpu |grep -oP '^Flags:\s+\K.+'")
+ _, stdout, _ = test_microvm.ssh.check_output(CPU_FEATURES_CMD)
flags = set(stdout.strip().split(" "))
assert flags == expected_cpu_features
@@ -67,12 +70,90 @@ def get_cpu_template_dir(cpu_template):
PLATFORM != "aarch64",
reason="This is aarch64 specific test.",
)
-def test_default_cpu_features(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_host_vs_guest_cpu_features_aarch64(uvm_nano):
+ """Check CPU features host vs guest"""
+
+ vm = uvm_nano
+ vm.add_net_iface()
+ vm.start()
+ host_feats = set(utils.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))
+ guest_feats = set(vm.ssh.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))
+
+ cpu_model = cpuid_utils.get_cpu_model_name()
+ match cpu_model:
+ case CpuModel.ARM_NEOVERSE_N1:
+ expected_guest_minus_host = set()
+ expected_host_minus_guest = set()
+
+ # Upstream kernel v6.11+ hides "ssbs" from "lscpu" on Neoverse-N1 and Neoverse-V1 since
+ # they have an errata whereby an MSR to the SSBS special-purpose register does not
+ # affect subsequent speculative instructions, permitting speculative store bypassing for
+ # a window of time.
+ # https://github.com/torvalds/linux/commit/adeec61a4723fd3e39da68db4cc4d924e6d7f641
+ #
+ # While Amazon Linux kernels (v5.10 and v6.1) backported the above commit, our test
+ # ubuntu kernel (v6.8) and our guest kernels (v5.10 and v6.1) don't pick it.
+ host_has_ssbs = global_props.host_os not in {
+ "amzn2",
+ "amzn2023",
+ } and global_props.host_linux_version_tpl < (6, 11)
+ guest_has_ssbs = vm.guest_kernel_version < (6, 11)
+
+ if host_has_ssbs and not guest_has_ssbs:
+ expected_host_minus_guest |= {"ssbs"}
+ if not host_has_ssbs and guest_has_ssbs:
+ expected_guest_minus_host |= {"ssbs"}
+
+ assert host_feats - guest_feats == expected_host_minus_guest
+ assert guest_feats - host_feats == expected_guest_minus_host
+ case CpuModel.ARM_NEOVERSE_V1:
+ expected_guest_minus_host = set()
+ # KVM does not enable PAC or SVE features by default
+ # and Firecracker does not enable them either.
+ expected_host_minus_guest = {
+ "paca",
+ "pacg",
+ "sve",
+ "svebf16",
+ "svei8mm",
+ }
+
+ # Upstream kernel v6.11+ hides "ssbs" from "lscpu" on Neoverse-N1 and Neoverse-V1 since
+ # they have an errata whereby an MSR to the SSBS special-purpose register does not
+ # affect subsequent speculative instructions, permitting speculative store bypassing for
+ # a window of time.
+ # https://github.com/torvalds/linux/commit/adeec61a4723fd3e39da68db4cc4d924e6d7f641
+ #
+ # While Amazon Linux kernels (v5.10 and v6.1) backported the above commit, our test
+ # ubuntu kernel (v6.8) and our guest kernels (v5.10 and v6.1) don't pick it.
+ host_has_ssbs = global_props.host_os not in {
+ "amzn2",
+ "amzn2023",
+ } and global_props.host_linux_version_tpl < (6, 11)
+ guest_has_ssbs = vm.guest_kernel_version < (6, 11)
+
+ if host_has_ssbs and not guest_has_ssbs:
+ expected_host_minus_guest |= {"ssbs"}
+ if not host_has_ssbs and guest_has_ssbs:
+ expected_guest_minus_host |= {"ssbs"}
+
+ assert host_feats - guest_feats == expected_host_minus_guest
+ assert guest_feats - host_feats == expected_guest_minus_host
+ case _:
+ if os.environ.get("BUILDKITE") is not None:
+ assert False, f"Cpu model {cpu_model} is not supported"
+
+
+@pytest.mark.skipif(
+ PLATFORM != "aarch64",
+ reason="This is aarch64 specific test.",
+)
+def test_default_cpu_features(microvm_factory, guest_kernel, rootfs):
"""
Check the CPU features for a microvm with the specified config.
"""
- vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False)
+ vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
vm.spawn()
vm.basic_config()
vm.add_net_iface()
@@ -86,13 +167,13 @@ def test_default_cpu_features(microvm_factory, guest_kernel, rootfs_ubuntu_22):
reason="This is aarch64 specific test.",
)
def test_cpu_features_with_static_template(
- microvm_factory, guest_kernel, rootfs_ubuntu_22, cpu_template
+ microvm_factory, guest_kernel, rootfs, cpu_template
):
"""
Check the CPU features for a microvm with the specified config.
"""
- vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False)
+ vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
vm.spawn()
vm.basic_config(cpu_template=cpu_template)
vm.add_net_iface()
@@ -114,13 +195,13 @@ def test_cpu_features_with_static_template(
reason="This is aarch64 specific test.",
)
def test_cpu_features_with_custom_template(
- microvm_factory, guest_kernel, rootfs_ubuntu_22, custom_cpu_template
+ microvm_factory, guest_kernel, rootfs, custom_cpu_template
):
"""
Check the CPU features for a microvm with the specified config.
"""
- vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False)
+ vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
vm.spawn()
vm.basic_config()
vm.api.cpu_config.put(**custom_cpu_template["template"])
diff --git a/tests/integration_tests/functional/test_cpu_features.py b/tests/integration_tests/functional/test_cpu_features_x86_64.py
similarity index 78%
rename from tests/integration_tests/functional/test_cpu_features.py
rename to tests/integration_tests/functional/test_cpu_features_x86_64.py
index 225bec620eb..23818ddc6b1 100644
--- a/tests/integration_tests/functional/test_cpu_features.py
+++ b/tests/integration_tests/functional/test_cpu_features_x86_64.py
@@ -22,6 +22,7 @@
from framework.defs import SUPPORTED_HOST_KERNELS
from framework.properties import global_props
from framework.utils_cpu_templates import SUPPORTED_CPU_TEMPLATES
+from framework.utils_cpuid import CPU_FEATURES_CMD, CpuModel
PLATFORM = platform.machine()
UNSUPPORTED_HOST_KERNEL = (
@@ -203,6 +204,293 @@ def test_brand_string(uvm_plain_any):
assert False
+@pytest.mark.skipif(
+ PLATFORM != "x86_64",
+ reason="This is x86_64 specific test.",
+)
+def test_host_vs_guest_cpu_features_x86_64(uvm_nano):
+ """Check CPU features host vs guest"""
+
+ vm = uvm_nano
+ vm.add_net_iface()
+ vm.start()
+ host_feats = set(utils.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))
+ guest_feats = set(vm.ssh.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))
+
+ cpu_model = cpuid_utils.get_cpu_codename()
+ match cpu_model:
+ case CpuModel.AMD_MILAN:
+ host_guest_diff_5_10 = {
+ "amd_ppin",
+ "aperfmperf",
+ "bpext",
+ "cat_l3",
+ "cdp_l3",
+ "cpb",
+ "cqm",
+ "cqm_llc",
+ "cqm_mbm_local",
+ "cqm_mbm_total",
+ "cqm_occup_llc",
+ "decodeassists",
+ "extapic",
+ "extd_apicid",
+ "flushbyasid",
+ "hw_pstate",
+ "ibs",
+ "irperf",
+ "lbrv",
+ "mba",
+ "monitor",
+ "mwaitx",
+ "overflow_recov",
+ "pausefilter",
+ "perfctr_llc",
+ "perfctr_nb",
+ "pfthreshold",
+ "rdpru",
+ "rdt_a",
+ "sev",
+ "sev_es",
+ "skinit",
+ "smca",
+ "sme",
+ "succor",
+ "svm_lock",
+ "tce",
+ "tsc_scale",
+ "v_vmsave_vmload",
+ "vgif",
+ "vmcb_clean",
+ "wdt",
+ }
+
+ host_guest_diff_6_1 = host_guest_diff_5_10 - {
+ "lbrv",
+ "pausefilter",
+ "pfthreshold",
+ "sme",
+ "tsc_scale",
+ "v_vmsave_vmload",
+ "vgif",
+ "vmcb_clean",
+ } | {"brs", "rapl", "v_spec_ctrl"}
+
+ if global_props.host_linux_version_tpl < (6, 1):
+ assert host_feats - guest_feats == host_guest_diff_5_10
+ else:
+ assert host_feats - guest_feats == host_guest_diff_6_1
+
+ assert guest_feats - host_feats == {
+ "hypervisor",
+ "tsc_adjust",
+ "tsc_deadline_timer",
+ "tsc_known_freq",
+ }
+ case CpuModel.INTEL_SKYLAKE:
+ assert host_feats - guest_feats == {
+ "acpi",
+ "aperfmperf",
+ "arch_perfmon",
+ "art",
+ "bts",
+ "cat_l3",
+ "cdp_l3",
+ "cqm",
+ "cqm_llc",
+ "cqm_mbm_local",
+ "cqm_mbm_total",
+ "cqm_occup_llc",
+ "dca",
+ "ds_cpl",
+ "dtes64",
+ "dtherm",
+ "dts",
+ "epb",
+ "ept",
+ "ept_ad",
+ "est",
+ "flexpriority",
+ "flush_l1d",
+ "hwp",
+ "hwp_act_window",
+ "hwp_epp",
+ "hwp_pkg_req",
+ "ida",
+ "intel_ppin",
+ "intel_pt",
+ "mba",
+ "monitor",
+ "pbe",
+ "pdcm",
+ "pebs",
+ "pln",
+ "pts",
+ "rdt_a",
+ "sdbg",
+ "smx",
+ "tm",
+ "tm2",
+ "tpr_shadow",
+ "vmx",
+ "vnmi",
+ "vpid",
+ "xtpr",
+ }
+ assert guest_feats - host_feats == {
+ "hypervisor",
+ "tsc_known_freq",
+ "umip",
+ }
+ case CpuModel.INTEL_CASCADELAKE:
+ expected_host_minus_guest = {
+ "acpi",
+ "aperfmperf",
+ "arch_perfmon",
+ "art",
+ "bts",
+ "cat_l3",
+ "cdp_l3",
+ "cqm",
+ "cqm_llc",
+ "cqm_mbm_local",
+ "cqm_mbm_total",
+ "cqm_occup_llc",
+ "dca",
+ "ds_cpl",
+ "dtes64",
+ "dtherm",
+ "dts",
+ "epb",
+ "ept",
+ "ept_ad",
+ "est",
+ "flexpriority",
+ "flush_l1d",
+ "hwp",
+ "hwp_act_window",
+ "hwp_epp",
+ "hwp_pkg_req",
+ "ida",
+ "intel_ppin",
+ "intel_pt",
+ "mba",
+ "monitor",
+ "pbe",
+ "pdcm",
+ "pebs",
+ "pln",
+ "pts",
+ "rdt_a",
+ "sdbg",
+ "smx",
+ "tm",
+ "tm2",
+ "tpr_shadow",
+ "vmx",
+ "vnmi",
+ "vpid",
+ "xtpr",
+ }
+ expected_guest_minus_host = {
+ "hypervisor",
+ "tsc_known_freq",
+ "umip",
+ }
+
+ # Linux kernel v6.4+ passes through the CPUID bit for "flush_l1d" to guests.
+ # https://github.com/torvalds/linux/commit/45cf86f26148e549c5ba4a8ab32a390e4bde216e
+ #
+ # Our test ubuntu host kernel is v6.8 and has the commit.
+ if global_props.host_linux_version_tpl >= (6, 4):
+ expected_host_minus_guest -= {"flush_l1d"}
+
+ # Linux kernel v6.6+ drops the "invpcid_single" synthetic feature bit.
+ # https://github.com/torvalds/linux/commit/54e3d9434ef61b97fd3263c141b928dc5635e50d
+ #
+ # Our test ubuntu host kernel is v6.8 and has the commit.
+ host_has_invpcid_single = global_props.host_linux_version_tpl < (6, 6)
+ guest_has_invpcid_single = vm.guest_kernel_version < (6, 6)
+ if host_has_invpcid_single and not guest_has_invpcid_single:
+ expected_host_minus_guest |= {"invpcid_single"}
+ if not host_has_invpcid_single and guest_has_invpcid_single:
+ expected_guest_minus_host |= {"invpcid_single"}
+
+ assert host_feats - guest_feats == expected_host_minus_guest
+ assert guest_feats - host_feats == expected_guest_minus_host
+ case CpuModel.INTEL_ICELAKE:
+ host_guest_diff_5_10 = {
+ "dtes64",
+ "hwp_act_window",
+ "pdcm",
+ "acpi",
+ "aperfmperf",
+ "arch_perfmon",
+ "art",
+ "bts",
+ "cat_l3",
+ "cqm",
+ "cqm_llc",
+ "cqm_mbm_local",
+ "cqm_mbm_total",
+ "cqm_occup_llc",
+ "dca",
+ "ds_cpl",
+ "dtherm",
+ "dts",
+ "epb",
+ "ept",
+ "ept_ad",
+ "est",
+ "flexpriority",
+ "flush_l1d",
+ "hwp",
+ "hwp_epp",
+ "hwp_pkg_req",
+ "ida",
+ "intel_ppin",
+ "intel_pt",
+ "mba",
+ "monitor",
+ "pbe",
+ "pconfig",
+ "pebs",
+ "pln",
+ "pts",
+ "rdt_a",
+ "sdbg",
+ "smx",
+ "split_lock_detect",
+ "tm",
+ "tm2",
+ "tme",
+ "tpr_shadow",
+ "vmx",
+ "vnmi",
+ "vpid",
+ "xtpr",
+ }
+ host_guest_diff_6_1 = host_guest_diff_5_10 - {
+ "bts",
+ "dtes64",
+ "dts",
+ "pebs",
+ }
+
+ if global_props.host_linux_version_tpl < (6, 1):
+ assert host_feats - guest_feats == host_guest_diff_5_10
+ else:
+ assert host_feats - guest_feats == host_guest_diff_6_1
+
+ assert guest_feats - host_feats == {
+ "hypervisor",
+ "tsc_known_freq",
+ }
+ case _:
+ if os.environ.get("BUILDKITE") is not None:
+ assert False, f"Cpu model {cpu_model} is not supported"
+
+
# From the `Intel® 64 Architecture x2APIC Specification`
# (https://courses.cs.washington.edu/courses/cse451/24wi/documentation/x2apic.pdf):
# > The X2APIC MSRs cannot to be loaded and stored on VMX transitions. A VMX transition fails
@@ -272,7 +560,7 @@ def msr_cpu_template_fxt(request):
@pytest.mark.timeout(900)
@pytest.mark.nonci
def test_cpu_rdmsr(
- microvm_factory, msr_cpu_template, guest_kernel, rootfs_ubuntu_22, results_dir
+ microvm_factory, msr_cpu_template, guest_kernel, rootfs, results_dir
):
"""
Test MSRs that are available to the guest.
@@ -307,7 +595,7 @@ def test_cpu_rdmsr(
"""
vcpus, guest_mem_mib = 1, 1024
- vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False)
+ vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
vm.spawn()
vm.add_net_iface()
vm.basic_config(
@@ -376,9 +664,7 @@ def dump_msr_state_to_file(dump_fname, ssh_conn, shared_names):
)
@pytest.mark.timeout(900)
@pytest.mark.nonci
-def test_cpu_wrmsr_snapshot(
- microvm_factory, guest_kernel, rootfs_ubuntu_22, msr_cpu_template
-):
+def test_cpu_wrmsr_snapshot(microvm_factory, guest_kernel, rootfs, msr_cpu_template):
"""
This is the first part of the test verifying
that MSRs retain their values after restoring from a snapshot.
@@ -398,7 +684,7 @@ def test_cpu_wrmsr_snapshot(
shared_names = SNAPSHOT_RESTORE_SHARED_NAMES
vcpus, guest_mem_mib = 1, 1024
- vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False)
+ vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
vm.spawn()
vm.add_net_iface()
vm.basic_config(
@@ -533,9 +819,7 @@ def dump_cpuid_to_file(dump_fname, ssh_conn):
)
@pytest.mark.timeout(900)
@pytest.mark.nonci
-def test_cpu_cpuid_snapshot(
- microvm_factory, guest_kernel, rootfs_ubuntu_22, msr_cpu_template
-):
+def test_cpu_cpuid_snapshot(microvm_factory, guest_kernel, rootfs, msr_cpu_template):
"""
This is the first part of the test verifying
that CPUID remains the same after restoring from a snapshot.
@@ -551,7 +835,7 @@ def test_cpu_cpuid_snapshot(
vm = microvm_factory.build(
kernel=guest_kernel,
- rootfs=rootfs_ubuntu_22,
+ rootfs=rootfs,
)
vm.spawn()
vm.add_net_iface()
@@ -927,9 +1211,9 @@ def check_enabled_features(test_microvm, cpu_template):
"enhanced REP MOVSB/STOSB": "true",
"SMAP: supervisor mode access prevention": "true",
# xsave_0xd_0
- "XCR0 supported: x87 state": "true",
- "XCR0 supported: SSE state": "true",
- "XCR0 supported: AVX state": "true",
+ "x87 state": "true",
+ "SSE state": "true",
+ "AVX state": "true",
# xsave_0xd_1
"XSAVEOPT instruction": "true",
# extended_080000001_edx
diff --git a/tests/integration_tests/functional/test_drive_vhost_user.py b/tests/integration_tests/functional/test_drive_vhost_user.py
index 31a11a75661..79cc41b0f3a 100644
--- a/tests/integration_tests/functional/test_drive_vhost_user.py
+++ b/tests/integration_tests/functional/test_drive_vhost_user.py
@@ -34,7 +34,7 @@ def _check_drives(test_microvm, assert_dict, keys_array):
assert blockdev_out_line_cols[col] == assert_dict[key]
-def test_vhost_user_block(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_vhost_user_block(microvm_factory, guest_kernel, rootfs):
"""
This test simply tries to boot a VM with
vhost-user-block as a root device.
@@ -44,13 +44,11 @@ def test_vhost_user_block(microvm_factory, guest_kernel, rootfs_ubuntu_22):
# We need to setup ssh keys manually because we did not specify rootfs
# in microvm_factory.build method
- ssh_key = rootfs_ubuntu_22.with_suffix(".id_rsa")
+ ssh_key = rootfs.with_suffix(".id_rsa")
vm.ssh_key = ssh_key
vm.spawn()
vm.basic_config(add_root_device=False)
- vm.add_vhost_user_drive(
- "rootfs", rootfs_ubuntu_22, is_root_device=True, is_read_only=True
- )
+ vm.add_vhost_user_drive("rootfs", rootfs, is_root_device=True, is_read_only=True)
vm.add_net_iface()
vhost_user_block_metrics = FcDeviceMetrics(
"vhost_user_block", 1, aggr_supported=False
@@ -67,7 +65,7 @@ def test_vhost_user_block(microvm_factory, guest_kernel, rootfs_ubuntu_22):
vhost_user_block_metrics.validate(vm)
-def test_vhost_user_block_read_write(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_vhost_user_block_read_write(microvm_factory, guest_kernel, rootfs):
"""
This test simply tries to boot a VM with
vhost-user-block as a root device.
@@ -78,14 +76,14 @@ def test_vhost_user_block_read_write(microvm_factory, guest_kernel, rootfs_ubunt
# We need to setup ssh keys manually because we did not specify rootfs
# in microvm_factory.build method
- ssh_key = rootfs_ubuntu_22.with_suffix(".id_rsa")
+ ssh_key = rootfs.with_suffix(".id_rsa")
vm.ssh_key = ssh_key
vm.spawn()
vm.basic_config(add_root_device=False)
# Create a rw rootfs file that is unique to the microVM
rootfs_rw = Path(vm.chroot()) / "rootfs"
- shutil.copy(rootfs_ubuntu_22, rootfs_rw)
+ shutil.copy(rootfs, rootfs_rw)
vm.add_vhost_user_drive("rootfs", rootfs_rw, is_root_device=True)
vm.add_net_iface()
@@ -100,7 +98,7 @@ def test_vhost_user_block_read_write(microvm_factory, guest_kernel, rootfs_ubunt
_check_drives(vm, assert_dict, assert_dict.keys())
-def test_vhost_user_block_disconnect(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_vhost_user_block_disconnect(microvm_factory, guest_kernel, rootfs):
"""
Test that even if backend is killed, Firecracker is still responsive.
"""
@@ -109,13 +107,11 @@ def test_vhost_user_block_disconnect(microvm_factory, guest_kernel, rootfs_ubunt
# We need to set up ssh keys manually because we did not specify rootfs
# in microvm_factory.build method
- ssh_key = rootfs_ubuntu_22.with_suffix(".id_rsa")
+ ssh_key = rootfs.with_suffix(".id_rsa")
vm.ssh_key = ssh_key
vm.spawn()
vm.basic_config(add_root_device=False)
- vm.add_vhost_user_drive(
- "rootfs", rootfs_ubuntu_22, is_root_device=True, is_read_only=True
- )
+ vm.add_vhost_user_drive("rootfs", rootfs, is_root_device=True, is_read_only=True)
vm.add_net_iface()
vm.start()
@@ -127,7 +123,7 @@ def test_vhost_user_block_disconnect(microvm_factory, guest_kernel, rootfs_ubunt
_config = vm.api.vm_config.get().json()
-def test_device_ordering(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_device_ordering(microvm_factory, guest_kernel, rootfs):
"""
Verify device ordering.
@@ -139,7 +135,7 @@ def test_device_ordering(microvm_factory, guest_kernel, rootfs_ubuntu_22):
# We need to setup ssh keys manually because we did not specify rootfs
# in microvm_factory.build method
- ssh_key = rootfs_ubuntu_22.with_suffix(".id_rsa")
+ ssh_key = rootfs.with_suffix(".id_rsa")
vm.ssh_key = ssh_key
vm.spawn()
vm.basic_config(add_root_device=False)
@@ -150,9 +146,7 @@ def test_device_ordering(microvm_factory, guest_kernel, rootfs_ubuntu_22):
vm.add_drive("scratch1", fs1.path)
# Adding second block device (rootfs)
- vm.add_vhost_user_drive(
- "rootfs", rootfs_ubuntu_22, is_root_device=True, is_read_only=True
- )
+ vm.add_vhost_user_drive("rootfs", rootfs, is_root_device=True, is_read_only=True)
# Adding third block device.
fs2 = drive_tools.FilesystemFile(os.path.join(vm.fsfiles, "scratch2"), size=512)
@@ -160,7 +154,7 @@ def test_device_ordering(microvm_factory, guest_kernel, rootfs_ubuntu_22):
# Create a rw rootfs file that is unique to the microVM
rootfs_rw = Path(vm.chroot()) / "rootfs"
- shutil.copy(rootfs_ubuntu_22, rootfs_rw)
+ shutil.copy(rootfs, rootfs_rw)
# Adding forth block device.
vm.add_vhost_user_drive("dummy_rootfs", rootfs_rw)
@@ -171,7 +165,7 @@ def test_device_ordering(microvm_factory, guest_kernel, rootfs_ubuntu_22):
)
vm.start()
- rootfs_size = rootfs_ubuntu_22.stat().st_size
+ rootfs_size = rootfs.stat().st_size
# The devices were added in this order: fs1, rootfs, fs2. fs3
# However, the rootfs is the root device and goes first,
@@ -203,7 +197,7 @@ def test_device_ordering(microvm_factory, guest_kernel, rootfs_ubuntu_22):
def test_partuuid_boot(
microvm_factory,
guest_kernel,
- rootfs_ubuntu_22,
+ rootfs,
):
"""
Test the output reported by blockdev when booting with PARTUUID.
@@ -213,15 +207,13 @@ def test_partuuid_boot(
# We need to setup ssh keys manually because we did not specify rootfs
# in microvm_factory.build method
- ssh_key = rootfs_ubuntu_22.with_suffix(".id_rsa")
+ ssh_key = rootfs.with_suffix(".id_rsa")
vm.ssh_key = ssh_key
vm.spawn()
vm.basic_config(add_root_device=False)
# Create a rootfs with partuuid unique to this microVM
- partuuid, disk_path = partuuid_and_disk_path(
- rootfs_ubuntu_22, Path(vm.chroot()) / "disk.img"
- )
+ partuuid, disk_path = partuuid_and_disk_path(rootfs, Path(vm.chroot()) / "disk.img")
vm.add_vhost_user_drive(
"1", disk_path, is_root_device=True, partuuid=partuuid, is_read_only=True
@@ -238,7 +230,7 @@ def test_partuuid_boot(
_check_drives(vm, assert_dict, assert_dict.keys())
-def test_partuuid_update(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_partuuid_update(microvm_factory, guest_kernel, rootfs):
"""
Test successful switching from PARTUUID boot to /dev/vda boot.
"""
@@ -247,7 +239,7 @@ def test_partuuid_update(microvm_factory, guest_kernel, rootfs_ubuntu_22):
# We need to setup ssh keys manually because we did not specify rootfs
# in microvm_factory.build method
- ssh_key = rootfs_ubuntu_22.with_suffix(".id_rsa")
+ ssh_key = rootfs.with_suffix(".id_rsa")
vm.ssh_key = ssh_key
vm.spawn()
vm.basic_config(add_root_device=False)
@@ -256,16 +248,14 @@ def test_partuuid_update(microvm_factory, guest_kernel, rootfs_ubuntu_22):
# Add the root block device specified through PARTUUID.
vm.add_vhost_user_drive(
"rootfs",
- rootfs_ubuntu_22,
+ rootfs,
is_root_device=True,
partuuid="0eaa91a0-01",
is_read_only=True,
)
# Adding a drive with the same ID creates another backend with another socket.
- vm.add_vhost_user_drive(
- "rootfs", rootfs_ubuntu_22, is_root_device=True, is_read_only=True
- )
+ vm.add_vhost_user_drive("rootfs", rootfs, is_root_device=True, is_read_only=True)
vhost_user_block_metrics = FcDeviceMetrics(
"vhost_user_block", 1, aggr_supported=False
diff --git a/tests/integration_tests/functional/test_drive_virtio.py b/tests/integration_tests/functional/test_drive_virtio.py
index dbebefa11a1..9c61ead56a9 100644
--- a/tests/integration_tests/functional/test_drive_virtio.py
+++ b/tests/integration_tests/functional/test_drive_virtio.py
@@ -14,12 +14,12 @@
@pytest.fixture
-def partuuid_and_disk_path_tmpfs(rootfs_ubuntu_22, tmp_path):
+def partuuid_and_disk_path_tmpfs(rootfs, tmp_path):
"""
We create a new file in tmpfs, get its partuuid and use it as a rootfs.
"""
disk_path = tmp_path / "disk.img"
- yield partuuid_and_disk_path(rootfs_ubuntu_22, disk_path)
+ yield partuuid_and_disk_path(rootfs, disk_path)
disk_path.unlink()
diff --git a/tests/integration_tests/functional/test_kernel_cmdline.py b/tests/integration_tests/functional/test_kernel_cmdline.py
index 14e369790f1..9707eb8a92c 100644
--- a/tests/integration_tests/functional/test_kernel_cmdline.py
+++ b/tests/integration_tests/functional/test_kernel_cmdline.py
@@ -29,4 +29,4 @@ def test_init_params(uvm_plain):
serial = Serial(vm)
serial.open()
# If the string does not show up, the test will fail.
- serial.rx(token="Ubuntu 22.04")
+ serial.rx(token="Ubuntu 24.04")
diff --git a/tests/integration_tests/functional/test_net.py b/tests/integration_tests/functional/test_net.py
index 12980c727b2..a804b8f90a8 100644
--- a/tests/integration_tests/functional/test_net.py
+++ b/tests/integration_tests/functional/test_net.py
@@ -10,7 +10,11 @@
from framework import utils
# The iperf version to run this tests with
-IPERF_BINARY = "iperf3"
+IPERF_BINARY_GUEST = "iperf3"
+# We are using iperf3-vsock instead of a regular iperf3,
+# because iperf3 3.16+ crashes on aarch64 sometimes
+# when running this test.
+IPERF_BINARY_HOST = "iperf3-vsock"
def test_high_ingress_traffic(uvm_plain_any):
@@ -33,15 +37,15 @@ def test_high_ingress_traffic(uvm_plain_any):
test_microvm.start()
# Start iperf3 server on the guest.
- test_microvm.ssh.run("{} -sD\n".format(IPERF_BINARY))
+ test_microvm.ssh.check_output("{} -sD\n".format(IPERF_BINARY_GUEST))
time.sleep(1)
# Start iperf3 client on the host. Send 1Gbps UDP traffic.
# If the net device breaks, iperf will freeze. We have to use a timeout.
- utils.run_cmd(
- "timeout 30 {} {} -c {} -u -V -b 1000000000 -t 30".format(
+ utils.check_output(
+ "timeout 31 {} {} -c {} -u -V -b 1000000000 -t 30".format(
test_microvm.netns.cmd_prefix(),
- IPERF_BINARY,
+ IPERF_BINARY_HOST,
guest_ip,
),
)
@@ -95,7 +99,7 @@ def run_udp_offload_test(vm):
# Start a UDP server in the guest
# vm.ssh.check_output(f"nohup socat UDP-LISTEN:{port} - > {out_filename} &")
vm.ssh.check_output(
- f"nohup socat UDP-LISTEN:{port} OPEN:{out_filename},creat > /dev/null 2>&1 &"
+ f"nohup socat UDP4-LISTEN:{port} OPEN:{out_filename},creat > /dev/null 2>&1 &"
)
# Try to send a UDP message from host with UDP offload enabled
@@ -123,11 +127,11 @@ def test_tap_offload_booted(uvm_plain_any):
run_udp_offload_test(vm)
-def test_tap_offload_restored(microvm_factory, guest_kernel, rootfs_ubuntu_22):
+def test_tap_offload_restored(microvm_factory, guest_kernel, rootfs):
"""
Verify that tap offload features are configured for a restored VM.
"""
- src = microvm_factory.build(guest_kernel, rootfs_ubuntu_22, monitor_memory=False)
+ src = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
src.spawn()
src.basic_config()
src.add_net_iface()
diff --git a/tests/integration_tests/functional/test_snapshot_not_losing_dirty_pages.py b/tests/integration_tests/functional/test_snapshot_not_losing_dirty_pages.py
index 812e706b926..5584cfceac8 100644
--- a/tests/integration_tests/functional/test_snapshot_not_losing_dirty_pages.py
+++ b/tests/integration_tests/functional/test_snapshot_not_losing_dirty_pages.py
@@ -25,14 +25,14 @@ def mount_tmpfs_small(worker_id):
def test_diff_snapshot_works_after_error(
- microvm_factory, guest_kernel_linux_5_10, rootfs_ubuntu_22, mount_tmpfs_small
+ microvm_factory, guest_kernel_linux_5_10, rootfs, mount_tmpfs_small
):
"""
Test that if a partial snapshot errors it will work after and not lose data
"""
uvm = microvm_factory.build(
guest_kernel_linux_5_10,
- rootfs_ubuntu_22,
+ rootfs,
jailer_kwargs={"chroot_base": mount_tmpfs_small},
)
diff --git a/tests/integration_tests/functional/test_snapshot_phase1.py b/tests/integration_tests/functional/test_snapshot_phase1.py
new file mode 100644
index 00000000000..7436c19d875
--- /dev/null
+++ b/tests/integration_tests/functional/test_snapshot_phase1.py
@@ -0,0 +1,108 @@
+# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+# SPDX-License-Identifier: Apache-2.0
+
+"""
+Creates snapshots for other tests like test_snapshot_restore_cross_kernel.py
+"""
+
+import json
+import platform
+import re
+
+import pytest
+
+from framework.utils import (
+ configure_mmds,
+ generate_mmds_get_request,
+ generate_mmds_session_token,
+)
+
+if platform.machine() != "x86_64":
+ pytestmark = pytest.mark.skip("only x86_64 architecture supported")
+
+# Default IPv4 address to route MMDS requests.
+IPV4_ADDRESS = "169.254.169.254"
+NET_IFACE_FOR_MMDS = "eth3"
+
+
+@pytest.mark.nonci
+def test_snapshot_phase1(
+ microvm_factory, guest_kernel, rootfs, cpu_template_any, results_dir
+):
+ """Create a snapshot and save it to disk"""
+
+ vm = microvm_factory.build(guest_kernel, rootfs, monitor_memory=False)
+ vm.spawn(log_level="Info")
+ vm.add_net_iface()
+
+ static_cpu_template = None
+ cpu_template_name = "None"
+ if isinstance(cpu_template_any, str):
+ static_cpu_template = cpu_template_any
+ cpu_template_name = f"static_{cpu_template_any}"
+ elif isinstance(cpu_template_any, dict):
+ vm.api.cpu_config.put(**cpu_template_any["template"])
+ cpu_template_name = f"custom_{cpu_template_any['name']}"
+ vm.basic_config(
+ vcpu_count=2,
+ mem_size_mib=512,
+ cpu_template=static_cpu_template,
+ )
+
+ guest_kernel_version = re.search("vmlinux-(.*)", vm.kernel_file.name)
+ snapshot_artifacts_dir = (
+ results_dir
+ / f"{guest_kernel_version.group(1)}_{cpu_template_name}_guest_snapshot"
+ )
+
+ # Add 4 network devices
+ for i in range(4):
+ vm.add_net_iface()
+ # Add a vsock device
+ vm.api.vsock.put(vsock_id="vsock0", guest_cid=3, uds_path="/v.sock")
+ # Add MMDS
+ configure_mmds(vm, ["eth3"], version="V2")
+ # Add a memory balloon.
+ vm.api.balloon.put(amount_mib=0, deflate_on_oom=True, stats_polling_interval_s=1)
+
+ vm.start()
+
+ # Populate MMDS.
+ data_store = {
+ "latest": {
+ "meta-data": {
+ "ami-id": "ami-12345678",
+ "reservation-id": "r-fea54097",
+ "local-hostname": "ip-10-251-50-12.ec2.internal",
+ "public-hostname": "ec2-203-0-113-25.compute-1.amazonaws.com",
+ }
+ }
+ }
+
+ # MMDS should be empty.
+ assert vm.api.mmds.get().json() == {}
+ # Populate MMDS with data.
+ vm.api.mmds.put(**data_store)
+ # Ensure data is persistent inside the data store.
+ assert vm.api.mmds.get().json() == data_store
+
+ # Iterate and validate connectivity on all ifaces after boot.
+ for i in range(4):
+ exit_code, _, _ = vm.ssh_iface(i).run("sync")
+ assert exit_code == 0
+
+ # Validate MMDS.
+ # Configure interface to route MMDS requests
+ vm.ssh.check_output(f"ip route add {IPV4_ADDRESS} dev {NET_IFACE_FOR_MMDS}")
+
+ # Fetch metadata to ensure MMDS is accessible.
+ token = generate_mmds_session_token(vm.ssh, IPV4_ADDRESS, token_ttl=60)
+ cmd = generate_mmds_get_request(IPV4_ADDRESS, token=token)
+ _, stdout, _ = vm.ssh.run(cmd)
+ assert json.loads(stdout) == data_store
+
+ # Copy snapshot files to be published to S3 for the 2nd part of the test
+ # Create snapshot artifacts directory specific for the kernel version used.
+ snapshot = vm.snapshot_full()
+ snapshot_artifacts_dir.mkdir(parents=True)
+ snapshot.save_to(snapshot_artifacts_dir)
diff --git a/tests/integration_tests/functional/test_uffd.py b/tests/integration_tests/functional/test_uffd.py
index 44de52ed2d5..fbb86c4c987 100644
--- a/tests/integration_tests/functional/test_uffd.py
+++ b/tests/integration_tests/functional/test_uffd.py
@@ -14,10 +14,10 @@
@pytest.fixture(scope="function", name="snapshot")
-def snapshot_fxt(microvm_factory, guest_kernel_linux_5_10, rootfs_ubuntu_22):
+def snapshot_fxt(microvm_factory, guest_kernel_linux_5_10, rootfs):
"""Create a snapshot of a microVM."""
- basevm = microvm_factory.build(guest_kernel_linux_5_10, rootfs_ubuntu_22)
+ basevm = microvm_factory.build(guest_kernel_linux_5_10, rootfs)
basevm.spawn()
basevm.basic_config(vcpu_count=2, mem_size_mib=256)
basevm.add_net_iface()
diff --git a/tests/integration_tests/performance/test_huge_pages.py b/tests/integration_tests/performance/test_huge_pages.py
index 034ee6749a0..8437d78c7d3 100644
--- a/tests/integration_tests/performance/test_huge_pages.py
+++ b/tests/integration_tests/performance/test_huge_pages.py
@@ -70,14 +70,14 @@ def test_hugetlbfs_boot(uvm_plain):
def test_hugetlbfs_snapshot(
- microvm_factory, guest_kernel_linux_5_10, rootfs_ubuntu_22, uffd_handler_paths
+ microvm_factory, guest_kernel_linux_5_10, rootfs, uffd_handler_paths
):
"""
Test hugetlbfs snapshot restore via uffd
"""
### Create Snapshot ###
- vm = microvm_factory.build(guest_kernel_linux_5_10, rootfs_ubuntu_22)
+ vm = microvm_factory.build(guest_kernel_linux_5_10, rootfs)
vm.memory_monitor = None
vm.spawn()
vm.basic_config(huge_pages=HugePagesConfig.HUGETLBFS_2MB, mem_size_mib=128)
@@ -152,7 +152,7 @@ def test_hugetlbfs_diff_snapshot(microvm_factory, uvm_plain, uffd_handler_paths)
def test_ept_violation_count(
microvm_factory,
guest_kernel_linux_5_10,
- rootfs_ubuntu_22,
+ rootfs,
uffd_handler_paths,
metrics,
huge_pages,
@@ -163,7 +163,7 @@ def test_ept_violation_count(
"""
### Create Snapshot ###
- vm = microvm_factory.build(guest_kernel_linux_5_10, rootfs_ubuntu_22)
+ vm = microvm_factory.build(guest_kernel_linux_5_10, rootfs)
vm.memory_monitor = None
vm.spawn()
vm.basic_config(huge_pages=huge_pages, mem_size_mib=256)
diff --git a/tests/integration_tests/performance/test_vhost_user_metrics.py b/tests/integration_tests/performance/test_vhost_user_metrics.py
index 45fb7a94114..fd20b34a47b 100644
--- a/tests/integration_tests/performance/test_vhost_user_metrics.py
+++ b/tests/integration_tests/performance/test_vhost_user_metrics.py
@@ -11,7 +11,7 @@
@pytest.mark.parametrize("vcpu_count", [1, 2], ids=["1vcpu", "2vcpu"])
def test_vhost_user_block_metrics(
- microvm_factory, guest_kernel_acpi, rootfs_ubuntu_22, vcpu_count, metrics
+ microvm_factory, guest_kernel_acpi, rootfs, vcpu_count, metrics
):
"""
This test tries to boot a VM with vhost-user-block
@@ -28,9 +28,7 @@ def test_vhost_user_block_metrics(
# low->high->low->high and so the numbers are not in monotonic sequence.
new_sizes = [20, 10, 30] # MB
- vm = microvm_factory.build(
- guest_kernel_acpi, rootfs_ubuntu_22, monitor_memory=False
- )
+ vm = microvm_factory.build(guest_kernel_acpi, rootfs, monitor_memory=False)
vm.spawn(log_level="Info")
vm.basic_config(vcpu_count=vcpu_count)
vm.add_net_iface()
diff --git a/tests/integration_tests/security/test_nv.py b/tests/integration_tests/security/test_nv.py
index ce848c6a789..5dd5acb2308 100644
--- a/tests/integration_tests/security/test_nv.py
+++ b/tests/integration_tests/security/test_nv.py
@@ -20,17 +20,15 @@
@pytest.fixture
-def uvm_with_cpu_template(
- microvm_factory, guest_kernel, rootfs_ubuntu_22, cpu_template_any
-):
+def uvm_with_cpu_template(microvm_factory, guest_kernel, rootfs, cpu_template_any):
"""A microvm fixture parametrized with all possible templates"""
- vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22)
+ vm = microvm_factory.build(guest_kernel, rootfs)
vm.spawn()
cpu_template = None
if isinstance(cpu_template_any, str):
cpu_template = cpu_template_any
vm.basic_config(cpu_template=cpu_template)
- if cpu_template is None:
+ if isinstance(cpu_template_any, dict):
vm.api.cpu_config.put(**cpu_template_any["template"])
vm.add_net_iface()
vm.start()
diff --git a/tests/integration_tests/security/test_vulnerabilities.py b/tests/integration_tests/security/test_vulnerabilities.py
index d00aeb9d3c8..fed9dbc96d7 100644
--- a/tests/integration_tests/security/test_vulnerabilities.py
+++ b/tests/integration_tests/security/test_vulnerabilities.py
@@ -67,13 +67,13 @@ def configure_microvm(
def build_microvm(
microvm_factory,
guest_kernel_linux_5_10,
- rootfs_ubuntu_22,
+ rootfs,
):
"""Fixture returning a factory function for a normal microvm"""
return lambda firecracker=None, jailer=None: configure_microvm(
microvm_factory,
guest_kernel_linux_5_10,
- rootfs_ubuntu_22,
+ rootfs,
firecracker=firecracker,
jailer=jailer,
)
@@ -81,13 +81,13 @@ def build_microvm(
@pytest.fixture
def build_microvm_with_template(
- microvm_factory, guest_kernel_linux_5_10, rootfs_ubuntu_22, cpu_template
+ microvm_factory, guest_kernel_linux_5_10, rootfs, cpu_template
):
"""Fixture returning a factory function for microvms with our built-in template"""
return lambda firecracker=None, jailer=None: configure_microvm(
microvm_factory,
guest_kernel_linux_5_10,
- rootfs_ubuntu_22,
+ rootfs,
firecracker=firecracker,
jailer=jailer,
cpu_template=cpu_template,
@@ -96,13 +96,13 @@ def build_microvm_with_template(
@pytest.fixture
def build_microvm_with_custom_template(
- microvm_factory, guest_kernel_linux_5_10, rootfs_ubuntu_22, custom_cpu_template
+ microvm_factory, guest_kernel_linux_5_10, rootfs, custom_cpu_template
):
"""Fixture returning a factory function for microvms with custom cpu templates"""
return lambda firecracker=None, jailer=None: configure_microvm(
microvm_factory,
guest_kernel_linux_5_10,
- rootfs_ubuntu_22,
+ rootfs,
firecracker=firecracker,
jailer=jailer,
custom_cpu_template=custom_cpu_template,
diff --git a/tools/create_snapshot_artifact/main.py b/tools/create_snapshot_artifact/main.py
deleted file mode 100755
index 75d439c1185..00000000000
--- a/tools/create_snapshot_artifact/main.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-# SPDX-License-Identifier: Apache-2.0
-"""Script used to generate snapshots of microVMs."""
-
-import json
-import os
-import platform
-import re
-import shutil
-import sys
-from pathlib import Path
-
-# Hack to be able to import testing framework functions.
-sys.path.append(os.path.join(os.getcwd(), "tests")) # noqa: E402
-
-# pylint: disable=wrong-import-position
-from framework.artifacts import disks, kernels
-from framework.microvm import MicroVMFactory
-from framework.utils import (
- configure_mmds,
- generate_mmds_get_request,
- generate_mmds_session_token,
-)
-from framework.utils_cpu_templates import get_supported_cpu_templates
-from host_tools.cargo_build import get_firecracker_binaries
-
-# pylint: enable=wrong-import-position
-
-# Default IPv4 address to route MMDS requests.
-IPV4_ADDRESS = "169.254.169.254"
-NET_IFACE_FOR_MMDS = "eth3"
-# Root directory for the snapshot artifacts.
-SNAPSHOT_ARTIFACTS_ROOT_DIR = "snapshot_artifacts"
-
-
-def populate_mmds(microvm, data_store):
- """Populate MMDS contents with json data provided."""
- # MMDS should be empty.
- response = microvm.api.mmds.get()
- assert response.json() == {}
-
- # Populate MMDS with data.
- microvm.api.mmds.put(**data_store)
-
- # Ensure data is persistent inside the data store.
- response = microvm.api.mmds.get()
- assert response.json() == data_store
-
-
-def validate_mmds(ssh_connection, data_store):
- """Validate that MMDS contents fetched from the guest."""
- # Configure interface to route MMDS requests
- cmd = "ip route add {} dev {}".format(IPV4_ADDRESS, NET_IFACE_FOR_MMDS)
- _, stdout, stderr = ssh_connection.run(cmd)
- assert stdout == stderr == ""
-
- # Fetch metadata to ensure MMDS is accessible.
- token = generate_mmds_session_token(ssh_connection, IPV4_ADDRESS, token_ttl=60)
-
- cmd = generate_mmds_get_request(IPV4_ADDRESS, token=token)
- _, stdout, _ = ssh_connection.run(cmd)
- assert json.loads(stdout) == data_store
-
-
-def main():
- """
- Run the main logic.
-
- Create snapshot artifacts from complex microVMs with all Firecracker's
- functionality enabled. The kernels are parametrized to include all guest
- supported versions.
-
- Artifacts are saved in the following format:
- snapshot_artifacts
- |
- -> __guest_snapshot
- |
- -> vm.mem
- -> vm.vmstate
- -> ubuntu-22.04.id_rsa
- -> ubuntu-22.04.ext4
- -> __guest_snapshot
- |
- ...
- """
- # Create directory dedicated to store snapshot artifacts for
- # each guest kernel version.
- print("Cleanup")
- shutil.rmtree(SNAPSHOT_ARTIFACTS_ROOT_DIR, ignore_errors=True)
- vm_factory = MicroVMFactory(*get_firecracker_binaries())
-
- cpu_templates = []
- if platform.machine() == "x86_64":
- cpu_templates = ["None"]
- cpu_templates += get_supported_cpu_templates()
-
- for cpu_template in cpu_templates:
- for kernel in kernels(glob="vmlinux-*"):
- for rootfs in disks(glob="ubuntu-*.squashfs"):
- print(kernel, rootfs, cpu_template)
- vm = vm_factory.build(kernel, rootfs)
- vm.spawn(log_level="Info")
- vm.basic_config(
- vcpu_count=2,
- mem_size_mib=1024,
- cpu_template=cpu_template,
- track_dirty_pages=True,
- )
- # Add 4 network devices
- for i in range(4):
- vm.add_net_iface()
- # Add a vsock device
- vm.api.vsock.put(vsock_id="vsock0", guest_cid=3, uds_path="/v.sock")
- # Add MMDS
- configure_mmds(vm, ["eth3"], version="V2")
- # Add a memory balloon.
- vm.api.balloon.put(
- amount_mib=0, deflate_on_oom=True, stats_polling_interval_s=1
- )
-
- vm.start()
-
- # Populate MMDS.
- data_store = {
- "latest": {
- "meta-data": {
- "ami-id": "ami-12345678",
- "reservation-id": "r-fea54097",
- "local-hostname": "ip-10-251-50-12.ec2.internal",
- "public-hostname": "ec2-203-0-113-25.compute-1.amazonaws.com",
- }
- }
- }
- populate_mmds(vm, data_store)
-
- # Iterate and validate connectivity on all ifaces after boot.
- for i in range(4):
- exit_code, _, _ = vm.ssh_iface(i).run("sync")
- assert exit_code == 0
-
- # Validate MMDS.
- validate_mmds(vm.ssh, data_store)
-
- # Snapshot the microVM.
- snapshot = vm.snapshot_diff()
-
- # Create snapshot artifacts directory specific for the kernel version used.
- guest_kernel_version = re.search("vmlinux-(.*)", kernel.name)
-
- snapshot_artifacts_dir = (
- Path(SNAPSHOT_ARTIFACTS_ROOT_DIR)
- / f"{guest_kernel_version.group(1)}_{cpu_template}_guest_snapshot"
- )
- snapshot_artifacts_dir.mkdir(parents=True)
- snapshot.save_to(snapshot_artifacts_dir)
- print(f"Copied snapshot to: {snapshot_artifacts_dir}.")
-
- vm.kill()
-
-
-if __name__ == "__main__":
- main()
diff --git a/tools/devctr/Dockerfile b/tools/devctr/Dockerfile
index eef52632a6a..f0c7c36f759 100644
--- a/tools/devctr/Dockerfile
+++ b/tools/devctr/Dockerfile
@@ -75,7 +75,7 @@ RUN apt-get update \
screen tmux \
tzdata \
tini \
- squashfs-tools \
+ squashfs-tools zstd \
# for aws-lc-rs
cmake \
# for Qemu vhost-user-blk backend
@@ -83,7 +83,7 @@ RUN apt-get update \
# for crosvm (vhost-user-blk backend)
libcap2 \
# for debugging
- gdb strace \
+ gdb strace trace-cmd \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 install --upgrade poetry
@@ -107,7 +107,7 @@ RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal --default-too
&& rustup target add x86_64-unknown-linux-musl \
&& rustup target add aarch64-unknown-linux-musl \
&& rustup component add llvm-tools-preview clippy rustfmt \
- && cargo install --locked cargo-audit cargo-deny grcov cargo-sort cargo-afl \
+ && cargo install --locked cargo-audit cargo-deny@0.16.1 grcov cargo-sort cargo-afl \
&& cargo install --locked kani-verifier && cargo kani setup \
\
&& apt-get update \
diff --git a/tools/devctr/poetry.lock b/tools/devctr/poetry.lock
index fef3e284ade..96f1d0c990a 100644
--- a/tools/devctr/poetry.lock
+++ b/tools/devctr/poetry.lock
@@ -13,112 +13,112 @@ files = [
[[package]]
name = "aiohttp"
-version = "3.10.5"
+version = "3.10.11"
description = "Async http client/server framework (asyncio)"
optional = false
python-versions = ">=3.8"
files = [
- {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3"},
- {file = "aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6"},
- {file = "aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699"},
- {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6"},
- {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1"},
- {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f"},
- {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb"},
- {file = "aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91"},
- {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f"},
- {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c"},
- {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69"},
- {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3"},
- {file = "aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683"},
- {file = "aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef"},
- {file = "aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088"},
- {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2"},
- {file = "aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf"},
- {file = "aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e"},
- {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77"},
- {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061"},
- {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697"},
- {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7"},
- {file = "aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0"},
- {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5"},
- {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e"},
- {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1"},
- {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277"},
- {file = "aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058"},
- {file = "aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072"},
- {file = "aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff"},
- {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487"},
- {file = "aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a"},
- {file = "aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d"},
- {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75"},
- {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178"},
- {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e"},
- {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f"},
- {file = "aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73"},
- {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf"},
- {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820"},
- {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca"},
- {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91"},
- {file = "aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6"},
- {file = "aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12"},
- {file = "aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc"},
- {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092"},
- {file = "aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77"},
- {file = "aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385"},
- {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972"},
- {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16"},
- {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6"},
- {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa"},
- {file = "aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689"},
- {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57"},
- {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f"},
- {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599"},
- {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5"},
- {file = "aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987"},
- {file = "aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04"},
- {file = "aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022"},
- {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f6f18898ace4bcd2d41a122916475344a87f1dfdec626ecde9ee802a711bc569"},
- {file = "aiohttp-3.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5ede29d91a40ba22ac1b922ef510aab871652f6c88ef60b9dcdf773c6d32ad7a"},
- {file = "aiohttp-3.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:673f988370f5954df96cc31fd99c7312a3af0a97f09e407399f61583f30da9bc"},
- {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58718e181c56a3c02d25b09d4115eb02aafe1a732ce5714ab70326d9776457c3"},
- {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b38b1570242fbab8d86a84128fb5b5234a2f70c2e32f3070143a6d94bc854cf"},
- {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:074d1bff0163e107e97bd48cad9f928fa5a3eb4b9d33366137ffce08a63e37fe"},
- {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd31f176429cecbc1ba499d4aba31aaccfea488f418d60376b911269d3b883c5"},
- {file = "aiohttp-3.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7384d0b87d4635ec38db9263e6a3f1eb609e2e06087f0aa7f63b76833737b471"},
- {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8989f46f3d7ef79585e98fa991e6ded55d2f48ae56d2c9fa5e491a6e4effb589"},
- {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c83f7a107abb89a227d6c454c613e7606c12a42b9a4ca9c5d7dad25d47c776ae"},
- {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cde98f323d6bf161041e7627a5fd763f9fd829bcfcd089804a5fdce7bb6e1b7d"},
- {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:676f94c5480d8eefd97c0c7e3953315e4d8c2b71f3b49539beb2aa676c58272f"},
- {file = "aiohttp-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2d21ac12dc943c68135ff858c3a989f2194a709e6e10b4c8977d7fcd67dfd511"},
- {file = "aiohttp-3.10.5-cp38-cp38-win32.whl", hash = "sha256:17e997105bd1a260850272bfb50e2a328e029c941c2708170d9d978d5a30ad9a"},
- {file = "aiohttp-3.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:1c19de68896747a2aa6257ae4cf6ef59d73917a36a35ee9d0a6f48cff0f94db8"},
- {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e"},
- {file = "aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172"},
- {file = "aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b"},
- {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b"},
- {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92"},
- {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22"},
- {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f"},
- {file = "aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32"},
- {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce"},
- {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db"},
- {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b"},
- {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857"},
- {file = "aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11"},
- {file = "aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1"},
- {file = "aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862"},
- {file = "aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691"},
+ {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5077b1a5f40ffa3ba1f40d537d3bec4383988ee51fbba6b74aa8fb1bc466599e"},
+ {file = "aiohttp-3.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d6a14a4d93b5b3c2891fca94fa9d41b2322a68194422bef0dd5ec1e57d7d298"},
+ {file = "aiohttp-3.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffbfde2443696345e23a3c597049b1dd43049bb65337837574205e7368472177"},
+ {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b3d9e416774d41813bc02fdc0663379c01817b0874b932b81c7f777f67b217"},
+ {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b943011b45ee6bf74b22245c6faab736363678e910504dd7531a58c76c9015a"},
+ {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48bc1d924490f0d0b3658fe5c4b081a4d56ebb58af80a6729d4bd13ea569797a"},
+ {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e12eb3f4b1f72aaaf6acd27d045753b18101524f72ae071ae1c91c1cd44ef115"},
+ {file = "aiohttp-3.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f14ebc419a568c2eff3c1ed35f634435c24ead2fe19c07426af41e7adb68713a"},
+ {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:72b191cdf35a518bfc7ca87d770d30941decc5aaf897ec8b484eb5cc8c7706f3"},
+ {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ab2328a61fdc86424ee540d0aeb8b73bbcad7351fb7cf7a6546fc0bcffa0038"},
+ {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aa93063d4af05c49276cf14e419550a3f45258b6b9d1f16403e777f1addf4519"},
+ {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:30283f9d0ce420363c24c5c2421e71a738a2155f10adbb1a11a4d4d6d2715cfc"},
+ {file = "aiohttp-3.10.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e5358addc8044ee49143c546d2182c15b4ac3a60be01c3209374ace05af5733d"},
+ {file = "aiohttp-3.10.11-cp310-cp310-win32.whl", hash = "sha256:e1ffa713d3ea7cdcd4aea9cddccab41edf6882fa9552940344c44e59652e1120"},
+ {file = "aiohttp-3.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:778cbd01f18ff78b5dd23c77eb82987ee4ba23408cbed233009fd570dda7e674"},
+ {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:80ff08556c7f59a7972b1e8919f62e9c069c33566a6d28586771711e0eea4f07"},
+ {file = "aiohttp-3.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c8f96e9ee19f04c4914e4e7a42a60861066d3e1abf05c726f38d9d0a466e695"},
+ {file = "aiohttp-3.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fb8601394d537da9221947b5d6e62b064c9a43e88a1ecd7414d21a1a6fba9c24"},
+ {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ea224cf7bc2d8856d6971cea73b1d50c9c51d36971faf1abc169a0d5f85a382"},
+ {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db9503f79e12d5d80b3efd4d01312853565c05367493379df76d2674af881caa"},
+ {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f449a50cc33f0384f633894d8d3cd020e3ccef81879c6e6245c3c375c448625"},
+ {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82052be3e6d9e0c123499127782a01a2b224b8af8c62ab46b3f6197035ad94e9"},
+ {file = "aiohttp-3.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20063c7acf1eec550c8eb098deb5ed9e1bb0521613b03bb93644b810986027ac"},
+ {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:489cced07a4c11488f47aab1f00d0c572506883f877af100a38f1fedaa884c3a"},
+ {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea9b3bab329aeaa603ed3bf605f1e2a6f36496ad7e0e1aa42025f368ee2dc07b"},
+ {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ca117819d8ad113413016cb29774b3f6d99ad23c220069789fc050267b786c16"},
+ {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2dfb612dcbe70fb7cdcf3499e8d483079b89749c857a8f6e80263b021745c730"},
+ {file = "aiohttp-3.10.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9b615d3da0d60e7d53c62e22b4fd1c70f4ae5993a44687b011ea3a2e49051b8"},
+ {file = "aiohttp-3.10.11-cp311-cp311-win32.whl", hash = "sha256:29103f9099b6068bbdf44d6a3d090e0a0b2be6d3c9f16a070dd9d0d910ec08f9"},
+ {file = "aiohttp-3.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:236b28ceb79532da85d59aa9b9bf873b364e27a0acb2ceaba475dc61cffb6f3f"},
+ {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7480519f70e32bfb101d71fb9a1f330fbd291655a4c1c922232a48c458c52710"},
+ {file = "aiohttp-3.10.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f65267266c9aeb2287a6622ee2bb39490292552f9fbf851baabc04c9f84e048d"},
+ {file = "aiohttp-3.10.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7400a93d629a0608dc1d6c55f1e3d6e07f7375745aaa8bd7f085571e4d1cee97"},
+ {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f34b97e4b11b8d4eb2c3a4f975be626cc8af99ff479da7de49ac2c6d02d35725"},
+ {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e7b825da878464a252ccff2958838f9caa82f32a8dbc334eb9b34a026e2c636"},
+ {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9f92a344c50b9667827da308473005f34767b6a2a60d9acff56ae94f895f385"},
+ {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f1ab987a27b83c5268a17218463c2ec08dbb754195113867a27b166cd6087"},
+ {file = "aiohttp-3.10.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1dc0f4ca54842173d03322793ebcf2c8cc2d34ae91cc762478e295d8e361e03f"},
+ {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7ce6a51469bfaacff146e59e7fb61c9c23006495d11cc24c514a455032bcfa03"},
+ {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:aad3cd91d484d065ede16f3cf15408254e2469e3f613b241a1db552c5eb7ab7d"},
+ {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f4df4b8ca97f658c880fb4b90b1d1ec528315d4030af1ec763247ebfd33d8b9a"},
+ {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2e4e18a0a2d03531edbc06c366954e40a3f8d2a88d2b936bbe78a0c75a3aab3e"},
+ {file = "aiohttp-3.10.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ce66780fa1a20e45bc753cda2a149daa6dbf1561fc1289fa0c308391c7bc0a4"},
+ {file = "aiohttp-3.10.11-cp312-cp312-win32.whl", hash = "sha256:a919c8957695ea4c0e7a3e8d16494e3477b86f33067478f43106921c2fef15bb"},
+ {file = "aiohttp-3.10.11-cp312-cp312-win_amd64.whl", hash = "sha256:b5e29706e6389a2283a91611c91bf24f218962717c8f3b4e528ef529d112ee27"},
+ {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:703938e22434d7d14ec22f9f310559331f455018389222eed132808cd8f44127"},
+ {file = "aiohttp-3.10.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9bc50b63648840854e00084c2b43035a62e033cb9b06d8c22b409d56eb098413"},
+ {file = "aiohttp-3.10.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f0463bf8b0754bc744e1feb61590706823795041e63edf30118a6f0bf577461"},
+ {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6c6dec398ac5a87cb3a407b068e1106b20ef001c344e34154616183fe684288"},
+ {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcaf2d79104d53d4dcf934f7ce76d3d155302d07dae24dff6c9fffd217568067"},
+ {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25fd5470922091b5a9aeeb7e75be609e16b4fba81cdeaf12981393fb240dd10e"},
+ {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbde2ca67230923a42161b1f408c3992ae6e0be782dca0c44cb3206bf330dee1"},
+ {file = "aiohttp-3.10.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:249c8ff8d26a8b41a0f12f9df804e7c685ca35a207e2410adbd3e924217b9006"},
+ {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:878ca6a931ee8c486a8f7b432b65431d095c522cbeb34892bee5be97b3481d0f"},
+ {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8663f7777ce775f0413324be0d96d9730959b2ca73d9b7e2c2c90539139cbdd6"},
+ {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6cd3f10b01f0c31481fba8d302b61603a2acb37b9d30e1d14e0f5a58b7b18a31"},
+ {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4e8d8aad9402d3aa02fdc5ca2fe68bcb9fdfe1f77b40b10410a94c7f408b664d"},
+ {file = "aiohttp-3.10.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:38e3c4f80196b4f6c3a85d134a534a56f52da9cb8d8e7af1b79a32eefee73a00"},
+ {file = "aiohttp-3.10.11-cp313-cp313-win32.whl", hash = "sha256:fc31820cfc3b2863c6e95e14fcf815dc7afe52480b4dc03393c4873bb5599f71"},
+ {file = "aiohttp-3.10.11-cp313-cp313-win_amd64.whl", hash = "sha256:4996ff1345704ffdd6d75fb06ed175938c133425af616142e7187f28dc75f14e"},
+ {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:74baf1a7d948b3d640badeac333af581a367ab916b37e44cf90a0334157cdfd2"},
+ {file = "aiohttp-3.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:473aebc3b871646e1940c05268d451f2543a1d209f47035b594b9d4e91ce8339"},
+ {file = "aiohttp-3.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c2f746a6968c54ab2186574e15c3f14f3e7f67aef12b761e043b33b89c5b5f95"},
+ {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d110cabad8360ffa0dec8f6ec60e43286e9d251e77db4763a87dcfe55b4adb92"},
+ {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0099c7d5d7afff4202a0c670e5b723f7718810000b4abcbc96b064129e64bc7"},
+ {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0316e624b754dbbf8c872b62fe6dcb395ef20c70e59890dfa0de9eafccd2849d"},
+ {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a5f7ab8baf13314e6b2485965cbacb94afff1e93466ac4d06a47a81c50f9cca"},
+ {file = "aiohttp-3.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c891011e76041e6508cbfc469dd1a8ea09bc24e87e4c204e05f150c4c455a5fa"},
+ {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9208299251370ee815473270c52cd3f7069ee9ed348d941d574d1457d2c73e8b"},
+ {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:459f0f32c8356e8125f45eeff0ecf2b1cb6db1551304972702f34cd9e6c44658"},
+ {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:14cdc8c1810bbd4b4b9f142eeee23cda528ae4e57ea0923551a9af4820980e39"},
+ {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:971aa438a29701d4b34e4943e91b5e984c3ae6ccbf80dd9efaffb01bd0b243a9"},
+ {file = "aiohttp-3.10.11-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9a309c5de392dfe0f32ee57fa43ed8fc6ddf9985425e84bd51ed66bb16bce3a7"},
+ {file = "aiohttp-3.10.11-cp38-cp38-win32.whl", hash = "sha256:9ec1628180241d906a0840b38f162a3215114b14541f1a8711c368a8739a9be4"},
+ {file = "aiohttp-3.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:9c6e0ffd52c929f985c7258f83185d17c76d4275ad22e90aa29f38e211aacbec"},
+ {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cdc493a2e5d8dc79b2df5bec9558425bcd39aff59fc949810cbd0832e294b106"},
+ {file = "aiohttp-3.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b3e70f24e7d0405be2348da9d5a7836936bf3a9b4fd210f8c37e8d48bc32eca6"},
+ {file = "aiohttp-3.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968b8fb2a5eee2770eda9c7b5581587ef9b96fbdf8dcabc6b446d35ccc69df01"},
+ {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deef4362af9493d1382ef86732ee2e4cbc0d7c005947bd54ad1a9a16dd59298e"},
+ {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:686b03196976e327412a1b094f4120778c7c4b9cff9bce8d2fdfeca386b89829"},
+ {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bf6d027d9d1d34e1c2e1645f18a6498c98d634f8e373395221121f1c258ace8"},
+ {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:099fd126bf960f96d34a760e747a629c27fb3634da5d05c7ef4d35ef4ea519fc"},
+ {file = "aiohttp-3.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c73c4d3dae0b4644bc21e3de546530531d6cdc88659cdeb6579cd627d3c206aa"},
+ {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0c5580f3c51eea91559db3facd45d72e7ec970b04528b4709b1f9c2555bd6d0b"},
+ {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fdf6429f0caabfd8a30c4e2eaecb547b3c340e4730ebfe25139779b9815ba138"},
+ {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d97187de3c276263db3564bb9d9fad9e15b51ea10a371ffa5947a5ba93ad6777"},
+ {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0acafb350cfb2eba70eb5d271f55e08bd4502ec35e964e18ad3e7d34d71f7261"},
+ {file = "aiohttp-3.10.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c13ed0c779911c7998a58e7848954bd4d63df3e3575f591e321b19a2aec8df9f"},
+ {file = "aiohttp-3.10.11-cp39-cp39-win32.whl", hash = "sha256:22b7c540c55909140f63ab4f54ec2c20d2635c0289cdd8006da46f3327f971b9"},
+ {file = "aiohttp-3.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:7b26b1551e481012575dab8e3727b16fe7dd27eb2711d2e63ced7368756268fb"},
+ {file = "aiohttp-3.10.11.tar.gz", hash = "sha256:9dc2b8f3dcab2e39e0fa309c8da50c3b55e6f34ab25f1a71d3288f24924d33a7"},
]
[package.dependencies]
aiohappyeyeballs = ">=2.3.0"
aiosignal = ">=1.1.2"
-async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
+async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""}
attrs = ">=17.3.0"
frozenlist = ">=1.1.1"
multidict = ">=4.5,<7.0"
-yarl = ">=1.0,<2.0"
+yarl = ">=1.12.0,<2.0"
[package.extras]
speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"]
@@ -1317,6 +1317,113 @@ files = [
[package.dependencies]
wcwidth = "*"
+[[package]]
+name = "propcache"
+version = "0.2.0"
+description = "Accelerated property cache"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58"},
+ {file = "propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b"},
+ {file = "propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110"},
+ {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2"},
+ {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a"},
+ {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577"},
+ {file = "propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850"},
+ {file = "propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61"},
+ {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37"},
+ {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48"},
+ {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630"},
+ {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394"},
+ {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b"},
+ {file = "propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336"},
+ {file = "propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad"},
+ {file = "propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99"},
+ {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354"},
+ {file = "propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de"},
+ {file = "propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87"},
+ {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016"},
+ {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb"},
+ {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2"},
+ {file = "propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4"},
+ {file = "propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504"},
+ {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178"},
+ {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d"},
+ {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2"},
+ {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db"},
+ {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b"},
+ {file = "propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b"},
+ {file = "propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1"},
+ {file = "propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71"},
+ {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2"},
+ {file = "propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7"},
+ {file = "propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8"},
+ {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793"},
+ {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09"},
+ {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89"},
+ {file = "propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e"},
+ {file = "propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9"},
+ {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4"},
+ {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c"},
+ {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887"},
+ {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57"},
+ {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23"},
+ {file = "propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348"},
+ {file = "propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5"},
+ {file = "propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3"},
+ {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7"},
+ {file = "propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763"},
+ {file = "propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d"},
+ {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a"},
+ {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b"},
+ {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb"},
+ {file = "propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf"},
+ {file = "propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2"},
+ {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f"},
+ {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136"},
+ {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325"},
+ {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44"},
+ {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83"},
+ {file = "propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544"},
+ {file = "propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032"},
+ {file = "propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e"},
+ {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:53d1bd3f979ed529f0805dd35ddaca330f80a9a6d90bc0121d2ff398f8ed8861"},
+ {file = "propcache-0.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:83928404adf8fb3d26793665633ea79b7361efa0287dfbd372a7e74311d51ee6"},
+ {file = "propcache-0.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:77a86c261679ea5f3896ec060be9dc8e365788248cc1e049632a1be682442063"},
+ {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:218db2a3c297a3768c11a34812e63b3ac1c3234c3a086def9c0fee50d35add1f"},
+ {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7735e82e3498c27bcb2d17cb65d62c14f1100b71723b68362872bca7d0913d90"},
+ {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20a617c776f520c3875cf4511e0d1db847a076d720714ae35ffe0df3e440be68"},
+ {file = "propcache-0.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b69535c870670c9f9b14a75d28baa32221d06f6b6fa6f77a0a13c5a7b0a5b9"},
+ {file = "propcache-0.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4569158070180c3855e9c0791c56be3ceeb192defa2cdf6a3f39e54319e56b89"},
+ {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:db47514ffdbd91ccdc7e6f8407aac4ee94cc871b15b577c1c324236b013ddd04"},
+ {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:2a60ad3e2553a74168d275a0ef35e8c0a965448ffbc3b300ab3a5bb9956c2162"},
+ {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:662dd62358bdeaca0aee5761de8727cfd6861432e3bb828dc2a693aa0471a563"},
+ {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:25a1f88b471b3bc911d18b935ecb7115dff3a192b6fef46f0bfaf71ff4f12418"},
+ {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:f60f0ac7005b9f5a6091009b09a419ace1610e163fa5deaba5ce3484341840e7"},
+ {file = "propcache-0.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:74acd6e291f885678631b7ebc85d2d4aec458dd849b8c841b57ef04047833bed"},
+ {file = "propcache-0.2.0-cp38-cp38-win32.whl", hash = "sha256:d9b6ddac6408194e934002a69bcaadbc88c10b5f38fb9307779d1c629181815d"},
+ {file = "propcache-0.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:676135dcf3262c9c5081cc8f19ad55c8a64e3f7282a21266d05544450bffc3a5"},
+ {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:25c8d773a62ce0451b020c7b29a35cfbc05de8b291163a7a0f3b7904f27253e6"},
+ {file = "propcache-0.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:375a12d7556d462dc64d70475a9ee5982465fbb3d2b364f16b86ba9135793638"},
+ {file = "propcache-0.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1ec43d76b9677637a89d6ab86e1fef70d739217fefa208c65352ecf0282be957"},
+ {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f45eec587dafd4b2d41ac189c2156461ebd0c1082d2fe7013571598abb8505d1"},
+ {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc092ba439d91df90aea38168e11f75c655880c12782facf5cf9c00f3d42b562"},
+ {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa1076244f54bb76e65e22cb6910365779d5c3d71d1f18b275f1dfc7b0d71b4d"},
+ {file = "propcache-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:682a7c79a2fbf40f5dbb1eb6bfe2cd865376deeac65acf9beb607505dced9e12"},
+ {file = "propcache-0.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e40876731f99b6f3c897b66b803c9e1c07a989b366c6b5b475fafd1f7ba3fb8"},
+ {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:363ea8cd3c5cb6679f1c2f5f1f9669587361c062e4899fce56758efa928728f8"},
+ {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:140fbf08ab3588b3468932974a9331aff43c0ab8a2ec2c608b6d7d1756dbb6cb"},
+ {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e70fac33e8b4ac63dfc4c956fd7d85a0b1139adcfc0d964ce288b7c527537fea"},
+ {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b33d7a286c0dc1a15f5fc864cc48ae92a846df287ceac2dd499926c3801054a6"},
+ {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f6d5749fdd33d90e34c2efb174c7e236829147a2713334d708746e94c4bde40d"},
+ {file = "propcache-0.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22aa8f2272d81d9317ff5756bb108021a056805ce63dd3630e27d042c8092798"},
+ {file = "propcache-0.2.0-cp39-cp39-win32.whl", hash = "sha256:73e4b40ea0eda421b115248d7e79b59214411109a5bc47d0d48e4c73e3b8fcf9"},
+ {file = "propcache-0.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:9517d5e9e0731957468c29dbfd0f976736a0e55afaea843726e887f36fe017df"},
+ {file = "propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036"},
+ {file = "propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70"},
+]
+
[[package]]
name = "psutil"
version = "6.0.0"
@@ -2155,108 +2262,99 @@ files = [
[[package]]
name = "yarl"
-version = "1.11.1"
+version = "1.17.2"
description = "Yet another URL library"
optional = false
-python-versions = ">=3.8"
-files = [
- {file = "yarl-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:400cd42185f92de559d29eeb529e71d80dfbd2f45c36844914a4a34297ca6f00"},
- {file = "yarl-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8258c86f47e080a258993eed877d579c71da7bda26af86ce6c2d2d072c11320d"},
- {file = "yarl-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2164cd9725092761fed26f299e3f276bb4b537ca58e6ff6b252eae9631b5c96e"},
- {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08ea567c16f140af8ddc7cb58e27e9138a1386e3e6e53982abaa6f2377b38cc"},
- {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:768ecc550096b028754ea28bf90fde071c379c62c43afa574edc6f33ee5daaec"},
- {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2909fa3a7d249ef64eeb2faa04b7957e34fefb6ec9966506312349ed8a7e77bf"},
- {file = "yarl-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01a8697ec24f17c349c4f655763c4db70eebc56a5f82995e5e26e837c6eb0e49"},
- {file = "yarl-1.11.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e286580b6511aac7c3268a78cdb861ec739d3e5a2a53b4809faef6b49778eaff"},
- {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4179522dc0305c3fc9782549175c8e8849252fefeb077c92a73889ccbcd508ad"},
- {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:27fcb271a41b746bd0e2a92182df507e1c204759f460ff784ca614e12dd85145"},
- {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f61db3b7e870914dbd9434b560075e0366771eecbe6d2b5561f5bc7485f39efd"},
- {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:c92261eb2ad367629dc437536463dc934030c9e7caca861cc51990fe6c565f26"},
- {file = "yarl-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d95b52fbef190ca87d8c42f49e314eace4fc52070f3dfa5f87a6594b0c1c6e46"},
- {file = "yarl-1.11.1-cp310-cp310-win32.whl", hash = "sha256:489fa8bde4f1244ad6c5f6d11bb33e09cf0d1d0367edb197619c3e3fc06f3d91"},
- {file = "yarl-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:476e20c433b356e16e9a141449f25161e6b69984fb4cdbd7cd4bd54c17844998"},
- {file = "yarl-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:946eedc12895873891aaceb39bceb484b4977f70373e0122da483f6c38faaa68"},
- {file = "yarl-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21a7c12321436b066c11ec19c7e3cb9aec18884fe0d5b25d03d756a9e654edfe"},
- {file = "yarl-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c35f493b867912f6fda721a59cc7c4766d382040bdf1ddaeeaa7fa4d072f4675"},
- {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25861303e0be76b60fddc1250ec5986c42f0a5c0c50ff57cc30b1be199c00e63"},
- {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4b53f73077e839b3f89c992223f15b1d2ab314bdbdf502afdc7bb18e95eae27"},
- {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:327c724b01b8641a1bf1ab3b232fb638706e50f76c0b5bf16051ab65c868fac5"},
- {file = "yarl-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4307d9a3417eea87715c9736d050c83e8c1904e9b7aada6ce61b46361b733d92"},
- {file = "yarl-1.11.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48a28bed68ab8fb7e380775f0029a079f08a17799cb3387a65d14ace16c12e2b"},
- {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:067b961853c8e62725ff2893226fef3d0da060656a9827f3f520fb1d19b2b68a"},
- {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8215f6f21394d1f46e222abeb06316e77ef328d628f593502d8fc2a9117bde83"},
- {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:498442e3af2a860a663baa14fbf23fb04b0dd758039c0e7c8f91cb9279799bff"},
- {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:69721b8effdb588cb055cc22f7c5105ca6fdaa5aeb3ea09021d517882c4a904c"},
- {file = "yarl-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e969fa4c1e0b1a391f3fcbcb9ec31e84440253325b534519be0d28f4b6b533e"},
- {file = "yarl-1.11.1-cp311-cp311-win32.whl", hash = "sha256:7d51324a04fc4b0e097ff8a153e9276c2593106a811704025bbc1d6916f45ca6"},
- {file = "yarl-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:15061ce6584ece023457fb8b7a7a69ec40bf7114d781a8c4f5dcd68e28b5c53b"},
- {file = "yarl-1.11.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a4264515f9117be204935cd230fb2a052dd3792789cc94c101c535d349b3dab0"},
- {file = "yarl-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f41fa79114a1d2eddb5eea7b912d6160508f57440bd302ce96eaa384914cd265"},
- {file = "yarl-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:02da8759b47d964f9173c8675710720b468aa1c1693be0c9c64abb9d8d9a4867"},
- {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9361628f28f48dcf8b2f528420d4d68102f593f9c2e592bfc842f5fb337e44fd"},
- {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b91044952da03b6f95fdba398d7993dd983b64d3c31c358a4c89e3c19b6f7aef"},
- {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74db2ef03b442276d25951749a803ddb6e270d02dda1d1c556f6ae595a0d76a8"},
- {file = "yarl-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e975a2211952a8a083d1b9d9ba26472981ae338e720b419eb50535de3c02870"},
- {file = "yarl-1.11.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aef97ba1dd2138112890ef848e17d8526fe80b21f743b4ee65947ea184f07a2"},
- {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7915ea49b0c113641dc4d9338efa9bd66b6a9a485ffe75b9907e8573ca94b84"},
- {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:504cf0d4c5e4579a51261d6091267f9fd997ef58558c4ffa7a3e1460bd2336fa"},
- {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3de5292f9f0ee285e6bd168b2a77b2a00d74cbcfa420ed078456d3023d2f6dff"},
- {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a34e1e30f1774fa35d37202bbeae62423e9a79d78d0874e5556a593479fdf239"},
- {file = "yarl-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66b63c504d2ca43bf7221a1f72fbe981ff56ecb39004c70a94485d13e37ebf45"},
- {file = "yarl-1.11.1-cp312-cp312-win32.whl", hash = "sha256:a28b70c9e2213de425d9cba5ab2e7f7a1c8ca23a99c4b5159bf77b9c31251447"},
- {file = "yarl-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:17b5a386d0d36fb828e2fb3ef08c8829c1ebf977eef88e5367d1c8c94b454639"},
- {file = "yarl-1.11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1fa2e7a406fbd45b61b4433e3aa254a2c3e14c4b3186f6e952d08a730807fa0c"},
- {file = "yarl-1.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:750f656832d7d3cb0c76be137ee79405cc17e792f31e0a01eee390e383b2936e"},
- {file = "yarl-1.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b8486f322d8f6a38539136a22c55f94d269addb24db5cb6f61adc61eabc9d93"},
- {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fce4da3703ee6048ad4138fe74619c50874afe98b1ad87b2698ef95bf92c96d"},
- {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed653638ef669e0efc6fe2acb792275cb419bf9cb5c5049399f3556995f23c7"},
- {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18ac56c9dd70941ecad42b5a906820824ca72ff84ad6fa18db33c2537ae2e089"},
- {file = "yarl-1.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:688654f8507464745ab563b041d1fb7dab5d9912ca6b06e61d1c4708366832f5"},
- {file = "yarl-1.11.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4973eac1e2ff63cf187073cd4e1f1148dcd119314ab79b88e1b3fad74a18c9d5"},
- {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:964a428132227edff96d6f3cf261573cb0f1a60c9a764ce28cda9525f18f7786"},
- {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6d23754b9939cbab02c63434776df1170e43b09c6a517585c7ce2b3d449b7318"},
- {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c2dc4250fe94d8cd864d66018f8344d4af50e3758e9d725e94fecfa27588ff82"},
- {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09696438cb43ea6f9492ef237761b043f9179f455f405279e609f2bc9100212a"},
- {file = "yarl-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da"},
- {file = "yarl-1.11.1-cp313-cp313-win32.whl", hash = "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979"},
- {file = "yarl-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367"},
- {file = "yarl-1.11.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dae7bd0daeb33aa3e79e72877d3d51052e8b19c9025ecf0374f542ea8ec120e4"},
- {file = "yarl-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3ff6b1617aa39279fe18a76c8d165469c48b159931d9b48239065767ee455b2b"},
- {file = "yarl-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3257978c870728a52dcce8c2902bf01f6c53b65094b457bf87b2644ee6238ddc"},
- {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f351fa31234699d6084ff98283cb1e852270fe9e250a3b3bf7804eb493bd937"},
- {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8aef1b64da41d18026632d99a06b3fefe1d08e85dd81d849fa7c96301ed22f1b"},
- {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7175a87ab8f7fbde37160a15e58e138ba3b2b0e05492d7351314a250d61b1591"},
- {file = "yarl-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba444bdd4caa2a94456ef67a2f383710928820dd0117aae6650a4d17029fa25e"},
- {file = "yarl-1.11.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ea9682124fc062e3d931c6911934a678cb28453f957ddccf51f568c2f2b5e05"},
- {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8418c053aeb236b20b0ab8fa6bacfc2feaaf7d4683dd96528610989c99723d5f"},
- {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:61a5f2c14d0a1adfdd82258f756b23a550c13ba4c86c84106be4c111a3a4e413"},
- {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f3a6d90cab0bdf07df8f176eae3a07127daafcf7457b997b2bf46776da2c7eb7"},
- {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:077da604852be488c9a05a524068cdae1e972b7dc02438161c32420fb4ec5e14"},
- {file = "yarl-1.11.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:15439f3c5c72686b6c3ff235279630d08936ace67d0fe5c8d5bbc3ef06f5a420"},
- {file = "yarl-1.11.1-cp38-cp38-win32.whl", hash = "sha256:238a21849dd7554cb4d25a14ffbfa0ef380bb7ba201f45b144a14454a72ffa5a"},
- {file = "yarl-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:67459cf8cf31da0e2cbdb4b040507e535d25cfbb1604ca76396a3a66b8ba37a6"},
- {file = "yarl-1.11.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:884eab2ce97cbaf89f264372eae58388862c33c4f551c15680dd80f53c89a269"},
- {file = "yarl-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a336eaa7ee7e87cdece3cedb395c9657d227bfceb6781295cf56abcd3386a26"},
- {file = "yarl-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87f020d010ba80a247c4abc335fc13421037800ca20b42af5ae40e5fd75e7909"},
- {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:637c7ddb585a62d4469f843dac221f23eec3cbad31693b23abbc2c366ad41ff4"},
- {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48dfd117ab93f0129084577a07287376cc69c08138694396f305636e229caa1a"},
- {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e0ae31fb5ccab6eda09ba1494e87eb226dcbd2372dae96b87800e1dcc98804"},
- {file = "yarl-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f46f81501160c28d0c0b7333b4f7be8983dbbc161983b6fb814024d1b4952f79"},
- {file = "yarl-1.11.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04293941646647b3bfb1719d1d11ff1028e9c30199509a844da3c0f5919dc520"},
- {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:250e888fa62d73e721f3041e3a9abf427788a1934b426b45e1b92f62c1f68366"},
- {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e8f63904df26d1a66aabc141bfd258bf738b9bc7bc6bdef22713b4f5ef789a4c"},
- {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:aac44097d838dda26526cffb63bdd8737a2dbdf5f2c68efb72ad83aec6673c7e"},
- {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:267b24f891e74eccbdff42241c5fb4f974de2d6271dcc7d7e0c9ae1079a560d9"},
- {file = "yarl-1.11.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6907daa4b9d7a688063ed098c472f96e8181733c525e03e866fb5db480a424df"},
- {file = "yarl-1.11.1-cp39-cp39-win32.whl", hash = "sha256:14438dfc5015661f75f85bc5adad0743678eefee266ff0c9a8e32969d5d69f74"},
- {file = "yarl-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:94d0caaa912bfcdc702a4204cd5e2bb01eb917fc4f5ea2315aa23962549561b0"},
- {file = "yarl-1.11.1-py3-none-any.whl", hash = "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38"},
- {file = "yarl-1.11.1.tar.gz", hash = "sha256:1bb2d9e212fb7449b8fb73bc461b51eaa17cc8430b4a87d87be7b25052d92f53"},
+python-versions = ">=3.9"
+files = [
+ {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:93771146ef048b34201bfa382c2bf74c524980870bb278e6df515efaf93699ff"},
+ {file = "yarl-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8281db240a1616af2f9c5f71d355057e73a1409c4648c8949901396dc0a3c151"},
+ {file = "yarl-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:170ed4971bf9058582b01a8338605f4d8c849bd88834061e60e83b52d0c76870"},
+ {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc61b005f6521fcc00ca0d1243559a5850b9dd1e1fe07b891410ee8fe192d0c0"},
+ {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871e1b47eec7b6df76b23c642a81db5dd6536cbef26b7e80e7c56c2fd371382e"},
+ {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a58a2f2ca7aaf22b265388d40232f453f67a6def7355a840b98c2d547bd037f"},
+ {file = "yarl-1.17.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:736bb076f7299c5c55dfef3eb9e96071a795cb08052822c2bb349b06f4cb2e0a"},
+ {file = "yarl-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8fd51299e21da709eabcd5b2dd60e39090804431292daacbee8d3dabe39a6bc0"},
+ {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:358dc7ddf25e79e1cc8ee16d970c23faee84d532b873519c5036dbb858965795"},
+ {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:50d866f7b1a3f16f98603e095f24c0eeba25eb508c85a2c5939c8b3870ba2df8"},
+ {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b9c4643e7d843a0dca9cd9d610a0876e90a1b2cbc4c5ba7930a0d90baf6903f"},
+ {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d63123bfd0dce5f91101e77c8a5427c3872501acece8c90df457b486bc1acd47"},
+ {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4e76381be3d8ff96a4e6c77815653063e87555981329cf8f85e5be5abf449021"},
+ {file = "yarl-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:734144cd2bd633a1516948e477ff6c835041c0536cef1d5b9a823ae29899665b"},
+ {file = "yarl-1.17.2-cp310-cp310-win32.whl", hash = "sha256:26bfb6226e0c157af5da16d2d62258f1ac578d2899130a50433ffee4a5dfa673"},
+ {file = "yarl-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:76499469dcc24759399accd85ec27f237d52dec300daaca46a5352fcbebb1071"},
+ {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:792155279dc093839e43f85ff7b9b6493a8eaa0af1f94f1f9c6e8f4de8c63500"},
+ {file = "yarl-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:38bc4ed5cae853409cb193c87c86cd0bc8d3a70fd2268a9807217b9176093ac6"},
+ {file = "yarl-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4a8c83f6fcdc327783bdc737e8e45b2e909b7bd108c4da1892d3bc59c04a6d84"},
+ {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6d5fed96f0646bfdf698b0a1cebf32b8aae6892d1bec0c5d2d6e2df44e1e2d"},
+ {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:782ca9c58f5c491c7afa55518542b2b005caedaf4685ec814fadfcee51f02493"},
+ {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ff6af03cac0d1a4c3c19e5dcc4c05252411bf44ccaa2485e20d0a7c77892ab6e"},
+ {file = "yarl-1.17.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a3f47930fbbed0f6377639503848134c4aa25426b08778d641491131351c2c8"},
+ {file = "yarl-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1fa68a3c921365c5745b4bd3af6221ae1f0ea1bf04b69e94eda60e57958907f"},
+ {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:187df91395c11e9f9dc69b38d12406df85aa5865f1766a47907b1cc9855b6303"},
+ {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:93d1c8cc5bf5df401015c5e2a3ce75a5254a9839e5039c881365d2a9dcfc6dc2"},
+ {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11d86c6145ac5c706c53d484784cf504d7d10fa407cb73b9d20f09ff986059ef"},
+ {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c42774d1d1508ec48c3ed29e7b110e33f5e74a20957ea16197dbcce8be6b52ba"},
+ {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8e589379ef0407b10bed16cc26e7392ef8f86961a706ade0a22309a45414d7"},
+ {file = "yarl-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1056cadd5e850a1c026f28e0704ab0a94daaa8f887ece8dfed30f88befb87bb0"},
+ {file = "yarl-1.17.2-cp311-cp311-win32.whl", hash = "sha256:be4c7b1c49d9917c6e95258d3d07f43cfba2c69a6929816e77daf322aaba6628"},
+ {file = "yarl-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:ac8eda86cc75859093e9ce390d423aba968f50cf0e481e6c7d7d63f90bae5c9c"},
+ {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dd90238d3a77a0e07d4d6ffdebc0c21a9787c5953a508a2231b5f191455f31e9"},
+ {file = "yarl-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c74f0b0472ac40b04e6d28532f55cac8090e34c3e81f118d12843e6df14d0909"},
+ {file = "yarl-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4d486ddcaca8c68455aa01cf53d28d413fb41a35afc9f6594a730c9779545876"},
+ {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25b7e93f5414b9a983e1a6c1820142c13e1782cc9ed354c25e933aebe97fcf2"},
+ {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a0baff7827a632204060f48dca9e63fbd6a5a0b8790c1a2adfb25dc2c9c0d50"},
+ {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:460024cacfc3246cc4d9f47a7fc860e4fcea7d1dc651e1256510d8c3c9c7cde0"},
+ {file = "yarl-1.17.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5870d620b23b956f72bafed6a0ba9a62edb5f2ef78a8849b7615bd9433384171"},
+ {file = "yarl-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2941756754a10e799e5b87e2319bbec481ed0957421fba0e7b9fb1c11e40509f"},
+ {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9611b83810a74a46be88847e0ea616794c406dbcb4e25405e52bff8f4bee2d0a"},
+ {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cd7e35818d2328b679a13268d9ea505c85cd773572ebb7a0da7ccbca77b6a52e"},
+ {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6b981316fcd940f085f646b822c2ff2b8b813cbd61281acad229ea3cbaabeb6b"},
+ {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:688058e89f512fb7541cb85c2f149c292d3fa22f981d5a5453b40c5da49eb9e8"},
+ {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56afb44a12b0864d17b597210d63a5b88915d680f6484d8d202ed68ade38673d"},
+ {file = "yarl-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:17931dfbb84ae18b287279c1f92b76a3abcd9a49cd69b92e946035cff06bcd20"},
+ {file = "yarl-1.17.2-cp312-cp312-win32.whl", hash = "sha256:ff8d95e06546c3a8c188f68040e9d0360feb67ba8498baf018918f669f7bc39b"},
+ {file = "yarl-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:4c840cc11163d3c01a9d8aad227683c48cd3e5be5a785921bcc2a8b4b758c4f3"},
+ {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3294f787a437cb5d81846de3a6697f0c35ecff37a932d73b1fe62490bef69211"},
+ {file = "yarl-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1e7fedb09c059efee2533119666ca7e1a2610072076926fa028c2ba5dfeb78c"},
+ {file = "yarl-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da9d3061e61e5ae3f753654813bc1cd1c70e02fb72cf871bd6daf78443e9e2b1"},
+ {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91c012dceadc695ccf69301bfdccd1fc4472ad714fe2dd3c5ab4d2046afddf29"},
+ {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f11fd61d72d93ac23718d393d2a64469af40be2116b24da0a4ca6922df26807e"},
+ {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46c465ad06971abcf46dd532f77560181387b4eea59084434bdff97524444032"},
+ {file = "yarl-1.17.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef6eee1a61638d29cd7c85f7fd3ac7b22b4c0fabc8fd00a712b727a3e73b0685"},
+ {file = "yarl-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4434b739a8a101a837caeaa0137e0e38cb4ea561f39cb8960f3b1e7f4967a3fc"},
+ {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:752485cbbb50c1e20908450ff4f94217acba9358ebdce0d8106510859d6eb19a"},
+ {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:17791acaa0c0f89323c57da7b9a79f2174e26d5debbc8c02d84ebd80c2b7bff8"},
+ {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5c6ea72fe619fee5e6b5d4040a451d45d8175f560b11b3d3e044cd24b2720526"},
+ {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db5ac3871ed76340210fe028f535392f097fb31b875354bcb69162bba2632ef4"},
+ {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:7a1606ba68e311576bcb1672b2a1543417e7e0aa4c85e9e718ba6466952476c0"},
+ {file = "yarl-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9bc27dd5cfdbe3dc7f381b05e6260ca6da41931a6e582267d5ca540270afeeb2"},
+ {file = "yarl-1.17.2-cp313-cp313-win32.whl", hash = "sha256:52492b87d5877ec405542f43cd3da80bdcb2d0c2fbc73236526e5f2c28e6db28"},
+ {file = "yarl-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:8e1bf59e035534ba4077f5361d8d5d9194149f9ed4f823d1ee29ef3e8964ace3"},
+ {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c556fbc6820b6e2cda1ca675c5fa5589cf188f8da6b33e9fc05b002e603e44fa"},
+ {file = "yarl-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f2f44a4247461965fed18b2573f3a9eb5e2c3cad225201ee858726cde610daca"},
+ {file = "yarl-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3a3ede8c248f36b60227eb777eac1dbc2f1022dc4d741b177c4379ca8e75571a"},
+ {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2654caaf5584449d49c94a6b382b3cb4a246c090e72453493ea168b931206a4d"},
+ {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d41c684f286ce41fa05ab6af70f32d6da1b6f0457459a56cf9e393c1c0b2217"},
+ {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2270d590997445a0dc29afa92e5534bfea76ba3aea026289e811bf9ed4b65a7f"},
+ {file = "yarl-1.17.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18662443c6c3707e2fc7fad184b4dc32dd428710bbe72e1bce7fe1988d4aa654"},
+ {file = "yarl-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:75ac158560dec3ed72f6d604c81090ec44529cfb8169b05ae6fcb3e986b325d9"},
+ {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1fee66b32e79264f428dc8da18396ad59cc48eef3c9c13844adec890cd339db5"},
+ {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:585ce7cd97be8f538345de47b279b879e091c8b86d9dbc6d98a96a7ad78876a3"},
+ {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:c019abc2eca67dfa4d8fb72ba924871d764ec3c92b86d5b53b405ad3d6aa56b0"},
+ {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c6e659b9a24d145e271c2faf3fa6dd1fcb3e5d3f4e17273d9e0350b6ab0fe6e2"},
+ {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d17832ba39374134c10e82d137e372b5f7478c4cceeb19d02ae3e3d1daed8721"},
+ {file = "yarl-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bc3003710e335e3f842ae3fd78efa55f11a863a89a72e9a07da214db3bf7e1f8"},
+ {file = "yarl-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f5ffc6b7ace5b22d9e73b2a4c7305740a339fbd55301d52735f73e21d9eb3130"},
+ {file = "yarl-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:48e424347a45568413deec6f6ee2d720de2cc0385019bedf44cd93e8638aa0ed"},
+ {file = "yarl-1.17.2-py3-none-any.whl", hash = "sha256:dd7abf4f717e33b7487121faf23560b3a50924f80e4bef62b22dab441ded8f3b"},
+ {file = "yarl-1.17.2.tar.gz", hash = "sha256:753eaaa0c7195244c84b5cc159dc8204b7fd99f716f11198f999f2332a86b178"},
]
[package.dependencies]
idna = ">=2.0"
multidict = ">=4.0"
+propcache = ">=0.2.0"
[metadata]
lock-version = "2.0"
diff --git a/tools/devtool b/tools/devtool
index e9eb3d48db0..c3b7b27ed98 100755
--- a/tools/devtool
+++ b/tools/devtool
@@ -417,7 +417,7 @@ cmd_help() {
echo " build_ci_artifacts [all|rootfs|kernels]"
echo " Builds the rootfs and guest kernel artifacts we use for our CI."
echo " Run './tools/devtool build_ci_artifacts help' for more details about the available commands."
- echo ""
+ echo ""
cat <]]
@@ -562,14 +562,12 @@ ensure_ci_artifacts() {
# Fetch all the artifacts so they are local
say "Fetching CI artifacts from S3"
- S3_URL=s3://spec.ccfc.min/firecracker-ci/v1.10/$(uname -m)
+ S3_URL=s3://spec.ccfc.min/firecracker-ci/v1.11/$(uname -m)
ARTIFACTS=$MICROVM_IMAGES_DIR/$(uname -m)
if [ ! -d "$ARTIFACTS" ]; then
mkdir -pv $ARTIFACTS
aws s3 sync --no-sign-request "$S3_URL" "$ARTIFACTS"
- # fix permissions
- find "$ARTIFACTS" -type f -name "*.id_rsa" |xargs chmod -c 400
- find "$ARTIFACTS/firecracker" -type f |xargs chmod -c 755
+ cmd_sh "./tools/setup-ci-artifacts.sh"
fi
}
@@ -1193,7 +1191,7 @@ cmd_install() {
# Install the binaries
for binary in "${binaries[@]}"; do
say "Installing $binary in $install_path"
- install -m 755 "$( build_bin_path "$target" "$profile" "$binary" )" "$install_path"
+ install -m 755 -D -t "$install_path" "$( build_bin_path "$target" "$profile" "$binary" )"
done
}
diff --git a/tools/sandbox.py b/tools/sandbox.py
index fb15eb17fab..3cdcec345a7 100755
--- a/tools/sandbox.py
+++ b/tools/sandbox.py
@@ -68,11 +68,12 @@ def parse_byte_size(param):
else:
bins = get_firecracker_binaries()
-print("This step may take a while to compile Firecracker ...")
cpu_template = None
if args.cpu_template_path is not None:
cpu_template = json.loads(args.cpu_template_path.read_text())
vmfcty = MicroVMFactory(*bins)
+
+print(f"uvm with kernel {args.kernel} ...")
uvm = vmfcty.build(args.kernel, args.rootfs)
uvm.help.enable_console()
uvm.help.resize_disk(uvm.rootfs_file, args.rootfs_size)
@@ -85,3 +86,15 @@ def parse_byte_size(param):
print(cpu_template)
uvm.start()
uvm.get_all_metrics()
+
+kernel_dbg_dir = args.kernel.parent / "debug"
+kernel_dbg = kernel_dbg_dir / args.kernel.name
+print(f"uvm2 with kernel {kernel_dbg} ...")
+uvm2 = vmfcty.build(kernel_dbg, args.rootfs)
+uvm2.spawn()
+uvm2.add_net_iface()
+uvm2.basic_config(vcpu_count=args.vcpus, mem_size_mib=args.guest_mem_size // 2**20)
+uvm2.start()
+# trace-cmd needs this (DNS resolution?)
+uvm2.help.enable_ip_forwarding()
+files = uvm2.help.trace_cmd_guest(["-l", "read_msr"], cmd="sleep 5")
diff --git a/tools/setup-ci-artifacts.sh b/tools/setup-ci-artifacts.sh
new file mode 100755
index 00000000000..0d524658b51
--- /dev/null
+++ b/tools/setup-ci-artifacts.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+# SPDX-License-Identifier: Apache-2.0
+
+# fail if we encounter an error, uninitialized variable or a pipe breaks
+set -eu -o pipefail
+
+TOOLS_DIR=$(dirname $0)
+source "$TOOLS_DIR/functions"
+
+say "Setup CI artifacts"
+cd build/img/$(uname -m)
+
+say "Fix executable permissions"
+find "firecracker" -type f |xargs chmod -c 755
+
+say "Generate SSH key to connect from host"
+if [ ! -s id_rsa ]; then
+ ssh-keygen -f id_rsa -N ""
+fi
+
+for SQUASHFS in *.squashfs; do
+ say "Include SSH key in $SQUASHFS"
+ RSA=$(basename $SQUASHFS .squashfs).id_rsa
+ EXT4=$(basename $SQUASHFS .squashfs).ext4
+ [ -s $SQUASHFS.orig ] && continue
+ unsquashfs $SQUASHFS
+ mkdir -pv squashfs-root/root/.ssh
+ # copy the SSH key into the rootfs
+ if [ ! -s $RSA ]; then
+ # append SSH key to the squashfs image
+ cp -v id_rsa.pub squashfs-root/root/.ssh/authorized_keys
+ cp -v id_rsa $RSA
+ fi
+ # re-squash
+ mv -v $SQUASHFS $SQUASHFS.orig
+ mksquashfs squashfs-root $SQUASHFS -all-root -noappend -comp zstd
+
+ # Create rw ext4 image from ro squashfs
+ [ -f $EXT4 ] && continue
+ say "Converting $SQUASHFS to $EXT4"
+ truncate -s 400M $EXT4
+ mkfs.ext4 -F $EXT4 -d squashfs-root
+ rm -rf squashfs-root
+done
+
+say "Uncompress debuginfo files"
+find . -name "*.debug.gz" -print0 | xargs -P4 -0 -t -n1 gunzip