diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index c32d9d1..b1fc2ec 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: ./scripts/ci/install-deps.sh - - run: ./scripts/cargo.sh build + - run: ./scripts/build/cargo.sh build test: name: cargo test runs-on: ubuntu-latest @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - run: ./scripts/ci/install-deps.sh - - run: ./scripts/cargo.sh test + - run: ./scripts/build/cargo.sh test clippy: name: cargo clippy runs-on: ubuntu-latest @@ -26,7 +26,7 @@ jobs: with: components: clippy - run: ./scripts/ci/install-deps.sh - - run: ./scripts/cargo.sh clippy + - run: ./scripts/build/cargo.sh clippy fmt: name: cargo fmt runs-on: ubuntu-latest @@ -36,7 +36,7 @@ jobs: with: components: rustfmt - run: ./scripts/ci/install-deps.sh - - run: ./scripts/cargo.sh fmt --all -- --check + - run: ./scripts/build/cargo.sh fmt --all -- --check initrd: name: initrd runs-on: ubuntu-latest @@ -46,4 +46,4 @@ jobs: with: targets: "x86_64-unknown-linux-gnu,x86_64-unknown-linux-musl" - run: ./scripts/ci/install-deps.sh - - run: ./initrd/build.sh + - run: ./scripts/initrd/build.sh diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml index 2534ce5..35b31df 100644 --- a/.github/workflows/kernel.yml +++ b/.github/workflows/kernel.yml @@ -13,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 - run: ./scripts/ci/install-deps.sh - - run: ./kernel/build.sh + - run: ./scripts/kernel/build.sh -j5 diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c9f5df1..4a78955 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -2,7 +2,7 @@ name: nightly on: workflow_dispatch: schedule: - - cron: "0 6 * * *" + - cron: "0 10 * * *" jobs: build: name: build @@ -13,9 +13,20 @@ jobs: with: targets: "x86_64-unknown-linux-gnu,x86_64-unknown-linux-musl" - run: ./scripts/ci/install-deps.sh - - run: ./scripts/bundle.sh + - run: ./scripts/dist/bundle.sh + env: + KRATA_KERNEL_BUILD_JOBS: "5" + - run: ./scripts/dist/deb.sh + env: + KRATA_BUNDLE_SKIP_KERNEL_BUILD: "1" - uses: actions/upload-artifact@v4 with: - name: krata-nightly-x86_64 - path: target/bundle/krata.tgz + name: krata-nightly-bundle-x86_64 + path: "target/dist/bundle.tgz" compression-level: 0 + - uses: actions/upload-artifact@v4 + with: + name: krata-nightly-debian-x86_64 + path: "target/dist/*_amd64.deb" + compression-level: 0 + \ No newline at end of file diff --git a/README.md b/README.md index bd28297..6c9dcec 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ # krata -An early version of the Edera hypervisor. Not for production use. +An early version of the Edera hypervisor. -[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. +[Join our community Discord](https://discord.gg/Sy7KrSd2qf), 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 krata? -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. +The krata hypervisor 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, 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. -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. +krata is in its early days and this project is still a work in progress. ## FAQs @@ -30,7 +30,7 @@ As such, no external contributions are accepted at this time. ### Are external contributions accepted? -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. +Currently no external contributions are accepted. krata is in its 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? @@ -44,9 +44,9 @@ krata is composed of three major executables: | Executable | Runs On | User Interaction | Dev Runner | Code Path | | ---------- | ------- | ---------------- | --------------------------- | ----------- | -| kratad | host | backend daemon | ./scripts/kratad-debug.sh | daemon | -| kratanet | host | backend daemon | ./scripts/kratanet-debug.sh | network | -| kratactl | host | CLI tool | ./scripts/kratactl-debug.sh | controller | +| kratad | host | backend daemon | ./scripts/debug/kratad.sh | daemon | +| kratanet | host | backend daemon | ./scripts/debug/kratanet.sh | network | +| kratactl | host | CLI tool | ./scripts/debug/kratactl.sh | controller | | krataguest | guest | none, guest init | N/A | guest | You will find the code to each executable available in the bin/ and src/ directories inside @@ -92,26 +92,26 @@ $ cd krata 6. Build a guest kernel image: ```sh -$ ./kernel/build.sh -j4 +$ ./scripts/kernel/build.sh -j4 ``` -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. Launch `./scripts/kratad-debug.sh` and keep it running in the foreground. +7. Copy the guest kernel image at `target/kernel/kernel` to `/var/lib/krata/guest/kernel` to have it automatically detected by kratad. +8. Launch `./scripts/debug/kratanet.sh` and keep it running in the foreground. +9. Launch `./scripts/debug/kratad.sh` and keep it running in the foreground. 10. Run kratactl to launch a guest: ```sh -$ ./scripts/kratactl-debug.sh launch --attach alpine:latest +$ ./scripts/debug/kratactl.sh launch --attach alpine:latest ``` To detach from the guest console, use `Ctrl + ]` on your keyboard. To list the running guests, run: ```sh -$ ./scripts/kratactl-debug.sh list +$ ./scripts/debug/kratactl.sh list ``` To destroy a running guest, copy it's UUID from either the launch command or the guest list and run: ```sh -$ ./scripts/kratactl-debug.sh destroy GUEST_UUID +$ ./scripts/debug/kratactl.sh destroy GUEST_UUID ``` diff --git a/daemon/src/runtime/mod.rs b/daemon/src/runtime/mod.rs index d10b876..80ff13c 100644 --- a/daemon/src/runtime/mod.rs +++ b/daemon/src/runtime/mod.rs @@ -1,4 +1,9 @@ -use std::{fs, path::PathBuf, str::FromStr, sync::Arc}; +use std::{ + fs, + path::{Path, PathBuf}, + str::FromStr, + sync::Arc, +}; use anyhow::{anyhow, Result}; use ipnetwork::IpNetwork; @@ -59,8 +64,9 @@ impl RuntimeContext { image_cache_path.push("image"); fs::create_dir_all(&image_cache_path)?; let image_cache = ImageCache::new(&image_cache_path)?; - let kernel = format!("{}/default/kernel", store); - let initrd = format!("{}/default/initrd", store); + let kernel = RuntimeContext::detect_guest_file(&store, "kernel")?; + let initrd = RuntimeContext::detect_guest_file(&store, "initrd")?; + Ok(RuntimeContext { image_cache, autoloop: AutoLoop::new(LoopControl::open()?), @@ -70,6 +76,15 @@ impl RuntimeContext { }) } + fn detect_guest_file(store: &str, name: &str) -> Result { + let path = PathBuf::from(format!("{}/{}", store, name)); + if path.is_file() { + return path_as_string(&path); + } + + Ok(format!("/usr/share/krata/guest/{}", name)) + } + pub async fn list(&mut self) -> Result> { let mut guests: Vec = Vec::new(); for domid_candidate in self.xen.store.list("/local/domain").await? { @@ -270,3 +285,9 @@ impl Runtime { Runtime::new((*self.store).clone()).await } } + +fn path_as_string(path: &Path) -> Result { + path.to_str() + .ok_or_else(|| anyhow!("unable to convert path to string")) + .map(|x| x.to_string()) +} diff --git a/kernel/.gitignore b/kernel/.gitignore index d892c06..4c0b24c 100644 --- a/kernel/.gitignore +++ b/kernel/.gitignore @@ -1,2 +1 @@ -linux-* -target/ +/linux-* diff --git a/kernel/build.sh b/kernel/build.sh deleted file mode 100755 index 3290c2c..0000000 --- a/kernel/build.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -set -e - -cd "$(dirname "${0}")" - -# shellcheck source=config.sh -. "${PWD}/config.sh" - -if [ ! -f "${SRC_DIR_NAME}/Makefile" ] -then - rm -rf "${SRC_DIR_NAME}" - curl -L -o "${SRC_DIR_NAME}.txz" "${KERNEL_SRC_URL}" - tar xf "${SRC_DIR_NAME}.txz" - rm "${SRC_DIR_NAME}.txz" -fi - -mkdir -p "${OUTPUT_DIR_NAME}" - -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" diff --git a/kernel/config.sh b/kernel/config.sh index b818e63..a4b064a 100644 --- a/kernel/config.sh +++ b/kernel/config.sh @@ -1,5 +1,3 @@ #!/bin/sh KERNEL_VERSION="6.7.8" KERNEL_SRC_URL="https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz" -SRC_DIR_NAME="linux-${KERNEL_VERSION}" -OUTPUT_DIR_NAME="target" diff --git a/kernel/krata.config b/kernel/krata-x86_64.config similarity index 100% rename from kernel/krata.config rename to kernel/krata-x86_64.config diff --git a/lefthook.toml b/lefthook.toml index a6d63c6..be06003 100644 --- a/lefthook.toml +++ b/lefthook.toml @@ -2,13 +2,13 @@ parallel = true [pre-commit.commands.build] -run = "./scripts/cargo.sh build" +run = "./scripts/build/cargo.sh build" [pre-commit.commands.test] -run = "./scripts/cargo.sh test" +run = "./scripts/build/cargo.sh test" [pre-commit.commands.fmt] -run = "./scripts/cargo.sh fmt --all -- --check" +run = "./scripts/build/cargo.sh fmt --all -- --check" [pre-commit.commands.clippy] -run = "./scripts/cargo.sh clippy" +run = "./scripts/build/cargo.sh clippy" diff --git a/resources/bundle/install.sh b/resources/bundle/install.sh new file mode 100755 index 0000000..82ab839 --- /dev/null +++ b/resources/bundle/install.sh @@ -0,0 +1,39 @@ +#!/bin/sh +set -e + +remove_service_if_exists() { + if systemctl show -P FragmentPath "${1}" > /dev/null + then + UNIT_PATH="$(systemctl show -P FragmentPath "${1}")" + if [ -f "${UNIT_PATH}" ] + then + echo "[WARN] disabling removing systemd unit ${UNIT_PATH}" > /dev/stderr + systemctl disable --now "${1}" || true + rm "${UNIT_PATH}" + fi + fi +} + +REAL_SCRIPT="$(realpath "${0}")" +cd "$(dirname "${REAL_SCRIPT}")" + +remove_service_if_exists kratad.service +remove_service_if_exists kratanet.service + +cp kratad.service /usr/lib/systemd/system/kratad.service +cp kratanet.service /usr/lib/systemd/system/kratanet.service + +cp kratad kratanet /usr/libexec +cp kratactl /usr/bin + +chmod +x /usr/libexec/kratad +chmod +x /usr/libexec/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 + +systemctl daemon-reload +systemctl enable kratad.service kratanet.service +systemctl restart kratad.service kratanet.service diff --git a/resources/bundle/uninstall.sh b/resources/bundle/uninstall.sh new file mode 100755 index 0000000..927677e --- /dev/null +++ b/resources/bundle/uninstall.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +systemctl disable --now kratad.service || true +systemctl disable --now kratanet.service || true + +rm -f /usr/lib/systemd/system/kratad.service +rm -f /usr/lib/systemd/system/kratanet.service + +rm -f /usr/bin/kratactl +rm -f /usr/libexec/kratad /usr/libexec/kratanet +rm -rf /usr/share/krata diff --git a/resources/install/install.sh b/resources/install/install.sh deleted file mode 100755 index 6a5fdb3..0000000 --- a/resources/install/install.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -set -e - -REAL_SCRIPT="$(realpath "${0}")" -cd "$(dirname "${REAL_SCRIPT}")" - -if [ -f "/etc/systemd/system/kratad.service" ] -then - systemctl disable --now kratad.service -fi - -if [ -f "/etc/systemd/system/kratanet.service" ] -then - systemctl disable --now kratanet.service -fi - -cp kratad.service /etc/systemd/system/kratad.service -cp kratanet.service /etc/systemd/system/kratanet.service - -cp kratad kratanet kratactl /usr/local/bin - -chmod +x /usr/local/bin/kratad -chmod +x /usr/local/bin/kratanet -chmod +x /usr/local/bin/kratactl - -mkdir -p /var/lib/krata/default -cp kernel /var/lib/krata/default/kernel -cp initrd /var/lib/krata/default/initrd - -systemctl daemon-reload -systemctl enable kratad.service kratanet.service -systemctl restart kratad.service kratanet.service diff --git a/resources/systemd/kratad.service b/resources/systemd/kratad.service index 84053e6..ce603db 100644 --- a/resources/systemd/kratad.service +++ b/resources/systemd/kratad.service @@ -1,11 +1,11 @@ [Unit] -Description=Krata Controller Daemon +Description=Krata Control Daemon [Service] Restart=on-failure Type=simple -WorkingDirectory=/var/lib/krata -ExecStart=/usr/local/bin/kratad -l unix:///var/lib/krata/daemon.socket +ExecStartPre=/bin/mkdir -p /var/lib/krata +ExecStart=/usr/libexec/kratad -l unix:///var/lib/krata/daemon.socket Environment=RUST_LOG=info User=root diff --git a/resources/systemd/kratanet.service b/resources/systemd/kratanet.service index 2ee22c9..084cb40 100644 --- a/resources/systemd/kratanet.service +++ b/resources/systemd/kratanet.service @@ -4,8 +4,7 @@ Description=Krata Networking Daemon [Service] Restart=on-failure Type=simple -WorkingDirectory=/var/lib/krata -ExecStart=/usr/local/bin/kratanet +ExecStart=/usr/libexec/kratanet Environment=RUST_LOG=info User=root diff --git a/scripts/build/arch.sh b/scripts/build/arch.sh new file mode 100755 index 0000000..562694f --- /dev/null +++ b/scripts/build/arch.sh @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +TOOLS_DIR="$(dirname "${0}")" + +RUST_TARGET="$("${TOOLS_DIR}/target.sh")" +TARGET_ARCH="$(echo "${RUST_TARGET}" | awk -F '-' '{print $1}')" + +if [ "${KRATA_ARCH_ALT_NAME}" = "1" ] || [ "${KRATA_ARCH_KERNEL_NAME}" = "1" ] +then + if [ "${TARGET_ARCH}" = "x86_64" ] && [ "${KRATA_ARCH_KERNEL_NAME}" != "1" ] + then + TARGET_ARCH="amd64" + fi + + if [ "${TARGET_ARCH}" = "aarch64" ] + then + TARGET_ARCH="arm64" + fi +fi + +echo "${TARGET_ARCH}" diff --git a/scripts/build/cargo.sh b/scripts/build/cargo.sh new file mode 100755 index 0000000..2e4d6ae --- /dev/null +++ b/scripts/build/cargo.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +TOOLS_DIR="$(dirname "${0}")" +RUST_TARGET="$("${TOOLS_DIR}/target.sh")" + +export CARGO_BUILD_TARGET="${RUST_TARGET}" +exec cargo "${@}" diff --git a/scripts/detect-rust-target.sh b/scripts/build/target.sh similarity index 100% rename from scripts/detect-rust-target.sh rename to scripts/build/target.sh diff --git a/scripts/bundle.sh b/scripts/bundle.sh deleted file mode 100755 index ea05343..0000000 --- a/scripts/bundle.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh -set -e - -REAL_SCRIPT="$(realpath "${0}")" -cd "$(dirname "${REAL_SCRIPT}")/.." -KRATA_DIR="${PWD}" - -OUTPUT_DIR="${KRATA_DIR}/target/bundle" -mkdir -p "${OUTPUT_DIR}" -BUNDLE_TAR="${OUTPUT_DIR}/krata.tgz" -rm -f "${BUNDLE_TAR}" -BUNDLE_DIR="$(mktemp -d /tmp/krata-bundle.XXXXXXXXXXXXX)" -BUNDLE_DIR="${BUNDLE_DIR}/krata" -mkdir -p "${BUNDLE_DIR}" -for X in kratad kratanet kratactl -do - ./scripts/cargo.sh build --release --bin "${X}" - RUST_TARGET="$(./scripts/detect-rust-target.sh)" - cp "${KRATA_DIR}/target/${RUST_TARGET}/release/${X}" "${BUNDLE_DIR}/${X}" -done -./initrd/build.sh -if [ "${KRATA_BUNDLE_SKIP_KERNEL_BUILD}" != "1" ] -then - ./kernel/build.sh -fi -cd "${BUNDLE_DIR}" -cp "${KRATA_DIR}/initrd/target/initrd" initrd -cp "${KRATA_DIR}/kernel/target/kernel" kernel -cp "${KRATA_DIR}/resources/systemd/kratad.service" kratad.service -cp "${KRATA_DIR}/resources/systemd/kratanet.service" kratanet.service -cp "${KRATA_DIR}/resources/install/install.sh" install.sh - -for X in install.sh kratactl kratad kratanet -do - chmod +x "${X}" -done - -cd .. -tar czf "${BUNDLE_TAR}" . -cd "${KRATA_DIR}" -rm -rf "$(dirname "${BUNDLE_DIR}")" diff --git a/scripts/cargo.sh b/scripts/cargo.sh deleted file mode 100755 index 86a2c71..0000000 --- a/scripts/cargo.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -set -e - -SCRIPTS_DIR="$(dirname "${0}")" -RUST_TARGET="$("${SCRIPTS_DIR}/detect-rust-target.sh")" - -export CARGO_BUILD_TARGET="${RUST_TARGET}" -exec cargo "${@}" diff --git a/scripts/ci/install-deps.sh b/scripts/ci/install-deps.sh index c967e17..669d633 100755 --- a/scripts/ci/install-deps.sh +++ b/scripts/ci/install-deps.sh @@ -5,3 +5,4 @@ sudo apt-get update sudo apt-get install -y \ build-essential libssl-dev libelf-dev musl-dev \ flex bison bc protobuf-compiler musl-tools +sudo gem install --no-document fpm diff --git a/scripts/code/fix.sh b/scripts/code/fix.sh new file mode 100755 index 0000000..13623f9 --- /dev/null +++ b/scripts/code/fix.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -e + +cd "$(dirname "${0}")/../.." +./scripts/build/cargo.sh clippy --fix --allow-dirty --allow-staged +cargo fmt --all diff --git a/scripts/krata-debug-common.sh b/scripts/debug/common.sh similarity index 56% rename from scripts/krata-debug-common.sh rename to scripts/debug/common.sh index ea56ff6..8342db8 100644 --- a/scripts/krata-debug-common.sh +++ b/scripts/debug/common.sh @@ -2,7 +2,7 @@ set -e REAL_SCRIPT="$(realpath "${0}")" -cd "$(dirname "${REAL_SCRIPT}")/.." +cd "$(dirname "${REAL_SCRIPT}")/../.." if [ -z "${RUST_LOG}" ] then @@ -19,12 +19,13 @@ fi build_and_run() { EXE_TARGET="${1}" shift + sudo mkdir -p /var/lib/krata/guest if [ "${KRATA_BUILD_INITRD}" = "1" ] then - ./initrd/build.sh -q - sudo cp "initrd/target/initrd" "/var/lib/krata/default/initrd" + ./scripts/initrd/build.sh -q + sudo cp "target/initrd/initrd" "/var/lib/krata/guest/initrd" fi - RUST_TARGET="$(./scripts/detect-rust-target.sh)" - ./scripts/cargo.sh build ${CARGO_BUILD_FLAGS} --bin "${EXE_TARGET}" + RUST_TARGET="$(./scripts/build/target.sh)" + ./scripts/build/cargo.sh build ${CARGO_BUILD_FLAGS} --bin "${EXE_TARGET}" exec sudo RUST_LOG="${RUST_LOG}" "target/${RUST_TARGET}/debug/${EXE_TARGET}" "${@}" } diff --git a/scripts/debug/kratactl.sh b/scripts/debug/kratactl.sh new file mode 100755 index 0000000..9a6c615 --- /dev/null +++ b/scripts/debug/kratactl.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +REAL_SCRIPT="$(realpath "${0}")" +DEBUG_DIR="$(dirname "${REAL_SCRIPT}")" +# shellcheck source=common.sh +. "${DEBUG_DIR}/common.sh" + +build_and_run kratactl "${@}" diff --git a/scripts/kratad-debug.sh b/scripts/debug/kratad.sh similarity index 50% rename from scripts/kratad-debug.sh rename to scripts/debug/kratad.sh index 13ede39..0007880 100755 --- a/scripts/kratad-debug.sh +++ b/scripts/debug/kratad.sh @@ -2,7 +2,8 @@ set -e REAL_SCRIPT="$(realpath "${0}")" -# shellcheck source-path=krata-debug-common.sh -. "$(dirname "${REAL_SCRIPT}")/krata-debug-common.sh" +DEBUG_DIR="$(dirname "${REAL_SCRIPT}")" +# shellcheck source=common.sh +. "${DEBUG_DIR}/common.sh" KRATA_BUILD_INITRD=1 build_and_run kratad "${@}" diff --git a/scripts/debug/kratanet.sh b/scripts/debug/kratanet.sh new file mode 100755 index 0000000..0b2fc6d --- /dev/null +++ b/scripts/debug/kratanet.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -e + +REAL_SCRIPT="$(realpath "${0}")" +DEBUG_DIR="$(dirname "${REAL_SCRIPT}")" +# shellcheck source=common.sh +. "${DEBUG_DIR}/common.sh" + +build_and_run kratanet "${@}" diff --git a/scripts/debug/session.sh b/scripts/debug/session.sh new file mode 100755 index 0000000..4eb2be4 --- /dev/null +++ b/scripts/debug/session.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -e + +stop_service_if_running() { + if sudo systemctl is-active "${1}" > /dev/null 2>&1 + then + sudo systemctl stop "${1}" + fi + +} + +stop_service_if_running "kratad.service" +stop_service_if_running "kratanet.service" +tmuxp load "$(dirname "${0}")/session.yml" diff --git a/scripts/debug/session.yml b/scripts/debug/session.yml new file mode 100644 index 0000000..ccd3af4 --- /dev/null +++ b/scripts/debug/session.yml @@ -0,0 +1,11 @@ +session_name: krata-dev +start_directory: ../.. +sleep_after: 3 +windows: +- window_name: live + layout: tiled + panes: + - shell_command: ./scripts/debug/kratad.sh + - shell_command: ./scripts/debug/kratanet.sh + - focus: true + shell_command: "alias kratactl=./scripts/debug/kratactl.sh" diff --git a/scripts/dist/bundle.sh b/scripts/dist/bundle.sh new file mode 100755 index 0000000..b55d9b9 --- /dev/null +++ b/scripts/dist/bundle.sh @@ -0,0 +1,46 @@ +#!/bin/sh +set -e + +# shellcheck source=common.sh +. "$(dirname "${0}")/common.sh" + +if [ -z "${KRATA_KERNEL_BUILD_JOBS}" ] +then + KRATA_KERNEL_BUILD_JOBS="2" +fi + +BUNDLE_TAR="${OUTPUT_DIR}/bundle.tgz" +rm -f "${BUNDLE_TAR}" +BUNDLE_DIR="$(mktemp -d /tmp/krata-bundle.XXXXXXXXXXXXX)" +BUNDLE_DIR="${BUNDLE_DIR}/krata" +mkdir -p "${BUNDLE_DIR}" +for X in kratad kratanet kratactl +do + ./scripts/build/cargo.sh build --release --bin "${X}" + RUST_TARGET="$(./scripts/build/target.sh)" + cp "${KRATA_DIR}/target/${RUST_TARGET}/release/${X}" "${BUNDLE_DIR}/${X}" +done +./scripts/initrd/build.sh +if [ "${KRATA_BUNDLE_SKIP_KERNEL_BUILD}" != "1" ] +then + ./scripts/kernel/build.sh "-j${KRATA_KERNEL_BUILD_JOBS}" +fi + +cd "${BUNDLE_DIR}" + +cp "${KRATA_DIR}/target/initrd/initrd" initrd +cp "${KRATA_DIR}/target/kernel/kernel" kernel +cp "${KRATA_DIR}/resources/systemd/kratad.service" kratad.service +cp "${KRATA_DIR}/resources/systemd/kratanet.service" kratanet.service +cp "${KRATA_DIR}/resources/bundle/install.sh" install.sh +cp "${KRATA_DIR}/resources/bundle/uninstall.sh" uninstall.sh + +for X in install.sh uninstall.sh kratactl kratad kratanet +do + chmod +x "${X}" +done + +cd .. +tar czf "${BUNDLE_TAR}" . +cd "${KRATA_DIR}" +rm -rf "$(dirname "${BUNDLE_DIR}")" diff --git a/scripts/dist/common.sh b/scripts/dist/common.sh new file mode 100644 index 0000000..6a3ce55 --- /dev/null +++ b/scripts/dist/common.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +REAL_SCRIPT="$(realpath "${0}")" +cd "$(dirname "${REAL_SCRIPT}")/../.." +KRATA_DIR="${PWD}" +OUTPUT_DIR="${KRATA_DIR}/target/dist" +mkdir -p "${OUTPUT_DIR}" diff --git a/scripts/dist/deb.sh b/scripts/dist/deb.sh new file mode 100755 index 0000000..f0892d9 --- /dev/null +++ b/scripts/dist/deb.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -e + +# shellcheck source=common.sh +. "$(dirname "${0}")/common.sh" + +"${KRATA_DIR}/scripts/dist/systar.sh" + +KRATA_VERSION="$("${KRATA_DIR}/scripts/dist/version.sh")" +TARGET_ARCH="$(KRATA_ARCH_ALT_NAME=1 "${KRATA_DIR}/scripts/build/arch.sh")" + +cd "${OUTPUT_DIR}" + +rm -f "krata_${KRATA_VERSION}_${TARGET_ARCH}.deb" + +fpm -s tar -t deb \ + --name krata \ + --license agpl3 \ + --version "${KRATA_VERSION}" \ + --architecture "${TARGET_ARCH}" \ + --depends "xen-system-${TARGET_ARCH}" \ + --description "Krata Hypervisor" \ + --url "https://krata.dev" \ + --maintainer "Edera Team " \ + -x "usr/lib/**" \ + --deb-systemd "${KRATA_DIR}/resources/systemd/kratad.service" \ + --deb-systemd "${KRATA_DIR}/resources/systemd/kratanet.service" \ + --deb-systemd-enable \ + --deb-systemd-auto-start \ + "${OUTPUT_DIR}/system.tgz" diff --git a/scripts/dist/systar.sh b/scripts/dist/systar.sh new file mode 100755 index 0000000..d1be503 --- /dev/null +++ b/scripts/dist/systar.sh @@ -0,0 +1,31 @@ +#!/bin/sh +set -e + +# shellcheck source=common.sh +. "$(dirname "${0}")/common.sh" + +"${KRATA_DIR}/scripts/dist/bundle.sh" + +SYSTAR="${OUTPUT_DIR}/system.tgz" +rm -f "${SYSTAR}" +SYSTAR_DIR="$(mktemp -d /tmp/krata-systar.XXXXXXXXXXXXX)" +cd "${SYSTAR_DIR}" +tar xf "${OUTPUT_DIR}/bundle.tgz" + +mkdir sys +cd sys + +mkdir -p usr/bin usr/libexec +mv ../krata/kratactl usr/bin +mv ../krata/kratanet ../krata/kratad usr/libexec/ + +mkdir -p usr/lib/systemd/system +mv ../krata/kratad.service ../krata/kratanet.service usr/lib/systemd/system/ + +mkdir -p usr/share/krata/guest +mv ../krata/kernel ../krata/initrd usr/share/krata/guest + +tar czf "${SYSTAR}" --owner 0 --group 0 . + +cd "${KRATA_DIR}" +rm -rf "${SYSTAR_DIR}" diff --git a/scripts/dist/version.sh b/scripts/dist/version.sh new file mode 100755 index 0000000..6107ae8 --- /dev/null +++ b/scripts/dist/version.sh @@ -0,0 +1,15 @@ +#!/bin/sh +set -e + +# shellcheck source=common.sh +. "$(dirname "${0}")/common.sh" +cd "${KRATA_DIR}" + +KRATA_VERSION="$(grep -A1 -F '[workspace.package]' Cargo.toml | grep 'version' | awk '{print $3}' | sed 's/"//g')" +if [ -z "${KRATA_VERSION}" ] +then + echo "ERROR: failed to determine krata version" > /dev/stderr + exit 1 +fi + +echo "${KRATA_VERSION}" diff --git a/scripts/fix.sh b/scripts/fix.sh deleted file mode 100755 index ed6958a..0000000 --- a/scripts/fix.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -set -e - -cd "$(dirname "${0}")/.." -./scripts/cargo.sh clippy --fix --allow-dirty --allow-staged -cargo fmt --all diff --git a/initrd/build.sh b/scripts/initrd/build.sh similarity index 58% rename from initrd/build.sh rename to scripts/initrd/build.sh index 435dbf5..6e616b7 100755 --- a/initrd/build.sh +++ b/scripts/initrd/build.sh @@ -1,17 +1,20 @@ #!/usr/bin/env bash set -e -export RUST_LIBC="musl" -RUST_TARGET="$(./scripts/detect-rust-target.sh)" - -export RUSTFLAGS="-Ctarget-feature=+crt-static" -cd "$(dirname "${0}")/.." +REAL_SCRIPT="$(realpath "${0}")" +cd "$(dirname "${REAL_SCRIPT}")/../.." KRATA_DIR="${PWD}" -./scripts/cargo.sh build -q --release --bin krataguest +cd "${KRATA_DIR}" + +export RUST_LIBC="musl" +RUST_TARGET="$(./scripts/build/target.sh)" +export RUSTFLAGS="-Ctarget-feature=+crt-static" + +./scripts/build/cargo.sh build "${@}" --release --bin krataguest INITRD_DIR="$(mktemp -d /tmp/krata-initrd.XXXXXXXXXXXXX)" cp "target/${RUST_TARGET}/release/krataguest" "${INITRD_DIR}/init" chmod +x "${INITRD_DIR}/init" cd "${INITRD_DIR}" -mkdir -p "${KRATA_DIR}/initrd/target" -find . | cpio -R 0:0 --reproducible -o -H newc --quiet > "${KRATA_DIR}/initrd/target/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}" diff --git a/scripts/kernel/build.sh b/scripts/kernel/build.sh new file mode 100755 index 0000000..76b556b --- /dev/null +++ b/scripts/kernel/build.sh @@ -0,0 +1,56 @@ +#!/bin/sh +set -e + +REAL_SCRIPT="$(realpath "${0}")" +cd "$(dirname "${REAL_SCRIPT}")/../.." +KRATA_DIR="${PWD}" +KERNEL_DIR="${KRATA_DIR}/kernel" + +cd "${KRATA_DIR}" + +# shellcheck source=../../kernel/config.sh +. "${KERNEL_DIR}/config.sh" +KERNEL_SRC="${KERNEL_DIR}/linux-${KERNEL_VERSION}" + +if [ ! -f "${KERNEL_SRC}/Makefile" ] +then + rm -rf "${KERNEL_SRC}" + curl --progress-bar -L -o "${KERNEL_SRC}.txz" "${KERNEL_SRC_URL}" + tar xf "${KERNEL_SRC}.txz" -C "${KERNEL_DIR}" + rm "${KERNEL_SRC}.txz" +fi + +OUTPUT_DIR="${KRATA_DIR}/target/kernel" +mkdir -p "${OUTPUT_DIR}" + +TARGET_ARCH="$(KRATA_ARCH_KERNEL_NAME=1 ./scripts/build/arch.sh)" + +KERNEL_CONFIG_FILE="${KERNEL_DIR}/krata-${TARGET_ARCH}.config" + +if [ ! -f "${KERNEL_CONFIG_FILE}" ] +then + echo "ERROR: kernel config file not found for ${TARGET_ARCH}" > /dev/stderr + exit 1 +fi + +cp "${KERNEL_CONFIG_FILE}" "${KERNEL_SRC}/.config" +make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" "${@}" olddefconfig + +if [ "${TARGET_ARCH}" = "x86_64" ] +then + make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" "${@}" bzImage +elif [ "${TARGET_ARCH}" = "arm64" ] +then + make -C "${KERNEL_SRC}" ARCH="${TARGET_ARCH}" "${@}" Image.gz +fi + +if [ "${TARGET_ARCH}" = "x86_64" ] +then + cp "${KERNEL_SRC}/arch/x86/boot/bzImage" "${OUTPUT_DIR}/kernel" +elif [ "${TARGET_ARCH}" = "arm64" ] +then + cp "${KERNEL_SRC}/arch/arm64/boot/Image.gz" "${OUTPUT_DIR}/kernel" +else + echo "ERROR: unable to determine what file is the vmlinuz for ${TARGET_ARCH}" > /dev/stderr + exit 1 +fi diff --git a/scripts/kernel/clean.sh b/scripts/kernel/clean.sh new file mode 100755 index 0000000..b2eef53 --- /dev/null +++ b/scripts/kernel/clean.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e + +REAL_SCRIPT="$(realpath "${0}")" +cd "$(dirname "${REAL_SCRIPT}")/../.." +KRATA_DIR="${PWD}" +KERNEL_DIR="${KRATA_DIR}/kernel" + +# shellcheck disable=SC2010 +for ITEM in $(ls "${KERNEL_DIR}" | grep "^linux-") +do + rm -rf "${KERNEL_DIR:?}/${ITEM}" +done diff --git a/scripts/kratactl-debug.sh b/scripts/kratactl-debug.sh deleted file mode 100755 index 860cd8a..0000000 --- a/scripts/kratactl-debug.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -set -e - -REAL_SCRIPT="$(realpath "${0}")" -# shellcheck source-path=krata-debug-common.sh -. "$(dirname "${REAL_SCRIPT}")/krata-debug-common.sh" - -KRATA_BUILD_INITRD=1 build_and_run kratactl "${@}" diff --git a/scripts/kratanet-debug.sh b/scripts/kratanet-debug.sh deleted file mode 100755 index 90b6986..0000000 --- a/scripts/kratanet-debug.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -set -e - -REAL_SCRIPT="$(realpath "${0}")" -# shellcheck source-path=krata-debug-common.sh -. "$(dirname "${REAL_SCRIPT}")/krata-debug-common.sh" - -build_and_run kratanet "${@}"