mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 12:50:54 +00:00
rebrand to krata
This commit is contained in:
parent
af50f1d996
commit
c582f15c54
54
README.md
54
README.md
@ -1,22 +1,22 @@
|
||||
# hypha
|
||||
# krata
|
||||
|
||||
An early prototype of the Mycelium hypervisor. Not for production use.
|
||||
An early version of the Edera hypervisor. Not for production use.
|
||||
|
||||
[Join our community Discord](https://discord.gg/UGZCtX9NG9), or follow the founders [Alex](https://social.treehouse.systems/@alex) and [Ariadne](https://social.treehouse.systems/@ariadne) on Mastodon to follow the future of hypha.
|
||||
[Join our community Discord](https://discord.gg/UGZCtX9NG9), or follow the founders [Alex](https://social.treehouse.systems/@alex) and [Ariadne](https://social.treehouse.systems/@ariadne) on Mastodon to follow the future of krata.
|
||||
|
||||
## What is hypha?
|
||||
## What is krata?
|
||||
|
||||
The hypha prototype makes it possible to launch OCI containers on a Xen hypervisor without utilizing the Xen userspace tooling. hypha contains just enough of the userspace of Xen (reimplemented in Rust) to start an x86_64 Xen Linux PV guest, and implements an Linux init process that can boot an OCI container. It does so by converting an OCI image into a squashfs file and packaging basic startup data in a bundle which the init container can read.
|
||||
The krata prototype makes it possible to launch OCI containers on a Xen hypervisor without utilizing the Xen userspace tooling. krata contains just enough of the userspace of Xen (reimplemented in Rust) to start an x86_64 Xen Linux PV guest, and implements a Linux init process that can boot an OCI container. It does so by converting an OCI image into a squashfs file and packaging basic startup data in a bundle which the init container can read.
|
||||
|
||||
In addition, due to the desire to reduce dependence on the dom0 network, hypha contains a networking daemon called hyphanet. hyphanet listens for hypha guests to startup and launches a userspace networking environment. hypha guests can access the dom0 networking stack via the proxynat layer that makes it possible to communicate over UDP, TCP, and ICMP (echo only) to the outside world. In addition, each hypha guest is provided a "gateway" IP (both in IPv4 and IPv6) which utilizes smoltcp to provide a virtual host. That virtual host in the future could dial connections into the container to access container networking resources.
|
||||
In addition, due to the desire to reduce dependence on the dom0 network, krata contains a networking daemon called kratanet. kratanet listens for krata guests to startup and launches a userspace networking environment. krata guests can access the dom0 networking stack via the proxynat layer that makes it possible to communicate over UDP, TCP, and ICMP (echo only) to the outside world. In addition, each krata guest is provided a "gateway" IP (both in IPv4 and IPv6) which utilizes smoltcp to provide a virtual host. That virtual host in the future could dial connections into the container to access container networking resources.
|
||||
|
||||
hypha is in it's early days and this project is provided as essentially a demo of what an OCI layer on Xen could look like.
|
||||
krata is in it's early days and this project is provided as essentially a demo of what an OCI layer on Xen could look like.
|
||||
|
||||
## FAQs
|
||||
|
||||
### Why utilize Xen instead of KVM?
|
||||
|
||||
Xen is a very interesting technology, and Mycelium believes that type-1 hypervisors are ideal for security. Most OCI isolation techniques use KVM, which is not a type-1 hypervisor, and thus is subject to the security limitations of the OS kernel. A type-1 hypervisor on the otherhand provides a minimal amount of attack surface upon which less-trusted guests can be launched on top of.
|
||||
Xen is a very interesting technology, and Edera believes that type-1 hypervisors are ideal for security. Most OCI isolation techniques use KVM, which is not a type-1 hypervisor, and thus is subject to the security limitations of the OS kernel. A type-1 hypervisor on the otherhand provides a minimal amount of attack surface upon which less-trusted guests can be launched on top of.
|
||||
|
||||
### Why not utilize pvcalls to provide access to the host network?
|
||||
|
||||
@ -24,29 +24,29 @@ pvcalls is extremely interesting, and although it is certainly possible to utili
|
||||
|
||||
### Why is this prototype utilizing AGPL?
|
||||
|
||||
This repository is licensed under AGPL. This is because what is here is not intended for anything other than curiosity and research. Mycelium will utilize a different license for any production versions of hypha.
|
||||
This repository is licensed under AGPL. This is because what is here is not intended for anything other than curiosity and research. Edera will utilize a different license for any production versions of krata.
|
||||
|
||||
As such, no external contributions are accepted at this time.
|
||||
|
||||
### Are external contributions accepted?
|
||||
|
||||
Currently no external contributions are accepted. hypha is in it's early days and the project is provided under AGPL. Mycelium may decide to change licensing as we start to build future plans, and so all code here is provided to show what is possible, not to work towards any future product goals.
|
||||
Currently no external contributions are accepted. krata is in it's early days and the project is provided under AGPL. Edera may decide to change licensing as we start to build future plans, and so all code here is provided to show what is possible, not to work towards any future product goals.
|
||||
|
||||
### What are the future plans?
|
||||
|
||||
Mycelium is trying to build a company to compete in the hypervisor space with fully open-source technology. More information to come soon on official channels.
|
||||
Edera is building a company to compete in the hypervisor space with open-source technology. More information to come soon on official channels.
|
||||
|
||||
## Development Guide
|
||||
|
||||
### Structure
|
||||
|
||||
hypha is composed of three major executables:
|
||||
krata is composed of three major executables:
|
||||
|
||||
| Executable | Runs On | User Interaction | Dev Runner | Code Path |
|
||||
| ---------- | ------- | ---------------- | --------------------------- | ----------- |
|
||||
| hyphanet | host | backend daemon | ./scripts/hyphanet-debug.sh | network |
|
||||
| hyphactl | host | CLI tool | ./scripts/hyphactl-debug.sh | controller |
|
||||
| hyphactr | guest | none, guest init | N/A | container |
|
||||
| kratanet | host | backend daemon | ./scripts/kratanet-debug.sh | network |
|
||||
| kratactl | host | CLI tool | ./scripts/kratactl-debug.sh | controller |
|
||||
| kratactr | guest | none, guest init | N/A | container |
|
||||
|
||||
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.
|
||||
@ -56,7 +56,7 @@ it's corresponding code path from the above table.
|
||||
| Component | Specification | Notes |
|
||||
| ------------- | ------------- | --------------------------------------------------------------------------------- |
|
||||
| Architecture | x86_64 | aarch64 support requires minimal effort, but limited to x86 for research phase |
|
||||
| Memory | At least 6GB | dom0 will need to be configured will lower memory limit to give hypha guests room |
|
||||
| Memory | At least 6GB | dom0 will need to be configured will lower memory limit to give krata guests 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 |
|
||||
@ -69,10 +69,10 @@ it's corresponding code path from the above table.
|
||||
|
||||
3. Install [rustup](https://rustup.rs) for managing a Rust environment.
|
||||
|
||||
4. Configure `/etc/default/grub.d/xen.cfg` to give hypha guests some room:
|
||||
4. Configure `/etc/default/grub.d/xen.cfg` to give krata guests some room:
|
||||
|
||||
```sh
|
||||
# Configure dom0_mem to be 4GB, but leave the rest of the RAM for hypha guests.
|
||||
# Configure dom0_mem to be 4GB, but leave the rest of the RAM for krata guests.
|
||||
GRUB_CMDLINE_XEN_DEFAULT="dom0_mem=4G,max:4G"
|
||||
```
|
||||
|
||||
@ -82,10 +82,10 @@ Then reboot to boot the system as a Xen dom0.
|
||||
|
||||
You can validate that Xen is setup by running `xl info` and ensuring it returns useful information about the Xen hypervisor.
|
||||
|
||||
5. Clone the hypha source code:
|
||||
5. Clone the krata source code:
|
||||
```sh
|
||||
$ git clone https://github.com/mycelium-eng/hypha.git hypha
|
||||
$ cd hypha
|
||||
$ git clone https://github.com/edera-dev/krata.git krata
|
||||
$ cd krata
|
||||
```
|
||||
|
||||
6. Build a guest kernel image:
|
||||
@ -94,22 +94,22 @@ $ cd hypha
|
||||
$ ./kernel/build.sh -j4
|
||||
```
|
||||
|
||||
7. Copy the guest kernel image at `kernel/target/kernel` to `/var/lib/hypha/default/kernel` to have it automatically detected by hyphactl.
|
||||
8. Launch `./scripts/hyphanet-debug.sh` and keep it running in the foreground.
|
||||
9. Run hyphactl to launch a container:
|
||||
7. Copy the guest kernel image at `kernel/target/kernel` to `/var/lib/krata/default/kernel` to have it automatically detected by kratactl.
|
||||
8. Launch `./scripts/kratanet-debug.sh` and keep it running in the foreground.
|
||||
9. Run kratactl to launch a container:
|
||||
|
||||
```sh
|
||||
$ ./scripts/hyphactl-debug.sh launch --attach mirror.gcr.io/library/alpine:latest /bin/busybox sh
|
||||
$ ./scripts/kratactl-debug.sh launch --attach mirror.gcr.io/library/alpine:latest /bin/busybox sh
|
||||
```
|
||||
|
||||
To detach from the container console, use `Ctrl + ]` on your keyboard.
|
||||
|
||||
To list the running containers, run:
|
||||
```sh
|
||||
$ ./scripts/hyphactl-debug.sh list
|
||||
$ ./scripts/kratactl-debug.sh list
|
||||
```
|
||||
|
||||
To destroy a running container, copy it's UUID from either the launch command or the container list and run:
|
||||
```sh
|
||||
$ ./scripts/hyphactl-debug.sh destroy CONTAINER_UUID
|
||||
$ ./scripts/kratactl-debug.sh destroy CONTAINER_UUID
|
||||
```
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "hyphactr"
|
||||
name = "kratactr"
|
||||
version.workspace = true
|
||||
edition = "2021"
|
||||
resolver = "2"
|
||||
@ -22,12 +22,12 @@ ipnetwork = { workspace = true }
|
||||
workspace = true
|
||||
features = ["process"]
|
||||
|
||||
[dependencies.hypha]
|
||||
[dependencies.krata]
|
||||
path = "../shared"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "hyphactr"
|
||||
name = "kratactr"
|
||||
path = "bin/init.rs"
|
||||
|
@ -1,19 +1,19 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use env_logger::Env;
|
||||
use hyphactr::init::ContainerInit;
|
||||
use kratactr::init::ContainerInit;
|
||||
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("HYPHA_UNSAFE_ALWAYS_ALLOW_INIT").unwrap_or("0".to_string()) != "1" {
|
||||
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 HYPHA_UNSAFE_ALWAYS_ALLOW_INIT=1 to bypass this check",
|
||||
run with KRATA_UNSAFE_ALWAYS_ALLOW_INIT=1 to bypass this check",
|
||||
pid
|
||||
));
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures::stream::TryStreamExt;
|
||||
use hypha::{LaunchInfo, LaunchNetwork};
|
||||
use ipnetwork::IpNetwork;
|
||||
use krata::{LaunchInfo, LaunchNetwork};
|
||||
use log::{trace, warn};
|
||||
use nix::libc::{c_int, dup2, ioctl, wait};
|
||||
use nix::unistd::{execve, fork, ForkResult, Pid};
|
||||
@ -289,7 +289,7 @@ impl ContainerInit {
|
||||
fs::create_dir(etc)?;
|
||||
}
|
||||
let resolv = PathBuf::from_str("/etc/resolv.conf")?;
|
||||
let mut lines = vec!["# hypha resolver configuration".to_string()];
|
||||
let mut lines = vec!["# krata resolver configuration".to_string()];
|
||||
for nameserver in &network.resolver.nameservers {
|
||||
lines.push(format!("nameserver {}", nameserver));
|
||||
}
|
||||
@ -386,7 +386,7 @@ impl ContainerInit {
|
||||
None => vec![],
|
||||
Some(value) => value.clone(),
|
||||
};
|
||||
env.push("HYPHA_CONTAINER=1".to_string());
|
||||
env.push("KRATA_CONTAINER=1".to_string());
|
||||
env.push("TERM=vt100".to_string());
|
||||
if let Some(extra_env) = &launch.env {
|
||||
env.extend_from_slice(extra_env.as_slice());
|
||||
@ -446,8 +446,8 @@ impl ContainerInit {
|
||||
}
|
||||
|
||||
fn death(&mut self, code: c_int) -> Result<()> {
|
||||
println!("[hypha] container process exited: status = {}", code);
|
||||
println!("[hypha] looping forever");
|
||||
println!("[krata] container process exited: status = {}", code);
|
||||
println!("[krata] looping forever");
|
||||
loop {
|
||||
sleep(Duration::from_secs(1));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "hyphactrl"
|
||||
name = "kratactrl"
|
||||
version.workspace = true
|
||||
edition = "2021"
|
||||
resolver = "2"
|
||||
@ -27,7 +27,7 @@ backhand = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
ipnetwork = { workspace = true }
|
||||
|
||||
[dependencies.hypha]
|
||||
[dependencies.krata]
|
||||
path = "../shared"
|
||||
|
||||
[dependencies.nix]
|
||||
@ -50,5 +50,5 @@ path = "../libs/xen/xenstore"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "hyphactl"
|
||||
name = "kratactl"
|
||||
path = "bin/control.rs"
|
||||
|
@ -1,7 +1,7 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use clap::{Parser, Subcommand};
|
||||
use env_logger::Env;
|
||||
use hyphactrl::ctl::{
|
||||
use kratactrl::ctl::{
|
||||
console::ControllerConsole,
|
||||
destroy::ControllerDestroy,
|
||||
launch::{ControllerLaunch, ControllerLaunchRequest},
|
||||
@ -156,9 +156,9 @@ fn default_store_path() -> Option<PathBuf> {
|
||||
let user_dirs = directories::UserDirs::new()?;
|
||||
let mut path = user_dirs.home_dir().to_path_buf();
|
||||
if path == PathBuf::from("/root") {
|
||||
path.push("/var/lib/hypha")
|
||||
path.push("/var/lib/krata")
|
||||
} else {
|
||||
path.push(".hypha");
|
||||
path.push(".krata");
|
||||
}
|
||||
Some(path)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::image::ImageInfo;
|
||||
use anyhow::Result;
|
||||
use backhand::{FilesystemWriter, NodeHeader};
|
||||
use hypha::LaunchInfo;
|
||||
use krata::LaunchInfo;
|
||||
use log::trace;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
@ -17,7 +17,7 @@ pub struct ConfigBlock<'a> {
|
||||
impl ConfigBlock<'_> {
|
||||
pub fn new<'a>(uuid: &Uuid, image_info: &'a ImageInfo) -> Result<ConfigBlock<'a>> {
|
||||
let mut dir = std::env::temp_dir().clone();
|
||||
dir.push(format!("hypha-cfg-{}", uuid));
|
||||
dir.push(format!("krata-cfg-{}", uuid));
|
||||
fs::create_dir_all(&dir)?;
|
||||
let mut file = dir.clone();
|
||||
file.push("config.squashfs");
|
||||
|
@ -23,20 +23,20 @@ impl ControllerDestroy<'_> {
|
||||
let domid = info.domid;
|
||||
let mut store = XsdClient::open()?;
|
||||
let dom_path = store.get_domain_path(domid)?;
|
||||
let uuid = match store.read_string_optional(format!("{}/hypha/uuid", dom_path).as_str())? {
|
||||
let uuid = match store.read_string_optional(format!("{}/krata/uuid", dom_path).as_str())? {
|
||||
None => {
|
||||
return Err(anyhow!(
|
||||
"domain {} was not found or not created by hypha",
|
||||
"domain {} was not found or not created by krata",
|
||||
domid
|
||||
))
|
||||
}
|
||||
Some(value) => value,
|
||||
};
|
||||
if uuid.is_empty() {
|
||||
return Err(anyhow!("unable to find hypha uuid based on the domain",));
|
||||
return Err(anyhow!("unable to find krata uuid based on the domain",));
|
||||
}
|
||||
let uuid = Uuid::parse_str(&uuid)?;
|
||||
let loops = store.read_string(format!("{}/hypha/loops", dom_path).as_str())?;
|
||||
let loops = store.read_string(format!("{}/krata/loops", dom_path).as_str())?;
|
||||
let loops = ControllerContext::parse_loop_set(&loops);
|
||||
self.context.xen.destroy(domid)?;
|
||||
for info in &loops {
|
||||
|
@ -2,10 +2,10 @@ use std::{fs, net::Ipv4Addr, str::FromStr};
|
||||
|
||||
use advmac::MacAddr6;
|
||||
use anyhow::{anyhow, Result};
|
||||
use hypha::{
|
||||
use ipnetwork::Ipv4Network;
|
||||
use krata::{
|
||||
LaunchInfo, LaunchNetwork, LaunchNetworkIpv4, LaunchNetworkIpv6, LaunchNetworkResolver,
|
||||
};
|
||||
use ipnetwork::Ipv4Network;
|
||||
use uuid::Uuid;
|
||||
use xenclient::{DomainConfig, DomainDisk, DomainNetworkInterface};
|
||||
use xenstore::client::XsdInterface;
|
||||
@ -36,7 +36,7 @@ impl ControllerLaunch<'_> {
|
||||
|
||||
pub fn perform(&mut self, request: ControllerLaunchRequest) -> Result<(Uuid, u32)> {
|
||||
let uuid = Uuid::new_v4();
|
||||
let name = format!("hypha-{uuid}");
|
||||
let name = format!("krata-{uuid}");
|
||||
let image_info = self.compile(request.image)?;
|
||||
|
||||
let mut gateway_mac = MacAddr6::random();
|
||||
@ -134,9 +134,9 @@ impl ControllerLaunch<'_> {
|
||||
}],
|
||||
filesystems: vec![],
|
||||
extra_keys: vec![
|
||||
("hypha/uuid".to_string(), uuid.to_string()),
|
||||
("krata/uuid".to_string(), uuid.to_string()),
|
||||
(
|
||||
"hypha/loops".to_string(),
|
||||
"krata/loops".to_string(),
|
||||
format!(
|
||||
"{}:{}:none,{}:{}:{}",
|
||||
&image_squashfs_loop.path,
|
||||
@ -146,29 +146,29 @@ impl ControllerLaunch<'_> {
|
||||
cfgblk_dir_path,
|
||||
),
|
||||
),
|
||||
("hypha/image".to_string(), request.image.to_string()),
|
||||
("krata/image".to_string(), request.image.to_string()),
|
||||
(
|
||||
"hypha/network/guest/ipv4".to_string(),
|
||||
"krata/network/guest/ipv4".to_string(),
|
||||
format!("{}/{}", guest_ipv4, ipv4_network_mask),
|
||||
),
|
||||
(
|
||||
"hypha/network/guest/ipv6".to_string(),
|
||||
"krata/network/guest/ipv6".to_string(),
|
||||
format!("{}/{}", guest_ipv6, ipv6_network_mask),
|
||||
),
|
||||
(
|
||||
"hypha/network/guest/mac".to_string(),
|
||||
"krata/network/guest/mac".to_string(),
|
||||
container_mac_string.clone(),
|
||||
),
|
||||
(
|
||||
"hypha/network/gateway/ipv4".to_string(),
|
||||
"krata/network/gateway/ipv4".to_string(),
|
||||
format!("{}/{}", gateway_ipv4, ipv4_network_mask),
|
||||
),
|
||||
(
|
||||
"hypha/network/gateway/ipv6".to_string(),
|
||||
"krata/network/gateway/ipv6".to_string(),
|
||||
format!("{}/{}", gateway_ipv6, ipv6_network_mask),
|
||||
),
|
||||
(
|
||||
"hypha/network/gateway/mac".to_string(),
|
||||
"krata/network/gateway/mac".to_string(),
|
||||
gateway_mac_string.clone(),
|
||||
),
|
||||
],
|
||||
@ -193,7 +193,7 @@ impl ControllerLaunch<'_> {
|
||||
];
|
||||
for domid_candidate in self.context.xen.store.list_any("/local/domain")? {
|
||||
let dom_path = format!("/local/domain/{}", domid_candidate);
|
||||
let ip_path = format!("{}/hypha/network/guest/ipv4", dom_path);
|
||||
let ip_path = format!("{}/krata/network/guest/ipv4", dom_path);
|
||||
let existing_ip = self.context.xen.store.read_string_optional(&ip_path)?;
|
||||
if let Some(existing_ip) = existing_ip {
|
||||
let ipv4_network = Ipv4Network::from_str(&existing_ip)?;
|
||||
|
@ -60,7 +60,7 @@ impl ControllerContext {
|
||||
let uuid_string = match self
|
||||
.xen
|
||||
.store
|
||||
.read_string_optional(&format!("{}/hypha/uuid", &dom_path))?
|
||||
.read_string_optional(&format!("{}/krata/uuid", &dom_path))?
|
||||
{
|
||||
None => continue,
|
||||
Some(value) => value,
|
||||
@ -71,22 +71,22 @@ impl ControllerContext {
|
||||
let image = self
|
||||
.xen
|
||||
.store
|
||||
.read_string_optional(&format!("{}/hypha/image", &dom_path))?
|
||||
.read_string_optional(&format!("{}/krata/image", &dom_path))?
|
||||
.unwrap_or("unknown".to_string());
|
||||
let loops = self
|
||||
.xen
|
||||
.store
|
||||
.read_string_optional(&format!("{}/hypha/loops", &dom_path))?
|
||||
.read_string_optional(&format!("{}/krata/loops", &dom_path))?
|
||||
.unwrap_or("".to_string());
|
||||
let ipv4 = self
|
||||
.xen
|
||||
.store
|
||||
.read_string_optional(&format!("{}/hypha/network/guest/ipv4", &dom_path))?
|
||||
.read_string_optional(&format!("{}/krata/network/guest/ipv4", &dom_path))?
|
||||
.unwrap_or("unknown".to_string());
|
||||
let ipv6: String = self
|
||||
.xen
|
||||
.store
|
||||
.read_string_optional(&format!("{}/hypha/network/guest/ipv6", &dom_path))?
|
||||
.read_string_optional(&format!("{}/krata/network/guest/ipv6", &dom_path))?
|
||||
.unwrap_or("unknown".to_string());
|
||||
let loops = ControllerContext::parse_loop_set(&loops);
|
||||
containers.push(ContainerInfo {
|
||||
@ -105,7 +105,7 @@ impl ControllerContext {
|
||||
for container in self.list()? {
|
||||
let uuid_string = container.uuid.to_string();
|
||||
let domid_string = container.domid.to_string();
|
||||
if uuid_string == id || domid_string == id || id == format!("hypha-{}", uuid_string) {
|
||||
if uuid_string == id || domid_string == id || id == format!("krata-{}", uuid_string) {
|
||||
return Ok(Some(container));
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ impl ImageCompiler<'_> {
|
||||
pub fn compile(&self, image: &ImageName) -> Result<ImageInfo> {
|
||||
debug!("ImageCompiler compile image={image}");
|
||||
let mut tmp_dir = std::env::temp_dir().clone();
|
||||
tmp_dir.push(format!("hypha-compile-{}", Uuid::new_v4()));
|
||||
tmp_dir.push(format!("krata-compile-{}", Uuid::new_v4()));
|
||||
|
||||
let mut image_dir = tmp_dir.clone();
|
||||
image_dir.push("image");
|
||||
|
@ -5,12 +5,12 @@ TARGET="x86_64-unknown-linux-gnu"
|
||||
|
||||
export RUSTFLAGS="-Ctarget-feature=+crt-static"
|
||||
cd "$(dirname "${0}")/.."
|
||||
HYPHA_DIR="${PWD}"
|
||||
cargo build --bin hyphactr --release --target "${TARGET}"
|
||||
INITRD_DIR="$(mktemp -d /tmp/hypha-initrd.XXXXXXXXXXXXX)"
|
||||
cp "target/${TARGET}/release/hyphactr" "${INITRD_DIR}/init"
|
||||
krata_DIR="${PWD}"
|
||||
cargo build -q --bin kratactr --release --target "${TARGET}"
|
||||
INITRD_DIR="$(mktemp -d /tmp/krata-initrd.XXXXXXXXXXXXX)"
|
||||
cp "target/${TARGET}/release/kratactr" "${INITRD_DIR}/init"
|
||||
chmod +x "${INITRD_DIR}/init"
|
||||
cd "${INITRD_DIR}"
|
||||
mkdir -p "${HYPHA_DIR}/target/initrd"
|
||||
find . | cpio -R 0:0 --reproducible -o -H newc --quiet > "${HYPHA_DIR}/target/initrd/initrd"
|
||||
mkdir -p "${krata_DIR}/target/initrd"
|
||||
find . | cpio -R 0:0 --reproducible -o -H newc --quiet > "${krata_DIR}/target/initrd/initrd"
|
||||
rm -rf "${INITRD_DIR}"
|
||||
|
@ -16,7 +16,7 @@ fi
|
||||
|
||||
mkdir -p "${OUTPUT_DIR_NAME}"
|
||||
|
||||
cp hypha.config "${SRC_DIR_NAME}/.config"
|
||||
cp krata.config "${SRC_DIR_NAME}/.config"
|
||||
make -C "${SRC_DIR_NAME}" "${@}" olddefconfig
|
||||
make -C "${SRC_DIR_NAME}" "${@}" bzImage
|
||||
cp "${SRC_DIR_NAME}/arch/x86/boot/bzImage" "${OUTPUT_DIR_NAME}/kernel"
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This package is from https://github.com/GamePad64/advmac
|
||||
# Mycelium maintains an in-tree version because of dependencies
|
||||
# Edera maintains an in-tree version because of dependencies
|
||||
# being out of date.
|
||||
[package]
|
||||
name = "advmac"
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This package is from https://github.com/stratis-storage/loopdev-3
|
||||
# Mycelium maintains an in-tree version because the goals of hypha mean that
|
||||
# Edera maintains an in-tree version because the goals of krata mean that
|
||||
# there is as little binding generation as possible, especially bindings which
|
||||
# prevent development from macOS, like the original library.
|
||||
[package]
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* originally generated by rust-bindgen */
|
||||
/* modified to remove unused content by Mycelium */
|
||||
/* modified to remove unused content by Edera */
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
pub const __BITS_PER_LONG: u32 = 64;
|
||||
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "hyphanet"
|
||||
name = "kratanet"
|
||||
version.workspace = true
|
||||
edition = "2021"
|
||||
resolver = "2"
|
||||
@ -31,7 +31,7 @@ path = "../libs/xen/xenstore"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "hyphanet"
|
||||
name = "kratanet"
|
||||
path = "bin/network.rs"
|
||||
|
||||
[[example]]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use env_logger::Env;
|
||||
use hyphanet::NetworkService;
|
||||
use kratanet::NetworkService;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct NetworkArgs {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{thread::sleep, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
use hyphanet::autonet::AutoNetworkCollector;
|
||||
use kratanet::autonet::AutoNetworkCollector;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut collector = AutoNetworkCollector::new()?;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::{net::Ipv6Addr, str::FromStr, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
use hyphanet::icmp::{IcmpClient, IcmpProtocol};
|
||||
use kratanet::icmp::{IcmpClient, IcmpProtocol};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
|
@ -53,7 +53,7 @@ impl AutoNetworkCollector {
|
||||
};
|
||||
|
||||
let dom_path = format!("/local/domain/{}", domid_string);
|
||||
let Some(uuid_string) = tx.read_string_optional(&format!("{}/hypha/uuid", dom_path))?
|
||||
let Some(uuid_string) = tx.read_string_optional(&format!("{}/krata/uuid", dom_path))?
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
@ -91,10 +91,10 @@ impl AutoNetworkCollector {
|
||||
dom_path: &str,
|
||||
side: &str,
|
||||
) -> Result<NetworkSide> {
|
||||
let side_path = format!("{}/hypha/network/{}", dom_path, side);
|
||||
let side_path = format!("{}/krata/network/{}", dom_path, side);
|
||||
let Some(ipv4) = tx.read_string_optional(&format!("{}/ipv4", side_path))? else {
|
||||
return Err(anyhow!(
|
||||
"hypha domain {} is missing {} ipv4 network entry",
|
||||
"krata domain {} is missing {} ipv4 network entry",
|
||||
uuid,
|
||||
side
|
||||
));
|
||||
@ -102,7 +102,7 @@ impl AutoNetworkCollector {
|
||||
|
||||
let Some(ipv6) = tx.read_string_optional(&format!("{}/ipv6", side_path))? else {
|
||||
return Err(anyhow!(
|
||||
"hypha domain {} is missing {} ipv6 network entry",
|
||||
"krata domain {} is missing {} ipv6 network entry",
|
||||
uuid,
|
||||
side
|
||||
));
|
||||
@ -110,7 +110,7 @@ impl AutoNetworkCollector {
|
||||
|
||||
let Some(mac) = tx.read_string_optional(&format!("{}/mac", side_path))? else {
|
||||
return Err(anyhow!(
|
||||
"hypha domain {} is missing {} mac address entry",
|
||||
"krata domain {} is missing {} mac address entry",
|
||||
uuid,
|
||||
side
|
||||
));
|
||||
@ -118,7 +118,7 @@ impl AutoNetworkCollector {
|
||||
|
||||
let Ok(ipv4) = Ipv4Cidr::from_str(&ipv4) else {
|
||||
return Err(anyhow!(
|
||||
"hypha domain {} has invalid {} ipv4 network cidr entry: {}",
|
||||
"krata domain {} has invalid {} ipv4 network cidr entry: {}",
|
||||
uuid,
|
||||
side,
|
||||
ipv4
|
||||
@ -127,7 +127,7 @@ impl AutoNetworkCollector {
|
||||
|
||||
let Ok(ipv6) = Ipv6Cidr::from_str(&ipv6) else {
|
||||
return Err(anyhow!(
|
||||
"hypha domain {} has invalid {} ipv6 network cidr entry: {}",
|
||||
"krata domain {} has invalid {} ipv6 network cidr entry: {}",
|
||||
uuid,
|
||||
side,
|
||||
ipv6
|
||||
@ -136,7 +136,7 @@ impl AutoNetworkCollector {
|
||||
|
||||
let Ok(mac) = EthernetAddress::from_str(&mac) else {
|
||||
return Err(anyhow!(
|
||||
"hypha domain {} has invalid {} mac address entry: {}",
|
||||
"krata domain {} has invalid {} mac address entry: {}",
|
||||
uuid,
|
||||
side,
|
||||
mac
|
||||
|
@ -16,7 +16,7 @@ use tokio::select;
|
||||
use tokio::sync::mpsc::{channel, Receiver};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
const TX_CHANNEL_BUFFER_LEN: usize = 300;
|
||||
const TX_CHANNEL_BUFFER_LEN: usize = 1000;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NetworkBackend {
|
||||
@ -151,12 +151,12 @@ impl NetworkBackend {
|
||||
pub async fn launch(self) -> Result<JoinHandle<()>> {
|
||||
Ok(tokio::task::spawn(async move {
|
||||
info!(
|
||||
"lauched network backend for hypha guest {}",
|
||||
"lauched network backend for krata guest {}",
|
||||
self.metadata.uuid
|
||||
);
|
||||
if let Err(error) = self.run().await {
|
||||
warn!(
|
||||
"network backend for hypha guest {} failed: {}",
|
||||
"network backend for krata guest {} failed: {}",
|
||||
self.metadata.uuid, error
|
||||
);
|
||||
}
|
||||
@ -167,7 +167,7 @@ impl NetworkBackend {
|
||||
impl Drop for NetworkBackend {
|
||||
fn drop(&mut self) {
|
||||
info!(
|
||||
"destroyed network backend for hypha guest {}",
|
||||
"destroyed network backend for krata guest {}",
|
||||
self.metadata.uuid
|
||||
);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use bytes::BytesMut;
|
||||
// Referenced https://github.com/vi/wgslirpy/blob/master/crates/libwgslirpy/src/channelized_smoltcp_device.rs
|
||||
use bytes::BytesMut;
|
||||
use log::{debug, warn};
|
||||
use smoltcp::phy::{Checksum, Device, Medium};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{collections::HashMap, time::Duration};
|
||||
use std::{collections::HashMap, thread, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
use autonet::{AutoNetworkChangeset, AutoNetworkCollector, NetworkMetadata};
|
||||
@ -64,6 +64,7 @@ impl NetworkService {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
let (launched, failed) = futures::executor::block_on(async move {
|
||||
let mut failed: Vec<Uuid> = Vec::new();
|
||||
let mut launched: Vec<(Uuid, JoinHandle<()>)> = Vec::new();
|
||||
@ -76,7 +77,7 @@ impl NetworkService {
|
||||
|
||||
Err((metadata, error)) => {
|
||||
warn!(
|
||||
"failed to launch network backend for hypha guest {}: {}",
|
||||
"failed to launch network backend for krata guest {}: {}",
|
||||
metadata.uuid, error
|
||||
);
|
||||
failed.push(metadata.uuid);
|
||||
|
@ -34,7 +34,7 @@ use super::key::NatKeyProtocol;
|
||||
use super::table::NatTable;
|
||||
|
||||
const RECLAIM_CHANNEL_QUEUE_LEN: usize = 10;
|
||||
const RECEIVE_CHANNEL_QUEUE_LEN: usize = 30;
|
||||
const RECEIVE_CHANNEL_QUEUE_LEN: usize = 1000;
|
||||
|
||||
pub struct NatProcessor {
|
||||
mtu: usize,
|
||||
|
@ -17,7 +17,7 @@ mod icmp;
|
||||
mod tcp;
|
||||
mod udp;
|
||||
|
||||
const RX_CHANNEL_BOUND: usize = 300;
|
||||
const RX_CHANNEL_QUEUE_LEN: usize = 1000;
|
||||
|
||||
pub struct ProxyNatHandlerFactory {}
|
||||
|
||||
@ -38,7 +38,7 @@ impl NatHandlerFactory for ProxyNatHandlerFactory {
|
||||
async fn nat(&self, context: NatHandlerContext) -> Option<Box<dyn NatHandler>> {
|
||||
match context.key.protocol {
|
||||
NatKeyProtocol::Udp => {
|
||||
let (rx_sender, rx_receiver) = channel::<BytesMut>(RX_CHANNEL_BOUND);
|
||||
let (rx_sender, rx_receiver) = channel::<BytesMut>(RX_CHANNEL_QUEUE_LEN);
|
||||
let mut handler = ProxyUdpHandler::new(rx_sender);
|
||||
|
||||
if let Err(error) = handler.spawn(context, rx_receiver).await {
|
||||
@ -50,7 +50,7 @@ impl NatHandlerFactory for ProxyNatHandlerFactory {
|
||||
}
|
||||
|
||||
NatKeyProtocol::Icmp => {
|
||||
let (rx_sender, rx_receiver) = channel::<BytesMut>(RX_CHANNEL_BOUND);
|
||||
let (rx_sender, rx_receiver) = channel::<BytesMut>(RX_CHANNEL_QUEUE_LEN);
|
||||
let mut handler = ProxyIcmpHandler::new(rx_sender);
|
||||
|
||||
if let Err(error) = handler.spawn(context, rx_receiver).await {
|
||||
@ -62,7 +62,7 @@ impl NatHandlerFactory for ProxyNatHandlerFactory {
|
||||
}
|
||||
|
||||
NatKeyProtocol::Tcp => {
|
||||
let (rx_sender, rx_receiver) = channel::<BytesMut>(RX_CHANNEL_BOUND);
|
||||
let (rx_sender, rx_receiver) = channel::<BytesMut>(RX_CHANNEL_QUEUE_LEN);
|
||||
let mut handler = ProxyTcpHandler::new(rx_sender);
|
||||
|
||||
if let Err(error) = handler.spawn(context, rx_receiver).await {
|
||||
|
@ -32,7 +32,7 @@ const TCP_BUFFER_SIZE: usize = 65535;
|
||||
const TCP_ACCEPT_TIMEOUT_SECS: u64 = 120;
|
||||
const TCP_DANGLE_TIMEOUT_SECS: u64 = 10;
|
||||
|
||||
const TCP_IP_BUFFER_LEN: usize = 300;
|
||||
const TCP_IP_BUFFER_LEN: usize = 1000;
|
||||
|
||||
pub struct ProxyTcpHandler {
|
||||
rx_sender: Sender<BytesMut>,
|
||||
|
@ -11,8 +11,8 @@ use tokio::select;
|
||||
use tokio::sync::mpsc::{channel, Receiver, Sender};
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
const RAW_SOCKET_TRANSMIT_QUEUE_LEN: usize = 500;
|
||||
const RAW_SOCKET_RECEIVE_QUEUE_LEN: usize = 500;
|
||||
const RAW_SOCKET_TRANSMIT_QUEUE_LEN: usize = 1000;
|
||||
const RAW_SOCKET_RECEIVE_QUEUE_LEN: usize = 1000;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RawSocketProtocol {
|
||||
|
@ -19,9 +19,9 @@ use tokio::{
|
||||
task::JoinHandle,
|
||||
};
|
||||
|
||||
const TO_BRIDGE_QUEUE_LEN: usize = 50;
|
||||
const FROM_BRIDGE_QUEUE_LEN: usize = 50;
|
||||
const BROADCAST_QUEUE_LEN: usize = 50;
|
||||
const TO_BRIDGE_QUEUE_LEN: usize = 1000;
|
||||
const FROM_BRIDGE_QUEUE_LEN: usize = 1000;
|
||||
const BROADCAST_QUEUE_LEN: usize = 1000;
|
||||
const MEMBER_LEAVE_QUEUE_LEN: usize = 10;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,13 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ -z "${RUST_LOG}" ]
|
||||
then
|
||||
RUST_LOG="INFO"
|
||||
fi
|
||||
|
||||
cd "$(dirname "${0}")/.."
|
||||
./initrd/build.sh
|
||||
sudo cp "target/initrd/initrd" "/var/lib/hypha/default/initrd"
|
||||
cargo build --target x86_64-unknown-linux-gnu --bin hyphactl
|
||||
exec sudo RUST_LOG="${RUST_LOG}" target/x86_64-unknown-linux-gnu/debug/hyphactl "${@}"
|
@ -1,11 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ -z "${RUST_LOG}" ]
|
||||
then
|
||||
RUST_LOG="INFO"
|
||||
fi
|
||||
|
||||
cd "$(dirname "${0}")/.."
|
||||
cargo build --target x86_64-unknown-linux-gnu --bin hyphanet
|
||||
exec sudo RUST_LOG="${RUST_LOG}" target/x86_64-unknown-linux-gnu/debug/hyphanet "${@}"
|
14
scripts/kratactl-debug.sh
Executable file
14
scripts/kratactl-debug.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ -z "${RUST_LOG}" ]
|
||||
then
|
||||
RUST_LOG="INFO"
|
||||
fi
|
||||
|
||||
REAL_SCRIPT="$(realpath "${0}")"
|
||||
cd "$(dirname "${REAL_SCRIPT}")/.."
|
||||
./initrd/build.sh -q
|
||||
sudo cp "target/initrd/initrd" "/var/lib/krata/default/initrd"
|
||||
cargo build -q --target x86_64-unknown-linux-gnu --bin kratactl
|
||||
exec sudo RUST_LOG="${RUST_LOG}" target/x86_64-unknown-linux-gnu/debug/kratactl "${@}"
|
12
scripts/kratanet-debug.sh
Executable file
12
scripts/kratanet-debug.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ -z "${RUST_LOG}" ]
|
||||
then
|
||||
RUST_LOG="INFO"
|
||||
fi
|
||||
|
||||
REAL_SCRIPT="$(realpath "${0}")"
|
||||
cd "$(dirname "${REAL_SCRIPT}")/.."
|
||||
cargo build -q --target x86_64-unknown-linux-gnu --bin kratanet
|
||||
exec sudo RUST_LOG="${RUST_LOG}" target/x86_64-unknown-linux-gnu/debug/kratanet "${@}"
|
@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "hypha"
|
||||
name = "krata"
|
||||
version.workspace = true
|
||||
edition = "2021"
|
||||
resolver = "2"
|
||||
|
Loading…
Reference in New Issue
Block a user