Compare commits

...

11 Commits

Author SHA1 Message Date
adb7b29354 chore: release (#341)
Co-authored-by: edera-cultivation[bot] <165992271+edera-cultivation[bot]@users.noreply.github.com>
2024-08-22 23:43:03 +00:00
bd448ee8d9 fix(network): allocate host ip from allocation pool (#353) 2024-08-22 22:52:38 +00:00
1647a07226 fix(daemon): turn off trace logging (#352) 2024-08-21 22:04:15 +00:00
151b43eeec feature(zone): kernel command line control on launch (#351) 2024-08-21 20:51:09 +00:00
1123a1a50a build(deps): bump the dep-updates group across 1 directory with 3 updates (#350)
Bumps the dep-updates group with 3 updates in the / directory: [flate2](https://github.com/rust-lang/flate2-rs), [libc](https://github.com/rust-lang/libc) and [reqwest](https://github.com/seanmonstar/reqwest).


Updates `flate2` from 1.0.31 to 1.0.32
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Changelog](https://github.com/rust-lang/flate2-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.0.31...1.0.32)

Updates `libc` from 0.2.157 to 0.2.158
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.158/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.157...0.2.158)

Updates `reqwest` from 0.12.5 to 0.12.7
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.5...v0.12.7)

---
updated-dependencies:
- dependency-name: flate2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
- dependency-name: libc
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
- dependency-name: reqwest
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-21 06:16:57 +00:00
6a6b5b6e0b feature(xen-preflight): test for hypervisor presence explicitly and error if missing (#347)
Fixes #309
2024-08-20 00:22:28 +00:00
274136825a build(deps): bump MarcoIeni/release-plz-action in the dep-updates group (#345)
Bumps the dep-updates group with 1 update: [MarcoIeni/release-plz-action](https://github.com/marcoieni/release-plz-action).


Updates `MarcoIeni/release-plz-action` from 0.5.64 to 0.5.65
- [Release notes](https://github.com/marcoieni/release-plz-action/releases)
- [Commits](92ae919a6b...e28810957e)

---
updated-dependencies:
- dependency-name: MarcoIeni/release-plz-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 00:01:47 +00:00
2ab2cda937 Add support for reading hypervisor console (#344)
* feature(xencall): add hypervisor SYSCTL_readconsole definitions

* feature(hypervisor-dmesg): xencall: add read_console_ring_raw hypercall wrapper

* feature(hypervisor-dmesg): protobuf: add ReadHypervisorConsoleRing RPC

* feature(hypervisor-dmesg): runtime: add read_hypervisor_console wrapper

* feature(hypervisor-dmesg): daemon: add ReadHypervisorConsoleRing rpc implementation

* feature(hypervisor-dmesg): ctl: add host hypervisor-messages command to get hypervisor messages

* feature(hypervisor-dmesg): cli: rename hypervisor-messages command to hv-console

* feature(hypervisor-dmesg): proto: change ReadHypervisorConsoleRing to ReadHypervisorConsole

* feature(hypervisor-dmesg): fix up kratactl protobuf calls
2024-08-19 23:49:02 +00:00
2519d76479 build(deps): bump the dep-updates group with 3 updates (#346)
Bumps the dep-updates group with 3 updates: [arrayvec](https://github.com/bluss/arrayvec), [libc](https://github.com/rust-lang/libc) and [tokio](https://github.com/tokio-rs/tokio).


Updates `arrayvec` from 0.7.4 to 0.7.6
- [Release notes](https://github.com/bluss/arrayvec/releases)
- [Changelog](https://github.com/bluss/arrayvec/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bluss/arrayvec/compare/0.7.4...0.7.6)

Updates `libc` from 0.2.156 to 0.2.157
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.157/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.156...0.2.157)

Updates `tokio` from 1.39.2 to 1.39.3
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.39.2...tokio-1.39.3)

---
updated-dependencies:
- dependency-name: arrayvec
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
- dependency-name: libc
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
- dependency-name: tokio
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 23:46:46 +00:00
dbeb8bf43b build(deps): bump the dep-updates group with 3 updates (#343)
Bumps the dep-updates group with 3 updates: [libc](https://github.com/rust-lang/libc), [clap](https://github.com/clap-rs/clap) and [serde](https://github.com/serde-rs/serde).


Updates `libc` from 0.2.155 to 0.2.156
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.156/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.155...0.2.156)

Updates `clap` from 4.5.15 to 4.5.16
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.15...clap_complete-v4.5.16)

Updates `serde` from 1.0.207 to 1.0.208
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.207...v1.0.208)

---
updated-dependencies:
- dependency-name: libc
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dep-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-16 06:39:43 +00:00
6093627bdd cleanup(ctl): move logic for branching ctl run steps into ControlCommands (#342) 2024-08-16 02:32:30 +00:00
38 changed files with 463 additions and 226 deletions

View File

@ -26,9 +26,8 @@ jobs:
rustup component add rustfmt rustup component add rustfmt
- name: install linux dependencies - name: install linux dependencies
run: ./hack/ci/install-linux-deps.sh run: ./hack/ci/install-linux-deps.sh
# Temporarily ignored: https://github.com/edera-dev/krata/issues/206
- name: cargo fmt - name: cargo fmt
run: ./hack/build/cargo.sh fmt --all -- --check || true run: ./hack/build/cargo.sh fmt --all -- --check
shellcheck: shellcheck:
name: shellcheck name: shellcheck
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -37,7 +37,7 @@ jobs:
- name: install linux dependencies - name: install linux dependencies
run: ./hack/ci/install-linux-deps.sh run: ./hack/ci/install-linux-deps.sh
- name: release-plz - name: release-plz
uses: MarcoIeni/release-plz-action@92ae919a6b3e27c0472659e3a7414ff4a00e833f # v0.5.64 uses: MarcoIeni/release-plz-action@e28810957ef1fedfa89b5e9692e750ce45f62a67 # v0.5.65
env: env:
GITHUB_TOKEN: "${{ steps.generate-token.outputs.token }}" GITHUB_TOKEN: "${{ steps.generate-token.outputs.token }}"
CARGO_REGISTRY_TOKEN: "${{ secrets.KRATA_RELEASE_CARGO_TOKEN }}" CARGO_REGISTRY_TOKEN: "${{ secrets.KRATA_RELEASE_CARGO_TOKEN }}"

View File

@ -6,6 +6,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.0.18](https://github.com/edera-dev/krata/compare/v0.0.17...v0.0.18) - 2024-08-22
### Added
- *(zone)* kernel command line control on launch ([#351](https://github.com/edera-dev/krata/pull/351))
- *(xen-preflight)* test for hypervisor presence explicitly and error if missing ([#347](https://github.com/edera-dev/krata/pull/347))
### Fixed
- *(network)* allocate host ip from allocation pool ([#353](https://github.com/edera-dev/krata/pull/353))
- *(daemon)* turn off trace logging ([#352](https://github.com/edera-dev/krata/pull/352))
### Other
- Add support for reading hypervisor console ([#344](https://github.com/edera-dev/krata/pull/344))
- *(ctl)* move logic for branching ctl run steps into ControlCommands ([#342](https://github.com/edera-dev/krata/pull/342))
- update Cargo.toml dependencies
## [0.0.17](https://github.com/edera-dev/krata/compare/v0.0.16...v0.0.17) - 2024-08-15 ## [0.0.17](https://github.com/edera-dev/krata/compare/v0.0.16...v0.0.17) - 2024-08-15
### Added ### Added

210
Cargo.lock generated
View File

@ -17,6 +17,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.11" version = "0.8.11"
@ -101,9 +107,9 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]] [[package]]
name = "arrayvec" name = "arrayvec"
version = "0.7.4" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@ -241,7 +247,7 @@ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
"libc", "libc",
"miniz_oxide", "miniz_oxide 0.7.4",
"object", "object",
"rustc-demangle", "rustc-demangle",
] ]
@ -381,9 +387,9 @@ checksum = "da987586004ae7c43b7df5e3f7693775068522e1086f8d9b2d74c778a0f43313"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.15" version = "4.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11d8838454fda655dafd3accb2b6e2bea645b9e4078abe84a22ceb947235c5cc" checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -808,12 +814,12 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.31" version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide 0.8.0",
] ]
[[package]] [[package]]
@ -1291,7 +1297,7 @@ dependencies = [
[[package]] [[package]]
name = "krata" name = "krata"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1331,7 +1337,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-buildtools" name = "krata-buildtools"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"env_logger", "env_logger",
@ -1346,7 +1352,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-ctl" name = "krata-ctl"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -1376,7 +1382,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-daemon" name = "krata-daemon"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -1408,14 +1414,14 @@ dependencies = [
[[package]] [[package]]
name = "krata-loopdev" name = "krata-loopdev"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "krata-network" name = "krata-network"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-trait", "async-trait",
@ -1439,7 +1445,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-oci" name = "krata-oci"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-compression", "async-compression",
@ -1466,7 +1472,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-runtime" name = "krata-runtime"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"backhand", "backhand",
@ -1507,7 +1513,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xencall" name = "krata-xencall"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"env_logger", "env_logger",
"libc", "libc",
@ -1520,7 +1526,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenclient" name = "krata-xenclient"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"env_logger", "env_logger",
@ -1538,7 +1544,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenevtchn" name = "krata-xenevtchn"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"libc", "libc",
@ -1550,7 +1556,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xengnt" name = "krata-xengnt"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"libc", "libc",
"nix 0.29.0", "nix 0.29.0",
@ -1559,7 +1565,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenplatform" name = "krata-xenplatform"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"c2rust-bitfields", "c2rust-bitfields",
@ -1582,7 +1588,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-xenstore" name = "krata-xenstore"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"env_logger", "env_logger",
@ -1594,7 +1600,7 @@ dependencies = [
[[package]] [[package]]
name = "krata-zone" name = "krata-zone"
version = "0.0.17" version = "0.0.18"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cgroups-rs", "cgroups-rs",
@ -1626,9 +1632,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.155" version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]] [[package]]
name = "libredox" name = "libredox"
@ -1716,6 +1722,15 @@ dependencies = [
"adler", "adler",
] ]
[[package]]
name = "miniz_oxide"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "1.0.2" version = "1.0.2"
@ -1929,7 +1944,7 @@ dependencies = [
"libc", "libc",
"redox_syscall 0.5.3", "redox_syscall 0.5.3",
"smallvec", "smallvec",
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
@ -2385,9 +2400,9 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.12.5" version = "0.12.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
dependencies = [ dependencies = [
"base64", "base64",
"bytes", "bytes",
@ -2422,7 +2437,7 @@ dependencies = [
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
"webpki-roots", "webpki-roots",
"winreg", "windows-registry",
] ]
[[package]] [[package]]
@ -2561,9 +2576,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.207" version = "1.0.208"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5665e14a49a4ea1b91029ba7d3bca9f299e1f7cfa194388ccc20f14743e784f2" checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@ -2580,9 +2595,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.207" version = "1.0.208"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aea2634c86b0e8ef2cfdc0c340baede54ec27b1e46febd7f80dffb2aa44a00e" checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2832,6 +2847,9 @@ name = "sync_wrapper"
version = "1.0.1" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
dependencies = [
"futures-core",
]
[[package]] [[package]]
name = "sys-mount" name = "sys-mount"
@ -2922,9 +2940,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.39.2" version = "1.39.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@ -3419,7 +3437,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
dependencies = [ dependencies = [
"windows-core", "windows-core",
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
@ -3430,8 +3448,8 @@ checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
dependencies = [ dependencies = [
"windows-implement", "windows-implement",
"windows-interface", "windows-interface",
"windows-result", "windows-result 0.1.2",
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
@ -3456,22 +3474,43 @@ dependencies = [
"syn 2.0.74", "syn 2.0.74",
] ]
[[package]]
name = "windows-registry"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
dependencies = [
"windows-result 0.2.0",
"windows-strings",
"windows-targets",
]
[[package]] [[package]]
name = "windows-result" name = "windows-result"
version = "0.1.2" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
dependencies = [ dependencies = [
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
name = "windows-sys" name = "windows-result"
version = "0.48.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
dependencies = [ dependencies = [
"windows-targets 0.48.5", "windows-targets",
]
[[package]]
name = "windows-strings"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
dependencies = [
"windows-result 0.2.0",
"windows-targets",
] ]
[[package]] [[package]]
@ -3480,7 +3519,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets 0.52.6", "windows-targets",
] ]
[[package]] [[package]]
@ -3489,22 +3528,7 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [ dependencies = [
"windows-targets 0.52.6", "windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
] ]
[[package]] [[package]]
@ -3513,46 +3537,28 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.52.6", "windows_aarch64_gnullvm",
"windows_aarch64_msvc 0.52.6", "windows_aarch64_msvc",
"windows_i686_gnu 0.52.6", "windows_i686_gnu",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc 0.52.6", "windows_i686_msvc",
"windows_x86_64_gnu 0.52.6", "windows_x86_64_gnu",
"windows_x86_64_gnullvm 0.52.6", "windows_x86_64_gnullvm",
"windows_x86_64_msvc 0.52.6", "windows_x86_64_msvc",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.6" version = "0.52.6"
@ -3565,48 +3571,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.6" version = "0.52.6"
@ -3631,16 +3613,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "wyz" name = "wyz"
version = "0.5.1" version = "0.5.1"

View File

@ -18,14 +18,14 @@ members = [
resolver = "2" resolver = "2"
[workspace.package] [workspace.package]
version = "0.0.17" version = "0.0.18"
homepage = "https://krata.dev" homepage = "https://krata.dev"
license = "Apache-2.0" license = "Apache-2.0"
repository = "https://github.com/edera-dev/krata" repository = "https://github.com/edera-dev/krata"
[workspace.dependencies] [workspace.dependencies]
anyhow = "1.0" anyhow = "1.0"
arrayvec = "0.7.4" arrayvec = "0.7.6"
async-compression = "0.4.12" async-compression = "0.4.12"
async-stream = "0.3.5" async-stream = "0.3.5"
async-trait = "0.1.81" async-trait = "0.1.81"
@ -94,7 +94,7 @@ walkdir = "2"
xz2 = "0.1" xz2 = "0.1"
[workspace.dependencies.clap] [workspace.dependencies.clap]
version = "4.5.15" version = "4.5.16"
features = ["derive"] features = ["derive"]
[workspace.dependencies.prost-reflect] [workspace.dependencies.prost-reflect]
@ -102,12 +102,12 @@ version = "0.14.0"
features = ["derive"] features = ["derive"]
[workspace.dependencies.reqwest] [workspace.dependencies.reqwest]
version = "0.12.5" version = "0.12.7"
default-features = false default-features = false
features = ["rustls-tls"] features = ["rustls-tls"]
[workspace.dependencies.serde] [workspace.dependencies.serde]
version = "1.0.207" version = "1.0.208"
features = ["derive"] features = ["derive"]
[workspace.dependencies.sys-mount] [workspace.dependencies.sys-mount]
@ -115,7 +115,7 @@ version = "3.0.0"
default-features = false default-features = false
[workspace.dependencies.tokio] [workspace.dependencies.tokio]
version = "1.39.2" version = "1.39.3"
features = ["full"] features = ["full"]
[workspace.dependencies.tokio-stream] [workspace.dependencies.tokio-stream]

View File

@ -16,7 +16,7 @@ oci-spec = { workspace = true }
scopeguard = { workspace = true } scopeguard = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
tokio-stream = { workspace = true } tokio-stream = { workspace = true }
krata-oci = { path = "../oci", version = "^0.0.17" } krata-oci = { path = "../oci", version = "^0.0.18" }
krata-tokio-tar = { workspace = true } krata-tokio-tar = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }

View File

@ -20,7 +20,7 @@ env_logger = { workspace = true }
fancy-duration = { workspace = true } fancy-duration = { workspace = true }
human_bytes = { workspace = true } human_bytes = { workspace = true }
indicatif = { workspace = true } indicatif = { workspace = true }
krata = { path = "../krata", version = "^0.0.17" } krata = { path = "../krata", version = "^0.0.18" }
log = { workspace = true } log = { workspace = true }
prost-reflect = { workspace = true, features = ["serde"] } prost-reflect = { workspace = true, features = ["serde"] }
prost-types = { workspace = true } prost-types = { workspace = true }

View File

@ -0,0 +1,23 @@
use anyhow::Result;
use clap::Parser;
use krata::v1::control::{
control_service_client::ControlServiceClient, ReadHypervisorConsoleRequest,
};
use tonic::{transport::Channel, Request};
#[derive(Parser)]
#[command(about = "Display hypervisor console output")]
pub struct HostHvConsoleCommand {}
impl HostHvConsoleCommand {
pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
let response = client
.read_hypervisor_console(Request::new(ReadHypervisorConsoleRequest {}))
.await?
.into_inner();
print!("{}", response.data);
Ok(())
}
}

View File

@ -17,6 +17,9 @@ impl HostStatusCommand {
println!("Host UUID: {}", response.host_uuid); println!("Host UUID: {}", response.host_uuid);
println!("Host Domain: {}", response.host_domid); println!("Host Domain: {}", response.host_domid);
println!("Krata Version: {}", response.krata_version); println!("Krata Version: {}", response.krata_version);
println!("Host IPv4: {}", response.host_ipv4);
println!("Host IPv6: {}", response.host_ipv6);
println!("Host Ethernet Address: {}", response.host_mac);
Ok(()) Ok(())
} }
} }

View File

@ -6,10 +6,12 @@ use krata::events::EventStream;
use krata::v1::control::control_service_client::ControlServiceClient; use krata::v1::control::control_service_client::ControlServiceClient;
use crate::cli::host::cpu_topology::HostCpuTopologyCommand; use crate::cli::host::cpu_topology::HostCpuTopologyCommand;
use crate::cli::host::hv_console::HostHvConsoleCommand;
use crate::cli::host::identify::HostStatusCommand; use crate::cli::host::identify::HostStatusCommand;
use crate::cli::host::idm_snoop::HostIdmSnoopCommand; use crate::cli::host::idm_snoop::HostIdmSnoopCommand;
pub mod cpu_topology; pub mod cpu_topology;
pub mod hv_console;
pub mod identify; pub mod identify;
pub mod idm_snoop; pub mod idm_snoop;
@ -35,6 +37,7 @@ pub enum HostCommands {
CpuTopology(HostCpuTopologyCommand), CpuTopology(HostCpuTopologyCommand),
Status(HostStatusCommand), Status(HostStatusCommand),
IdmSnoop(HostIdmSnoopCommand), IdmSnoop(HostIdmSnoopCommand),
HvConsole(HostHvConsoleCommand),
} }
impl HostCommands { impl HostCommands {
@ -49,6 +52,8 @@ impl HostCommands {
HostCommands::Status(status) => status.run(client).await, HostCommands::Status(status) => status.run(client).await,
HostCommands::IdmSnoop(snoop) => snoop.run(client, events).await, HostCommands::IdmSnoop(snoop) => snoop.run(client, events).await,
HostCommands::HvConsole(hvconsole) => hvconsole.run(client).await,
} }
} }
} }

View File

@ -31,6 +31,7 @@ pub struct ControlCommand {
command: ControlCommands, command: ControlCommands,
} }
#[allow(clippy::large_enum_variant)]
#[derive(Parser)] #[derive(Parser)]
pub enum ControlCommands { pub enum ControlCommands {
Zone(ZoneCommand), Zone(ZoneCommand),
@ -43,8 +44,17 @@ impl ControlCommand {
pub async fn run(self) -> Result<()> { pub async fn run(self) -> Result<()> {
let client = ControlClientProvider::dial(self.connection.parse()?).await?; let client = ControlClientProvider::dial(self.connection.parse()?).await?;
let events = EventStream::open(client.clone()).await?; let events = EventStream::open(client.clone()).await?;
self.command.run(client, events).await
}
}
match self.command { impl ControlCommands {
pub async fn run(
self,
client: ControlServiceClient<Channel>,
events: EventStream,
) -> Result<()> {
match self {
ControlCommands::Zone(zone) => zone.run(client, events).await, ControlCommands::Zone(zone) => zone.run(client, events).await,
ControlCommands::Image(image) => image.run(client, events).await, ControlCommands::Image(image) => image.run(client, events).await,

View File

@ -6,8 +6,8 @@ use krata::{
events::EventStream, events::EventStream,
v1::{ v1::{
common::{ common::{
zone_image_spec::Image, OciImageFormat, ZoneImageSpec, ZoneOciImageSpec, zone_image_spec::Image, OciImageFormat, ZoneImageSpec, ZoneKernelOptionsSpec,
ZoneResourceSpec, ZoneSpec, ZoneSpecDevice, ZoneState, ZoneTaskSpec, ZoneOciImageSpec, ZoneResourceSpec, ZoneSpec, ZoneSpecDevice, ZoneState, ZoneTaskSpec,
ZoneTaskSpecEnvVar, ZoneTaskSpecEnvVar,
}, },
control::{ control::{
@ -91,6 +91,10 @@ pub struct ZoneLaunchCommand {
initrd: Option<String>, initrd: Option<String>,
#[arg(short = 'w', long, help = "Working directory")] #[arg(short = 'w', long, help = "Working directory")]
working_directory: Option<String>, working_directory: Option<String>,
#[arg(long, help = "Enable verbose logging on the kernel")]
kernel_verbose: bool,
#[arg(long, help = "Additional kernel cmdline options")]
kernel_cmdline_append: Option<String>,
#[arg(help = "Container image for zone to use")] #[arg(help = "Container image for zone to use")]
oci: String, oci: String,
#[arg( #[arg(
@ -166,6 +170,10 @@ impl ZoneLaunchCommand {
.iter() .iter()
.map(|name| ZoneSpecDevice { name: name.clone() }) .map(|name| ZoneSpecDevice { name: name.clone() })
.collect(), .collect(),
kernel_options: Some(ZoneKernelOptionsSpec {
verbose: self.kernel_verbose,
cmdline_append: self.kernel_cmdline_append.clone().unwrap_or_default(),
}),
}), }),
}; };
let response = client let response = client

View File

@ -26,7 +26,7 @@ pub mod logs;
pub mod metrics; pub mod metrics;
pub mod resolve; pub mod resolve;
pub mod top; pub mod top;
mod update_resources; pub mod update_resources;
pub mod watch; pub mod watch;
#[derive(Parser)] #[derive(Parser)]
@ -46,6 +46,7 @@ impl ZoneCommand {
} }
} }
#[allow(clippy::large_enum_variant)]
#[derive(Subcommand)] #[derive(Subcommand)]
pub enum ZoneCommands { pub enum ZoneCommands {
Attach(ZoneAttachCommand), Attach(ZoneAttachCommand),

View File

@ -19,9 +19,9 @@ clap = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
ipnetwork = { workspace = true } ipnetwork = { workspace = true }
krata = { path = "../krata", version = "^0.0.17" } krata = { path = "../krata", version = "^0.0.18" }
krata-oci = { path = "../oci", version = "^0.0.17" } krata-oci = { path = "../oci", version = "^0.0.18" }
krata-runtime = { path = "../runtime", version = "^0.0.17" } krata-runtime = { path = "../runtime", version = "^0.0.18" }
log = { workspace = true } log = { workspace = true }
prost = { workspace = true } prost = { workspace = true }
redb = { workspace = true } redb = { workspace = true }

View File

@ -15,7 +15,7 @@ use kratad::command::DaemonCommand;
async fn main() -> Result<()> { async fn main() -> Result<()> {
let mut builder = env_logger::Builder::new(); let mut builder = env_logger::Builder::new();
builder builder
.filter_level(LevelFilter::Trace) .filter_level(LevelFilter::Info)
.parse_default_env() .parse_default_env()
.filter(Some("backhand::filesystem::writer"), LevelFilter::Warn); .filter(Some("backhand::filesystem::writer"), LevelFilter::Warn);

View File

@ -97,7 +97,7 @@ fn default_network_ipv4() -> DaemonIpv4NetworkConfig {
} }
fn default_network_ipv4_subnet() -> String { fn default_network_ipv4_subnet() -> String {
"10.75.80.0/24".to_string() "10.75.0.0/16".to_string()
} }
fn default_network_ipv6() -> DaemonIpv6NetworkConfig { fn default_network_ipv6() -> DaemonIpv6NetworkConfig {

View File

@ -24,7 +24,7 @@ type BufferMap = Arc<Mutex<HashMap<u32, ConsoleBuffer>>>;
#[derive(Clone)] #[derive(Clone)]
pub struct DaemonConsoleHandle { pub struct DaemonConsoleHandle {
glt: ZoneLookupTable, zlt: ZoneLookupTable,
listeners: ListenerMap, listeners: ListenerMap,
buffers: BufferMap, buffers: BufferMap,
sender: Sender<(u32, Vec<u8>)>, sender: Sender<(u32, Vec<u8>)>,
@ -57,7 +57,7 @@ impl DaemonConsoleHandle {
uuid: Uuid, uuid: Uuid,
sender: Sender<Vec<u8>>, sender: Sender<Vec<u8>>,
) -> Result<DaemonConsoleAttachHandle> { ) -> Result<DaemonConsoleAttachHandle> {
let Some(domid) = self.glt.lookup_domid_by_uuid(&uuid).await else { let Some(domid) = self.zlt.lookup_domid_by_uuid(&uuid).await else {
return Err(anyhow!("unable to find domain {}", uuid)); return Err(anyhow!("unable to find domain {}", uuid));
}; };
let buffers = self.buffers.lock().await; let buffers = self.buffers.lock().await;
@ -84,7 +84,7 @@ impl Drop for DaemonConsoleHandle {
} }
pub struct DaemonConsole { pub struct DaemonConsole {
glt: ZoneLookupTable, zlt: ZoneLookupTable,
listeners: ListenerMap, listeners: ListenerMap,
buffers: BufferMap, buffers: BufferMap,
receiver: Receiver<(u32, Option<Vec<u8>>)>, receiver: Receiver<(u32, Option<Vec<u8>>)>,
@ -93,14 +93,14 @@ pub struct DaemonConsole {
} }
impl DaemonConsole { impl DaemonConsole {
pub async fn new(glt: ZoneLookupTable) -> Result<DaemonConsole> { pub async fn new(zlt: ZoneLookupTable) -> Result<DaemonConsole> {
let (service, sender, receiver) = let (service, sender, receiver) =
ChannelService::new("krata-console".to_string(), Some(0)).await?; ChannelService::new("krata-console".to_string(), Some(0)).await?;
let task = service.launch().await?; let task = service.launch().await?;
let listeners = Arc::new(Mutex::new(HashMap::new())); let listeners = Arc::new(Mutex::new(HashMap::new()));
let buffers = Arc::new(Mutex::new(HashMap::new())); let buffers = Arc::new(Mutex::new(HashMap::new()));
Ok(DaemonConsole { Ok(DaemonConsole {
glt, zlt,
listeners, listeners,
buffers, buffers,
receiver, receiver,
@ -110,7 +110,7 @@ impl DaemonConsole {
} }
pub async fn launch(mut self) -> Result<DaemonConsoleHandle> { pub async fn launch(mut self) -> Result<DaemonConsoleHandle> {
let glt = self.glt.clone(); let zlt = self.zlt.clone();
let listeners = self.listeners.clone(); let listeners = self.listeners.clone();
let buffers = self.buffers.clone(); let buffers = self.buffers.clone();
let sender = self.sender.clone(); let sender = self.sender.clone();
@ -120,7 +120,7 @@ impl DaemonConsole {
} }
}); });
Ok(DaemonConsoleHandle { Ok(DaemonConsoleHandle {
glt, zlt,
listeners, listeners,
buffers, buffers,
sender, sender,

View File

@ -1,4 +1,5 @@
use crate::db::zone::ZoneStore; use crate::db::zone::ZoneStore;
use crate::ip::assignment::IpAssignment;
use crate::{ use crate::{
command::DaemonCommand, console::DaemonConsoleHandle, devices::DaemonDeviceManager, command::DaemonCommand, console::DaemonConsoleHandle, devices::DaemonDeviceManager,
event::DaemonEventContext, idm::DaemonIdmHandle, metrics::idm_metric_to_api, event::DaemonEventContext, idm::DaemonIdmHandle, metrics::idm_metric_to_api,
@ -25,8 +26,9 @@ use krata::{
ExecInsideZoneRequest, GetHostCpuTopologyReply, GetHostCpuTopologyRequest, ExecInsideZoneRequest, GetHostCpuTopologyReply, GetHostCpuTopologyRequest,
HostCpuTopologyInfo, HostStatusReply, HostStatusRequest, ListDevicesReply, HostCpuTopologyInfo, HostStatusReply, HostStatusRequest, ListDevicesReply,
ListDevicesRequest, ListZonesReply, ListZonesRequest, PullImageReply, PullImageRequest, ListDevicesRequest, ListZonesReply, ListZonesRequest, PullImageReply, PullImageRequest,
ReadZoneMetricsReply, ReadZoneMetricsRequest, ResolveZoneIdReply, ResolveZoneIdRequest, ReadHypervisorConsoleReply, ReadHypervisorConsoleRequest, ReadZoneMetricsReply,
SnoopIdmReply, SnoopIdmRequest, UpdateZoneResourcesReply, UpdateZoneResourcesRequest, ReadZoneMetricsRequest, ResolveZoneIdReply, ResolveZoneIdRequest, SnoopIdmReply,
SnoopIdmRequest, UpdateZoneResourcesReply, UpdateZoneResourcesRequest,
WatchEventsReply, WatchEventsRequest, ZoneConsoleReply, ZoneConsoleRequest, WatchEventsReply, WatchEventsRequest, ZoneConsoleReply, ZoneConsoleRequest,
}, },
}, },
@ -67,12 +69,13 @@ impl From<ApiError> for Status {
#[derive(Clone)] #[derive(Clone)]
pub struct DaemonControlService { pub struct DaemonControlService {
glt: ZoneLookupTable, zlt: ZoneLookupTable,
devices: DaemonDeviceManager, devices: DaemonDeviceManager,
events: DaemonEventContext, events: DaemonEventContext,
console: DaemonConsoleHandle, console: DaemonConsoleHandle,
idm: DaemonIdmHandle, idm: DaemonIdmHandle,
zones: ZoneStore, zones: ZoneStore,
ip: IpAssignment,
zone_reconciler_notify: Sender<Uuid>, zone_reconciler_notify: Sender<Uuid>,
packer: OciPackerService, packer: OciPackerService,
runtime: Runtime, runtime: Runtime,
@ -81,23 +84,25 @@ pub struct DaemonControlService {
impl DaemonControlService { impl DaemonControlService {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
glt: ZoneLookupTable, zlt: ZoneLookupTable,
devices: DaemonDeviceManager, devices: DaemonDeviceManager,
events: DaemonEventContext, events: DaemonEventContext,
console: DaemonConsoleHandle, console: DaemonConsoleHandle,
idm: DaemonIdmHandle, idm: DaemonIdmHandle,
zones: ZoneStore, zones: ZoneStore,
ip: IpAssignment,
zone_reconciler_notify: Sender<Uuid>, zone_reconciler_notify: Sender<Uuid>,
packer: OciPackerService, packer: OciPackerService,
runtime: Runtime, runtime: Runtime,
) -> Self { ) -> Self {
Self { Self {
glt, zlt,
devices, devices,
events, events,
console, console,
idm, idm,
zones, zones,
ip,
zone_reconciler_notify, zone_reconciler_notify,
packer, packer,
runtime, runtime,
@ -137,10 +142,29 @@ impl ControlService for DaemonControlService {
request: Request<HostStatusRequest>, request: Request<HostStatusRequest>,
) -> Result<Response<HostStatusReply>, Status> { ) -> Result<Response<HostStatusReply>, Status> {
let _ = request.into_inner(); let _ = request.into_inner();
let host_reservation =
self.ip
.retrieve(self.zlt.host_uuid())
.await
.map_err(|x| ApiError {
message: x.to_string(),
})?;
Ok(Response::new(HostStatusReply { Ok(Response::new(HostStatusReply {
host_domid: self.glt.host_domid(), host_domid: self.zlt.host_domid(),
host_uuid: self.glt.host_uuid().to_string(), host_uuid: self.zlt.host_uuid().to_string(),
krata_version: DaemonCommand::version(), krata_version: DaemonCommand::version(),
host_ipv4: host_reservation
.as_ref()
.map(|x| format!("{}/{}", x.ipv4, x.ipv4_prefix))
.unwrap_or_default(),
host_ipv6: host_reservation
.as_ref()
.map(|x| format!("{}/{}", x.ipv6, x.ipv6_prefix))
.unwrap_or_default(),
host_mac: host_reservation
.as_ref()
.map(|x| x.mac.to_string().to_lowercase().replace('-', ":"))
.unwrap_or_default(),
})) }))
} }
@ -167,7 +191,7 @@ impl ControlService for DaemonControlService {
exit_status: None, exit_status: None,
error_status: None, error_status: None,
resource_status: None, resource_status: None,
host: self.glt.host_uuid().to_string(), host: self.zlt.host_uuid().to_string(),
domid: u32::MAX, domid: u32::MAX,
}), }),
spec: Some(spec), spec: Some(spec),
@ -530,13 +554,13 @@ impl ControlService for DaemonControlService {
) -> Result<Response<Self::SnoopIdmStream>, Status> { ) -> Result<Response<Self::SnoopIdmStream>, Status> {
let _ = request.into_inner(); let _ = request.into_inner();
let mut messages = self.idm.snoop(); let mut messages = self.idm.snoop();
let glt = self.glt.clone(); let zlt = self.zlt.clone();
let output = try_stream! { let output = try_stream! {
while let Ok(event) = messages.recv().await { while let Ok(event) = messages.recv().await {
let Some(from_uuid) = glt.lookup_uuid_by_domid(event.from).await else { let Some(from_uuid) = zlt.lookup_uuid_by_domid(event.from).await else {
continue; continue;
}; };
let Some(to_uuid) = glt.lookup_uuid_by_domid(event.to).await else { let Some(to_uuid) = zlt.lookup_uuid_by_domid(event.to).await else {
continue; continue;
}; };
yield SnoopIdmReply { from: from_uuid.to_string(), to: to_uuid.to_string(), packet: Some(event.packet) }; yield SnoopIdmReply { from: from_uuid.to_string(), to: to_uuid.to_string(), packet: Some(event.packet) };
@ -710,4 +734,20 @@ impl ControlService for DaemonControlService {
.map_err(ApiError::from)?; .map_err(ApiError::from)?;
Ok(Response::new(UpdateZoneResourcesReply {})) Ok(Response::new(UpdateZoneResourcesReply {}))
} }
async fn read_hypervisor_console(
&self,
_request: Request<ReadHypervisorConsoleRequest>,
) -> Result<Response<ReadHypervisorConsoleReply>, Status> {
let data = self
.runtime
.read_hypervisor_console(false)
.await
.map_err(|error| ApiError {
message: error.to_string(),
})?;
Ok(Response::new(ReadHypervisorConsoleReply {
data: data.to_string(),
}))
}
} }

View File

@ -31,7 +31,7 @@ type ClientMap = Arc<Mutex<HashMap<u32, IdmInternalClient>>>;
#[derive(Clone)] #[derive(Clone)]
pub struct DaemonIdmHandle { pub struct DaemonIdmHandle {
glt: ZoneLookupTable, zlt: ZoneLookupTable,
clients: ClientMap, clients: ClientMap,
feeds: BackendFeedMap, feeds: BackendFeedMap,
tx_sender: Sender<(u32, IdmTransportPacket)>, tx_sender: Sender<(u32, IdmTransportPacket)>,
@ -45,7 +45,7 @@ impl DaemonIdmHandle {
} }
pub async fn client(&self, uuid: Uuid) -> Result<IdmInternalClient> { pub async fn client(&self, uuid: Uuid) -> Result<IdmInternalClient> {
let Some(domid) = self.glt.lookup_domid_by_uuid(&uuid).await else { let Some(domid) = self.zlt.lookup_domid_by_uuid(&uuid).await else {
return Err(anyhow!("unable to find domain {}", uuid)); return Err(anyhow!("unable to find domain {}", uuid));
}; };
self.client_by_domid(domid).await self.client_by_domid(domid).await
@ -72,7 +72,7 @@ pub struct DaemonIdmSnoopPacket {
} }
pub struct DaemonIdm { pub struct DaemonIdm {
glt: ZoneLookupTable, zlt: ZoneLookupTable,
clients: ClientMap, clients: ClientMap,
feeds: BackendFeedMap, feeds: BackendFeedMap,
tx_sender: Sender<(u32, IdmTransportPacket)>, tx_sender: Sender<(u32, IdmTransportPacket)>,
@ -84,7 +84,7 @@ pub struct DaemonIdm {
} }
impl DaemonIdm { impl DaemonIdm {
pub async fn new(glt: ZoneLookupTable) -> Result<DaemonIdm> { pub async fn new(zlt: ZoneLookupTable) -> Result<DaemonIdm> {
debug!("allocating channel service for idm"); debug!("allocating channel service for idm");
let (service, tx_raw_sender, rx_receiver) = let (service, tx_raw_sender, rx_receiver) =
ChannelService::new("krata-channel".to_string(), None).await?; ChannelService::new("krata-channel".to_string(), None).await?;
@ -98,7 +98,7 @@ impl DaemonIdm {
let feeds = Arc::new(Mutex::new(HashMap::new())); let feeds = Arc::new(Mutex::new(HashMap::new()));
Ok(DaemonIdm { Ok(DaemonIdm {
glt, zlt,
rx_receiver, rx_receiver,
tx_receiver, tx_receiver,
tx_sender, tx_sender,
@ -111,7 +111,7 @@ impl DaemonIdm {
} }
pub async fn launch(mut self) -> Result<DaemonIdmHandle> { pub async fn launch(mut self) -> Result<DaemonIdmHandle> {
let glt = self.glt.clone(); let zlt = self.zlt.clone();
let clients = self.clients.clone(); let clients = self.clients.clone();
let feeds = self.feeds.clone(); let feeds = self.feeds.clone();
let tx_sender = self.tx_sender.clone(); let tx_sender = self.tx_sender.clone();
@ -124,7 +124,7 @@ impl DaemonIdm {
} }
}); });
Ok(DaemonIdmHandle { Ok(DaemonIdmHandle {
glt, zlt,
clients, clients,
feeds, feeds,
tx_sender, tx_sender,

View File

@ -36,13 +36,13 @@ impl IpAssignment {
store: IpReservationStore, store: IpReservationStore,
) -> Result<Self> { ) -> Result<Self> {
let mut state = IpAssignment::fetch_current_state(&store).await?; let mut state = IpAssignment::fetch_current_state(&store).await?;
let reservation = if let Some(reservation) = store.read(host_uuid).await? { let gateway_reservation = if let Some(reservation) = store.read(Uuid::nil()).await? {
reservation reservation
} else { } else {
IpAssignment::allocate( IpAssignment::allocate(
&mut state, &mut state,
&store, &store,
host_uuid, Uuid::nil(),
ipv4_network, ipv4_network,
ipv6_network, ipv6_network,
None, None,
@ -51,12 +51,27 @@ impl IpAssignment {
) )
.await? .await?
}; };
if store.read(host_uuid).await?.is_none() {
let _ = IpAssignment::allocate(
&mut state,
&store,
host_uuid,
ipv4_network,
ipv6_network,
Some(gateway_reservation.gateway_ipv4),
Some(gateway_reservation.gateway_ipv6),
Some(gateway_reservation.gateway_mac),
)
.await?;
}
let assignment = IpAssignment { let assignment = IpAssignment {
ipv4_network, ipv4_network,
ipv6_network, ipv6_network,
gateway_ipv4: reservation.ipv4, gateway_ipv4: gateway_reservation.ipv4,
gateway_ipv6: reservation.ipv6, gateway_ipv6: gateway_reservation.ipv6,
gateway_mac: reservation.gateway_mac, gateway_mac: gateway_reservation.mac,
store, store,
state: Arc::new(RwLock::new(state)), state: Arc::new(RwLock::new(state)),
}; };
@ -92,13 +107,17 @@ impl IpAssignment {
.filter(|ip| { .filter(|ip| {
let last = ip.octets()[3]; let last = ip.octets()[3];
// filter for IPs ending in .1 to .250 because .250+ can have special meaning // filter for IPs ending in .1 to .250 because .250+ can have special meaning
last > 0 && last < 250 (1..250).contains(&last)
}) })
.find(|ip| !state.ipv4.contains_key(ip)); .find(|ip| !state.ipv4.contains_key(ip));
let found_ipv6: Option<Ipv6Addr> = ipv6_network let found_ipv6: Option<Ipv6Addr> = ipv6_network
.iter() .iter()
.filter(|ip| !ip.is_loopback() && !ip.is_multicast()) .filter(|ip| !ip.is_loopback() && !ip.is_multicast())
.filter(|ip| {
let last = ip.octets()[15];
last > 0
})
.find(|ip| !state.ipv6.contains_key(ip)); .find(|ip| !state.ipv6.contains_key(ip));
let Some(ipv4) = found_ipv4 else { let Some(ipv4) = found_ipv4 else {
@ -114,7 +133,7 @@ impl IpAssignment {
}; };
let mut mac = MacAddr6::random(); let mut mac = MacAddr6::random();
mac.set_local(false); mac.set_local(true);
mac.set_multicast(false); mac.set_multicast(false);
let reservation = IpReservation { let reservation = IpReservation {

View File

@ -45,9 +45,10 @@ pub mod zlt;
pub struct Daemon { pub struct Daemon {
store: String, store: String,
_config: Arc<DaemonConfig>, _config: Arc<DaemonConfig>,
glt: ZoneLookupTable, zlt: ZoneLookupTable,
devices: DaemonDeviceManager, devices: DaemonDeviceManager,
zones: ZoneStore, zones: ZoneStore,
ip: IpAssignment,
events: DaemonEventContext, events: DaemonEventContext,
zone_reconciler_task: JoinHandle<()>, zone_reconciler_task: JoinHandle<()>,
zone_reconciler_notify: Sender<Uuid>, zone_reconciler_notify: Sender<Uuid>,
@ -127,7 +128,7 @@ impl Daemon {
let ipv4_network = Ipv4Network::from_str(&config.network.ipv4.subnet)?; let ipv4_network = Ipv4Network::from_str(&config.network.ipv4.subnet)?;
let ipv6_network = Ipv6Network::from_str(&config.network.ipv6.subnet)?; let ipv6_network = Ipv6Network::from_str(&config.network.ipv6.subnet)?;
let ip_reservation_store = IpReservationStore::open(database)?; let ip_reservation_store = IpReservationStore::open(database)?;
let ip_assignment = let ip =
IpAssignment::new(host_uuid, ipv4_network, ipv6_network, ip_reservation_store).await?; IpAssignment::new(host_uuid, ipv4_network, ipv6_network, ip_reservation_store).await?;
debug!("initializing zone reconciler"); debug!("initializing zone reconciler");
let zone_reconciler = ZoneReconciler::new( let zone_reconciler = ZoneReconciler::new(
@ -141,7 +142,7 @@ impl Daemon {
kernel_path, kernel_path,
initrd_path, initrd_path,
addons_path, addons_path,
ip_assignment, ip.clone(),
config.clone(), config.clone(),
)?; )?;
@ -161,9 +162,10 @@ impl Daemon {
Ok(Self { Ok(Self {
store, store,
_config: config, _config: config,
glt: zlt, zlt,
devices, devices,
zones, zones,
ip,
events, events,
zone_reconciler_task, zone_reconciler_task,
zone_reconciler_notify, zone_reconciler_notify,
@ -178,12 +180,13 @@ impl Daemon {
pub async fn listen(&mut self, addr: ControlDialAddress) -> Result<()> { pub async fn listen(&mut self, addr: ControlDialAddress) -> Result<()> {
debug!("starting control service"); debug!("starting control service");
let control_service = DaemonControlService::new( let control_service = DaemonControlService::new(
self.glt.clone(), self.zlt.clone(),
self.devices.clone(), self.devices.clone(),
self.events.clone(), self.events.clone(),
self.console.clone(), self.console.clone(),
self.idm.clone(), self.idm.clone(),
self.zones.clone(), self.zones.clone(),
self.ip.clone(),
self.zone_reconciler_notify.clone(), self.zone_reconciler_notify.clone(),
self.packer.clone(), self.packer.clone(),
self.runtime.clone(), self.runtime.clone(),

View File

@ -184,10 +184,19 @@ impl ZoneCreator<'_> {
initial_resources.max_cpus = initial_resources.target_cpus; initial_resources.max_cpus = initial_resources.target_cpus;
} }
spec.initial_resources = Some(initial_resources); spec.initial_resources = Some(initial_resources);
let kernel_options = spec.kernel_options.clone().unwrap_or_default();
let info = self let info = self
.runtime .runtime
.launch(ZoneLaunchRequest { .launch(ZoneLaunchRequest {
format: LaunchPackedFormat::Squashfs, format: match image.format {
OciPackedFormat::Squashfs => LaunchPackedFormat::Squashfs,
OciPackedFormat::Erofs => LaunchPackedFormat::Erofs,
_ => {
return Err(anyhow!(
"oci image is in an invalid format, which isn't compatible with launch"
));
}
},
uuid: Some(uuid), uuid: Some(uuid),
name: if spec.name.is_empty() { name: if spec.name.is_empty() {
None None
@ -208,7 +217,8 @@ impl ZoneCreator<'_> {
.map(|x| (x.key.clone(), x.value.clone())) .map(|x| (x.key.clone(), x.value.clone()))
.collect::<HashMap<_, _>>(), .collect::<HashMap<_, _>>(),
run: empty_vec_optional(task.command.clone()), run: empty_vec_optional(task.command.clone()),
debug: false, kernel_verbose: kernel_options.verbose,
kernel_cmdline_append: kernel_options.cmdline_append,
addons_image: Some(self.addons_path.to_path_buf()), addons_image: Some(self.addons_path.to_path_buf()),
network: ZoneLaunchNetwork { network: ZoneLaunchNetwork {
ipv4: reservation.ipv4.to_string(), ipv4: reservation.ipv4.to_string(),

View File

@ -380,9 +380,9 @@ pub fn ip_reservation_to_network_status(ip: &IpReservation) -> ZoneNetworkStatus
ZoneNetworkStatus { ZoneNetworkStatus {
zone_ipv4: format!("{}/{}", ip.ipv4, ip.ipv4_prefix), zone_ipv4: format!("{}/{}", ip.ipv4, ip.ipv4_prefix),
zone_ipv6: format!("{}/{}", ip.ipv6, ip.ipv6_prefix), zone_ipv6: format!("{}/{}", ip.ipv6, ip.ipv6_prefix),
zone_mac: ip.mac.to_string().replace('-', ":"), zone_mac: ip.mac.to_string().to_lowercase().replace('-', ":"),
gateway_ipv4: format!("{}/{}", ip.gateway_ipv4, ip.ipv4_prefix), gateway_ipv4: format!("{}/{}", ip.gateway_ipv4, ip.ipv4_prefix),
gateway_ipv6: format!("{}/{}", ip.gateway_ipv6, ip.ipv6_prefix), gateway_ipv6: format!("{}/{}", ip.gateway_ipv6, ip.ipv6_prefix),
gateway_mac: ip.gateway_mac.to_string().replace('-', ":"), gateway_mac: ip.gateway_mac.to_string().to_lowercase().replace('-', ":"),
} }
} }

View File

@ -25,6 +25,7 @@ message ZoneSpec {
ZoneTaskSpec task = 6; ZoneTaskSpec task = 6;
repeated ZoneSpecAnnotation annotations = 7; repeated ZoneSpecAnnotation annotations = 7;
repeated ZoneSpecDevice devices = 8; repeated ZoneSpecDevice devices = 8;
ZoneKernelOptionsSpec kernel_options = 9;
} }
message ZoneResourceSpec { message ZoneResourceSpec {
@ -40,6 +41,11 @@ message ZoneImageSpec {
} }
} }
message ZoneKernelOptionsSpec {
bool verbose = 1;
string cmdline_append = 2;
}
enum OciImageFormat { enum OciImageFormat {
OCI_IMAGE_FORMAT_UNKNOWN = 0; OCI_IMAGE_FORMAT_UNKNOWN = 0;
OCI_IMAGE_FORMAT_SQUASHFS = 1; OCI_IMAGE_FORMAT_SQUASHFS = 1;

View File

@ -35,6 +35,8 @@ service ControlService {
rpc ReadZoneMetrics(ReadZoneMetricsRequest) returns (ReadZoneMetricsReply); rpc ReadZoneMetrics(ReadZoneMetricsRequest) returns (ReadZoneMetricsReply);
rpc WatchEvents(WatchEventsRequest) returns (stream WatchEventsReply); rpc WatchEvents(WatchEventsRequest) returns (stream WatchEventsReply);
rpc ReadHypervisorConsole(ReadHypervisorConsoleRequest) returns (ReadHypervisorConsoleReply);
} }
message HostStatusRequest {} message HostStatusRequest {}
@ -43,6 +45,9 @@ message HostStatusReply {
string host_uuid = 1; string host_uuid = 1;
uint32 host_domid = 2; uint32 host_domid = 2;
string krata_version = 3; string krata_version = 3;
string host_ipv4 = 4;
string host_ipv6 = 5;
string host_mac = 6;
} }
message CreateZoneRequest { message CreateZoneRequest {
@ -252,3 +257,9 @@ message UpdateZoneResourcesRequest {
} }
message UpdateZoneResourcesReply {} message UpdateZoneResourcesReply {}
message ReadHypervisorConsoleRequest {}
message ReadHypervisorConsoleReply {
string data = 1;
}

View File

@ -16,7 +16,7 @@ clap = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
etherparse = { workspace = true } etherparse = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
krata = { path = "../krata", version = "^0.0.17" } krata = { path = "../krata", version = "^0.0.18" }
krata-advmac = { workspace = true } krata-advmac = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }

View File

@ -127,7 +127,8 @@ impl NetworkBackend {
let (tx_sender, tx_receiver) = channel::<BytesMut>(TX_CHANNEL_BUFFER_LEN); let (tx_sender, tx_receiver) = channel::<BytesMut>(TX_CHANNEL_BUFFER_LEN);
let mut udev = ChannelDevice::new(mtu, Medium::Ethernet, tx_sender.clone()); let mut udev = ChannelDevice::new(mtu, Medium::Ethernet, tx_sender.clone());
let mac = self.metadata.gateway.mac; let mac = self.metadata.gateway.mac;
let nat = Nat::new(mtu, proxy, mac, addresses.clone(), tx_sender.clone())?; let local_cidrs = addresses.clone();
let nat = Nat::new(mtu, proxy, mac, local_cidrs, tx_sender.clone())?;
let hardware_addr = HardwareAddress::Ethernet(mac); let hardware_addr = HardwareAddress::Ethernet(mac);
let config = Config::new(hardware_addr); let config = Config::new(hardware_addr);
let mut iface = Interface::new(config, &mut udev, Instant::now()); let mut iface = Interface::new(config, &mut udev, Instant::now());

View File

@ -1,21 +1,15 @@
use std::{ use std::{io::ErrorKind, net::IpAddr};
io::ErrorKind,
net::{IpAddr, Ipv4Addr},
};
use advmac::MacAddr6;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use bytes::BytesMut; use bytes::BytesMut;
use futures::TryStreamExt; use futures::TryStreamExt;
use log::error; use log::error;
use smoltcp::wire::EthernetAddress; use smoltcp::wire::{EthernetAddress, Ipv4Cidr, Ipv6Cidr};
use tokio::{select, task::JoinHandle}; use tokio::{select, task::JoinHandle};
use tokio_tun::Tun; use tokio_tun::Tun;
use crate::vbridge::{BridgeJoinHandle, VirtualBridge}; use crate::vbridge::{BridgeJoinHandle, VirtualBridge};
const HOST_IPV4_ADDR: Ipv4Addr = Ipv4Addr::new(10, 75, 0, 1);
#[derive(Debug)] #[derive(Debug)]
enum HostBridgeProcessSelect { enum HostBridgeProcessSelect {
Send(Option<BytesMut>), Send(Option<BytesMut>),
@ -27,7 +21,14 @@ pub struct HostBridge {
} }
impl HostBridge { impl HostBridge {
pub async fn new(mtu: usize, interface: String, bridge: &VirtualBridge) -> Result<HostBridge> { pub async fn new(
mtu: usize,
interface: String,
bridge: &VirtualBridge,
ipv4: Ipv4Cidr,
ipv6: Ipv6Cidr,
mac: EthernetAddress,
) -> Result<HostBridge> {
let tun = Tun::builder() let tun = Tun::builder()
.name(&interface) .name(&interface)
.tap(true) .tap(true)
@ -38,10 +39,6 @@ impl HostBridge {
let (connection, handle, _) = rtnetlink::new_connection()?; let (connection, handle, _) = rtnetlink::new_connection()?;
tokio::spawn(connection); tokio::spawn(connection);
let mut mac = MacAddr6::random();
mac.set_local(true);
mac.set_multicast(false);
let mut links = handle.link().get().match_name(interface.clone()).execute(); let mut links = handle.link().get().match_name(interface.clone()).execute();
let link = links.try_next().await?; let link = links.try_next().await?;
if link.is_none() { if link.is_none() {
@ -54,25 +51,32 @@ impl HostBridge {
handle handle
.address() .address()
.add(link.header.index, IpAddr::V4(HOST_IPV4_ADDR), 16) .add(
link.header.index,
IpAddr::V4(ipv4.address().into()),
ipv4.prefix_len(),
)
.execute() .execute()
.await?; .await?;
handle handle
.address() .address()
.add(link.header.index, IpAddr::V6(mac.to_link_local_ipv6()), 10) .add(
link.header.index,
IpAddr::V6(ipv6.address().into()),
ipv6.prefix_len(),
)
.execute() .execute()
.await?; .await?;
handle handle
.link() .link()
.set(link.header.index) .set(link.header.index)
.address(mac.to_array().to_vec()) .address(mac.0.to_vec())
.up() .up()
.execute() .execute()
.await?; .await?;
let mac = EthernetAddress(mac.to_array());
let bridge_handle = bridge.join(mac).await?; let bridge_handle = bridge.join(mac).await?;
let task = tokio::task::spawn(async move { let task = tokio::task::spawn(async move {

View File

@ -1,17 +1,21 @@
use std::{collections::HashMap, time::Duration}; use std::{collections::HashMap, str::FromStr, time::Duration};
use anyhow::Result; use anyhow::{anyhow, Result};
use autonet::{AutoNetworkChangeset, AutoNetworkWatcher, NetworkMetadata}; use autonet::{AutoNetworkChangeset, AutoNetworkWatcher, NetworkMetadata};
use futures::{future::join_all, TryFutureExt}; use futures::{future::join_all, TryFutureExt};
use hbridge::HostBridge; use hbridge::HostBridge;
use krata::{ use krata::{
client::ControlClientProvider, client::ControlClientProvider,
dial::ControlDialAddress, dial::ControlDialAddress,
v1::{common::Zone, control::control_service_client::ControlServiceClient}, v1::{
common::Zone,
control::{control_service_client::ControlServiceClient, HostStatusRequest},
},
}; };
use log::warn; use log::warn;
use smoltcp::wire::{EthernetAddress, Ipv4Cidr, Ipv6Cidr};
use tokio::{task::JoinHandle, time::sleep}; use tokio::{task::JoinHandle, time::sleep};
use tonic::transport::Channel; use tonic::{transport::Channel, Request};
use uuid::Uuid; use uuid::Uuid;
use vbridge::VirtualBridge; use vbridge::VirtualBridge;
@ -41,10 +45,27 @@ pub struct NetworkService {
impl NetworkService { impl NetworkService {
pub async fn new(control_address: ControlDialAddress) -> Result<NetworkService> { pub async fn new(control_address: ControlDialAddress) -> Result<NetworkService> {
let control = ControlClientProvider::dial(control_address).await?; let mut control = ControlClientProvider::dial(control_address).await?;
let host_status = control
.host_status(Request::new(HostStatusRequest {}))
.await?
.into_inner();
let host_ipv4 = Ipv4Cidr::from_str(&host_status.host_ipv4)
.map_err(|_| anyhow!("failed to parse host ipv4 cidr"))?;
let host_ipv6 = Ipv6Cidr::from_str(&host_status.host_ipv6)
.map_err(|_| anyhow!("failed to parse host ipv6 cidr"))?;
let host_mac = EthernetAddress::from_str(&host_status.host_mac)
.map_err(|_| anyhow!("failed to parse host mac address"))?;
let bridge = VirtualBridge::new()?; let bridge = VirtualBridge::new()?;
let hbridge = let hbridge = HostBridge::new(
HostBridge::new(HOST_BRIDGE_MTU + EXTRA_MTU, "krata0".to_string(), &bridge).await?; HOST_BRIDGE_MTU + EXTRA_MTU,
"krata0".to_string(),
&bridge,
host_ipv4,
host_ipv6,
host_mac,
)
.await?;
Ok(NetworkService { Ok(NetworkService {
control, control,
zones: HashMap::new(), zones: HashMap::new(),

View File

@ -12,20 +12,20 @@ resolver = "2"
anyhow = { workspace = true } anyhow = { workspace = true }
backhand = { workspace = true } backhand = { workspace = true }
ipnetwork = { workspace = true } ipnetwork = { workspace = true }
krata = { path = "../krata", version = "^0.0.17" } krata = { path = "../krata", version = "^0.0.18" }
krata-advmac = { workspace = true } krata-advmac = { workspace = true }
krata-oci = { path = "../oci", version = "^0.0.17" } krata-oci = { path = "../oci", version = "^0.0.18" }
log = { workspace = true } log = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
krata-loopdev = { path = "../loopdev", version = "^0.0.17" } krata-loopdev = { path = "../loopdev", version = "^0.0.18" }
krata-xencall = { path = "../xen/xencall", version = "^0.0.17" } krata-xencall = { path = "../xen/xencall", version = "^0.0.18" }
krata-xenclient = { path = "../xen/xenclient", version = "^0.0.17" } krata-xenclient = { path = "../xen/xenclient", version = "^0.0.18" }
krata-xenevtchn = { path = "../xen/xenevtchn", version = "^0.0.17" } krata-xenevtchn = { path = "../xen/xenevtchn", version = "^0.0.18" }
krata-xengnt = { path = "../xen/xengnt", version = "^0.0.17" } krata-xengnt = { path = "../xen/xengnt", version = "^0.0.18" }
krata-xenplatform = { path = "../xen/xenplatform", version = "^0.0.17" } krata-xenplatform = { path = "../xen/xenplatform", version = "^0.0.18" }
krata-xenstore = { path = "../xen/xenstore", version = "^0.0.17" } krata-xenstore = { path = "../xen/xenstore", version = "^0.0.18" }
walkdir = { workspace = true } walkdir = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }

View File

@ -37,7 +37,8 @@ pub struct ZoneLaunchRequest {
pub env: HashMap<String, String>, pub env: HashMap<String, String>,
pub run: Option<Vec<String>>, pub run: Option<Vec<String>>,
pub pcis: Vec<PciDevice>, pub pcis: Vec<PciDevice>,
pub debug: bool, pub kernel_verbose: bool,
pub kernel_cmdline_append: String,
pub image: OciPackedImage, pub image: OciPackedImage,
pub addons_image: Option<PathBuf>, pub addons_image: Option<PathBuf>,
pub network: ZoneLaunchNetwork, pub network: ZoneLaunchNetwork,
@ -139,9 +140,14 @@ impl ZoneLauncher {
None None
}; };
let mut cmdline_options = ["console=hvc0"].to_vec(); let mut cmdline_options = ["console=hvc0"].to_vec();
if !request.debug { if !request.kernel_verbose {
cmdline_options.push("quiet"); cmdline_options.push("quiet");
} }
if !request.kernel_cmdline_append.is_empty() {
cmdline_options.push(&request.kernel_cmdline_append);
}
let cmdline = cmdline_options.join(" "); let cmdline = cmdline_options.join(" ");
let zone_mac_string = request.network.zone_mac.to_string().replace('-', ":"); let zone_mac_string = request.network.zone_mac.to_string().replace('-', ":");

View File

@ -1,5 +1,6 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use krataloopdev::LoopControl; use krataloopdev::LoopControl;
use log::debug;
use std::{fs, path::PathBuf, str::FromStr, sync::Arc}; use std::{fs, path::PathBuf, str::FromStr, sync::Arc};
use tokio::sync::Semaphore; use tokio::sync::Semaphore;
use uuid::Uuid; use uuid::Uuid;
@ -168,6 +169,13 @@ pub struct Runtime {
impl Runtime { impl Runtime {
pub async fn new() -> Result<Self> { pub async fn new() -> Result<Self> {
let context = RuntimeContext::new().await?; let context = RuntimeContext::new().await?;
debug!("testing for hypervisor presence");
context
.xen
.call
.get_version_capabilities()
.await
.map_err(|_| anyhow!("hypervisor is not present"))?;
Ok(Self { Ok(Self {
context, context,
launch_semaphore: Arc::new(Semaphore::new(10)), launch_semaphore: Arc::new(Semaphore::new(10)),
@ -297,4 +305,16 @@ impl Runtime {
let context = RuntimeContext::new().await?; let context = RuntimeContext::new().await?;
Ok(PowerManagementContext { context }) Ok(PowerManagementContext { context })
} }
pub async fn read_hypervisor_console(&self, clear: bool) -> Result<Arc<str>> {
let index = 0_u32;
let (rawbuf, newindex) = self
.context
.xen
.call
.read_console_ring_raw(clear, index)
.await?;
let buf = std::str::from_utf8(&rawbuf[..newindex as usize])?;
Ok(Arc::from(buf))
}
} }

View File

@ -0,0 +1,18 @@
use xencall::error::Result;
use xencall::XenCall;
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
let call = XenCall::open(0)?;
let index = 0_u32;
let (buf, newindex) = call.read_console_ring_raw(false, index).await?;
match std::str::from_utf8(&buf[..newindex as usize]) {
Ok(v) => print!("{}", v),
_ => panic!("unable to decode Xen console messages"),
};
Ok(())
}

View File

@ -26,12 +26,12 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use sys::{ use sys::{
CpuId, E820Entry, ForeignMemoryMap, PhysdevMapPirq, Sysctl, SysctlCputopo, SysctlCputopoinfo, CpuId, E820Entry, ForeignMemoryMap, PhysdevMapPirq, Sysctl, SysctlCputopo, SysctlCputopoinfo,
SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlSetCpuFreqGov, SysctlValue, SysctlPhysinfo, SysctlPmOp, SysctlPmOpValue, SysctlReadconsole, SysctlSetCpuFreqGov,
VcpuGuestContextAny, HYPERVISOR_PHYSDEV_OP, HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ, SysctlValue, VcpuGuestContextAny, HYPERVISOR_PHYSDEV_OP, HYPERVISOR_SYSCTL, PHYSDEVOP_MAP_PIRQ,
XEN_DOMCTL_MAX_INTERFACE_VERSION, XEN_DOMCTL_MIN_INTERFACE_VERSION, XEN_MEM_SET_MEMORY_MAP, XEN_DOMCTL_MAX_INTERFACE_VERSION, XEN_DOMCTL_MIN_INTERFACE_VERSION, XEN_MEM_SET_MEMORY_MAP,
XEN_SYSCTL_CPUTOPOINFO, XEN_SYSCTL_MAX_INTERFACE_VERSION, XEN_SYSCTL_MIN_INTERFACE_VERSION, XEN_SYSCTL_CPUTOPOINFO, XEN_SYSCTL_MAX_INTERFACE_VERSION, XEN_SYSCTL_MIN_INTERFACE_VERSION,
XEN_SYSCTL_PHYSINFO, XEN_SYSCTL_PM_OP, XEN_SYSCTL_PM_OP_DISABLE_TURBO, XEN_SYSCTL_PHYSINFO, XEN_SYSCTL_PM_OP, XEN_SYSCTL_PM_OP_DISABLE_TURBO,
XEN_SYSCTL_PM_OP_ENABLE_TURBO, XEN_SYSCTL_PM_OP_SET_CPUFREQ_GOV, XEN_SYSCTL_PM_OP_ENABLE_TURBO, XEN_SYSCTL_PM_OP_SET_CPUFREQ_GOV, XEN_SYSCTL_READCONSOLE,
}; };
use tokio::sync::Semaphore; use tokio::sync::Semaphore;
use tokio::time::sleep; use tokio::time::sleep;
@ -1087,4 +1087,33 @@ impl XenCall {
.await?; .await?;
Ok(()) Ok(())
} }
pub async fn read_console_ring_raw(
&self,
clear: bool,
index: u32,
) -> Result<([u8; 16384], u32)> {
let mut u8buf = [0u8; 16384];
let mut sysctl = Sysctl {
cmd: XEN_SYSCTL_READCONSOLE,
interface_version: self.sysctl_interface_version,
value: SysctlValue {
console: SysctlReadconsole {
clear: clear as u8,
incremental: 1,
pad: 0,
index,
buffer: addr_of_mut!(u8buf) as u64,
count: 16384,
},
},
};
self.hypercall1(HYPERVISOR_SYSCTL, addr_of_mut!(sysctl) as c_ulong)
.await?;
// Safety: We are passing a SysctlReadconsole struct as part of the hypercall, and
// calling the hypercall is known to not change the underlying value outside changing
// the values on some SysctlReadconsole fields.
let newindex = unsafe { sysctl.value.console.index };
Ok((u8buf, newindex))
}
} }

View File

@ -752,6 +752,7 @@ pub struct SysctlCputopoinfo {
#[repr(C)] #[repr(C)]
pub union SysctlValue { pub union SysctlValue {
pub console: SysctlReadconsole,
pub cputopoinfo: SysctlCputopoinfo, pub cputopoinfo: SysctlCputopoinfo,
pub pm_op: SysctlPmOp, pub pm_op: SysctlPmOp,
pub phys_info: SysctlPhysinfo, pub phys_info: SysctlPhysinfo,
@ -765,6 +766,7 @@ pub struct Sysctl {
pub value: SysctlValue, pub value: SysctlValue,
} }
pub const XEN_SYSCTL_READCONSOLE: u32 = 1;
pub const XEN_SYSCTL_PHYSINFO: u32 = 3; pub const XEN_SYSCTL_PHYSINFO: u32 = 3;
pub const XEN_SYSCTL_PM_OP: u32 = 12; pub const XEN_SYSCTL_PM_OP: u32 = 12;
pub const XEN_SYSCTL_CPUTOPOINFO: u32 = 16; pub const XEN_SYSCTL_CPUTOPOINFO: u32 = 16;
@ -802,3 +804,14 @@ pub struct SysctlPhysinfo {
pub max_mfn: u64, pub max_mfn: u64,
pub hw_cap: [u32; 8], pub hw_cap: [u32; 8],
} }
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SysctlReadconsole {
pub clear: u8,
pub incremental: u8,
pub pad: u16,
pub index: u32,
pub buffer: u64,
pub count: u32,
}

View File

@ -13,9 +13,9 @@ async-trait = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
krata-xencall = { path = "../xencall", version = "^0.0.17" } krata-xencall = { path = "../xencall", version = "^0.0.18" }
krata-xenplatform = { path = "../xenplatform", version = "^0.0.17" } krata-xenplatform = { path = "../xenplatform", version = "^0.0.18" }
krata-xenstore = { path = "../xenstore", version = "^0.0.17" } krata-xenstore = { path = "../xenstore", version = "^0.0.18" }
regex = { workspace = true } regex = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }

View File

@ -16,7 +16,7 @@ flate2 = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
krata-xencall = { path = "../xencall", version = "^0.0.17" } krata-xencall = { path = "../xencall", version = "^0.0.18" }
memchr = { workspace = true } memchr = { workspace = true }
nix = { workspace = true } nix = { workspace = true }
regex = { workspace = true } regex = { workspace = true }

View File

@ -14,8 +14,8 @@ cgroups-rs = { workspace = true }
env_logger = { workspace = true } env_logger = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
ipnetwork = { workspace = true } ipnetwork = { workspace = true }
krata = { path = "../krata", version = "^0.0.17" } krata = { path = "../krata", version = "^0.0.18" }
krata-xenstore = { path = "../xen/xenstore", version = "^0.0.17" } krata-xenstore = { path = "../xen/xenstore", version = "^0.0.18" }
libc = { workspace = true } libc = { workspace = true }
log = { workspace = true } log = { workspace = true }
nix = { workspace = true, features = ["ioctl", "process", "fs"] } nix = { workspace = true, features = ["ioctl", "process", "fs"] }