Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
fa39e59
stub child spawner, refactor manager
korewaChino Apr 8, 2026
56428e7
Update create_vm.rs
korewaChino Apr 9, 2026
909f0fe
implement some HTTP actor routes, VM agent cache
korewaChino Apr 9, 2026
df6b1c1
implement agent api routes
korewaChino Apr 9, 2026
fbc2982
rename some fields, implement messaging
korewaChino Apr 9, 2026
b171783
merge imports
korewaChino Apr 9, 2026
e98c407
remove provisioner traits
korewaChino Apr 9, 2026
3970f5a
do keepalive pings
korewaChino Apr 9, 2026
ba7cd93
fix IPAM MAC address calculation
korewaChino Apr 9, 2026
a87521f
scheduler: call VM actor directly isntead of going through agent for VM
korewaChino Apr 10, 2026
bc96091
don't unwrap delete vm request
korewaChino Apr 10, 2026
68e907d
logging: add pretty log only on debug builds
korewaChino Apr 10, 2026
607f537
actor info ideas
TheHeroBrine422 Apr 10, 2026
c45043f
implement basic live migration
korewaChino Apr 11, 2026
f42f773
dx: set up sccache and mold
korewaChino Apr 13, 2026
808b236
add check action
korewaChino Apr 13, 2026
8e07218
build on all branches
korewaChino Apr 13, 2026
6727819
oops
korewaChino Apr 13, 2026
48d405d
actions: write
korewaChino Apr 13, 2026
b575c1f
Update check.yml
korewaChino Apr 13, 2026
e4a3049
ci(rva23): copy script directly in CI image
korewaChino Apr 13, 2026
f221e7b
use clippy instead
korewaChino Apr 13, 2026
a1076b8
run analysis on all branches
korewaChino Apr 13, 2026
cc01cae
also cache clippy lmao
korewaChino Apr 13, 2026
d7e569d
use upload-artifact v7, do not zip artifacts
korewaChino Apr 13, 2026
c743069
do SARIF v4 action
korewaChino Apr 13, 2026
aec68de
upload artifacts separately
korewaChino Apr 13, 2026
8472617
add CH schemas, rename storage driver
korewaChino Apr 14, 2026
5bf1744
update new CH API client
korewaChino Apr 14, 2026
7f2a540
use full semver
korewaChino Apr 14, 2026
1bcd825
clean up docs for refactor
korewaChino Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions .github/workflows/build_riscv_rva23.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ name: Build RISC V RVA23 via x86 cross-compile

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always
Expand All @@ -27,10 +25,19 @@ jobs:
run: podman build -t odorobo-builder:rva23 .
- name: Build binaries
run: podman run --rm -v ${{ github.workspace }}:/code -w /code odorobo-builder:rva23 cargo build --release --verbose
- name: Upload artifact
uses: actions/upload-artifact@v4


- name: Upload artifact - agent
uses: actions/upload-artifact@v7
with:
name: odorobo_riscv_rva23
archive: false
name: odorobo-agent-riscv_rva23
path: |
target/riscv64a23-unknown-linux-gnu/release/odorobo-agent
- name: Upload artifact - odoroboctl
uses: actions/upload-artifact@v7
with:
archive: false
name: odoroboctl-riscv_rva23
path: |
target/riscv64a23-unknown-linux-gnu/release/odoroboctl
23 changes: 18 additions & 5 deletions .github/workflows/build_x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
CARGO_TERM_COLOR: always
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"

jobs:
build:
Expand All @@ -16,14 +16,27 @@

steps:
- uses: actions/checkout@v4
- uses: rui314/setup-mold@v1

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Build x86' step
Uses Step
uses 'rui314/setup-mold' with ref 'v1', not a pinned commit hash
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.9

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Build x86' step
Uses Step
uses 'mozilla-actions/sccache-action' with ref 'v0.0.9', not a pinned commit hash

- name: Build
run: cargo build --verbose --release
- name: Upload artifact
uses: actions/upload-artifact@v4
- name: Upload artifact - agent
uses: actions/upload-artifact@v7
with:
name: odorobo_x86
archive: false
name: odorobo-agent-x86
path: |
target/release/odorobo-agent

- name: Upload artifact - odoroboctl
uses: actions/upload-artifact@v7
with:
archive: false
name: odoroboctl-x86
path: |
target/release/odoroboctl

- name: Run tests
run: cargo test --verbose
64 changes: 64 additions & 0 deletions .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# rust-clippy is a tool that runs a bunch of lints to catch common
# mistakes in your Rust code and help improve your Rust code.
# More details at https://github.com/rust-lang/rust-clippy
# and https://rust-lang.github.io/rust-clippy/

name: rust-clippy analyze

on:
push:
pull_request:
schedule:
- cron: '39 6 * * 6'


env:
CARGO_TERM_COLOR: always
SCCACHE_GHA_ENABLED: "true"
RUSTC_WRAPPER: "sccache"

jobs:
rust-clippy-analyze:
name: Run rust-clippy analyzing
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af #@v1
with:
profile: minimal
toolchain: stable
components: clippy
override: true


- uses: rui314/setup-mold@v1

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'rust-clippy analyze' step
Uses Step
uses 'rui314/setup-mold' with ref 'v1', not a pinned commit hash
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.9

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'rust-clippy analyze' step
Uses Step
uses 'mozilla-actions/sccache-action' with ref 'v0.0.9', not a pinned commit hash


- name: Install required cargo
run: cargo install clippy-sarif sarif-fmt

- name: Run rust-clippy
run:
cargo clippy
--all-features
--message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt
continue-on-error: true

- name: Upload analysis results to GitHub
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: rust-clippy-results.sarif
wait-for-processing: true
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ tracing-subscriber = { version = "0.3", features = [
"fmt",
"json",
] }
cloud-hypervisor-client = "0.3"
cloud-hypervisor-client = { git = "https://github.com/FyraStack/cloud-hypervisor-client.git" }
serde_json = "1.0.149"
serde = "1.0"
axum = { version = "0.8.8", features = ["ws"] }
Expand All @@ -24,6 +24,7 @@ ahash = { version = "0.8.12", features = ["serde"] }
ulid = { version = "1.2", features = ["serde", "uuid"] }
# aide needs an older version of schemars
schemars = "0.9"
dirs = "6.0.0"
bytesize = { version = "2.3.1", features = ["serde"] }
odorobo-shared = { path = "odorobo-shared" }
odorobo-agent = { path = "odorobo-agent" }
Expand Down
5 changes: 3 additions & 2 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ RUN rustup-init \
--profile minimal \
--target riscv64a23-unknown-linux-gnu \
-y
COPY scripts/zig-cc-rva23.sh /scripts/zig-cc-rva23.sh
ENV CARGO_BUILD_TARGET="riscv64a23-unknown-linux-gnu"
ENV PATH="/root/.cargo/bin:$PATH"
ENV CC_riscv64a23_unknown_linux_gnu="/code/scripts/zig-cc-rva23.sh"
ENV CARGO_TARGET_RISCV64A23_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C linker=scripts/zig-cc-rva23.sh"
ENV CC_riscv64a23_unknown_linux_gnu="/scripts/zig-cc-rva23.sh"
ENV CARGO_TARGET_RISCV64A23_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C linker=/scripts/zig-cc-rva23.sh"
67 changes: 7 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,20 @@ Odorobo Agent is meant to be run as a system agent on each bare-metal node (or a

Build the Agent binary with `cargo build --release` and run it on the host machine. The Agent will listen for commands from the Gateway to create, manage, and delete VMs.

Install the systemd integration first:
```bash
# Install unit hook scripts
sudo just install_script
# finally, install the unit
sudo just install_unit
```

Then build and run the agent:
```bash
# Build the Agent
cargo build --release
# Run the Agent (requires write permissions to /run/odorobo, and access to systemd's system session bus
# preferrably as the same user as Cloud Hypervisor, see `systemd/odorobo-ch@.service`
# for the CH service template)
sudo ./target/release/odorobo-agent
```

For debugging and/or small-scale single-node usage, the CLI is available to interact directly with the agent.
You will now be required to run the manager process:
```
# Build the Manager
cargo build --release -p odorobo-manager
# Run the Manager
./target/release/odorobo-manager
```

Install the CLI helper

Expand All @@ -67,12 +62,6 @@ Now apply the [Cloud Hypervisor VM spec](https://github.com/cloud-hypervisor/clo
odoroboctl create my-vm --boot ./my-vm.json
```

Now the VM should be running. You can connect to the VM's serial console via the agent's WebSocket proxy:

```bash
websocat --binary ws://127.0.0.1:8890/vms/my-vm/console
```

To connect directly on the host, look up the PTY path from the VM info:

```bash
Expand All @@ -85,45 +74,3 @@ See [docs/console.md](docs/console.md) for WebSocket console usage and integrati
For more advanced usage, Odorobo Agent also exposes a passthrough route for the local Cloud Hypervisor API, allowing you to call the full Cloud Hypervisor API directly through the agent's REST API

See `docs/ch-passthrough.md` for Cloud Hypervisor API passthrough usage.

## Live Migration

To start a live migration, you will first need to spawn a VM on the destination node with `odoroboctl spawn`, then call the `migrate` command on the source node with the destination node's address:

```bash
odoroboctl spawn my-vm-dest
```

Now, on the same destination VM, start accepting migrations:

```bash
odoroboctl migrate-receive my-vm-dest
```

You will now receive a response with the listening address and port for the destination machine. Use this information to start the migration from the source node.

```json
{"listening_address":"tcp:0.0.0.0:49152"}
```

Replace `0.0.0.0` with the actual IP address of the destination node, and use the provided port (e.g. `49152`)

Finally, start migration from the source node:

```bash
odoroboctl migrate-send my-vm-source tcp:<DEST-IP>:49152
```

This will start the live migration process. The source VM will continue running until the final switchover phase, at which point it will be paused, the remaining state will be transferred to the destination, and then the destination VM will be resumed.

You will have to manually manage networking and storage for the VM during migration, as Odorobo does not currently have any built-in network or storage management features. Migrations may fail if the networking configuration is unmigratable.

This part is currently out-of-scope for Odorobo, as the orchestrator should be responsible for coordinating with the network and storage layers to ensure that the VM's resources are available on the destination node before starting migration.

Odorobo however has support for custom pre and post-migration hooks, which can be used to implement custom logic before and after migration, such as preparing the destination node's network and storage configuration, or cleaning up the source node after migration. See `odorobo-agent/src/state/provisioning/hooks` for more details on how to implement and configure lifecycle hooks.

## Security notes

Currently, the `odorobo-ch@.service` unit is configured to be sandboxed and confined to a list of read-writable paths that are necessary for operation, and by default only has access to `/var/lib/odorobo` and `/dev` for runtime data.

To allow Cloud Hypervisor to access the disk, you will have to either move your disk images into `/var/lib/odorobo` or add additional read access to the paths where your disk images are stored.
20 changes: 20 additions & 0 deletions actor_info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
manager:

http server (mvp)
websocket server for serial terminal (mvp)

ip management (future roadmap) (also should be a trait so we can swap this out with netbox or something custom later)

managed hosting provider (hits schedulers to auto manage containers, ansible, docker compose, or anything else, and do it to a new vm, an existing vm, or create a new dedicated server and use it)

scheduler_non-ha (mvp) (needs a scheduler trait so schedulers are similar, should be based on inital scheduler_non_ha)
scheduler_ha (future roadmap)
scheduler_other_clusters (future roadmap)
scheduler_to_other_manager (future roadmap)



agent:
server actor (mvp) (needs to be a trait so we can swap for other things in the future)
vm actor (mvp) (needs to be a trait so we can swap for other things in the future

3 changes: 3 additions & 0 deletions docs/schemas/BalloonConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/BalloonConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/ConsoleConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/ConsoleConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/ConsoleMode.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/ConsoleMode"
}
3 changes: 3 additions & 0 deletions docs/schemas/CoreSchedulingMode.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/CoreSchedulingMode"
}
3 changes: 3 additions & 0 deletions docs/schemas/CpuAffinity.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/CpuAffinity"
}
3 changes: 3 additions & 0 deletions docs/schemas/CpuFeatures.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/CpuFeatures"
}
3 changes: 3 additions & 0 deletions docs/schemas/CpuTopology.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/CpuTopology"
}
3 changes: 3 additions & 0 deletions docs/schemas/CpusConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/CpusConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/DebugConsoleConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/DebugConsoleConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/DeviceConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/DeviceConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/DeviceNode.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/DeviceNode"
}
3 changes: 3 additions & 0 deletions docs/schemas/DiskConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/DiskConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/FsConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/FsConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/GenericVhostUserConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/GenericVhostUserConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/ImageType.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/ImageType"
}
3 changes: 3 additions & 0 deletions docs/schemas/LandlockConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/LandlockConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/LockGranularity.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/LockGranularity"
}
3 changes: 3 additions & 0 deletions docs/schemas/MemoryConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/MemoryConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/MemoryRestoreMode.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/MemoryRestoreMode"
}
3 changes: 3 additions & 0 deletions docs/schemas/MemoryZoneConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/MemoryZoneConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/NetConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/NetConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/NumaConfig.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/NumaConfig"
}
3 changes: 3 additions & 0 deletions docs/schemas/NumaDistance.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"$ref": "cloud-hypervisor.json#/components/schemas/NumaDistance"
}
Loading
Loading