diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 326d3e5..3d12b03 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -127,7 +127,7 @@ jobs: run: ./hack/ci/install-linux-deps.sh - name: cargo clippy run: ./hack/build/cargo.sh clippy - guest-init: + zone-initrd: runs-on: ubuntu-latest strategy: matrix: @@ -136,7 +136,7 @@ jobs: - aarch64 env: TARGET_ARCH: "${{ matrix.arch }}" - name: guest-init ${{ matrix.arch }} + name: zone initrd ${{ matrix.arch }} steps: - name: harden runner uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 40444a4..9ab819e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -124,7 +124,7 @@ jobs: - kratactl - kratad - kratanet - - krata-guest-init + - krata-zone name: nightly oci build ${{ matrix.component }} permissions: contents: read diff --git a/.github/workflows/release-assets.yml b/.github/workflows/release-assets.yml index 186ce51..b259db4 100644 --- a/.github/workflows/release-assets.yml +++ b/.github/workflows/release-assets.yml @@ -121,7 +121,7 @@ jobs: - kratactl - kratad - kratanet - - krata-guest-init + - krata-zone name: release-assets oci ${{ matrix.component }} permissions: contents: read diff --git a/Cargo.lock b/Cargo.lock index 79eb416..cabc5e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1393,31 +1393,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "krata-guest" -version = "0.0.12" -dependencies = [ - "anyhow", - "cgroups-rs", - "env_logger", - "futures", - "ipnetwork", - "krata", - "krata-xenstore", - "libc", - "log", - "nix 0.29.0", - "oci-spec", - "path-absolutize", - "platform-info", - "rtnetlink", - "serde", - "serde_json", - "sys-mount", - "sysinfo", - "tokio", -] - [[package]] name = "krata-loopdev" version = "0.0.12" @@ -1603,6 +1578,31 @@ dependencies = [ "tokio", ] +[[package]] +name = "krata-zone" +version = "0.0.12" +dependencies = [ + "anyhow", + "cgroups-rs", + "env_logger", + "futures", + "ipnetwork", + "krata", + "krata-xenstore", + "libc", + "log", + "nix 0.29.0", + "oci-spec", + "path-absolutize", + "platform-info", + "rtnetlink", + "serde", + "serde_json", + "sys-mount", + "sysinfo", + "tokio", +] + [[package]] name = "lazy_static" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 83ce999..9ebd98e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [ "crates/build", "crates/krata", "crates/oci", - "crates/guest", + "crates/zone", "crates/runtime", "crates/daemon", "crates/network", diff --git a/DEV.md b/DEV.md index 103777e..a051d38 100644 --- a/DEV.md +++ b/DEV.md @@ -9,7 +9,7 @@ krata is composed of four major executables: | kratad | host | backend daemon | ./hack/debug/kratad.sh | crates/daemon | | kratanet | host | backend daemon | ./hack/debug/kratanet.sh | crates/network | | kratactl | host | CLI tool | ./hack/debug/kratactl.sh | crates/ctl | -| krataguest | guest | none, guest init | N/A | crates/guest | +| kratazone | zone | none, zone init | N/A | crates/zone | You will find the code to each executable available in the bin/ and src/ directories inside it's corresponding code path from the above table. @@ -19,7 +19,7 @@ it's corresponding code path from the above table. | Component | Specification | Notes | | ------------- | ------------- | --------------------------------------------------------------------------------- | | Architecture | x86_64 | aarch64 support is still in development | -| Memory | At least 6GB | dom0 will need to be configured with lower memory limit to give krata guests room | +| Memory | At least 6GB | dom0 will need to be configured with lower memory limit to give krata zones room | | Xen | 4.17 | Temporary due to hardcoded interface version constants | | Debian | stable / sid | Debian is recommended due to the ease of Xen setup | | rustup | any | Install Rustup from https://rustup.rs | @@ -45,10 +45,10 @@ $ rustup target add x86_64-unknown-linux-gnu $ rustup target add x86_64-unknown-linux-musl ``` -4. Configure `/etc/default/grub.d/xen.cfg` to give krata guests some room: +4. Configure `/etc/default/grub.d/xen.cfg` to give krata zones some room: ```sh -# Configure dom0_mem to be 4GB, but leave the rest of the RAM for krata guests. +# Configure dom0_mem to be 4GB, but leave the rest of the RAM for krata zones. GRUB_CMDLINE_XEN_DEFAULT="dom0_mem=4G,max:4G" ``` @@ -64,36 +64,36 @@ $ git clone https://github.com/edera-dev/krata.git krata $ cd krata ``` -6. Fetch the guest kernel image: +6. Fetch the zone kernel image: ```sh $ ./hack/kernel/fetch.sh -u ``` -7. Copy the guest kernel artifacts to `/var/lib/krata/guest/kernel` so it is automatically detected by kratad: +7. Copy the zone kernel artifacts to `/var/lib/krata/zone/kernel` so it is automatically detected by kratad: ```sh -$ mkdir -p /var/lib/krata/guest -$ cp target/kernel/kernel-x86_64 /var/lib/krata/guest/kernel -$ cp target/kernel/addons-x86_64.squashfs /var/lib/krata/guest/addons.squashfs +$ mkdir -p /var/lib/krata/zone +$ cp target/kernel/kernel-x86_64 /var/lib/krata/zone/kernel +$ cp target/kernel/addons-x86_64.squashfs /var/lib/krata/zone/addons.squashfs ``` 8. Launch `./hack/debug/kratad.sh` and keep it running in the foreground. 9. Launch `./hack/debug/kratanet.sh` and keep it running in the foreground. -10. Run `kratactl` to launch a guest: +10. Run `kratactl` to launch a zone: ```sh $ ./hack/debug/kratactl.sh launch --attach alpine:latest ``` -To detach from the guest console, use `Ctrl + ]` on your keyboard. +To detach from the zone console, use `Ctrl + ]` on your keyboard. -To list the running guests, run: +To list the running zones, run: ```sh $ ./hack/debug/kratactl.sh list ``` -To destroy a running guest, copy it's UUID from either the launch command or the guest list and run: +To destroy a running zone, copy it's UUID from either the launch command or the zone list and run: ```sh -$ ./hack/debug/kratactl.sh destroy GUEST_UUID +$ ./hack/debug/kratactl.sh destroy ZONE_UUID ``` diff --git a/crates/build/bin/fetch_kernel.rs b/crates/build/bin/fetch_kernel.rs index dcc98d9..cd70fbc 100644 --- a/crates/build/bin/fetch_kernel.rs +++ b/crates/build/bin/fetch_kernel.rs @@ -39,7 +39,7 @@ async fn main() -> Result<()> { ); let image = ImageName::parse(&args().nth(1).unwrap())?; - let mut cache_dir = std::env::temp_dir().clone(); + let mut cache_dir = env::temp_dir().clone(); cache_dir.push(format!("krata-cache-{}", Uuid::new_v4())); fs::create_dir_all(&cache_dir).await?; diff --git a/crates/ctl/src/cli/attach.rs b/crates/ctl/src/cli/attach.rs index 24c10f4..82796da 100644 --- a/crates/ctl/src/cli/attach.rs +++ b/crates/ctl/src/cli/attach.rs @@ -7,13 +7,13 @@ use tonic::transport::Channel; use crate::console::StdioConsoleStream; -use super::resolve_guest; +use super::resolve_zone; #[derive(Parser)] -#[command(about = "Attach to the guest console")] +#[command(about = "Attach to the zone console")] pub struct AttachCommand { - #[arg(help = "Guest to attach to, either the name or the uuid")] - guest: String, + #[arg(help = "Zone to attach to, either the name or the uuid")] + zone: String, } impl AttachCommand { @@ -22,12 +22,12 @@ impl AttachCommand { mut client: ControlServiceClient, events: EventStream, ) -> Result<()> { - let guest_id: String = resolve_guest(&mut client, &self.guest).await?; - let input = StdioConsoleStream::stdin_stream(guest_id.clone()).await; - let output = client.console_data(input).await?.into_inner(); + let zone_id: String = resolve_zone(&mut client, &self.zone).await?; + let input = StdioConsoleStream::stdin_stream(zone_id.clone()).await; + let output = client.attach_zone_console(input).await?.into_inner(); let stdout_handle = tokio::task::spawn(async move { StdioConsoleStream::stdout(output).await }); - let exit_hook_task = StdioConsoleStream::guest_exit_hook(guest_id.clone(), events).await?; + let exit_hook_task = StdioConsoleStream::zone_exit_hook(zone_id.clone(), events).await?; let code = select! { x = stdout_handle => { x??; diff --git a/crates/ctl/src/cli/destroy.rs b/crates/ctl/src/cli/destroy.rs index 60db259..38eae76 100644 --- a/crates/ctl/src/cli/destroy.rs +++ b/crates/ctl/src/cli/destroy.rs @@ -3,10 +3,10 @@ use clap::Parser; use krata::{ events::EventStream, v1::{ - common::GuestStatus, + common::ZoneStatus, control::{ control_service_client::ControlServiceClient, watch_events_reply::Event, - DestroyGuestRequest, + DestroyZoneRequest, }, }, }; @@ -14,19 +14,19 @@ use krata::{ use log::error; use tonic::{transport::Channel, Request}; -use crate::cli::resolve_guest; +use crate::cli::resolve_zone; #[derive(Parser)] -#[command(about = "Destroy a guest")] +#[command(about = "Destroy a zone")] pub struct DestroyCommand { #[arg( short = 'W', long, - help = "Wait for the destruction of the guest to complete" + help = "Wait for the destruction of the zone to complete" )] wait: bool, - #[arg(help = "Guest to destroy, either the name or the uuid")] - guest: String, + #[arg(help = "Zone to destroy, either the name or the uuid")] + zone: String, } impl DestroyCommand { @@ -35,46 +35,46 @@ impl DestroyCommand { mut client: ControlServiceClient, events: EventStream, ) -> Result<()> { - let guest_id: String = resolve_guest(&mut client, &self.guest).await?; + let zone_id: String = resolve_zone(&mut client, &self.zone).await?; let _ = client - .destroy_guest(Request::new(DestroyGuestRequest { - guest_id: guest_id.clone(), + .destroy_zone(Request::new(DestroyZoneRequest { + zone_id: zone_id.clone(), })) .await? .into_inner(); if self.wait { - wait_guest_destroyed(&guest_id, events).await?; + wait_zone_destroyed(&zone_id, events).await?; } Ok(()) } } -async fn wait_guest_destroyed(id: &str, events: EventStream) -> Result<()> { +async fn wait_zone_destroyed(id: &str, events: EventStream) -> Result<()> { let mut stream = events.subscribe(); while let Ok(event) = stream.recv().await { - let Event::GuestChanged(changed) = event; - let Some(guest) = changed.guest else { + let Event::ZoneChanged(changed) = event; + let Some(zone) = changed.zone else { continue; }; - if guest.id != id { + if zone.id != id { continue; } - let Some(state) = guest.state else { + let Some(state) = zone.state else { continue; }; if let Some(ref error) = state.error_info { - if state.status() == GuestStatus::Failed { + if state.status() == ZoneStatus::Failed { error!("destroy failed: {}", error.message); std::process::exit(1); } else { - error!("guest error: {}", error.message); + error!("zone error: {}", error.message); } } - if state.status() == GuestStatus::Destroyed { + if state.status() == ZoneStatus::Destroyed { std::process::exit(0); } } diff --git a/crates/ctl/src/cli/exec.rs b/crates/ctl/src/cli/exec.rs index 8b56223..d2c124a 100644 --- a/crates/ctl/src/cli/exec.rs +++ b/crates/ctl/src/cli/exec.rs @@ -4,42 +4,42 @@ use anyhow::Result; use clap::Parser; use krata::v1::{ - common::{GuestTaskSpec, GuestTaskSpecEnvVar}, - control::{control_service_client::ControlServiceClient, ExecGuestRequest}, + common::{ZoneTaskSpec, ZoneTaskSpecEnvVar}, + control::{control_service_client::ControlServiceClient, ExecZoneRequest}, }; use tonic::{transport::Channel, Request}; use crate::console::StdioConsoleStream; -use super::resolve_guest; +use super::resolve_zone; #[derive(Parser)] -#[command(about = "Execute a command inside the guest")] +#[command(about = "Execute a command inside the zone")] pub struct ExecCommand { #[arg[short, long, help = "Environment variables"]] env: Option>, #[arg(short = 'w', long, help = "Working directory")] working_directory: Option, - #[arg(help = "Guest to exec inside, either the name or the uuid")] - guest: String, + #[arg(help = "Zone to exec inside, either the name or the uuid")] + zone: String, #[arg( allow_hyphen_values = true, trailing_var_arg = true, - help = "Command to run inside the guest" + help = "Command to run inside the zone" )] command: Vec, } impl ExecCommand { pub async fn run(self, mut client: ControlServiceClient) -> Result<()> { - let guest_id: String = resolve_guest(&mut client, &self.guest).await?; - let initial = ExecGuestRequest { - guest_id, - task: Some(GuestTaskSpec { + let zone_id: String = resolve_zone(&mut client, &self.zone).await?; + let initial = ExecZoneRequest { + zone_id, + task: Some(ZoneTaskSpec { environment: env_map(&self.env.unwrap_or_default()) .iter() - .map(|(key, value)| GuestTaskSpecEnvVar { + .map(|(key, value)| ZoneTaskSpecEnvVar { key: key.clone(), value: value.clone(), }) @@ -52,7 +52,7 @@ impl ExecCommand { let stream = StdioConsoleStream::stdin_stream_exec(initial).await; - let response = client.exec_guest(Request::new(stream)).await?.into_inner(); + let response = client.exec_zone(Request::new(stream)).await?.into_inner(); let code = StdioConsoleStream::exec_output(response).await?; std::process::exit(code); diff --git a/crates/ctl/src/cli/launch.rs b/crates/ctl/src/cli/launch.rs index 64ab4fe..fb4a251 100644 --- a/crates/ctl/src/cli/launch.rs +++ b/crates/ctl/src/cli/launch.rs @@ -6,12 +6,12 @@ use krata::{ events::EventStream, v1::{ common::{ - guest_image_spec::Image, GuestImageSpec, GuestOciImageSpec, GuestSpec, GuestSpecDevice, - GuestStatus, GuestTaskSpec, GuestTaskSpecEnvVar, OciImageFormat, + zone_image_spec::Image, OciImageFormat, ZoneImageSpec, ZoneOciImageSpec, ZoneSpec, + ZoneSpecDevice, ZoneStatus, ZoneTaskSpec, ZoneTaskSpecEnvVar, }, control::{ control_service_client::ControlServiceClient, watch_events_reply::Event, - CreateGuestRequest, PullImageRequest, + CreateZoneRequest, PullImageRequest, }, }, }; @@ -28,56 +28,51 @@ pub enum LaunchImageFormat { } #[derive(Parser)] -#[command(about = "Launch a new guest")] +#[command(about = "Launch a new zone")] pub struct LaunchCommand { #[arg(long, default_value = "squashfs", help = "Image format")] image_format: LaunchImageFormat, #[arg(long, help = "Overwrite image cache on pull")] pull_overwrite_cache: bool, - #[arg(short, long, help = "Name of the guest")] + #[arg(short, long, help = "Name of the zone")] name: Option, - #[arg( - short, - long, - default_value_t = 1, - help = "vCPUs available to the guest" - )] + #[arg(short, long, default_value_t = 1, help = "vCPUs available to the zone")] cpus: u32, #[arg( short, long, default_value_t = 512, - help = "Memory available to the guest, in megabytes" + help = "Memory available to the zone, in megabytes" )] mem: u64, - #[arg[short = 'D', long = "device", help = "Devices to request for the guest"]] + #[arg[short = 'D', long = "device", help = "Devices to request for the zone"]] device: Vec, - #[arg[short, long, help = "Environment variables set in the guest"]] + #[arg[short, long, help = "Environment variables set in the zone"]] env: Option>, #[arg( short, long, - help = "Attach to the guest after guest starts, implies --wait" + help = "Attach to the zone after zone starts, implies --wait" )] attach: bool, #[arg( short = 'W', long, - help = "Wait for the guest to start, implied by --attach" + help = "Wait for the zone to start, implied by --attach" )] wait: bool, - #[arg(short = 'k', long, help = "OCI kernel image for guest to use")] + #[arg(short = 'k', long, help = "OCI kernel image for zone to use")] kernel: Option, - #[arg(short = 'I', long, help = "OCI initrd image for guest to use")] + #[arg(short = 'I', long, help = "OCI initrd image for zone to use")] initrd: Option, #[arg(short = 'w', long, help = "Working directory")] working_directory: Option, - #[arg(help = "Container image for guest to use")] + #[arg(help = "Container image for zone to use")] oci: String, #[arg( allow_hyphen_values = true, trailing_var_arg = true, - help = "Command to run inside the guest" + help = "Command to run inside the zone" )] command: Vec, } @@ -117,18 +112,18 @@ impl LaunchCommand { None }; - let request = CreateGuestRequest { - spec: Some(GuestSpec { + let request = CreateZoneRequest { + spec: Some(ZoneSpec { name: self.name.unwrap_or_default(), image: Some(image), kernel, initrd, vcpus: self.cpus, mem: self.mem, - task: Some(GuestTaskSpec { + task: Some(ZoneTaskSpec { environment: env_map(&self.env.unwrap_or_default()) .iter() - .map(|(key, value)| GuestTaskSpecEnvVar { + .map(|(key, value)| ZoneTaskSpecEnvVar { key: key.clone(), value: value.clone(), }) @@ -140,26 +135,26 @@ impl LaunchCommand { devices: self .device .iter() - .map(|name| GuestSpecDevice { name: name.clone() }) + .map(|name| ZoneSpecDevice { name: name.clone() }) .collect(), }), }; let response = client - .create_guest(Request::new(request)) + .create_zone(Request::new(request)) .await? .into_inner(); - let id = response.guest_id; + let id = response.zone_id; if self.wait || self.attach { - wait_guest_started(&id, events.clone()).await?; + wait_zone_started(&id, events.clone()).await?; } let code = if self.attach { let input = StdioConsoleStream::stdin_stream(id.clone()).await; - let output = client.console_data(input).await?.into_inner(); + let output = client.attach_zone_console(input).await?.into_inner(); let stdout_handle = tokio::task::spawn(async move { StdioConsoleStream::stdout(output).await }); - let exit_hook_task = StdioConsoleStream::guest_exit_hook(id.clone(), events).await?; + let exit_hook_task = StdioConsoleStream::zone_exit_hook(id.clone(), events).await?; select! { x = stdout_handle => { x??; @@ -180,7 +175,7 @@ impl LaunchCommand { client: &mut ControlServiceClient, image: &str, format: OciImageFormat, - ) -> Result { + ) -> Result { let response = client .pull_image(PullImageRequest { image: image.to_string(), @@ -189,8 +184,8 @@ impl LaunchCommand { }) .await?; let reply = pull_interactive_progress(response.into_inner()).await?; - Ok(GuestImageSpec { - image: Some(Image::Oci(GuestOciImageSpec { + Ok(ZoneImageSpec { + image: Some(Image::Oci(ZoneOciImageSpec { digest: reply.digest, format: reply.format, })), @@ -198,38 +193,38 @@ impl LaunchCommand { } } -async fn wait_guest_started(id: &str, events: EventStream) -> Result<()> { +async fn wait_zone_started(id: &str, events: EventStream) -> Result<()> { let mut stream = events.subscribe(); while let Ok(event) = stream.recv().await { match event { - Event::GuestChanged(changed) => { - let Some(guest) = changed.guest else { + Event::ZoneChanged(changed) => { + let Some(zone) = changed.zone else { continue; }; - if guest.id != id { + if zone.id != id { continue; } - let Some(state) = guest.state else { + let Some(state) = zone.state else { continue; }; if let Some(ref error) = state.error_info { - if state.status() == GuestStatus::Failed { + if state.status() == ZoneStatus::Failed { error!("launch failed: {}", error.message); std::process::exit(1); } else { - error!("guest error: {}", error.message); + error!("zone error: {}", error.message); } } - if state.status() == GuestStatus::Destroyed { - error!("guest destroyed"); + if state.status() == ZoneStatus::Destroyed { + error!("zone destroyed"); std::process::exit(1); } - if state.status() == GuestStatus::Started { + if state.status() == ZoneStatus::Started { break; } } diff --git a/crates/ctl/src/cli/list.rs b/crates/ctl/src/cli/list.rs index 142abb8..65589ff 100644 --- a/crates/ctl/src/cli/list.rs +++ b/crates/ctl/src/cli/list.rs @@ -4,9 +4,9 @@ use comfy_table::{presets::UTF8_FULL_CONDENSED, Cell, Color, Table}; use krata::{ events::EventStream, v1::{ - common::{Guest, GuestStatus}, + common::{Zone, ZoneStatus}, control::{ - control_service_client::ControlServiceClient, ListGuestsRequest, ResolveGuestRequest, + control_service_client::ControlServiceClient, ListZonesRequest, ResolveZoneRequest, }, }, }; @@ -14,7 +14,7 @@ use krata::{ use serde_json::Value; use tonic::{transport::Channel, Request}; -use crate::format::{guest_simple_line, guest_status_text, kv2line, proto2dynamic, proto2kv}; +use crate::format::{kv2line, proto2dynamic, proto2kv, zone_simple_line, zone_status_text}; #[derive(ValueEnum, Clone, Debug, PartialEq, Eq)] enum ListFormat { @@ -28,12 +28,12 @@ enum ListFormat { } #[derive(Parser)] -#[command(about = "List the guests on the isolation engine")] +#[command(about = "List the zones on the isolation engine")] pub struct ListCommand { #[arg(short, long, default_value = "table", help = "Output format")] format: ListFormat, - #[arg(help = "Limit to a single guest, either the name or the uuid")] - guest: Option, + #[arg(help = "Limit to a single zone, either the name or the uuid")] + zone: Option, } impl ListCommand { @@ -42,27 +42,25 @@ impl ListCommand { mut client: ControlServiceClient, _events: EventStream, ) -> Result<()> { - let mut guests = if let Some(ref guest) = self.guest { + let mut zones = if let Some(ref zone) = self.zone { let reply = client - .resolve_guest(Request::new(ResolveGuestRequest { - name: guest.clone(), - })) + .resolve_zone(Request::new(ResolveZoneRequest { name: zone.clone() })) .await? .into_inner(); - if let Some(guest) = reply.guest { - vec![guest] + if let Some(zone) = reply.zone { + vec![zone] } else { - return Err(anyhow!("unable to resolve guest '{}'", guest)); + return Err(anyhow!("unable to resolve zone '{}'", zone)); } } else { client - .list_guests(Request::new(ListGuestsRequest {})) + .list_zones(Request::new(ListZonesRequest {})) .await? .into_inner() - .guests + .zones }; - guests.sort_by(|a, b| { + zones.sort_by(|a, b| { a.spec .as_ref() .map(|x| x.name.as_str()) @@ -72,19 +70,19 @@ impl ListCommand { match self.format { ListFormat::Table => { - self.print_guest_table(guests)?; + self.print_zone_table(zones)?; } ListFormat::Simple => { - for guest in guests { - println!("{}", guest_simple_line(&guest)); + for zone in zones { + println!("{}", zone_simple_line(&zone)); } } ListFormat::Json | ListFormat::JsonPretty | ListFormat::Yaml => { let mut values = Vec::new(); - for guest in guests { - let message = proto2dynamic(guest)?; + for zone in zones { + let message = proto2dynamic(zone)?; values.push(serde_json::to_value(message)?); } let value = Value::Array(values); @@ -99,64 +97,62 @@ impl ListCommand { } ListFormat::Jsonl => { - for guest in guests { - let message = proto2dynamic(guest)?; + for zone in zones { + let message = proto2dynamic(zone)?; println!("{}", serde_json::to_string(&message)?); } } ListFormat::KeyValue => { - self.print_key_value(guests)?; + self.print_key_value(zones)?; } } Ok(()) } - fn print_guest_table(&self, guests: Vec) -> Result<()> { + fn print_zone_table(&self, zones: Vec) -> Result<()> { let mut table = Table::new(); table.load_preset(UTF8_FULL_CONDENSED); table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic); table.set_header(vec!["name", "uuid", "status", "ipv4", "ipv6"]); - for guest in guests { - let ipv4 = guest + for zone in zones { + let ipv4 = zone .state .as_ref() .and_then(|x| x.network.as_ref()) - .map(|x| x.guest_ipv4.as_str()) + .map(|x| x.zone_ipv4.as_str()) .unwrap_or("n/a"); - let ipv6 = guest + let ipv6 = zone .state .as_ref() .and_then(|x| x.network.as_ref()) - .map(|x| x.guest_ipv6.as_str()) + .map(|x| x.zone_ipv6.as_str()) .unwrap_or("n/a"); - let Some(spec) = guest.spec else { + let Some(spec) = zone.spec else { continue; }; - let status = guest.state.as_ref().cloned().unwrap_or_default().status(); - let status_text = guest_status_text(status); + let status = zone.state.as_ref().cloned().unwrap_or_default().status(); + let status_text = zone_status_text(status); let status_color = match status { - GuestStatus::Destroyed | GuestStatus::Failed => Color::Red, - GuestStatus::Destroying | GuestStatus::Exited | GuestStatus::Starting => { - Color::Yellow - } - GuestStatus::Started => Color::Green, + ZoneStatus::Destroyed | ZoneStatus::Failed => Color::Red, + ZoneStatus::Destroying | ZoneStatus::Exited | ZoneStatus::Starting => Color::Yellow, + ZoneStatus::Started => Color::Green, _ => Color::Reset, }; table.add_row(vec![ Cell::new(spec.name), - Cell::new(guest.id), + Cell::new(zone.id), Cell::new(status_text).fg(status_color), Cell::new(ipv4.to_string()), Cell::new(ipv6.to_string()), ]); } if table.is_empty() { - if self.guest.is_none() { - println!("no guests have been launched"); + if self.zone.is_none() { + println!("no zones have been launched"); } } else { println!("{}", table); @@ -164,9 +160,9 @@ impl ListCommand { Ok(()) } - fn print_key_value(&self, guests: Vec) -> Result<()> { - for guest in guests { - let kvs = proto2kv(guest)?; + fn print_key_value(&self, zones: Vec) -> Result<()> { + for zone in zones { + let kvs = proto2kv(zone)?; println!("{}", kv2line(kvs),); } Ok(()) diff --git a/crates/ctl/src/cli/logs.rs b/crates/ctl/src/cli/logs.rs index 33a794a..2d12ea1 100644 --- a/crates/ctl/src/cli/logs.rs +++ b/crates/ctl/src/cli/logs.rs @@ -3,7 +3,7 @@ use async_stream::stream; use clap::Parser; use krata::{ events::EventStream, - v1::control::{control_service_client::ControlServiceClient, ConsoleDataRequest}, + v1::control::{control_service_client::ControlServiceClient, ZoneConsoleRequest}, }; use tokio::select; @@ -12,15 +12,15 @@ use tonic::transport::Channel; use crate::console::StdioConsoleStream; -use super::resolve_guest; +use super::resolve_zone; #[derive(Parser)] -#[command(about = "View the logs of a guest")] +#[command(about = "View the logs of a zone")] pub struct LogsCommand { - #[arg(short, long, help = "Follow output from the guest")] + #[arg(short, long, help = "Follow output from the zone")] follow: bool, - #[arg(help = "Guest to show logs for, either the name or the uuid")] - guest: String, + #[arg(help = "Zone to show logs for, either the name or the uuid")] + zone: String, } impl LogsCommand { @@ -29,22 +29,22 @@ impl LogsCommand { mut client: ControlServiceClient, events: EventStream, ) -> Result<()> { - let guest_id: String = resolve_guest(&mut client, &self.guest).await?; - let guest_id_stream = guest_id.clone(); + let zone_id: String = resolve_zone(&mut client, &self.zone).await?; + let zone_id_stream = zone_id.clone(); let follow = self.follow; let input = stream! { - yield ConsoleDataRequest { guest_id: guest_id_stream, data: Vec::new() }; + yield ZoneConsoleRequest { zone_id: zone_id_stream, data: Vec::new() }; if follow { - let mut pending = pending::(); + let mut pending = pending::(); while let Some(x) = pending.next().await { yield x; } } }; - let output = client.console_data(input).await?.into_inner(); + let output = client.attach_zone_console(input).await?.into_inner(); let stdout_handle = tokio::task::spawn(async move { StdioConsoleStream::stdout(output).await }); - let exit_hook_task = StdioConsoleStream::guest_exit_hook(guest_id.clone(), events).await?; + let exit_hook_task = StdioConsoleStream::zone_exit_hook(zone_id.clone(), events).await?; let code = select! { x = stdout_handle => { x??; diff --git a/crates/ctl/src/cli/metrics.rs b/crates/ctl/src/cli/metrics.rs index 17def04..31a8737 100644 --- a/crates/ctl/src/cli/metrics.rs +++ b/crates/ctl/src/cli/metrics.rs @@ -3,8 +3,8 @@ use clap::{Parser, ValueEnum}; use krata::{ events::EventStream, v1::{ - common::GuestMetricNode, - control::{control_service_client::ControlServiceClient, ReadGuestMetricsRequest}, + common::ZoneMetricNode, + control::{control_service_client::ControlServiceClient, ReadZoneMetricsRequest}, }, }; @@ -12,7 +12,7 @@ use tonic::transport::Channel; use crate::format::{kv2line, metrics_flat, metrics_tree, proto2dynamic}; -use super::resolve_guest; +use super::resolve_zone; #[derive(ValueEnum, Clone, Debug, PartialEq, Eq)] enum MetricsFormat { @@ -24,12 +24,12 @@ enum MetricsFormat { } #[derive(Parser)] -#[command(about = "Read metrics from the guest")] +#[command(about = "Read metrics from the zone")] pub struct MetricsCommand { #[arg(short, long, default_value = "tree", help = "Output format")] format: MetricsFormat, - #[arg(help = "Guest to read metrics for, either the name or the uuid")] - guest: String, + #[arg(help = "Zone to read metrics for, either the name or the uuid")] + zone: String, } impl MetricsCommand { @@ -38,9 +38,9 @@ impl MetricsCommand { mut client: ControlServiceClient, _events: EventStream, ) -> Result<()> { - let guest_id: String = resolve_guest(&mut client, &self.guest).await?; + let zone_id: String = resolve_zone(&mut client, &self.zone).await?; let root = client - .read_guest_metrics(ReadGuestMetricsRequest { guest_id }) + .read_zone_metrics(ReadZoneMetricsRequest { zone_id }) .await? .into_inner() .root @@ -70,12 +70,12 @@ impl MetricsCommand { Ok(()) } - fn print_metrics_tree(&self, root: GuestMetricNode) -> Result<()> { + fn print_metrics_tree(&self, root: ZoneMetricNode) -> Result<()> { print!("{}", metrics_tree(root)); Ok(()) } - fn print_key_value(&self, metrics: GuestMetricNode) -> Result<()> { + fn print_key_value(&self, metrics: ZoneMetricNode) -> Result<()> { let kvs = metrics_flat(metrics); println!("{}", kv2line(kvs)); Ok(()) diff --git a/crates/ctl/src/cli/mod.rs b/crates/ctl/src/cli/mod.rs index 43c7516..e0e42f6 100644 --- a/crates/ctl/src/cli/mod.rs +++ b/crates/ctl/src/cli/mod.rs @@ -19,7 +19,7 @@ use clap::{Parser, Subcommand}; use krata::{ client::ControlClientProvider, events::EventStream, - v1::control::{control_service_client::ControlServiceClient, ResolveGuestRequest}, + v1::control::{control_service_client::ControlServiceClient, ResolveZoneRequest}, }; use tonic::{transport::Channel, Request}; @@ -135,20 +135,20 @@ impl ControlCommand { } } -pub async fn resolve_guest( +pub async fn resolve_zone( client: &mut ControlServiceClient, name: &str, ) -> Result { let reply = client - .resolve_guest(Request::new(ResolveGuestRequest { + .resolve_zone(Request::new(ResolveZoneRequest { name: name.to_string(), })) .await? .into_inner(); - if let Some(guest) = reply.guest { - Ok(guest.id) + if let Some(zone) = reply.zone { + Ok(zone.id) } else { - Err(anyhow!("unable to resolve guest '{}'", name)) + Err(anyhow!("unable to resolve zone '{}'", name)) } } diff --git a/crates/ctl/src/cli/resolve.rs b/crates/ctl/src/cli/resolve.rs index 4ed3a39..b7ed19e 100644 --- a/crates/ctl/src/cli/resolve.rs +++ b/crates/ctl/src/cli/resolve.rs @@ -1,26 +1,26 @@ use anyhow::Result; use clap::Parser; -use krata::v1::control::{control_service_client::ControlServiceClient, ResolveGuestRequest}; +use krata::v1::control::{control_service_client::ControlServiceClient, ResolveZoneRequest}; use tonic::{transport::Channel, Request}; #[derive(Parser)] -#[command(about = "Resolve a guest name to a uuid")] +#[command(about = "Resolve a zone name to a uuid")] pub struct ResolveCommand { - #[arg(help = "Guest name")] - guest: String, + #[arg(help = "Zone name")] + zone: String, } impl ResolveCommand { pub async fn run(self, mut client: ControlServiceClient) -> Result<()> { let reply = client - .resolve_guest(Request::new(ResolveGuestRequest { - name: self.guest.clone(), + .resolve_zone(Request::new(ResolveZoneRequest { + name: self.zone.clone(), })) .await? .into_inner(); - if let Some(guest) = reply.guest { - println!("{}", guest.id); + if let Some(zone) = reply.zone { + println!("{}", zone.id); } else { std::process::exit(1); } diff --git a/crates/ctl/src/cli/top.rs b/crates/ctl/src/cli/top.rs index 477fefb..90fdc97 100644 --- a/crates/ctl/src/cli/top.rs +++ b/crates/ctl/src/cli/top.rs @@ -24,14 +24,14 @@ use ratatui::{ }; use crate::{ - format::guest_status_text, + format::zone_status_text, metrics::{ lookup_metric_value, MultiMetricCollector, MultiMetricCollectorHandle, MultiMetricState, }, }; #[derive(Parser)] -#[command(about = "Dashboard for running guests")] +#[command(about = "Dashboard for running zones")] pub struct TopCommand {} pub type Tui = Terminal>; @@ -46,7 +46,7 @@ impl TopCommand { let collector = collector.launch().await?; let mut tui = TopCommand::init()?; let mut app = TopApp { - metrics: MultiMetricState { guests: vec![] }, + metrics: MultiMetricState { zones: vec![] }, exit: false, table: TableState::new(), }; @@ -152,12 +152,12 @@ impl Widget for &mut TopApp { let mut rows = vec![]; - for ms in &self.metrics.guests { - let Some(ref spec) = ms.guest.spec else { + for ms in &self.metrics.zones { + let Some(ref spec) = ms.zone.spec else { continue; }; - let Some(ref state) = ms.guest.state else { + let Some(ref state) = ms.zone.state else { continue; }; @@ -176,8 +176,8 @@ impl Widget for &mut TopApp { let row = Row::new(vec![ spec.name.clone(), - ms.guest.id.clone(), - guest_status_text(state.status()), + ms.zone.id.clone(), + zone_status_text(state.status()), memory_total.unwrap_or_default(), memory_used.unwrap_or_default(), memory_free.unwrap_or_default(), diff --git a/crates/ctl/src/cli/watch.rs b/crates/ctl/src/cli/watch.rs index e535ca6..9cbc1ac 100644 --- a/crates/ctl/src/cli/watch.rs +++ b/crates/ctl/src/cli/watch.rs @@ -2,12 +2,12 @@ use anyhow::Result; use clap::{Parser, ValueEnum}; use krata::{ events::EventStream, - v1::{common::Guest, control::watch_events_reply::Event}, + v1::{common::Zone, control::watch_events_reply::Event}, }; use prost_reflect::ReflectMessage; use serde_json::Value; -use crate::format::{guest_simple_line, kv2line, proto2dynamic, proto2kv}; +use crate::format::{kv2line, proto2dynamic, proto2kv, zone_simple_line}; #[derive(ValueEnum, Clone, Debug, PartialEq, Eq)] enum WatchFormat { @@ -17,7 +17,7 @@ enum WatchFormat { } #[derive(Parser)] -#[command(about = "Watch for guest changes")] +#[command(about = "Watch for zone changes")] pub struct WatchCommand { #[arg(short, long, default_value = "simple", help = "Output format")] format: WatchFormat, @@ -29,22 +29,17 @@ impl WatchCommand { loop { let event = stream.recv().await?; - let Event::GuestChanged(changed) = event; - let guest = changed.guest.clone(); - self.print_event("guest.changed", changed, guest)?; + let Event::ZoneChanged(changed) = event; + let zone = changed.zone.clone(); + self.print_event("zone.changed", changed, zone)?; } } - fn print_event( - &self, - typ: &str, - event: impl ReflectMessage, - guest: Option, - ) -> Result<()> { + fn print_event(&self, typ: &str, event: impl ReflectMessage, zone: Option) -> Result<()> { match self.format { WatchFormat::Simple => { - if let Some(guest) = guest { - println!("{}", guest_simple_line(&guest)); + if let Some(zone) = zone { + println!("{}", zone_simple_line(&zone)); } } diff --git a/crates/ctl/src/console.rs b/crates/ctl/src/console.rs index 57efb67..8884c36 100644 --- a/crates/ctl/src/console.rs +++ b/crates/ctl/src/console.rs @@ -7,10 +7,10 @@ use crossterm::{ use krata::{ events::EventStream, v1::{ - common::GuestStatus, + common::ZoneStatus, control::{ - watch_events_reply::Event, ConsoleDataReply, ConsoleDataRequest, ExecGuestReply, - ExecGuestRequest, + watch_events_reply::Event, ExecZoneReply, ExecZoneRequest, ZoneConsoleReply, + ZoneConsoleRequest, }, }, }; @@ -25,10 +25,10 @@ use tonic::Streaming; pub struct StdioConsoleStream; impl StdioConsoleStream { - pub async fn stdin_stream(guest: String) -> impl Stream { + pub async fn stdin_stream(zone: String) -> impl Stream { let mut stdin = stdin(); stream! { - yield ConsoleDataRequest { guest_id: guest, data: vec![] }; + yield ZoneConsoleRequest { zone_id: zone, data: vec![] }; let mut buffer = vec![0u8; 60]; loop { @@ -43,14 +43,14 @@ impl StdioConsoleStream { if size == 1 && buffer[0] == 0x1d { break; } - yield ConsoleDataRequest { guest_id: String::default(), data }; + yield ZoneConsoleRequest { zone_id: String::default(), data }; } } } pub async fn stdin_stream_exec( - initial: ExecGuestRequest, - ) -> impl Stream { + initial: ExecZoneRequest, + ) -> impl Stream { let mut stdin = stdin(); stream! { yield initial; @@ -68,12 +68,12 @@ impl StdioConsoleStream { if size == 1 && buffer[0] == 0x1d { break; } - yield ExecGuestRequest { guest_id: String::default(), task: None, data }; + yield ExecZoneRequest { zone_id: String::default(), task: None, data }; } } } - pub async fn stdout(mut stream: Streaming) -> Result<()> { + pub async fn stdout(mut stream: Streaming) -> Result<()> { if stdin().is_tty() { enable_raw_mode()?; StdioConsoleStream::register_terminal_restore_hook()?; @@ -90,7 +90,7 @@ impl StdioConsoleStream { Ok(()) } - pub async fn exec_output(mut stream: Streaming) -> Result { + pub async fn exec_output(mut stream: Streaming) -> Result { let mut stdout = stdout(); let mut stderr = stderr(); while let Some(reply) = stream.next().await { @@ -106,33 +106,33 @@ impl StdioConsoleStream { } if reply.exited { - if reply.error.is_empty() { - return Ok(reply.exit_code); + return if reply.error.is_empty() { + Ok(reply.exit_code) } else { - return Err(anyhow!("exec failed: {}", reply.error)); - } + Err(anyhow!("exec failed: {}", reply.error)) + }; } } Ok(-1) } - pub async fn guest_exit_hook( + pub async fn zone_exit_hook( id: String, events: EventStream, ) -> Result>> { Ok(tokio::task::spawn(async move { let mut stream = events.subscribe(); while let Ok(event) = stream.recv().await { - let Event::GuestChanged(changed) = event; - let Some(guest) = changed.guest else { + let Event::ZoneChanged(changed) = event; + let Some(zone) = changed.zone else { continue; }; - let Some(state) = guest.state else { + let Some(state) = zone.state else { continue; }; - if guest.id != id { + if zone.id != id { continue; } @@ -141,7 +141,7 @@ impl StdioConsoleStream { } let status = state.status(); - if status == GuestStatus::Destroying || status == GuestStatus::Destroyed { + if status == ZoneStatus::Destroying || status == ZoneStatus::Destroyed { return Some(10); } } diff --git a/crates/ctl/src/format.rs b/crates/ctl/src/format.rs index 5e9f232..d95e514 100644 --- a/crates/ctl/src/format.rs +++ b/crates/ctl/src/format.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, time::Duration}; use anyhow::Result; use fancy_duration::FancyDuration; use human_bytes::human_bytes; -use krata::v1::common::{Guest, GuestMetricFormat, GuestMetricNode, GuestStatus}; +use krata::v1::common::{Zone, ZoneMetricFormat, ZoneMetricNode, ZoneStatus}; use prost_reflect::{DynamicMessage, ReflectMessage}; use prost_types::Value; use termtree::Tree; @@ -75,32 +75,31 @@ pub fn kv2line(map: HashMap) -> String { .join(" ") } -pub fn guest_status_text(status: GuestStatus) -> String { +pub fn zone_status_text(status: ZoneStatus) -> String { match status { - GuestStatus::Starting => "starting", - GuestStatus::Started => "started", - GuestStatus::Destroying => "destroying", - GuestStatus::Destroyed => "destroyed", - GuestStatus::Exited => "exited", - GuestStatus::Failed => "failed", + ZoneStatus::Starting => "starting", + ZoneStatus::Started => "started", + ZoneStatus::Destroying => "destroying", + ZoneStatus::Destroyed => "destroyed", + ZoneStatus::Exited => "exited", + ZoneStatus::Failed => "failed", _ => "unknown", } .to_string() } -pub fn guest_simple_line(guest: &Guest) -> String { - let state = guest_status_text( - guest - .state +pub fn zone_simple_line(zone: &Zone) -> String { + let state = zone_status_text( + zone.state .as_ref() .map(|x| x.status()) - .unwrap_or(GuestStatus::Unknown), + .unwrap_or(ZoneStatus::Unknown), ); - let name = guest.spec.as_ref().map(|x| x.name.as_str()).unwrap_or(""); - let network = guest.state.as_ref().and_then(|x| x.network.as_ref()); - let ipv4 = network.map(|x| x.guest_ipv4.as_str()).unwrap_or(""); - let ipv6 = network.map(|x| x.guest_ipv6.as_str()).unwrap_or(""); - format!("{}\t{}\t{}\t{}\t{}", guest.id, state, name, ipv4, ipv6) + let name = zone.spec.as_ref().map(|x| x.name.as_str()).unwrap_or(""); + let network = zone.state.as_ref().and_then(|x| x.network.as_ref()); + let ipv4 = network.map(|x| x.zone_ipv4.as_str()).unwrap_or(""); + let ipv6 = network.map(|x| x.zone_ipv6.as_str()).unwrap_or(""); + format!("{}\t{}\t{}\t{}\t{}", zone.id, state, name, ipv4, ipv6) } fn metrics_value_string(value: Value) -> String { @@ -116,18 +115,18 @@ fn metrics_value_numeric(value: Value) -> f64 { string.parse::().ok().unwrap_or(f64::NAN) } -pub fn metrics_value_pretty(value: Value, format: GuestMetricFormat) -> String { +pub fn metrics_value_pretty(value: Value, format: ZoneMetricFormat) -> String { match format { - GuestMetricFormat::Bytes => human_bytes(metrics_value_numeric(value)), - GuestMetricFormat::Integer => (metrics_value_numeric(value) as u64).to_string(), - GuestMetricFormat::DurationSeconds => { + ZoneMetricFormat::Bytes => human_bytes(metrics_value_numeric(value)), + ZoneMetricFormat::Integer => (metrics_value_numeric(value) as u64).to_string(), + ZoneMetricFormat::DurationSeconds => { FancyDuration(Duration::from_secs_f64(metrics_value_numeric(value))).to_string() } _ => metrics_value_string(value), } } -fn metrics_flat_internal(prefix: &str, node: GuestMetricNode, map: &mut HashMap) { +fn metrics_flat_internal(prefix: &str, node: ZoneMetricNode, map: &mut HashMap) { if let Some(value) = node.value { map.insert(prefix.to_string(), metrics_value_string(value)); } @@ -142,13 +141,13 @@ fn metrics_flat_internal(prefix: &str, node: GuestMetricNode, map: &mut HashMap< } } -pub fn metrics_flat(root: GuestMetricNode) -> HashMap { +pub fn metrics_flat(root: ZoneMetricNode) -> HashMap { let mut map = HashMap::new(); metrics_flat_internal("", root, &mut map); map } -pub fn metrics_tree(node: GuestMetricNode) -> Tree { +pub fn metrics_tree(node: ZoneMetricNode) -> Tree { let mut name = node.name.to_string(); let format = node.format(); if let Some(value) = node.value { diff --git a/crates/ctl/src/metrics.rs b/crates/ctl/src/metrics.rs index 570d593..faad956 100644 --- a/crates/ctl/src/metrics.rs +++ b/crates/ctl/src/metrics.rs @@ -2,10 +2,10 @@ use anyhow::Result; use krata::{ events::EventStream, v1::{ - common::{Guest, GuestMetricNode, GuestStatus}, + common::{Zone, ZoneMetricNode, ZoneStatus}, control::{ control_service_client::ControlServiceClient, watch_events_reply::Event, - ListGuestsRequest, ReadGuestMetricsRequest, + ListZonesRequest, ReadZoneMetricsRequest, }, }, }; @@ -22,12 +22,12 @@ use tonic::transport::Channel; use crate::format::metrics_value_pretty; pub struct MetricState { - pub guest: Guest, - pub root: Option, + pub zone: Zone, + pub root: Option, } pub struct MultiMetricState { - pub guests: Vec, + pub zones: Vec, } pub struct MultiMetricCollector { @@ -72,26 +72,26 @@ impl MultiMetricCollector { pub async fn process(&mut self, sender: Sender) -> Result<()> { let mut events = self.events.subscribe(); - let mut guests: Vec = self + let mut zones: Vec = self .client - .list_guests(ListGuestsRequest {}) + .list_zones(ListZonesRequest {}) .await? .into_inner() - .guests; + .zones; loop { let collect = select! { x = events.recv() => match x { Ok(event) => { - let Event::GuestChanged(changed) = event; - let Some(guest) = changed.guest else { + let Event::ZoneChanged(changed) = event; + let Some(zone) = changed.zone else { continue; }; - let Some(ref state) = guest.state else { + let Some(ref state) = zone.state else { continue; }; - guests.retain(|x| x.id != guest.id); - if state.status() != GuestStatus::Destroying { - guests.push(guest); + zones.retain(|x| x.id != zone.id); + if state.status() != ZoneStatus::Destroying { + zones.push(zone); } false }, @@ -111,19 +111,19 @@ impl MultiMetricCollector { } let mut metrics = Vec::new(); - for guest in &guests { - let Some(ref state) = guest.state else { + for zone in &zones { + let Some(ref state) = zone.state else { continue; }; - if state.status() != GuestStatus::Started { + if state.status() != ZoneStatus::Started { continue; } let root = timeout( Duration::from_secs(5), - self.client.read_guest_metrics(ReadGuestMetricsRequest { - guest_id: guest.id.clone(), + self.client.read_zone_metrics(ReadZoneMetricsRequest { + zone_id: zone.id.clone(), }), ) .await @@ -132,16 +132,16 @@ impl MultiMetricCollector { .map(|x| x.into_inner()) .and_then(|x| x.root); metrics.push(MetricState { - guest: guest.clone(), + zone: zone.clone(), root, }); } - sender.send(MultiMetricState { guests: metrics }).await?; + sender.send(MultiMetricState { zones: metrics }).await?; } } } -pub fn lookup<'a>(node: &'a GuestMetricNode, path: &str) -> Option<&'a GuestMetricNode> { +pub fn lookup<'a>(node: &'a ZoneMetricNode, path: &str) -> Option<&'a ZoneMetricNode> { let Some((what, b)) = path.split_once('/') else { return node.children.iter().find(|x| x.name == path); }; @@ -149,7 +149,7 @@ pub fn lookup<'a>(node: &'a GuestMetricNode, path: &str) -> Option<&'a GuestMetr return lookup(next, b); } -pub fn lookup_metric_value(node: &GuestMetricNode, path: &str) -> Option { +pub fn lookup_metric_value(node: &ZoneMetricNode, path: &str) -> Option { lookup(node, path).and_then(|x| { x.value .as_ref() diff --git a/crates/daemon/src/console.rs b/crates/daemon/src/console.rs index 8c35b71..44bbaed 100644 --- a/crates/daemon/src/console.rs +++ b/crates/daemon/src/console.rs @@ -13,7 +13,7 @@ use tokio::{ }; use uuid::Uuid; -use crate::glt::GuestLookupTable; +use crate::zlt::ZoneLookupTable; const CONSOLE_BUFFER_SIZE: usize = 1024 * 1024; type RawConsoleBuffer = CircularBuffer; @@ -24,7 +24,7 @@ type BufferMap = Arc>>; #[derive(Clone)] pub struct DaemonConsoleHandle { - glt: GuestLookupTable, + glt: ZoneLookupTable, listeners: ListenerMap, buffers: BufferMap, sender: Sender<(u32, Vec)>, @@ -84,7 +84,7 @@ impl Drop for DaemonConsoleHandle { } pub struct DaemonConsole { - glt: GuestLookupTable, + glt: ZoneLookupTable, listeners: ListenerMap, buffers: BufferMap, receiver: Receiver<(u32, Option>)>, @@ -93,7 +93,7 @@ pub struct DaemonConsole { } impl DaemonConsole { - pub async fn new(glt: GuestLookupTable) -> Result { + pub async fn new(glt: ZoneLookupTable) -> Result { let (service, sender, receiver) = ChannelService::new("krata-console".to_string(), Some(0)).await?; let task = service.launch().await?; diff --git a/crates/daemon/src/control.rs b/crates/daemon/src/control.rs index 0af24b3..fa14cd7 100644 --- a/crates/daemon/src/control.rs +++ b/crates/daemon/src/control.rs @@ -7,16 +7,16 @@ use krata::{ ExecStreamRequestStdin, ExecStreamRequestUpdate, MetricsRequest, Request as IdmRequest, }, v1::{ - common::{Guest, GuestState, GuestStatus, OciImageFormat}, + common::{OciImageFormat, Zone, ZoneState, ZoneStatus}, control::{ - control_service_server::ControlService, ConsoleDataReply, ConsoleDataRequest, - CreateGuestReply, CreateGuestRequest, DestroyGuestReply, DestroyGuestRequest, - DeviceInfo, ExecGuestReply, ExecGuestRequest, HostCpuTopologyInfo, - HostCpuTopologyReply, HostCpuTopologyRequest, HostPowerManagementPolicy, - IdentifyHostReply, IdentifyHostRequest, ListDevicesReply, ListDevicesRequest, - ListGuestsReply, ListGuestsRequest, PullImageReply, PullImageRequest, - ReadGuestMetricsReply, ReadGuestMetricsRequest, ResolveGuestReply, ResolveGuestRequest, - SnoopIdmReply, SnoopIdmRequest, WatchEventsReply, WatchEventsRequest, + control_service_server::ControlService, CreateZoneReply, CreateZoneRequest, + DestroyZoneReply, DestroyZoneRequest, DeviceInfo, ExecZoneReply, ExecZoneRequest, + HostCpuTopologyInfo, HostCpuTopologyReply, HostCpuTopologyRequest, + HostPowerManagementPolicy, IdentifyHostReply, IdentifyHostRequest, ListDevicesReply, + ListDevicesRequest, ListZonesReply, ListZonesRequest, PullImageReply, PullImageRequest, + ReadZoneMetricsReply, ReadZoneMetricsRequest, ResolveZoneReply, ResolveZoneRequest, + SnoopIdmReply, SnoopIdmRequest, WatchEventsReply, WatchEventsRequest, ZoneConsoleReply, + ZoneConsoleRequest, }, }, }; @@ -37,9 +37,9 @@ use tonic::{Request, Response, Status, Streaming}; use uuid::Uuid; use crate::{ - command::DaemonCommand, console::DaemonConsoleHandle, db::GuestStore, - devices::DaemonDeviceManager, event::DaemonEventContext, glt::GuestLookupTable, - idm::DaemonIdmHandle, metrics::idm_metric_to_api, oci::convert_oci_progress, + command::DaemonCommand, console::DaemonConsoleHandle, db::ZoneStore, + devices::DaemonDeviceManager, event::DaemonEventContext, idm::DaemonIdmHandle, + metrics::idm_metric_to_api, oci::convert_oci_progress, zlt::ZoneLookupTable, }; pub struct ApiError { @@ -62,13 +62,13 @@ impl From for Status { #[derive(Clone)] pub struct DaemonControlService { - glt: GuestLookupTable, + glt: ZoneLookupTable, devices: DaemonDeviceManager, events: DaemonEventContext, console: DaemonConsoleHandle, idm: DaemonIdmHandle, - guests: GuestStore, - guest_reconciler_notify: Sender, + zones: ZoneStore, + zone_reconciler_notify: Sender, packer: OciPackerService, runtime: Runtime, } @@ -76,13 +76,13 @@ pub struct DaemonControlService { impl DaemonControlService { #[allow(clippy::too_many_arguments)] pub fn new( - glt: GuestLookupTable, + glt: ZoneLookupTable, devices: DaemonDeviceManager, events: DaemonEventContext, console: DaemonConsoleHandle, idm: DaemonIdmHandle, - guests: GuestStore, - guest_reconciler_notify: Sender, + zones: ZoneStore, + zone_reconciler_notify: Sender, packer: OciPackerService, runtime: Runtime, ) -> Self { @@ -92,8 +92,8 @@ impl DaemonControlService { events, console, idm, - guests, - guest_reconciler_notify, + zones, + zone_reconciler_notify, packer, runtime, } @@ -102,7 +102,7 @@ impl DaemonControlService { enum ConsoleDataSelect { Read(Option>), - Write(Option>), + Write(Option>), } enum PullImageSelect { @@ -112,11 +112,11 @@ enum PullImageSelect { #[tonic::async_trait] impl ControlService for DaemonControlService { - type ExecGuestStream = - Pin> + Send + 'static>>; + type ExecZoneStream = + Pin> + Send + 'static>>; - type ConsoleDataStream = - Pin> + Send + 'static>>; + type AttachZoneConsoleStream = + Pin> + Send + 'static>>; type PullImageStream = Pin> + Send + 'static>>; @@ -139,25 +139,25 @@ impl ControlService for DaemonControlService { })) } - async fn create_guest( + async fn create_zone( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let request = request.into_inner(); let Some(spec) = request.spec else { return Err(ApiError { - message: "guest spec not provided".to_string(), + message: "zone spec not provided".to_string(), } .into()); }; let uuid = Uuid::new_v4(); - self.guests + self.zones .update( uuid, - Guest { + Zone { id: uuid.to_string(), - state: Some(GuestState { - status: GuestStatus::Starting.into(), + state: Some(ZoneState { + status: ZoneStatus::Starting.into(), network: None, exit_info: None, error_info: None, @@ -169,21 +169,21 @@ impl ControlService for DaemonControlService { ) .await .map_err(ApiError::from)?; - self.guest_reconciler_notify + self.zone_reconciler_notify .send(uuid) .await .map_err(|x| ApiError { message: x.to_string(), })?; - Ok(Response::new(CreateGuestReply { - guest_id: uuid.to_string(), + Ok(Response::new(CreateZoneReply { + zone_id: uuid.to_string(), })) } - async fn exec_guest( + async fn exec_zone( &self, - request: Request>, - ) -> Result, Status> { + request: Request>, + ) -> Result, Status> { let mut input = request.into_inner(); let Some(request) = input.next().await else { return Err(ApiError { @@ -200,7 +200,7 @@ impl ControlService for DaemonControlService { .into()); }; - let uuid = Uuid::from_str(&request.guest_id).map_err(|error| ApiError { + let uuid = Uuid::from_str(&request.zone_id).map_err(|error| ApiError { message: error.to_string(), })?; let idm = self.idm.client(uuid).await.map_err(|error| ApiError { @@ -232,7 +232,7 @@ impl ControlService for DaemonControlService { loop { select! { x = input.next() => if let Some(update) = x { - let update: Result = update.map_err(|error| ApiError { + let update: Result = update.map_err(|error| ApiError { message: error.to_string() }.into()); @@ -252,7 +252,7 @@ impl ControlService for DaemonControlService { let Some(IdmResponseType::ExecStream(update)) = response.response else { break; }; - let reply = ExecGuestReply { + let reply = ExecZoneReply { exited: update.exited, error: update.error, exit_code: update.exit_code, @@ -269,80 +269,80 @@ impl ControlService for DaemonControlService { } }; - Ok(Response::new(Box::pin(output) as Self::ExecGuestStream)) + Ok(Response::new(Box::pin(output) as Self::ExecZoneStream)) } - async fn destroy_guest( + async fn destroy_zone( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let request = request.into_inner(); - let uuid = Uuid::from_str(&request.guest_id).map_err(|error| ApiError { + let uuid = Uuid::from_str(&request.zone_id).map_err(|error| ApiError { message: error.to_string(), })?; - let Some(mut guest) = self.guests.read(uuid).await.map_err(ApiError::from)? else { + let Some(mut zone) = self.zones.read(uuid).await.map_err(ApiError::from)? else { return Err(ApiError { - message: "guest not found".to_string(), + message: "zone not found".to_string(), } .into()); }; - guest.state = Some(guest.state.as_mut().cloned().unwrap_or_default()); + zone.state = Some(zone.state.as_mut().cloned().unwrap_or_default()); - if guest.state.as_ref().unwrap().status() == GuestStatus::Destroyed { + if zone.state.as_ref().unwrap().status() == ZoneStatus::Destroyed { return Err(ApiError { - message: "guest already destroyed".to_string(), + message: "zone already destroyed".to_string(), } .into()); } - guest.state.as_mut().unwrap().status = GuestStatus::Destroying.into(); - self.guests - .update(uuid, guest) + zone.state.as_mut().unwrap().status = ZoneStatus::Destroying.into(); + self.zones + .update(uuid, zone) .await .map_err(ApiError::from)?; - self.guest_reconciler_notify + self.zone_reconciler_notify .send(uuid) .await .map_err(|x| ApiError { message: x.to_string(), })?; - Ok(Response::new(DestroyGuestReply {})) + Ok(Response::new(DestroyZoneReply {})) } - async fn list_guests( + async fn list_zones( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let _ = request.into_inner(); - let guests = self.guests.list().await.map_err(ApiError::from)?; - let guests = guests.into_values().collect::>(); - Ok(Response::new(ListGuestsReply { guests })) + let zones = self.zones.list().await.map_err(ApiError::from)?; + let zones = zones.into_values().collect::>(); + Ok(Response::new(ListZonesReply { zones })) } - async fn resolve_guest( + async fn resolve_zone( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let request = request.into_inner(); - let guests = self.guests.list().await.map_err(ApiError::from)?; - let guests = guests + let zones = self.zones.list().await.map_err(ApiError::from)?; + let zones = zones .into_values() .filter(|x| { let comparison_spec = x.spec.as_ref().cloned().unwrap_or_default(); (!request.name.is_empty() && comparison_spec.name == request.name) || x.id == request.name }) - .collect::>(); - Ok(Response::new(ResolveGuestReply { - guest: guests.first().cloned(), + .collect::>(); + Ok(Response::new(ResolveZoneReply { + zone: zones.first().cloned(), })) } - async fn console_data( + async fn attach_zone_console( &self, - request: Request>, - ) -> Result, Status> { + request: Request>, + ) -> Result, Status> { let mut input = request.into_inner(); let Some(request) = input.next().await else { return Err(ApiError { @@ -351,7 +351,7 @@ impl ControlService for DaemonControlService { .into()); }; let request = request?; - let uuid = Uuid::from_str(&request.guest_id).map_err(|error| ApiError { + let uuid = Uuid::from_str(&request.zone_id).map_err(|error| ApiError { message: error.to_string(), })?; let (sender, mut receiver) = channel(100); @@ -364,7 +364,7 @@ impl ControlService for DaemonControlService { })?; let output = try_stream! { - yield ConsoleDataReply { data: console.initial.clone(), }; + yield ZoneConsoleReply { data: console.initial.clone(), }; loop { let what = select! { x = receiver.recv() => ConsoleDataSelect::Read(x), @@ -373,7 +373,7 @@ impl ControlService for DaemonControlService { match what { ConsoleDataSelect::Read(Some(data)) => { - yield ConsoleDataReply { data, }; + yield ZoneConsoleReply { data, }; }, ConsoleDataSelect::Read(None) => { @@ -396,15 +396,17 @@ impl ControlService for DaemonControlService { } }; - Ok(Response::new(Box::pin(output) as Self::ConsoleDataStream)) + Ok(Response::new( + Box::pin(output) as Self::AttachZoneConsoleStream + )) } - async fn read_guest_metrics( + async fn read_zone_metrics( &self, - request: Request, - ) -> Result, Status> { + request: Request, + ) -> Result, Status> { let request = request.into_inner(); - let uuid = Uuid::from_str(&request.guest_id).map_err(|error| ApiError { + let uuid = Uuid::from_str(&request.zone_id).map_err(|error| ApiError { message: error.to_string(), })?; let client = self.idm.client(uuid).await.map_err(|error| ApiError { @@ -420,7 +422,7 @@ impl ControlService for DaemonControlService { message: error.to_string(), })?; - let mut reply = ReadGuestMetricsReply::default(); + let mut reply = ReadZoneMetricsReply::default(); if let Some(IdmResponseType::Metrics(metrics)) = response.response { reply.root = metrics.root.map(idm_metric_to_api); } diff --git a/crates/daemon/src/db.rs b/crates/daemon/src/db.rs index 120ee20..df2c78d 100644 --- a/crates/daemon/src/db.rs +++ b/crates/daemon/src/db.rs @@ -1,66 +1,66 @@ use std::{collections::HashMap, path::Path, sync::Arc}; use anyhow::Result; -use krata::v1::common::Guest; +use krata::v1::common::Zone; use log::error; use prost::Message; use redb::{Database, ReadableTable, TableDefinition}; use uuid::Uuid; -const GUESTS: TableDefinition = TableDefinition::new("guests"); +const ZONES: TableDefinition = TableDefinition::new("zones"); #[derive(Clone)] -pub struct GuestStore { +pub struct ZoneStore { database: Arc, } -impl GuestStore { +impl ZoneStore { pub fn open(path: &Path) -> Result { let database = Database::create(path)?; let write = database.begin_write()?; - let _ = write.open_table(GUESTS); + let _ = write.open_table(ZONES); write.commit()?; - Ok(GuestStore { + Ok(ZoneStore { database: Arc::new(database), }) } - pub async fn read(&self, id: Uuid) -> Result> { + pub async fn read(&self, id: Uuid) -> Result> { let read = self.database.begin_read()?; - let table = read.open_table(GUESTS)?; + let table = read.open_table(ZONES)?; let Some(entry) = table.get(id.to_u128_le())? else { return Ok(None); }; let bytes = entry.value(); - Ok(Some(Guest::decode(bytes)?)) + Ok(Some(Zone::decode(bytes)?)) } - pub async fn list(&self) -> Result> { - let mut guests: HashMap = HashMap::new(); + pub async fn list(&self) -> Result> { + let mut zones: HashMap = HashMap::new(); let read = self.database.begin_read()?; - let table = read.open_table(GUESTS)?; + let table = read.open_table(ZONES)?; for result in table.iter()? { let (key, value) = result?; let uuid = Uuid::from_u128_le(key.value()); - let state = match Guest::decode(value.value()) { + let state = match Zone::decode(value.value()) { Ok(state) => state, Err(error) => { error!( - "found invalid guest state in database for uuid {}: {}", + "found invalid zone state in database for uuid {}: {}", uuid, error ); continue; } }; - guests.insert(uuid, state); + zones.insert(uuid, state); } - Ok(guests) + Ok(zones) } - pub async fn update(&self, id: Uuid, entry: Guest) -> Result<()> { + pub async fn update(&self, id: Uuid, entry: Zone) -> Result<()> { let write = self.database.begin_write()?; { - let mut table = write.open_table(GUESTS)?; + let mut table = write.open_table(ZONES)?; let bytes = entry.encode_to_vec(); table.insert(id.to_u128_le(), bytes.as_slice())?; } @@ -71,7 +71,7 @@ impl GuestStore { pub async fn remove(&self, id: Uuid) -> Result<()> { let write = self.database.begin_write()?; { - let mut table = write.open_table(GUESTS)?; + let mut table = write.open_table(ZONES)?; table.remove(id.to_u128_le())?; } write.commit()?; diff --git a/crates/daemon/src/devices.rs b/crates/daemon/src/devices.rs index fe63073..2d4cc43 100644 --- a/crates/daemon/src/devices.rs +++ b/crates/daemon/src/devices.rs @@ -31,7 +31,7 @@ impl DaemonDeviceManager { let mut devices = self.devices.write().await; let Some(state) = devices.get_mut(device) else { return Err(anyhow!( - "unable to claim unknown device '{}' for guest {}", + "unable to claim unknown device '{}' for zone {}", device, uuid )); @@ -39,7 +39,7 @@ impl DaemonDeviceManager { if let Some(owner) = state.owner { return Err(anyhow!( - "unable to claim device '{}' for guest {}: already claimed by {}", + "unable to claim device '{}' for zone {}: already claimed by {}", device, uuid, owner @@ -92,7 +92,7 @@ impl DaemonDeviceManager { for (name, uuid) in &claims { if !devices.contains_key(name) { - warn!("unknown device '{}' assigned to guest {}", name, uuid); + warn!("unknown device '{}' assigned to zone {}", name, uuid); } } diff --git a/crates/daemon/src/event.rs b/crates/daemon/src/event.rs index f637314..f92c215 100644 --- a/crates/daemon/src/event.rs +++ b/crates/daemon/src/event.rs @@ -4,10 +4,12 @@ use std::{ time::Duration, }; +use crate::{db::ZoneStore, idm::DaemonIdmHandle}; use anyhow::Result; +use krata::v1::common::ZoneExitInfo; use krata::{ idm::{internal::event::Event as EventType, internal::Event}, - v1::common::{GuestExitInfo, GuestState, GuestStatus}, + v1::common::{ZoneState, ZoneStatus}, }; use log::{error, warn}; use tokio::{ @@ -21,8 +23,6 @@ use tokio::{ }; use uuid::Uuid; -use crate::{db::GuestStore, idm::DaemonIdmHandle}; - pub type DaemonEvent = krata::v1::control::watch_events_reply::Event; const EVENT_CHANNEL_QUEUE_LEN: usize = 1000; @@ -45,8 +45,8 @@ impl DaemonEventContext { } pub struct DaemonEventGenerator { - guests: GuestStore, - guest_reconciler_notify: Sender, + zones: ZoneStore, + zone_reconciler_notify: Sender, feed: broadcast::Receiver, idm: DaemonIdmHandle, idms: HashMap)>, @@ -57,15 +57,15 @@ pub struct DaemonEventGenerator { impl DaemonEventGenerator { pub async fn new( - guests: GuestStore, - guest_reconciler_notify: Sender, + zones: ZoneStore, + zone_reconciler_notify: Sender, idm: DaemonIdmHandle, ) -> Result<(DaemonEventContext, DaemonEventGenerator)> { let (sender, _) = broadcast::channel(EVENT_CHANNEL_QUEUE_LEN); let (idm_sender, idm_receiver) = channel(IDM_EVENT_CHANNEL_QUEUE_LEN); let generator = DaemonEventGenerator { - guests, - guest_reconciler_notify, + zones, + zone_reconciler_notify, feed: sender.subscribe(), idm, idms: HashMap::new(), @@ -78,20 +78,20 @@ impl DaemonEventGenerator { } async fn handle_feed_event(&mut self, event: &DaemonEvent) -> Result<()> { - let DaemonEvent::GuestChanged(changed) = event; - let Some(ref guest) = changed.guest else { + let DaemonEvent::ZoneChanged(changed) = event; + let Some(ref zone) = changed.zone else { return Ok(()); }; - let Some(ref state) = guest.state else { + let Some(ref state) = zone.state else { return Ok(()); }; let status = state.status(); - let id = Uuid::from_str(&guest.id)?; + let id = Uuid::from_str(&zone.id)?; let domid = state.domid; match status { - GuestStatus::Started => { + ZoneStatus::Started => { if let Entry::Vacant(e) = self.idms.entry(domid) { let client = self.idm.client_by_domid(domid).await?; let mut receiver = client.subscribe().await?; @@ -111,7 +111,7 @@ impl DaemonEventGenerator { } } - GuestStatus::Destroyed => { + ZoneStatus::Destroyed => { if let Some((_, handle)) = self.idms.remove(&domid) { handle.abort(); } @@ -130,18 +130,18 @@ impl DaemonEventGenerator { } async fn handle_exit_code(&mut self, id: Uuid, code: i32) -> Result<()> { - if let Some(mut guest) = self.guests.read(id).await? { - guest.state = Some(GuestState { - status: GuestStatus::Exited.into(), - network: guest.state.clone().unwrap_or_default().network, - exit_info: Some(GuestExitInfo { code }), + if let Some(mut zone) = self.zones.read(id).await? { + zone.state = Some(ZoneState { + status: ZoneStatus::Exited.into(), + network: zone.state.clone().unwrap_or_default().network, + exit_info: Some(ZoneExitInfo { code }), error_info: None, - host: guest.state.clone().map(|x| x.host).unwrap_or_default(), - domid: guest.state.clone().map(|x| x.domid).unwrap_or(u32::MAX), + host: zone.state.clone().map(|x| x.host).unwrap_or_default(), + domid: zone.state.clone().map(|x| x.domid).unwrap_or(u32::MAX), }); - self.guests.update(id, guest).await?; - self.guest_reconciler_notify.send(id).await?; + self.zones.update(id, zone).await?; + self.zone_reconciler_notify.send(id).await?; } Ok(()) } diff --git a/crates/daemon/src/idm.rs b/crates/daemon/src/idm.rs index 1aff9a2..6ff1607 100644 --- a/crates/daemon/src/idm.rs +++ b/crates/daemon/src/idm.rs @@ -24,14 +24,14 @@ use tokio::{ }; use uuid::Uuid; -use crate::glt::GuestLookupTable; +use crate::zlt::ZoneLookupTable; type BackendFeedMap = Arc>>>; type ClientMap = Arc>>; #[derive(Clone)] pub struct DaemonIdmHandle { - glt: GuestLookupTable, + glt: ZoneLookupTable, clients: ClientMap, feeds: BackendFeedMap, tx_sender: Sender<(u32, IdmTransportPacket)>, @@ -72,7 +72,7 @@ pub struct DaemonIdmSnoopPacket { } pub struct DaemonIdm { - glt: GuestLookupTable, + glt: ZoneLookupTable, clients: ClientMap, feeds: BackendFeedMap, tx_sender: Sender<(u32, IdmTransportPacket)>, @@ -84,7 +84,7 @@ pub struct DaemonIdm { } impl DaemonIdm { - pub async fn new(glt: GuestLookupTable) -> Result { + pub async fn new(glt: ZoneLookupTable) -> Result { let (service, tx_raw_sender, rx_receiver) = ChannelService::new("krata-channel".to_string(), None).await?; let (tx_sender, tx_receiver) = channel(100); diff --git a/crates/daemon/src/lib.rs b/crates/daemon/src/lib.rs index d510779..6e75aea 100644 --- a/crates/daemon/src/lib.rs +++ b/crates/daemon/src/lib.rs @@ -4,16 +4,15 @@ use anyhow::{anyhow, Result}; use config::DaemonConfig; use console::{DaemonConsole, DaemonConsoleHandle}; use control::DaemonControlService; -use db::GuestStore; +use db::ZoneStore; use devices::DaemonDeviceManager; use event::{DaemonEventContext, DaemonEventGenerator}; -use glt::GuestLookupTable; use idm::{DaemonIdm, DaemonIdmHandle}; use krata::{dial::ControlDialAddress, v1::control::control_service_server::ControlServiceServer}; use krataoci::{packer::service::OciPackerService, registry::OciPlatform}; use kratart::Runtime; use log::info; -use reconcile::guest::GuestReconciler; +use reconcile::zone::ZoneReconciler; use tokio::{ fs, net::UnixListener, @@ -23,6 +22,7 @@ use tokio::{ use tokio_stream::wrappers::UnixListenerStream; use tonic::transport::{Identity, Server, ServerTlsConfig}; use uuid::Uuid; +use zlt::ZoneLookupTable; pub mod command; pub mod config; @@ -31,21 +31,21 @@ pub mod control; pub mod db; pub mod devices; pub mod event; -pub mod glt; pub mod idm; pub mod metrics; pub mod oci; pub mod reconcile; +pub mod zlt; pub struct Daemon { store: String, _config: Arc, - glt: GuestLookupTable, + glt: ZoneLookupTable, devices: DaemonDeviceManager, - guests: GuestStore, + zones: ZoneStore, events: DaemonEventContext, - guest_reconciler_task: JoinHandle<()>, - guest_reconciler_notify: Sender, + zone_reconciler_task: JoinHandle<()>, + zone_reconciler_notify: Sender, generator_task: JoinHandle<()>, idm: DaemonIdmHandle, console: DaemonConsoleHandle, @@ -53,7 +53,7 @@ pub struct Daemon { runtime: Runtime, } -const GUEST_RECONCILER_QUEUE_LEN: usize = 1000; +const ZONE_RECONCILER_QUEUE_LEN: usize = 1000; impl Daemon { pub async fn new(store: String) -> Result { @@ -89,40 +89,40 @@ impl Daemon { generated }; - let initrd_path = detect_guest_path(&store, "initrd")?; - let kernel_path = detect_guest_path(&store, "kernel")?; - let addons_path = detect_guest_path(&store, "addons.squashfs")?; + let initrd_path = detect_zone_path(&store, "initrd")?; + let kernel_path = detect_zone_path(&store, "kernel")?; + let addons_path = detect_zone_path(&store, "addons.squashfs")?; let seed = config.oci.seed.clone().map(PathBuf::from); let packer = OciPackerService::new(seed, &image_cache_dir, OciPlatform::current()).await?; let runtime = Runtime::new(host_uuid).await?; - let glt = GuestLookupTable::new(0, host_uuid); - let guests_db_path = format!("{}/guests.db", store); - let guests = GuestStore::open(&PathBuf::from(guests_db_path))?; - let (guest_reconciler_notify, guest_reconciler_receiver) = - channel::(GUEST_RECONCILER_QUEUE_LEN); + let glt = ZoneLookupTable::new(0, host_uuid); + let zones_db_path = format!("{}/zones.db", store); + let zones = ZoneStore::open(&PathBuf::from(zones_db_path))?; + let (zone_reconciler_notify, zone_reconciler_receiver) = + channel::(ZONE_RECONCILER_QUEUE_LEN); let idm = DaemonIdm::new(glt.clone()).await?; let idm = idm.launch().await?; let console = DaemonConsole::new(glt.clone()).await?; let console = console.launch().await?; let (events, generator) = - DaemonEventGenerator::new(guests.clone(), guest_reconciler_notify.clone(), idm.clone()) + DaemonEventGenerator::new(zones.clone(), zone_reconciler_notify.clone(), idm.clone()) .await?; let runtime_for_reconciler = runtime.dupe().await?; - let guest_reconciler = GuestReconciler::new( + let zone_reconciler = ZoneReconciler::new( devices.clone(), glt.clone(), - guests.clone(), + zones.clone(), events.clone(), runtime_for_reconciler, packer.clone(), - guest_reconciler_notify.clone(), + zone_reconciler_notify.clone(), kernel_path, initrd_path, addons_path, )?; - let guest_reconciler_task = guest_reconciler.launch(guest_reconciler_receiver).await?; + let zone_reconciler_task = zone_reconciler.launch(zone_reconciler_receiver).await?; let generator_task = generator.launch().await?; // TODO: Create a way of abstracting early init tasks in kratad. @@ -139,10 +139,10 @@ impl Daemon { _config: config, glt, devices, - guests, + zones, events, - guest_reconciler_task, - guest_reconciler_notify, + zone_reconciler_task, + zone_reconciler_notify, generator_task, idm, console, @@ -158,8 +158,8 @@ impl Daemon { self.events.clone(), self.console.clone(), self.idm.clone(), - self.guests.clone(), - self.guest_reconciler_notify.clone(), + self.zones.clone(), + self.zone_reconciler_notify.clone(), self.packer.clone(), self.runtime.clone(), ); @@ -214,20 +214,20 @@ impl Daemon { impl Drop for Daemon { fn drop(&mut self) { - self.guest_reconciler_task.abort(); + self.zone_reconciler_task.abort(); self.generator_task.abort(); } } -fn detect_guest_path(store: &str, name: &str) -> Result { - let mut path = PathBuf::from(format!("{}/guest/{}", store, name)); +fn detect_zone_path(store: &str, name: &str) -> Result { + let mut path = PathBuf::from(format!("{}/zone/{}", store, name)); if path.is_file() { return Ok(path); } - path = PathBuf::from(format!("/usr/share/krata/guest/{}", name)); + path = PathBuf::from(format!("/usr/share/krata/zone/{}", name)); if path.is_file() { return Ok(path); } - Err(anyhow!("unable to find required guest file: {}", name)) + Err(anyhow!("unable to find required zone file: {}", name)) } diff --git a/crates/daemon/src/metrics.rs b/crates/daemon/src/metrics.rs index abeae15..1390b54 100644 --- a/crates/daemon/src/metrics.rs +++ b/crates/daemon/src/metrics.rs @@ -1,20 +1,20 @@ use krata::{ idm::internal::{MetricFormat, MetricNode}, - v1::common::{GuestMetricFormat, GuestMetricNode}, + v1::common::{ZoneMetricFormat, ZoneMetricNode}, }; -fn idm_metric_format_to_api(format: MetricFormat) -> GuestMetricFormat { +fn idm_metric_format_to_api(format: MetricFormat) -> ZoneMetricFormat { match format { - MetricFormat::Unknown => GuestMetricFormat::Unknown, - MetricFormat::Bytes => GuestMetricFormat::Bytes, - MetricFormat::Integer => GuestMetricFormat::Integer, - MetricFormat::DurationSeconds => GuestMetricFormat::DurationSeconds, + MetricFormat::Unknown => ZoneMetricFormat::Unknown, + MetricFormat::Bytes => ZoneMetricFormat::Bytes, + MetricFormat::Integer => ZoneMetricFormat::Integer, + MetricFormat::DurationSeconds => ZoneMetricFormat::DurationSeconds, } } -pub fn idm_metric_to_api(node: MetricNode) -> GuestMetricNode { +pub fn idm_metric_to_api(node: MetricNode) -> ZoneMetricNode { let format = node.format(); - GuestMetricNode { + ZoneMetricNode { name: node.name, value: node.value, format: idm_metric_format_to_api(format).into(), diff --git a/crates/daemon/src/reconcile/mod.rs b/crates/daemon/src/reconcile/mod.rs index 051b1c0..3c29b2c 100644 --- a/crates/daemon/src/reconcile/mod.rs +++ b/crates/daemon/src/reconcile/mod.rs @@ -1 +1 @@ -pub mod guest; +pub mod zone; diff --git a/crates/daemon/src/reconcile/guest/mod.rs b/crates/daemon/src/reconcile/zone/mod.rs similarity index 51% rename from crates/daemon/src/reconcile/guest/mod.rs rename to crates/daemon/src/reconcile/zone/mod.rs index 1d403a4..1be6f46 100644 --- a/crates/daemon/src/reconcile/guest/mod.rs +++ b/crates/daemon/src/reconcile/zone/mod.rs @@ -7,11 +7,11 @@ use std::{ use anyhow::Result; use krata::v1::{ - common::{Guest, GuestErrorInfo, GuestExitInfo, GuestNetworkState, GuestState, GuestStatus}, - control::GuestChangedEvent, + common::{Zone, ZoneErrorInfo, ZoneExitInfo, ZoneNetworkState, ZoneState, ZoneStatus}, + control::ZoneChangedEvent, }; use krataoci::packer::service::OciPackerService; -use kratart::{GuestInfo, Runtime}; +use kratart::{Runtime, ZoneInfo}; use log::{error, info, trace, warn}; use tokio::{ select, @@ -25,69 +25,69 @@ use tokio::{ use uuid::Uuid; use crate::{ - db::GuestStore, + db::ZoneStore, devices::DaemonDeviceManager, event::{DaemonEvent, DaemonEventContext}, - glt::GuestLookupTable, + zlt::ZoneLookupTable, }; -use self::start::GuestStarter; +use self::start::ZoneStarter; mod start; const PARALLEL_LIMIT: u32 = 5; #[derive(Debug)] -enum GuestReconcilerResult { +enum ZoneReconcilerResult { Unchanged, Changed { rerun: bool }, } -struct GuestReconcilerEntry { +struct ZoneReconcilerEntry { task: JoinHandle<()>, sender: Sender<()>, } -impl Drop for GuestReconcilerEntry { +impl Drop for ZoneReconcilerEntry { fn drop(&mut self) { self.task.abort(); } } #[derive(Clone)] -pub struct GuestReconciler { +pub struct ZoneReconciler { devices: DaemonDeviceManager, - glt: GuestLookupTable, - guests: GuestStore, + zlt: ZoneLookupTable, + zones: ZoneStore, events: DaemonEventContext, runtime: Runtime, packer: OciPackerService, kernel_path: PathBuf, initrd_path: PathBuf, addons_path: PathBuf, - tasks: Arc>>, - guest_reconciler_notify: Sender, - reconcile_lock: Arc>, + tasks: Arc>>, + zone_reconciler_notify: Sender, + zone_reconcile_lock: Arc>, } -impl GuestReconciler { +impl ZoneReconciler { #[allow(clippy::too_many_arguments)] pub fn new( devices: DaemonDeviceManager, - glt: GuestLookupTable, - guests: GuestStore, + zlt: ZoneLookupTable, + zones: ZoneStore, events: DaemonEventContext, runtime: Runtime, packer: OciPackerService, - guest_reconciler_notify: Sender, + zone_reconciler_notify: Sender, kernel_path: PathBuf, initrd_path: PathBuf, modules_path: PathBuf, ) -> Result { Ok(Self { devices, - glt, - guests, + zlt, + zones, events, runtime, packer, @@ -95,8 +95,8 @@ impl GuestReconciler { initrd_path, addons_path: modules_path, tasks: Arc::new(Mutex::new(HashMap::new())), - guest_reconciler_notify, - reconcile_lock: Arc::new(RwLock::with_max_readers((), PARALLEL_LIMIT)), + zone_reconciler_notify, + zone_reconcile_lock: Arc::new(RwLock::with_max_readers((), PARALLEL_LIMIT)), }) } @@ -115,13 +115,13 @@ impl GuestReconciler { Some(uuid) => { if let Err(error) = self.launch_task_if_needed(uuid).await { - error!("failed to start guest reconciler task {}: {}", uuid, error); + error!("failed to start zone reconciler task {}: {}", uuid, error); } let map = self.tasks.lock().await; if let Some(entry) = map.get(&uuid) { if let Err(error) = entry.sender.send(()).await { - error!("failed to notify guest reconciler task {}: {}", uuid, error); + error!("failed to notify zone reconciler task {}: {}", uuid, error); } } } @@ -138,52 +138,52 @@ impl GuestReconciler { } pub async fn reconcile_runtime(&self, initial: bool) -> Result<()> { - let _permit = self.reconcile_lock.write().await; + let _permit = self.zone_reconcile_lock.write().await; trace!("reconciling runtime"); - let runtime_guests = self.runtime.list().await?; - let stored_guests = self.guests.list().await?; + let runtime_zones = self.runtime.list().await?; + let stored_zones = self.zones.list().await?; - let non_existent_guests = runtime_guests + let non_existent_zones = runtime_zones .iter() - .filter(|x| !stored_guests.iter().any(|g| *g.0 == x.uuid)) + .filter(|x| !stored_zones.iter().any(|g| *g.0 == x.uuid)) .collect::>(); - for guest in non_existent_guests { - warn!("destroying unknown runtime guest {}", guest.uuid); - if let Err(error) = self.runtime.destroy(guest.uuid).await { + for zone in non_existent_zones { + warn!("destroying unknown runtime zone {}", zone.uuid); + if let Err(error) = self.runtime.destroy(zone.uuid).await { error!( - "failed to destroy unknown runtime guest {}: {}", - guest.uuid, error + "failed to destroy unknown runtime zone {}: {}", + zone.uuid, error ); } - self.guests.remove(guest.uuid).await?; + self.zones.remove(zone.uuid).await?; } let mut device_claims = HashMap::new(); - for (uuid, mut stored_guest) in stored_guests { - let previous_guest = stored_guest.clone(); - let runtime_guest = runtime_guests.iter().find(|x| x.uuid == uuid); - match runtime_guest { + for (uuid, mut stored_zone) in stored_zones { + let previous_zone = stored_zone.clone(); + let runtime_zone = runtime_zones.iter().find(|x| x.uuid == uuid); + match runtime_zone { None => { - let mut state = stored_guest.state.as_mut().cloned().unwrap_or_default(); - if state.status() == GuestStatus::Started { - state.status = GuestStatus::Starting.into(); + let mut state = stored_zone.state.as_mut().cloned().unwrap_or_default(); + if state.status() == ZoneStatus::Started { + state.status = ZoneStatus::Starting.into(); } - stored_guest.state = Some(state); + stored_zone.state = Some(state); } Some(runtime) => { - self.glt.associate(uuid, runtime.domid).await; - let mut state = stored_guest.state.as_mut().cloned().unwrap_or_default(); + self.zlt.associate(uuid, runtime.domid).await; + let mut state = stored_zone.state.as_mut().cloned().unwrap_or_default(); if let Some(code) = runtime.state.exit_code { - state.status = GuestStatus::Exited.into(); - state.exit_info = Some(GuestExitInfo { code }); + state.status = ZoneStatus::Exited.into(); + state.exit_info = Some(ZoneExitInfo { code }); } else { - state.status = GuestStatus::Started.into(); + state.status = ZoneStatus::Started.into(); } - for device in &stored_guest + for device in &stored_zone .spec .as_ref() .cloned() @@ -193,16 +193,16 @@ impl GuestReconciler { device_claims.insert(device.name.clone(), uuid); } - state.network = Some(guestinfo_to_networkstate(runtime)); - stored_guest.state = Some(state); + state.network = Some(zoneinfo_to_networkstate(runtime)); + stored_zone.state = Some(state); } } - let changed = stored_guest != previous_guest; + let changed = stored_zone != previous_zone; if changed || initial { - self.guests.update(uuid, stored_guest).await?; - let _ = self.guest_reconciler_notify.try_send(uuid); + self.zones.update(uuid, stored_zone).await?; + let _ = self.zone_reconciler_notify.try_send(uuid); } } @@ -212,59 +212,59 @@ impl GuestReconciler { } pub async fn reconcile(&self, uuid: Uuid) -> Result { - let _runtime_reconcile_permit = self.reconcile_lock.read().await; - let Some(mut guest) = self.guests.read(uuid).await? else { + let _runtime_reconcile_permit = self.zone_reconcile_lock.read().await; + let Some(mut zone) = self.zones.read(uuid).await? else { warn!( - "notified of reconcile for guest {} but it didn't exist", + "notified of reconcile for zone {} but it didn't exist", uuid ); return Ok(false); }; - info!("reconciling guest {}", uuid); + info!("reconciling zone {}", uuid); self.events - .send(DaemonEvent::GuestChanged(GuestChangedEvent { - guest: Some(guest.clone()), + .send(DaemonEvent::ZoneChanged(ZoneChangedEvent { + zone: Some(zone.clone()), }))?; - let start_status = guest.state.as_ref().map(|x| x.status()).unwrap_or_default(); + let start_status = zone.state.as_ref().map(|x| x.status()).unwrap_or_default(); let result = match start_status { - GuestStatus::Starting => self.start(uuid, &mut guest).await, - GuestStatus::Exited => self.exited(&mut guest).await, - GuestStatus::Destroying => self.destroy(uuid, &mut guest).await, - _ => Ok(GuestReconcilerResult::Unchanged), + ZoneStatus::Starting => self.start(uuid, &mut zone).await, + ZoneStatus::Exited => self.exited(&mut zone).await, + ZoneStatus::Destroying => self.destroy(uuid, &mut zone).await, + _ => Ok(ZoneReconcilerResult::Unchanged), }; let result = match result { Ok(result) => result, Err(error) => { - guest.state = Some(guest.state.as_mut().cloned().unwrap_or_default()); - guest.state.as_mut().unwrap().status = GuestStatus::Failed.into(); - guest.state.as_mut().unwrap().error_info = Some(GuestErrorInfo { + zone.state = Some(zone.state.as_mut().cloned().unwrap_or_default()); + zone.state.as_mut().unwrap().status = ZoneStatus::Failed.into(); + zone.state.as_mut().unwrap().error_info = Some(ZoneErrorInfo { message: error.to_string(), }); - warn!("failed to start guest {}: {}", guest.id, error); - GuestReconcilerResult::Changed { rerun: false } + warn!("failed to start zone {}: {}", zone.id, error); + ZoneReconcilerResult::Changed { rerun: false } } }; - info!("reconciled guest {}", uuid); + info!("reconciled zone {}", uuid); - let status = guest.state.as_ref().map(|x| x.status()).unwrap_or_default(); - let destroyed = status == GuestStatus::Destroyed; + let status = zone.state.as_ref().map(|x| x.status()).unwrap_or_default(); + let destroyed = status == ZoneStatus::Destroyed; - let rerun = if let GuestReconcilerResult::Changed { rerun } = result { - let event = DaemonEvent::GuestChanged(GuestChangedEvent { - guest: Some(guest.clone()), + let rerun = if let ZoneReconcilerResult::Changed { rerun } = result { + let event = DaemonEvent::ZoneChanged(ZoneChangedEvent { + zone: Some(zone.clone()), }); if destroyed { - self.guests.remove(uuid).await?; + self.zones.remove(uuid).await?; let mut map = self.tasks.lock().await; map.remove(&uuid); } else { - self.guests.update(uuid, guest.clone()).await?; + self.zones.update(uuid, zone.clone()).await?; } self.events.send(event)?; @@ -276,50 +276,50 @@ impl GuestReconciler { Ok(rerun) } - async fn start(&self, uuid: Uuid, guest: &mut Guest) -> Result { - let starter = GuestStarter { + async fn start(&self, uuid: Uuid, zone: &mut Zone) -> Result { + let starter = ZoneStarter { devices: &self.devices, kernel_path: &self.kernel_path, initrd_path: &self.initrd_path, addons_path: &self.addons_path, packer: &self.packer, - glt: &self.glt, + glt: &self.zlt, runtime: &self.runtime, }; - starter.start(uuid, guest).await + starter.start(uuid, zone).await } - async fn exited(&self, guest: &mut Guest) -> Result { - if let Some(ref mut state) = guest.state { - state.set_status(GuestStatus::Destroying); - Ok(GuestReconcilerResult::Changed { rerun: true }) + async fn exited(&self, zone: &mut Zone) -> Result { + if let Some(ref mut state) = zone.state { + state.set_status(ZoneStatus::Destroying); + Ok(ZoneReconcilerResult::Changed { rerun: true }) } else { - Ok(GuestReconcilerResult::Unchanged) + Ok(ZoneReconcilerResult::Unchanged) } } - async fn destroy(&self, uuid: Uuid, guest: &mut Guest) -> Result { + async fn destroy(&self, uuid: Uuid, zone: &mut Zone) -> Result { if let Err(error) = self.runtime.destroy(uuid).await { - trace!("failed to destroy runtime guest {}: {}", uuid, error); + trace!("failed to destroy runtime zone {}: {}", uuid, error); } - let domid = guest.state.as_ref().map(|x| x.domid); + let domid = zone.state.as_ref().map(|x| x.domid); if let Some(domid) = domid { - self.glt.remove(uuid, domid).await; + self.zlt.remove(uuid, domid).await; } - info!("destroyed guest {}", uuid); - guest.state = Some(GuestState { - status: GuestStatus::Destroyed.into(), + info!("destroyed zone {}", uuid); + zone.state = Some(ZoneState { + status: ZoneStatus::Destroyed.into(), network: None, exit_info: None, error_info: None, - host: self.glt.host_uuid().to_string(), + host: self.zlt.host_uuid().to_string(), domid: domid.unwrap_or(u32::MAX), }); self.devices.release_all(uuid).await?; - Ok(GuestReconcilerResult::Changed { rerun: false }) + Ok(ZoneReconcilerResult::Changed { rerun: false }) } async fn launch_task_if_needed(&self, uuid: Uuid) -> Result<()> { @@ -333,7 +333,7 @@ impl GuestReconciler { Ok(()) } - async fn launch_task(&self, uuid: Uuid) -> Result { + async fn launch_task(&self, uuid: Uuid) -> Result { let this = self.clone(); let (sender, mut receiver) = channel(10); let task = tokio::task::spawn(async move { @@ -346,7 +346,7 @@ impl GuestReconciler { let rerun = match this.reconcile(uuid).await { Ok(rerun) => rerun, Err(error) => { - error!("failed to reconcile guest {}: {}", uuid, error); + error!("failed to reconcile zone {}: {}", uuid, error); false } }; @@ -358,15 +358,15 @@ impl GuestReconciler { } } }); - Ok(GuestReconcilerEntry { task, sender }) + Ok(ZoneReconcilerEntry { task, sender }) } } -pub fn guestinfo_to_networkstate(info: &GuestInfo) -> GuestNetworkState { - GuestNetworkState { - guest_ipv4: info.guest_ipv4.map(|x| x.to_string()).unwrap_or_default(), - guest_ipv6: info.guest_ipv6.map(|x| x.to_string()).unwrap_or_default(), - guest_mac: info.guest_mac.as_ref().cloned().unwrap_or_default(), +pub fn zoneinfo_to_networkstate(info: &ZoneInfo) -> ZoneNetworkState { + ZoneNetworkState { + zone_ipv4: info.zone_ipv4.map(|x| x.to_string()).unwrap_or_default(), + zone_ipv6: info.zone_ipv6.map(|x| x.to_string()).unwrap_or_default(), + zone_mac: info.zone_mac.as_ref().cloned().unwrap_or_default(), gateway_ipv4: info.gateway_ipv4.map(|x| x.to_string()).unwrap_or_default(), gateway_ipv6: info.gateway_ipv6.map(|x| x.to_string()).unwrap_or_default(), gateway_mac: info.gateway_mac.as_ref().cloned().unwrap_or_default(), diff --git a/crates/daemon/src/reconcile/guest/start.rs b/crates/daemon/src/reconcile/zone/start.rs similarity index 87% rename from crates/daemon/src/reconcile/guest/start.rs rename to crates/daemon/src/reconcile/zone/start.rs index 82c0fc6..e1bdcf2 100644 --- a/crates/daemon/src/reconcile/guest/start.rs +++ b/crates/daemon/src/reconcile/zone/start.rs @@ -6,40 +6,40 @@ use std::sync::atomic::{AtomicBool, Ordering}; use anyhow::{anyhow, Result}; use futures::StreamExt; use krata::launchcfg::LaunchPackedFormat; -use krata::v1::common::GuestOciImageSpec; -use krata::v1::common::{guest_image_spec::Image, Guest, GuestState, GuestStatus, OciImageFormat}; +use krata::v1::common::ZoneOciImageSpec; +use krata::v1::common::{OciImageFormat, Zone, ZoneState, ZoneStatus}; use krataoci::packer::{service::OciPackerService, OciPackedFormat}; use kratart::launch::{PciBdf, PciDevice, PciRdmReservePolicy}; -use kratart::{launch::GuestLaunchRequest, Runtime}; +use kratart::{launch::ZoneLaunchRequest, Runtime}; use log::info; +use crate::config::DaemonPciDeviceRdmReservePolicy; +use crate::devices::DaemonDeviceManager; +use crate::{ + reconcile::zone::{zoneinfo_to_networkstate, ZoneReconcilerResult}, + zlt::ZoneLookupTable, +}; +use krata::v1::common::zone_image_spec::Image; use tokio::fs::{self, File}; use tokio::io::AsyncReadExt; use tokio_tar::Archive; use uuid::Uuid; -use crate::config::DaemonPciDeviceRdmReservePolicy; -use crate::devices::DaemonDeviceManager; -use crate::{ - glt::GuestLookupTable, - reconcile::guest::{guestinfo_to_networkstate, GuestReconcilerResult}, -}; - -pub struct GuestStarter<'a> { +pub struct ZoneStarter<'a> { pub devices: &'a DaemonDeviceManager, pub kernel_path: &'a Path, pub initrd_path: &'a Path, pub addons_path: &'a Path, pub packer: &'a OciPackerService, - pub glt: &'a GuestLookupTable, + pub glt: &'a ZoneLookupTable, pub runtime: &'a Runtime, } -impl GuestStarter<'_> { +impl ZoneStarter<'_> { pub async fn oci_spec_tar_read_file( &self, file: &Path, - oci: &GuestOciImageSpec, + oci: &ZoneOciImageSpec, ) -> Result> { if oci.format() != OciImageFormat::Tar { return Err(anyhow!( @@ -75,9 +75,9 @@ impl GuestStarter<'_> { )) } - pub async fn start(&self, uuid: Uuid, guest: &mut Guest) -> Result { - let Some(ref spec) = guest.spec else { - return Err(anyhow!("guest spec not specified")); + pub async fn start(&self, uuid: Uuid, zone: &mut Zone) -> Result { + let Some(ref spec) = zone.spec else { + return Err(anyhow!("zone spec not specified")); }; let Some(ref image) = spec.image else { @@ -100,7 +100,7 @@ impl GuestStarter<'_> { OciImageFormat::Squashfs => OciPackedFormat::Squashfs, OciImageFormat::Erofs => OciPackedFormat::Erofs, OciImageFormat::Tar => { - return Err(anyhow!("tar image format is not supported for guests")); + return Err(anyhow!("tar image format is not supported for zones")); } }, ) @@ -176,7 +176,7 @@ impl GuestStarter<'_> { let info = self .runtime - .launch(GuestLaunchRequest { + .launch(ZoneLaunchRequest { format: LaunchPackedFormat::Squashfs, uuid: Some(uuid), name: if spec.name.is_empty() { @@ -201,17 +201,17 @@ impl GuestStarter<'_> { }) .await?; self.glt.associate(uuid, info.domid).await; - info!("started guest {}", uuid); - guest.state = Some(GuestState { - status: GuestStatus::Started.into(), - network: Some(guestinfo_to_networkstate(&info)), + info!("started zone {}", uuid); + zone.state = Some(ZoneState { + status: ZoneStatus::Started.into(), + network: Some(zoneinfo_to_networkstate(&info)), exit_info: None, error_info: None, host: self.glt.host_uuid().to_string(), domid: info.domid, }); success.store(true, Ordering::Release); - Ok(GuestReconcilerResult::Changed { rerun: false }) + Ok(ZoneReconcilerResult::Changed { rerun: false }) } } diff --git a/crates/daemon/src/glt.rs b/crates/daemon/src/zlt.rs similarity index 83% rename from crates/daemon/src/glt.rs rename to crates/daemon/src/zlt.rs index e91a0cf..4832003 100644 --- a/crates/daemon/src/glt.rs +++ b/crates/daemon/src/zlt.rs @@ -3,18 +3,18 @@ use std::{collections::HashMap, sync::Arc}; use tokio::sync::RwLock; use uuid::Uuid; -struct GuestLookupTableState { +struct ZoneLookupTableState { domid_to_uuid: HashMap, uuid_to_domid: HashMap, } -impl GuestLookupTableState { +impl ZoneLookupTableState { pub fn new(host_uuid: Uuid) -> Self { let mut domid_to_uuid = HashMap::new(); let mut uuid_to_domid = HashMap::new(); domid_to_uuid.insert(0, host_uuid); uuid_to_domid.insert(host_uuid, 0); - GuestLookupTableState { + ZoneLookupTableState { domid_to_uuid, uuid_to_domid, } @@ -22,18 +22,18 @@ impl GuestLookupTableState { } #[derive(Clone)] -pub struct GuestLookupTable { +pub struct ZoneLookupTable { host_domid: u32, host_uuid: Uuid, - state: Arc>, + state: Arc>, } -impl GuestLookupTable { +impl ZoneLookupTable { pub fn new(host_domid: u32, host_uuid: Uuid) -> Self { - GuestLookupTable { + ZoneLookupTable { host_domid, host_uuid, - state: Arc::new(RwLock::new(GuestLookupTableState::new(host_uuid))), + state: Arc::new(RwLock::new(ZoneLookupTableState::new(host_uuid))), } } diff --git a/crates/guest/bin/init.rs b/crates/guest/bin/init.rs deleted file mode 100644 index 62678e2..0000000 --- a/crates/guest/bin/init.rs +++ /dev/null @@ -1,30 +0,0 @@ -use anyhow::{anyhow, Result}; -use env_logger::Env; -use krataguest::{death, init::GuestInit}; -use log::error; -use std::env; - -#[tokio::main] -async fn main() -> Result<()> { - env::set_var("RUST_BACKTRACE", "1"); - env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); - if env::var("KRATA_UNSAFE_ALWAYS_ALLOW_INIT").unwrap_or("0".to_string()) != "1" { - let pid = std::process::id(); - if pid > 3 { - return Err(anyhow!( - "not running because the pid of {} indicates this is probably not \ - the right context for the init daemon. \ - run with KRATA_UNSAFE_ALWAYS_ALLOW_INIT=1 to bypass this check", - pid - )); - } - } - let mut guest = GuestInit::new(); - if let Err(error) = guest.init().await { - error!("failed to initialize guest: {}", error); - death(127).await?; - return Ok(()); - } - death(1).await?; - Ok(()) -} diff --git a/crates/krata/proto/krata/v1/common.proto b/crates/krata/proto/krata/v1/common.proto index 75f8b1e..a8b18d1 100644 --- a/crates/krata/proto/krata/v1/common.proto +++ b/crates/krata/proto/krata/v1/common.proto @@ -8,29 +8,29 @@ option java_outer_classname = "CommonProto"; import "google/protobuf/struct.proto"; -message Guest { +message Zone { string id = 1; - GuestSpec spec = 2; - GuestState state = 3; + ZoneSpec spec = 2; + ZoneState state = 3; } -message GuestSpec { +message ZoneSpec { string name = 1; - GuestImageSpec image = 2; + ZoneImageSpec image = 2; // If not specified, defaults to the daemon default kernel. - GuestImageSpec kernel = 3; + ZoneImageSpec kernel = 3; // If not specified, defaults to the daemon default initrd. - GuestImageSpec initrd = 4; + ZoneImageSpec initrd = 4; uint32 vcpus = 5; uint64 mem = 6; - GuestTaskSpec task = 7; - repeated GuestSpecAnnotation annotations = 8; - repeated GuestSpecDevice devices = 9; + ZoneTaskSpec task = 7; + repeated ZoneSpecAnnotation annotations = 8; + repeated ZoneSpecDevice devices = 9; } -message GuestImageSpec { +message ZoneImageSpec { oneof image { - GuestOciImageSpec oci = 1; + ZoneOciImageSpec oci = 1; } } @@ -42,77 +42,77 @@ enum OciImageFormat { OCI_IMAGE_FORMAT_TAR = 3; } -message GuestOciImageSpec { +message ZoneOciImageSpec { string digest = 1; OciImageFormat format = 2; } -message GuestTaskSpec { - repeated GuestTaskSpecEnvVar environment = 1; +message ZoneTaskSpec { + repeated ZoneTaskSpecEnvVar environment = 1; repeated string command = 2; string working_directory = 3; } -message GuestTaskSpecEnvVar { +message ZoneTaskSpecEnvVar { string key = 1; string value = 2; } -message GuestSpecAnnotation { +message ZoneSpecAnnotation { string key = 1; string value = 2; } -message GuestSpecDevice { +message ZoneSpecDevice { string name = 1; } -message GuestState { - GuestStatus status = 1; - GuestNetworkState network = 2; - GuestExitInfo exit_info = 3; - GuestErrorInfo error_info = 4; +message ZoneState { + ZoneStatus status = 1; + ZoneNetworkState network = 2; + ZoneExitInfo exit_info = 3; + ZoneErrorInfo error_info = 4; string host = 5; uint32 domid = 6; } -enum GuestStatus { - GUEST_STATUS_UNKNOWN = 0; - GUEST_STATUS_STARTING = 1; - GUEST_STATUS_STARTED = 2; - GUEST_STATUS_EXITED = 3; - GUEST_STATUS_DESTROYING = 4; - GUEST_STATUS_DESTROYED = 5; - GUEST_STATUS_FAILED = 6; +enum ZoneStatus { + ZONE_STATUS_UNKNOWN = 0; + ZONE_STATUS_STARTING = 1; + ZONE_STATUS_STARTED = 2; + ZONE_STATUS_EXITED = 3; + ZONE_STATUS_DESTROYING = 4; + ZONE_STATUS_DESTROYED = 5; + ZONE_STATUS_FAILED = 6; } -message GuestNetworkState { - string guest_ipv4 = 1; - string guest_ipv6 = 2; - string guest_mac = 3; +message ZoneNetworkState { + string zone_ipv4 = 1; + string zone_ipv6 = 2; + string zone_mac = 3; string gateway_ipv4 = 4; string gateway_ipv6 = 5; string gateway_mac = 6; } -message GuestExitInfo { +message ZoneExitInfo { int32 code = 1; } -message GuestErrorInfo { +message ZoneErrorInfo { string message = 1; } -message GuestMetricNode { +message ZoneMetricNode { string name = 1; google.protobuf.Value value = 2; - GuestMetricFormat format = 3; - repeated GuestMetricNode children = 4; + ZoneMetricFormat format = 3; + repeated ZoneMetricNode children = 4; } -enum GuestMetricFormat { - GUEST_METRIC_FORMAT_UNKNOWN = 0; - GUEST_METRIC_FORMAT_BYTES = 1; - GUEST_METRIC_FORMAT_INTEGER = 2; - GUEST_METRIC_FORMAT_DURATION_SECONDS = 3; +enum ZoneMetricFormat { + ZONE_METRIC_FORMAT_UNKNOWN = 0; + ZONE_METRIC_FORMAT_BYTES = 1; + ZONE_METRIC_FORMAT_INTEGER = 2; + ZONE_METRIC_FORMAT_DURATION_SECONDS = 3; } diff --git a/crates/krata/proto/krata/v1/control.proto b/crates/krata/proto/krata/v1/control.proto index 2456258..4362777 100644 --- a/crates/krata/proto/krata/v1/control.proto +++ b/crates/krata/proto/krata/v1/control.proto @@ -12,17 +12,17 @@ import "krata/v1/common.proto"; service ControlService { rpc IdentifyHost(IdentifyHostRequest) returns (IdentifyHostReply); - rpc CreateGuest(CreateGuestRequest) returns (CreateGuestReply); - rpc DestroyGuest(DestroyGuestRequest) returns (DestroyGuestReply); - rpc ResolveGuest(ResolveGuestRequest) returns (ResolveGuestReply); - rpc ListGuests(ListGuestsRequest) returns (ListGuestsReply); + rpc CreateZone(CreateZoneRequest) returns (CreateZoneReply); + rpc DestroyZone(DestroyZoneRequest) returns (DestroyZoneReply); + rpc ResolveZone(ResolveZoneRequest) returns (ResolveZoneReply); + rpc ListZones(ListZonesRequest) returns (ListZonesReply); rpc ListDevices(ListDevicesRequest) returns (ListDevicesReply); - rpc ExecGuest(stream ExecGuestRequest) returns (stream ExecGuestReply); + rpc ExecZone(stream ExecZoneRequest) returns (stream ExecZoneReply); + + rpc AttachZoneConsole(stream ZoneConsoleRequest) returns (stream ZoneConsoleReply); + rpc ReadZoneMetrics(ReadZoneMetricsRequest) returns (ReadZoneMetricsReply); - rpc ConsoleData(stream ConsoleDataRequest) returns (stream ConsoleDataReply); - rpc ReadGuestMetrics(ReadGuestMetricsRequest) returns (ReadGuestMetricsReply); - rpc SnoopIdm(SnoopIdmRequest) returns (stream SnoopIdmReply); rpc WatchEvents(WatchEventsRequest) returns (stream WatchEventsReply); @@ -40,41 +40,41 @@ message IdentifyHostReply { string krata_version = 3; } -message CreateGuestRequest { - krata.v1.common.GuestSpec spec = 1; +message CreateZoneRequest { + krata.v1.common.ZoneSpec spec = 1; } -message CreateGuestReply { - string guest_id = 1; +message CreateZoneReply { + string Zone_id = 1; } -message DestroyGuestRequest { - string guest_id = 1; +message DestroyZoneRequest { + string Zone_id = 1; } -message DestroyGuestReply {} +message DestroyZoneReply {} -message ResolveGuestRequest { +message ResolveZoneRequest { string name = 1; } -message ResolveGuestReply { - krata.v1.common.Guest guest = 1; +message ResolveZoneReply { + krata.v1.common.Zone Zone = 1; } -message ListGuestsRequest {} +message ListZonesRequest {} -message ListGuestsReply { - repeated krata.v1.common.Guest guests = 1; +message ListZonesReply { + repeated krata.v1.common.Zone Zones = 1; } -message ExecGuestRequest { - string guest_id = 1; - krata.v1.common.GuestTaskSpec task = 2; +message ExecZoneRequest { + string Zone_id = 1; + krata.v1.common.ZoneTaskSpec task = 2; bytes data = 3; } -message ExecGuestReply { +message ExecZoneReply { bool exited = 1; string error = 2; int32 exit_code = 3; @@ -82,12 +82,12 @@ message ExecGuestReply { bytes stderr = 5; } -message ConsoleDataRequest { - string guest_id = 1; +message ZoneConsoleRequest { + string Zone_id = 1; bytes data = 2; } -message ConsoleDataReply { +message ZoneConsoleReply { bytes data = 1; } @@ -95,20 +95,20 @@ message WatchEventsRequest {} message WatchEventsReply { oneof event { - GuestChangedEvent guest_changed = 1; + ZoneChangedEvent Zone_changed = 1; } } -message GuestChangedEvent { - krata.v1.common.Guest guest = 1; +message ZoneChangedEvent { + krata.v1.common.Zone Zone = 1; } -message ReadGuestMetricsRequest { - string guest_id = 1; +message ReadZoneMetricsRequest { + string Zone_id = 1; } -message ReadGuestMetricsReply { - krata.v1.common.GuestMetricNode root = 1; +message ReadZoneMetricsReply { + krata.v1.common.ZoneMetricNode root = 1; } message SnoopIdmRequest {} diff --git a/crates/network/src/autonet.rs b/crates/network/src/autonet.rs index 9b27d62..6a5477a 100644 --- a/crates/network/src/autonet.rs +++ b/crates/network/src/autonet.rs @@ -2,10 +2,10 @@ use anyhow::Result; use krata::{ events::EventStream, v1::{ - common::Guest, + common::Zone, control::{ control_service_client::ControlServiceClient, watch_events_reply::Event, - ListGuestsRequest, + ListZonesRequest, }, }, }; @@ -33,7 +33,7 @@ pub struct NetworkSide { pub struct NetworkMetadata { pub domid: u32, pub uuid: Uuid, - pub guest: NetworkSide, + pub zone: NetworkSide, pub gateway: NetworkSide, } @@ -60,23 +60,23 @@ impl AutoNetworkWatcher { } pub async fn read(&mut self) -> Result> { - let mut all_guests: HashMap = HashMap::new(); - for guest in self + let mut all_zones: HashMap = HashMap::new(); + for zone in self .control - .list_guests(ListGuestsRequest {}) + .list_zones(ListZonesRequest {}) .await? .into_inner() - .guests + .zones { - let Ok(uuid) = Uuid::from_str(&guest.id) else { + let Ok(uuid) = Uuid::from_str(&zone.id) else { continue; }; - all_guests.insert(uuid, guest); + all_zones.insert(uuid, zone); } let mut networks: Vec = Vec::new(); - for (uuid, guest) in &all_guests { - let Some(ref state) = guest.state else { + for (uuid, zone) in &all_zones { + let Some(ref state) = zone.state else { continue; }; @@ -88,15 +88,15 @@ impl AutoNetworkWatcher { continue; }; - let Ok(guest_ipv4_cidr) = Ipv4Cidr::from_str(&network.guest_ipv4) else { + let Ok(zone_ipv4_cidr) = Ipv4Cidr::from_str(&network.zone_ipv4) else { continue; }; - let Ok(guest_ipv6_cidr) = Ipv6Cidr::from_str(&network.guest_ipv6) else { + let Ok(zone_ipv6_cidr) = Ipv6Cidr::from_str(&network.zone_ipv6) else { continue; }; - let Ok(guest_mac) = EthernetAddress::from_str(&network.guest_mac) else { + let Ok(zone_mac) = EthernetAddress::from_str(&network.zone_mac) else { continue; }; @@ -115,10 +115,10 @@ impl AutoNetworkWatcher { networks.push(NetworkMetadata { domid: state.domid, uuid: *uuid, - guest: NetworkSide { - ipv4: guest_ipv4_cidr, - ipv6: guest_ipv6_cidr, - mac: guest_mac, + zone: NetworkSide { + ipv4: zone_ipv4_cidr, + ipv6: zone_ipv6_cidr, + mac: zone_mac, }, gateway: NetworkSide { ipv4: gateway_ipv4_cidr, @@ -175,7 +175,7 @@ impl AutoNetworkWatcher { loop { select! { x = receiver.recv() => match x { - Ok(Event::GuestChanged(_)) => { + Ok(Event::ZoneChanged(_)) => { break; }, diff --git a/crates/network/src/backend.rs b/crates/network/src/backend.rs index 2953099..3475e20 100644 --- a/crates/network/src/backend.rs +++ b/crates/network/src/backend.rs @@ -54,11 +54,11 @@ impl NetworkStack<'_> { match what { NetworkStackSelect::Receive(Some(packet)) => { if let Err(error) = self.bridge.to_bridge_sender.try_send(packet.clone()) { - trace!("failed to send guest packet to bridge: {}", error); + trace!("failed to send zone packet to bridge: {}", error); } if let Err(error) = self.nat.receive_sender.try_send(packet.clone()) { - trace!("failed to send guest packet to nat: {}", error); + trace!("failed to send zone packet to nat: {}", error); } self.udev.rx = Some(packet); @@ -137,7 +137,7 @@ impl NetworkBackend { .expect("failed to set ip addresses"); }); let sockets = SocketSet::new(vec![]); - let handle = self.bridge.join(self.metadata.guest.mac).await?; + let handle = self.bridge.join(self.metadata.zone.mac).await?; let kdev = AsyncRawSocketChannel::new(mtu, kdev)?; Ok(NetworkStack { tx: tx_receiver, @@ -153,12 +153,12 @@ impl NetworkBackend { pub async fn launch(self) -> Result> { Ok(tokio::task::spawn(async move { info!( - "launched network backend for krata guest {}", + "launched network backend for krata zone {}", self.metadata.uuid ); if let Err(error) = self.run().await { warn!( - "network backend for krata guest {} failed: {}", + "network backend for krata zone {} failed: {}", self.metadata.uuid, error ); } @@ -169,7 +169,7 @@ impl NetworkBackend { impl Drop for NetworkBackend { fn drop(&mut self) { info!( - "destroyed network backend for krata guest {}", + "destroyed network backend for krata zone {}", self.metadata.uuid ); } diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index 027da73..b43deff 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -7,7 +7,7 @@ use hbridge::HostBridge; use krata::{ client::ControlClientProvider, dial::ControlDialAddress, - v1::{common::Guest, control::control_service_client::ControlServiceClient}, + v1::{common::Zone, control::control_service_client::ControlServiceClient}, }; use log::warn; use tokio::{task::JoinHandle, time::sleep}; @@ -33,7 +33,7 @@ pub const EXTRA_MTU: usize = 20; pub struct NetworkService { pub control: ControlServiceClient, - pub guests: HashMap, + pub zones: HashMap, pub backends: HashMap>, pub bridge: VirtualBridge, pub hbridge: HostBridge, @@ -47,7 +47,7 @@ impl NetworkService { HostBridge::new(HOST_BRIDGE_MTU + EXTRA_MTU, "krata0".to_string(), &bridge).await?; Ok(NetworkService { control, - guests: HashMap::new(), + zones: HashMap::new(), backends: HashMap::new(), bridge, hbridge, @@ -99,7 +99,7 @@ impl NetworkService { Err((metadata, error)) => { warn!( - "failed to launch network backend for krata guest {}: {}", + "failed to launch network backend for krata zone {}: {}", metadata.uuid, error ); failed.push(metadata.uuid); diff --git a/crates/runtime/Cargo.toml b/crates/runtime/Cargo.toml index 25a2c51..e6292a6 100644 --- a/crates/runtime/Cargo.toml +++ b/crates/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "krata-runtime" -description = "Runtime for running guests on the krata isolation engine" +description = "Runtime for managing zones on the krata isolation engine" license.workspace = true version.workspace = true homepage.workspace = true diff --git a/crates/runtime/src/ip.rs b/crates/runtime/src/ip.rs index 9fedd89..9ffccdb 100644 --- a/crates/runtime/src/ip.rs +++ b/crates/runtime/src/ip.rs @@ -99,23 +99,23 @@ impl IpVendor { continue; }; let assigned_ipv4 = store - .read_string(format!("{}/krata/network/guest/ipv4", dom_path)) + .read_string(format!("{}/krata/network/zone/ipv4", dom_path)) .await? .and_then(|x| Ipv4Network::from_str(&x).ok()); let assigned_ipv6 = store - .read_string(format!("{}/krata/network/guest/ipv6", dom_path)) + .read_string(format!("{}/krata/network/zone/ipv6", dom_path)) .await? .and_then(|x| Ipv6Network::from_str(&x).ok()); if let Some(existing_ipv4) = assigned_ipv4 { if let Some(previous) = state.ipv4.insert(existing_ipv4.ip(), uuid) { - error!("ipv4 conflict detected: guest {} owned {} but {} also claimed to own it, giving it to {}", previous, existing_ipv4.ip(), uuid, uuid); + error!("ipv4 conflict detected: zone {} owned {} but {} also claimed to own it, giving it to {}", previous, existing_ipv4.ip(), uuid, uuid); } } if let Some(existing_ipv6) = assigned_ipv6 { if let Some(previous) = state.ipv6.insert(existing_ipv6.ip(), uuid) { - error!("ipv6 conflict detected: guest {} owned {} but {} also claimed to own it, giving it to {}", previous, existing_ipv6.ip(), uuid, uuid); + error!("ipv6 conflict detected: zone {} owned {} but {} also claimed to own it, giving it to {}", previous, existing_ipv6.ip(), uuid, uuid); } } } @@ -251,13 +251,13 @@ impl IpVendor { intermediate.ipv6.insert(self.gateway_ipv6, self.host_uuid); for (ipv4, uuid) in &state.pending_ipv4 { if let Some(previous) = intermediate.ipv4.insert(*ipv4, *uuid) { - error!("ipv4 conflict detected: guest {} owned (pending) {} but {} also claimed to own it, giving it to {}", previous, ipv4, uuid, uuid); + error!("ipv4 conflict detected: zone {} owned (pending) {} but {} also claimed to own it, giving it to {}", previous, ipv4, uuid, uuid); } intermediate.pending_ipv4.insert(*ipv4, *uuid); } for (ipv6, uuid) in &state.pending_ipv6 { if let Some(previous) = intermediate.ipv6.insert(*ipv6, *uuid) { - error!("ipv6 conflict detected: guest {} owned (pending) {} but {} also claimed to own it, giving it to {}", previous, ipv6, uuid, uuid); + error!("ipv6 conflict detected: zone {} owned (pending) {} but {} also claimed to own it, giving it to {}", previous, ipv6, uuid, uuid); } intermediate.pending_ipv6.insert(*ipv6, *uuid); } @@ -271,16 +271,16 @@ impl IpVendor { domid: u32, ) -> Result> { let dom_path = format!("/local/domain/{}", domid); - let Some(guest_ipv4) = self + let Some(zone_ipv4) = self .store - .read_string(format!("{}/krata/network/guest/ipv4", dom_path)) + .read_string(format!("{}/krata/network/zone/ipv4", dom_path)) .await? else { return Ok(None); }; - let Some(guest_ipv6) = self + let Some(zone_ipv6) = self .store - .read_string(format!("{}/krata/network/guest/ipv6", dom_path)) + .read_string(format!("{}/krata/network/zone/ipv6", dom_path)) .await? else { return Ok(None); @@ -300,10 +300,10 @@ impl IpVendor { return Ok(None); }; - let Some(guest_ipv4) = Ipv4Network::from_str(&guest_ipv4).ok() else { + let Some(zone_ipv4) = Ipv4Network::from_str(&zone_ipv4).ok() else { return Ok(None); }; - let Some(guest_ipv6) = Ipv6Network::from_str(&guest_ipv6).ok() else { + let Some(zone_ipv6) = Ipv6Network::from_str(&zone_ipv6).ok() else { return Ok(None); }; let Some(gateway_ipv4) = Ipv4Network::from_str(&gateway_ipv4).ok() else { @@ -315,10 +315,10 @@ impl IpVendor { Ok(Some(IpAssignment { vendor: self.clone(), uuid, - ipv4: guest_ipv4.ip(), - ipv4_prefix: guest_ipv4.prefix(), - ipv6: guest_ipv6.ip(), - ipv6_prefix: guest_ipv6.prefix(), + ipv4: zone_ipv4.ip(), + ipv4_prefix: zone_ipv4.prefix(), + ipv6: zone_ipv6.ip(), + ipv6_prefix: zone_ipv6.prefix(), gateway_ipv4: gateway_ipv4.ip(), gateway_ipv6: gateway_ipv6.ip(), committed: true, diff --git a/crates/runtime/src/launch.rs b/crates/runtime/src/launch.rs index 307310e..d0e7845 100644 --- a/crates/runtime/src/launch.rs +++ b/crates/runtime/src/launch.rs @@ -20,13 +20,13 @@ use xenplatform::domain::BaseDomainConfig; use crate::cfgblk::ConfigBlock; use crate::RuntimeContext; -use super::{GuestInfo, GuestState}; +use super::{ZoneInfo, ZoneState}; pub use xenclient::{ pci::PciBdf, DomainPciDevice as PciDevice, DomainPciRdmReservePolicy as PciRdmReservePolicy, }; -pub struct GuestLaunchRequest { +pub struct ZoneLaunchRequest { pub format: LaunchPackedFormat, pub kernel: Vec, pub initrd: Vec, @@ -42,11 +42,11 @@ pub struct GuestLaunchRequest { pub addons_image: Option, } -pub struct GuestLauncher { +pub struct ZoneLauncher { pub launch_semaphore: Arc, } -impl GuestLauncher { +impl ZoneLauncher { pub fn new(launch_semaphore: Arc) -> Result { Ok(Self { launch_semaphore }) } @@ -54,16 +54,16 @@ impl GuestLauncher { pub async fn launch( &mut self, context: &RuntimeContext, - request: GuestLaunchRequest, - ) -> Result { + request: ZoneLaunchRequest, + ) -> Result { let uuid = request.uuid.unwrap_or_else(Uuid::new_v4); let xen_name = format!("krata-{uuid}"); let mut gateway_mac = MacAddr6::random(); gateway_mac.set_local(true); gateway_mac.set_multicast(false); - let mut container_mac = MacAddr6::random(); - container_mac.set_local(true); - container_mac.set_multicast(false); + let mut zone_mac = MacAddr6::random(); + zone_mac.set_local(true); + zone_mac.set_multicast(false); let _launch_permit = self.launch_semaphore.acquire().await?; let mut ip = context.ipvendor.assign(uuid).await?; @@ -145,7 +145,7 @@ impl GuestLauncher { } let cmdline = cmdline_options.join(" "); - let guest_mac_string = container_mac.to_string().replace('-', ":"); + let zone_mac_string = zone_mac.to_string().replace('-', ":"); let gateway_mac_string = gateway_mac.to_string().replace('-', ":"); let mut disks = vec![ @@ -191,16 +191,16 @@ impl GuestLauncher { ("krata/uuid".to_string(), uuid.to_string()), ("krata/loops".to_string(), loops.join(",")), ( - "krata/network/guest/ipv4".to_string(), + "krata/network/zone/ipv4".to_string(), format!("{}/{}", ip.ipv4, ip.ipv4_prefix), ), ( - "krata/network/guest/ipv6".to_string(), + "krata/network/zone/ipv6".to_string(), format!("{}/{}", ip.ipv6, ip.ipv6_prefix), ), ( - "krata/network/guest/mac".to_string(), - guest_mac_string.clone(), + "krata/network/zone/mac".to_string(), + zone_mac_string.clone(), ), ( "krata/network/gateway/ipv4".to_string(), @@ -240,7 +240,7 @@ impl GuestLauncher { initialized: false, }], vifs: vec![DomainNetworkInterface { - mac: guest_mac_string.clone(), + mac: zone_mac_string.clone(), mtu: 1500, bridge: None, script: None, @@ -248,20 +248,20 @@ impl GuestLauncher { pcis: request.pcis.clone(), filesystems: vec![], extra_keys, - extra_rw_paths: vec!["krata/guest".to_string()], + extra_rw_paths: vec!["krata/zone".to_string()], }; match context.xen.create(&config).await { Ok(created) => { ip.commit().await?; - Ok(GuestInfo { + Ok(ZoneInfo { name: request.name.as_ref().map(|x| x.to_string()), uuid, domid: created.domid, image: request.image.digest, loops: vec![], - guest_ipv4: Some(IpNetwork::new(IpAddr::V4(ip.ipv4), ip.ipv4_prefix)?), - guest_ipv6: Some(IpNetwork::new(IpAddr::V6(ip.ipv6), ip.ipv6_prefix)?), - guest_mac: Some(guest_mac_string.clone()), + zone_ipv4: Some(IpNetwork::new(IpAddr::V4(ip.ipv4), ip.ipv4_prefix)?), + zone_ipv6: Some(IpNetwork::new(IpAddr::V6(ip.ipv6), ip.ipv6_prefix)?), + zone_mac: Some(zone_mac_string.clone()), gateway_ipv4: Some(IpNetwork::new( IpAddr::V4(ip.gateway_ipv4), ip.ipv4_prefix, @@ -271,7 +271,7 @@ impl GuestLauncher { ip.ipv6_prefix, )?), gateway_mac: Some(gateway_mac_string.clone()), - state: GuestState { exit_code: None }, + state: ZoneState { exit_code: None }, }) } Err(error) => { diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index 45399cf..85468f4 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -12,7 +12,7 @@ use xenstore::{XsdClient, XsdInterface}; use self::{ autoloop::AutoLoop, - launch::{GuestLaunchRequest, GuestLauncher}, + launch::{ZoneLaunchRequest, ZoneLauncher}, power::PowerManagementContext, }; @@ -29,29 +29,32 @@ type RuntimePlatform = xenplatform::x86pv::X86PvPlatform; #[cfg(not(target_arch = "x86_64"))] type RuntimePlatform = xenplatform::unsupported::UnsupportedPlatform; -pub struct GuestLoopInfo { +#[derive(Clone)] +pub struct ZoneLoopInfo { pub device: String, pub file: String, pub delete: Option, } -pub struct GuestState { +#[derive(Clone)] +pub struct ZoneState { pub exit_code: Option, } -pub struct GuestInfo { +#[derive(Clone)] +pub struct ZoneInfo { pub name: Option, pub uuid: Uuid, pub domid: u32, pub image: String, - pub loops: Vec, - pub guest_ipv4: Option, - pub guest_ipv6: Option, - pub guest_mac: Option, + pub loops: Vec, + pub zone_ipv4: Option, + pub zone_ipv6: Option, + pub zone_mac: Option, pub gateway_ipv4: Option, pub gateway_ipv6: Option, pub gateway_mac: Option, - pub state: GuestState, + pub state: ZoneState, } #[derive(Clone)] @@ -75,8 +78,8 @@ impl RuntimeContext { }) } - pub async fn list(&self) -> Result> { - let mut guests: Vec = Vec::new(); + pub async fn list(&self) -> Result> { + let mut zones: Vec = Vec::new(); for domid_candidate in self.xen.store.list("/local/domain").await? { if domid_candidate == "0" { continue; @@ -112,20 +115,20 @@ impl RuntimeContext { .store .read_string(&format!("{}/krata/loops", &dom_path)) .await?; - let guest_ipv4 = self + let zone_ipv4 = self .xen .store - .read_string(&format!("{}/krata/network/guest/ipv4", &dom_path)) + .read_string(&format!("{}/krata/network/zone/ipv4", &dom_path)) .await?; - let guest_ipv6 = self + let zone_ipv6 = self .xen .store - .read_string(&format!("{}/krata/network/guest/ipv6", &dom_path)) + .read_string(&format!("{}/krata/network/zone/ipv6", &dom_path)) .await?; - let guest_mac = self + let zone_mac = self .xen .store - .read_string(&format!("{}/krata/network/guest/mac", &dom_path)) + .read_string(&format!("{}/krata/network/zone/mac", &dom_path)) .await?; let gateway_ipv4 = self .xen @@ -143,14 +146,14 @@ impl RuntimeContext { .read_string(&format!("{}/krata/network/gateway/mac", &dom_path)) .await?; - let guest_ipv4 = if let Some(guest_ipv4) = guest_ipv4 { - IpNetwork::from_str(&guest_ipv4).ok() + let zone_ipv4 = if let Some(zone_ipv4) = zone_ipv4 { + IpNetwork::from_str(&zone_ipv4).ok() } else { None }; - let guest_ipv6 = if let Some(guest_ipv6) = guest_ipv6 { - IpNetwork::from_str(&guest_ipv6).ok() + let zone_ipv6 = if let Some(zone_ipv6) = zone_ipv6 { + IpNetwork::from_str(&zone_ipv6).ok() } else { None }; @@ -170,7 +173,7 @@ impl RuntimeContext { let exit_code = self .xen .store - .read_string(&format!("{}/krata/guest/exit-code", &dom_path)) + .read_string(&format!("{}/krata/zone/exit-code", &dom_path)) .await?; let exit_code: Option = match exit_code { @@ -178,37 +181,37 @@ impl RuntimeContext { None => None, }; - let state = GuestState { exit_code }; + let state = ZoneState { exit_code }; let loops = RuntimeContext::parse_loop_set(&loops); - guests.push(GuestInfo { + zones.push(ZoneInfo { name, uuid, domid, image, loops, - guest_ipv4, - guest_ipv6, - guest_mac, + zone_ipv4, + zone_ipv6, + zone_mac, gateway_ipv4, gateway_ipv6, gateway_mac, state, }); } - Ok(guests) + Ok(zones) } - pub async fn resolve(&self, uuid: Uuid) -> Result> { - for guest in self.list().await? { - if guest.uuid == uuid { - return Ok(Some(guest)); + pub async fn resolve(&self, uuid: Uuid) -> Result> { + for zone in self.list().await? { + if zone.uuid == uuid { + return Ok(Some(zone)); } } Ok(None) } - fn parse_loop_set(input: &Option) -> Vec { + fn parse_loop_set(input: &Option) -> Vec { let Some(input) = input else { return Vec::new(); }; @@ -219,7 +222,7 @@ impl RuntimeContext { .map(|x| (x[0].clone(), x[1].clone(), x[2].clone())) .collect::>(); sets.iter() - .map(|(device, file, delete)| GuestLoopInfo { + .map(|(device, file, delete)| ZoneLoopInfo { device: device.clone(), file: file.clone(), delete: if delete == "none" { @@ -228,7 +231,7 @@ impl RuntimeContext { Some(delete.clone()) }, }) - .collect::>() + .collect::>() } } @@ -249,8 +252,8 @@ impl Runtime { }) } - pub async fn launch(&self, request: GuestLaunchRequest) -> Result { - let mut launcher = GuestLauncher::new(self.launch_semaphore.clone())?; + pub async fn launch(&self, request: ZoneLaunchRequest) -> Result { + let mut launcher = ZoneLauncher::new(self.launch_semaphore.clone())?; launcher.launch(&self.context, request).await } @@ -259,7 +262,7 @@ impl Runtime { .context .resolve(uuid) .await? - .ok_or_else(|| anyhow!("unable to resolve guest: {}", uuid))?; + .ok_or_else(|| anyhow!("unable to resolve zone: {}", uuid))?; let domid = info.domid; let store = XsdClient::open().await?; let dom_path = store.get_domain_path(domid).await?; @@ -307,7 +310,7 @@ impl Runtime { if let Some(ip) = ip { if let Err(error) = self.context.ipvendor.recall(&ip).await { error!( - "failed to recall ip assignment for guest {}: {}", + "failed to recall ip assignment for zone {}: {}", uuid, error ); } @@ -316,7 +319,7 @@ impl Runtime { Ok(uuid) } - pub async fn list(&self) -> Result> { + pub async fn list(&self) -> Result> { self.context.list().await } diff --git a/crates/runtime/src/power.rs b/crates/runtime/src/power.rs index 0eaa2b6..40f3236 100644 --- a/crates/runtime/src/power.rs +++ b/crates/runtime/src/power.rs @@ -25,7 +25,7 @@ pub struct CpuTopologyInfo { pub class: CpuClass, } -fn labelled_topo(input: &[SysctlCputopo]) -> Vec { +fn labeled_topology(input: &[SysctlCputopo]) -> Vec { let mut cores: IndexMap<(u32, u32, u32), Vec> = IndexMap::new(); let mut pe_cores = false; let mut last: Option = None; @@ -140,9 +140,9 @@ impl PowerManagementContext { /// If there is a p-core/e-core split, then CPU class will be defined as /// `CpuClass::Performance` or `CpuClass::Efficiency`, else `CpuClass::Standard`. pub async fn cpu_topology(&self) -> Result> { - let xentopo = self.context.xen.call.cpu_topology().await?; - let logicaltopo = labelled_topo(&xentopo); - Ok(logicaltopo) + let xen_topology = self.context.xen.call.cpu_topology().await?; + let logical_topology = labeled_topology(&xen_topology); + Ok(logical_topology) } /// Enable or disable SMT awareness in the scheduler. diff --git a/crates/guest/Cargo.toml b/crates/zone/Cargo.toml similarity index 87% rename from crates/guest/Cargo.toml rename to crates/zone/Cargo.toml index 169b978..ee5b253 100644 --- a/crates/guest/Cargo.toml +++ b/crates/zone/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "krata-guest" -description = "Guest services for the krata isolation engine" +name = "krata-zone" +description = "zone services for the krata isolation engine" license.workspace = true version.workspace = true homepage.workspace = true @@ -30,8 +30,8 @@ sysinfo = { workspace = true } tokio = { workspace = true } [lib] -name = "krataguest" +name = "kratazone" [[bin]] -name = "krataguest" +name = "krata-zone" path = "bin/init.rs" diff --git a/crates/zone/bin/init.rs b/crates/zone/bin/init.rs new file mode 100644 index 0000000..f6aecb2 --- /dev/null +++ b/crates/zone/bin/init.rs @@ -0,0 +1,19 @@ +use anyhow::Result; +use env_logger::Env; +use kratazone::{death, init::ZoneInit}; +use log::error; +use std::env; + +#[tokio::main] +async fn main() -> Result<()> { + env::set_var("RUST_BACKTRACE", "1"); + env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init(); + let mut zone = ZoneInit::new(); + if let Err(error) = zone.init().await { + error!("failed to initialize zone: {}", error); + death(127).await?; + return Ok(()); + } + death(1).await?; + Ok(()) +} diff --git a/crates/guest/src/background.rs b/crates/zone/src/background.rs similarity index 94% rename from crates/guest/src/background.rs rename to crates/zone/src/background.rs index ddd21b5..bb44d51 100644 --- a/crates/guest/src/background.rs +++ b/crates/zone/src/background.rs @@ -1,7 +1,7 @@ use crate::{ childwait::{ChildEvent, ChildWait}, death, - exec::GuestExecTask, + exec::ZoneExecTask, metrics::MetricsCollector, }; use anyhow::Result; @@ -18,20 +18,16 @@ use log::debug; use nix::unistd::Pid; use tokio::{select, sync::broadcast}; -pub struct GuestBackground { +pub struct ZoneBackground { idm: IdmInternalClient, child: Pid, _cgroup: Cgroup, wait: ChildWait, } -impl GuestBackground { - pub async fn new( - idm: IdmInternalClient, - cgroup: Cgroup, - child: Pid, - ) -> Result { - Ok(GuestBackground { +impl ZoneBackground { + pub async fn new(idm: IdmInternalClient, cgroup: Cgroup, child: Pid) -> Result { + Ok(ZoneBackground { idm, child, _cgroup: cgroup, @@ -134,7 +130,7 @@ impl GuestBackground { ) -> Result<()> { if let Some(RequestType::ExecStream(_)) = &handle.initial.request { tokio::task::spawn(async move { - let exec = GuestExecTask { handle }; + let exec = ZoneExecTask { handle }; if let Err(error) = exec.run().await { let _ = exec .handle diff --git a/crates/guest/src/childwait.rs b/crates/zone/src/childwait.rs similarity index 100% rename from crates/guest/src/childwait.rs rename to crates/zone/src/childwait.rs diff --git a/crates/guest/src/exec.rs b/crates/zone/src/exec.rs similarity index 99% rename from crates/guest/src/exec.rs rename to crates/zone/src/exec.rs index 82fb360..35f0f59 100644 --- a/crates/guest/src/exec.rs +++ b/crates/zone/src/exec.rs @@ -15,11 +15,11 @@ use tokio::{ process::Command, }; -pub struct GuestExecTask { +pub struct ZoneExecTask { pub handle: IdmClientStreamResponseHandle, } -impl GuestExecTask { +impl ZoneExecTask { pub async fn run(&self) -> Result<()> { let mut receiver = self.handle.take().await?; diff --git a/crates/guest/src/init.rs b/crates/zone/src/init.rs similarity index 96% rename from crates/guest/src/init.rs rename to crates/zone/src/init.rs index e01c794..5eff50c 100644 --- a/crates/guest/src/init.rs +++ b/crates/zone/src/init.rs @@ -26,7 +26,7 @@ use std::str::FromStr; use sys_mount::{FilesystemType, Mount, MountFlags}; use tokio::fs; -use crate::background::GuestBackground; +use crate::background::ZoneBackground; const IMAGE_BLOCK_DEVICE_PATH: &str = "/dev/xvda"; const CONFIG_BLOCK_DEVICE_PATH: &str = "/dev/xvdb"; @@ -57,17 +57,17 @@ const ADDONS_MODULES_PATH: &str = "/addons/modules"; ioctl_write_int_bad!(set_controlling_terminal, TIOCSCTTY); -pub struct GuestInit {} +pub struct ZoneInit {} -impl Default for GuestInit { +impl Default for ZoneInit { fn default() -> Self { Self::new() } } -impl GuestInit { - pub fn new() -> GuestInit { - GuestInit {} +impl ZoneInit { + pub fn new() -> ZoneInit { + ZoneInit {} } pub async fn init(&mut self) -> Result<()> { @@ -127,7 +127,7 @@ impl GuestInit { } if let Some(cfg) = config.config() { - trace!("running guest task"); + trace!("running zone task"); self.run(cfg, &launch, idm).await?; } else { return Err(anyhow!( @@ -521,7 +521,7 @@ impl GuestInit { let mut env = HashMap::new(); if let Some(config_env) = config.env() { - env.extend(GuestInit::env_map(config_env)); + env.extend(ZoneInit::env_map(config_env)); } env.extend(launch.env.clone()); env.insert("KRATA_CONTAINER".to_string(), "1".to_string()); @@ -540,13 +540,13 @@ impl GuestInit { return Err(anyhow!("cannot get file name of command path as str")); }; cmd.insert(0, file_name.to_string()); - let env = GuestInit::env_list(env); + let env = ZoneInit::env_list(env); - trace!("running guest command: {}", cmd.join(" ")); + trace!("running zone command: {}", cmd.join(" ")); let path = CString::new(path.as_os_str().as_bytes())?; - let cmd = GuestInit::strings_as_cstrings(cmd)?; - let env = GuestInit::strings_as_cstrings(env)?; + let cmd = ZoneInit::strings_as_cstrings(cmd)?; + let env = ZoneInit::strings_as_cstrings(env)?; let mut working_dir = config .working_dir() .as_ref() @@ -566,7 +566,7 @@ impl GuestInit { async fn init_cgroup(&self) -> Result { trace!("initializing cgroup"); let hierarchy = cgroups_rs::hierarchies::auto(); - let cgroup = Cgroup::new(hierarchy, "krata-guest-task")?; + let cgroup = Cgroup::new(hierarchy, "krata-zone-task")?; cgroup.set_cgroup_type("threaded")?; trace!("initialized cgroup"); Ok(cgroup) @@ -619,7 +619,7 @@ impl GuestInit { cmd: Vec, env: Vec, ) -> Result<()> { - GuestInit::set_controlling_terminal()?; + ZoneInit::set_controlling_terminal()?; std::env::set_current_dir(working_dir)?; cgroup.add_task(CgroupPid::from(std::process::id() as u64))?; execve(&path, &cmd, &env)?; @@ -640,7 +640,7 @@ impl GuestInit { cgroup: Cgroup, executed: Pid, ) -> Result<()> { - let mut background = GuestBackground::new(idm, cgroup, executed).await?; + let mut background = ZoneBackground::new(idm, cgroup, executed).await?; background.run().await?; Ok(()) } diff --git a/crates/guest/src/lib.rs b/crates/zone/src/lib.rs similarity index 86% rename from crates/guest/src/lib.rs rename to crates/zone/src/lib.rs index a5afc46..035dc0c 100644 --- a/crates/guest/src/lib.rs +++ b/crates/zone/src/lib.rs @@ -13,7 +13,7 @@ pub mod metrics; pub async fn death(code: c_int) -> Result<()> { let store = XsdClient::open().await?; store - .write_string("krata/guest/exit-code", &code.to_string()) + .write_string("krata/zone/exit-code", &code.to_string()) .await?; drop(store); loop { diff --git a/crates/guest/src/metrics.rs b/crates/zone/src/metrics.rs similarity index 99% rename from crates/guest/src/metrics.rs rename to crates/zone/src/metrics.rs index 5f97a2d..d67526c 100644 --- a/crates/guest/src/metrics.rs +++ b/crates/zone/src/metrics.rs @@ -14,7 +14,7 @@ impl MetricsCollector { pub fn collect(&self) -> Result { let mut sysinfo = sysinfo::System::new(); Ok(MetricNode::structural( - "guest", + "zone", vec![ self.collect_system(&mut sysinfo)?, self.collect_processes(&mut sysinfo)?, diff --git a/hack/debug/common.sh b/hack/debug/common.sh index 250715c..43ac157 100644 --- a/hack/debug/common.sh +++ b/hack/debug/common.sh @@ -19,12 +19,12 @@ fi build_and_run() { EXE_TARGET="${1}" shift - sudo mkdir -p /var/lib/krata/guest + sudo mkdir -p /var/lib/krata/zone if [ "${KRATA_BUILD_INITRD}" = "1" ] then TARGET_ARCH="$(./hack/build/arch.sh)" ./hack/initrd/build.sh ${CARGO_BUILD_FLAGS} - sudo cp "target/initrd/initrd-${TARGET_ARCH}" "/var/lib/krata/guest/initrd" + sudo cp "target/initrd/initrd-${TARGET_ARCH}" "/var/lib/krata/zone/initrd" fi RUST_TARGET="$(./hack/build/target.sh)" ./hack/build/cargo.sh build ${CARGO_BUILD_FLAGS} --bin "${EXE_TARGET}" diff --git a/hack/dist/systar.sh b/hack/dist/systar.sh index 168a190..c1672aa 100755 --- a/hack/dist/systar.sh +++ b/hack/dist/systar.sh @@ -38,9 +38,9 @@ else mv ../krata/kratad.service ../krata/kratanet.service usr/lib/systemd/system/ fi -mkdir -p usr/share/krata/guest -mv ../krata/kernel ../krata/initrd usr/share/krata/guest -mv ../krata/addons.squashfs usr/share/krata/guest/addons.squashfs +mkdir -p usr/share/krata/zone +mv ../krata/kernel ../krata/initrd usr/share/krata/zone +mv ../krata/addons.squashfs usr/share/krata/zone/addons.squashfs tar czf "${SYSTAR}" --owner 0 --group 0 . diff --git a/hack/initrd/build.sh b/hack/initrd/build.sh index 81d1815..585acce 100755 --- a/hack/initrd/build.sh +++ b/hack/initrd/build.sh @@ -12,9 +12,9 @@ export TARGET_LIBC="musl" RUST_TARGET="$(./hack/build/target.sh)" export RUSTFLAGS="-Ctarget-feature=+crt-static" -./hack/build/cargo.sh build "${@}" --release --bin krataguest +./hack/build/cargo.sh build "${@}" --release --bin krata-zone INITRD_DIR="$(mktemp -d /tmp/krata-initrd.XXXXXXXXXXXXX)" -cp "target/${RUST_TARGET}/release/krataguest" "${INITRD_DIR}/init" +cp "target/${RUST_TARGET}/release/krata-zone" "${INITRD_DIR}/init" chmod +x "${INITRD_DIR}/init" cd "${INITRD_DIR}" mkdir -p "${KRATA_DIR}/target/initrd" diff --git a/images/Dockerfile.krata-guest-init b/images/Dockerfile.krata-zone similarity index 100% rename from images/Dockerfile.krata-guest-init rename to images/Dockerfile.krata-zone diff --git a/release-plz.toml b/release-plz.toml index 4f1be25..2260caa 100644 --- a/release-plz.toml +++ b/release-plz.toml @@ -14,7 +14,7 @@ changelog_path = "./CHANGELOG.md" changelog_include = [ "krata-daemon", "krata-ctl", - "krata-guest", + "krata-zone", "krata-network", "krata-runtime", "krata-oci", diff --git a/resources/bundle/install.sh b/resources/bundle/install.sh index 62eea59..92bc506 100755 --- a/resources/bundle/install.sh +++ b/resources/bundle/install.sh @@ -30,9 +30,9 @@ chmod +x /usr/sbin/kratad chmod +x /usr/sbin/kratanet chmod +x /usr/bin/kratactl -mkdir -p /var/lib/krata /usr/share/krata/guest -cp kernel /usr/share/krata/guest/kernel -cp initrd /usr/share/krata/guest/initrd +mkdir -p /var/lib/krata /usr/share/krata/zone +cp kernel /usr/share/krata/zone/kernel +cp initrd /usr/share/krata/zone/initrd systemctl daemon-reload systemctl enable kratad.service kratanet.service