diff --git a/.github/actions/setup-build-env/action.yml b/.github/actions/setup-build-env/action.yml new file mode 100644 index 000000000..c5e5a1d37 --- /dev/null +++ b/.github/actions/setup-build-env/action.yml @@ -0,0 +1,42 @@ +name: 'Setup Build Environment' +description: 'Common setup for Rust builds with all required packages (Linux & macOS)' +runs: + using: 'composite' + steps: + - name: Install Rust toolchain + shell: bash + run: | + rustup update stable + rustup default stable + rustup component add rustfmt clippy + + - name: Cache Cargo dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + target + key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Set up Homebrew (macOS) + if: runner.os == 'macOS' + uses: Homebrew/actions/setup-homebrew@master + + - name: Install packages (macOS) + if: runner.os == 'macOS' + shell: bash + run: brew tap slp/krunkit && brew install virglrenderer clang-format llvm + + - name: Install packages (Linux) + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y \ + libvirglrenderer-dev \ + libepoxy-dev \ + libdrm-dev \ + libpipewire-0.3-dev \ + clang-format \ + libclang-dev diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 000000000..8465a3c7d --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,165 @@ +name: Code Quality +on: [pull_request] + +jobs: + code-quality-linux-x86_64: + name: libkrun (Linux x86_64) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: Create a fake init + run: touch init/init + + - name: Clippy (default) + run: cargo clippy --locked -- -D warnings + + - name: Clippy (amd-sev) + run: cargo clippy --locked --features amd-sev -- -D warnings + + - name: Clippy (tdx) + run: cargo clippy --locked --features tdx -- -D warnings + + - name: Clippy (net+blk+gpu+snd) + run: cargo clippy --locked --features net,blk,gpu,snd -- -D warnings + + code-quality-linux-aarch64: + name: libkrun (Linux aarch64) + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: Create a fake init + run: touch init/init + + - name: Clippy (default) + run: cargo clippy --locked -- -D warnings + + - name: Clippy (net+blk+gpu+snd) + run: cargo clippy --locked --features net,blk,gpu,snd -- -D warnings + + code-quality-macos: + name: libkrun (macOS aarch64) + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: Create a fake init + run: touch init/init + + - name: Clippy (efi+gpu) + run: cargo clippy --locked --features efi,gpu -- -D warnings + + code-quality-examples: + name: ${{ matrix.name }} + strategy: + matrix: + include: + - name: "Examples (Linux x86_64)" + runner: ubuntu-latest + + - name: "Examples (Linux aarch64)" + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: Cache GLib 2.82 + GTK 4.16 build + uses: actions/cache@v4 + id: gtk-cache + with: + path: ~/gtk-prefix + key: ${{ runner.os }}-${{ runner.arch }}-gtk-4.16.0 + + - name: Install GTK system dependencies + run: | + sudo apt-get update + sudo apt-get install -yqq --no-install-recommends \ + libffi-dev \ + libmount-dev \ + libpcre2-dev \ + zlib1g-dev \ + libcairo2-dev \ + libpango1.0-dev \ + libgdk-pixbuf-2.0-dev \ + libgraphene-1.0-dev \ + libepoxy-dev \ + libxkbcommon-dev \ + wayland-protocols \ + libwayland-dev + + - name: Add GLib + GTK paths to environment + run: | + case "$(uname -m)" in + x86_64) + GTK_PKG_CONFIG_PATH="$HOME/gtk-prefix/lib/x86_64-linux-gnu/pkgconfig" + GTK_LIB_PATH="$HOME/gtk-prefix/lib/x86_64-linux-gnu" ;; + aarch64) + GTK_PKG_CONFIG_PATH="$HOME/gtk-prefix/lib/aarch64-linux-gnu/pkgconfig" + GTK_LIB_PATH="$HOME/gtk-prefix/lib/aarch64-linux-gnu" ;; + *) + echo "ERROR: Unsupported architecture: $(uname -m)" + exit 1 ;; + esac + + echo "PKG_CONFIG_PATH=$GTK_PKG_CONFIG_PATH:$PKG_CONFIG_PATH" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=$GTK_LIB_PATH:$LD_LIBRARY_PATH" >> $GITHUB_ENV + + - name: Build and install GTK 4.16 from source + if: steps.gtk-cache.outputs.cache-hit != 'true' + run: | + # Install build-only dependencies + sudo apt-get install -yqq --no-install-recommends \ + build-essential \ + meson \ + ninja-build + + + # Build GLib first + cd /tmp + curl -L -o glib-2.82.2.tar.xz https://download.gnome.org/sources/glib/2.82/glib-2.82.2.tar.xz + tar -xf glib-2.82.2.tar.xz + cd glib-2.82.2 + meson setup builddir --prefix=$HOME/gtk-prefix --buildtype=release + meson compile -C builddir + meson install -C builddir + + # Build GTK + cd /tmp + curl -L -o gtk-4.16.0.tar.xz https://download.gnome.org/sources/gtk/4.16/gtk-4.16.0.tar.xz + tar -xf gtk-4.16.0.tar.xz + cd gtk-4.16.0 + meson setup builddir --prefix=$HOME/gtk-prefix --buildtype=release \ + -Dmedia-gstreamer=disabled \ + -Dintrospection=disabled \ + -Dx11-backend=false \ + -Dprint-cups=disabled \ + -Dcloudproviders=disabled \ + -Dtracker=disabled \ + -Dcolord=disabled \ + -Dsysprof=disabled \ + -Dvulkan=disabled + meson compile -C builddir + meson install -C builddir + + - name: Build and install libkrun to local prefix + run: | + mkdir -p $HOME/libkrun-prefix + GPU=1 NET=1 INPUT=1 PREFIX=$HOME/libkrun-prefix make && PREFIX=$HOME/libkrun-prefix make install + + - name: Clippy (examples workspace) + run: | + cd examples + PKG_CONFIG_PATH="$HOME/libkrun-prefix/lib64/pkgconfig:$PKG_CONFIG_PATH" LD_LIBRARY_PATH="$HOME/libkrun-prefix/lib64:$LD_LIBRARY_PATH" cargo clippy --locked -- -D warnings diff --git a/.github/workflows/code_quality-aarch64-darwin.yml b/.github/workflows/code_quality-aarch64-darwin.yml deleted file mode 100644 index ee9a13c60..000000000 --- a/.github/workflows/code_quality-aarch64-darwin.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: macOS-aarch64 -on: [pull_request, create] - -jobs: - build: - if: github.event_name == 'pull_request' - name: Code Quality (fmt, clippy) - runs-on: macos-latest - steps: - - name: Code checkout - uses: actions/checkout@v2 - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Set up Homebrew - id: set-up-homebrew - uses: Homebrew/actions/setup-homebrew@master - - - name: Install dependencies - run: brew tap slp/krunkit && brew install virglrenderer clang-format llvm - - - name: Create a fake init - run: touch init/init - - - name: Formatting (clang-format) - run: find init -iname '*.h' -o -iname '*.c' | xargs clang-format -n -Werror - - - name: Formatting (rustfmt) - run: cargo fmt -- --check - - - name: Clippy (efi+gpu features) - run: LIBCLANG_PATH=/opt/homebrew/opt/llvm/lib cargo clippy --features efi,gpu -- -D warnings diff --git a/.github/workflows/code_quality-aarch64.yml b/.github/workflows/code_quality-aarch64.yml deleted file mode 100644 index 5714177a9..000000000 --- a/.github/workflows/code_quality-aarch64.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: linux-aarch64 -on: [pull_request, create] - -jobs: - build: - if: github.event_name == 'pull_request' - name: Code Quality (fmt, clippy, clang-format) - runs-on: ubuntu-24.04-arm - steps: - - name: Code checkout - uses: actions/checkout@v2 - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Install packages - run: sudo apt-get update && sudo apt-get install -y libvirglrenderer-dev libepoxy-dev libdrm-dev libpipewire-0.3-dev clang-format libclang-dev - - - name: Formatting (clang-format) - run: find init -iname '*.h' -o -iname '*.c' | xargs clang-format -n -Werror - - - name: Create a fake init - run: touch init/init - - - name: Formatting (rustfmt) - run: cargo fmt -- --check - - - name: Clippy (default features) - run: cargo clippy -- -D warnings - - - name: Clippy (net+blk+gpu+snd features) - run: cargo clippy --features net,blk,gpu,snd -- -D warnings diff --git a/.github/workflows/code_quality-x86_64.yml b/.github/workflows/code_quality-x86_64.yml deleted file mode 100644 index ca19d04eb..000000000 --- a/.github/workflows/code_quality-x86_64.yml +++ /dev/null @@ -1,98 +0,0 @@ -name: linux-x86_64 -on: [pull_request, create] - -jobs: - build: - if: github.event_name == 'pull_request' - name: Code Quality (fmt, clippy, clang-format) - runs-on: ubuntu-latest - steps: - - name: Code checkout - uses: actions/checkout@v2 - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Install packages - run: sudo apt-get update && sudo apt-get install -y libvirglrenderer-dev libepoxy-dev libdrm-dev libpipewire-0.3-dev clang-format libclang-dev - - - name: Formatting (clang-format) - run: find init -iname '*.h' -o -iname '*.c' | xargs clang-format -n -Werror - - - name: Create a fake init - run: touch init/init - - - name: Formatting (rustfmt) - run: cargo fmt -- --check - - - name: Clippy (default features) - run: cargo clippy -- -D warnings - - - name: Clippy (amd-sev feature) - run: cargo clippy --features amd-sev -- -D warnings - - - name: Clippy (tdx feature) - run: cargo clippy --features tdx -- -D warnings - - - name: Clippy (net+blk+gpu+snd features) - run: cargo clippy --features net,blk,gpu,snd -- -D warnings - - unit: - if: github.event_name == 'pull_request' - name: Unit Tests - runs-on: ubuntu-latest - steps: - - name: Code checkout - uses: actions/checkout@v2 - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt, clippy - - - name: Enable KVM group perms - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - sudo usermod -a -G kvm $USER - - - name: Install packages - run: sudo apt-get update && sudo apt-get install -y libvirglrenderer-dev libepoxy-dev libdrm-dev libpipewire-0.3-dev libclang-dev - - - name: Create a fake init - run: touch init/init - - - name: Unit tests - run: cargo test - - integration: - if: github.event_name == 'pull_request' - name: Integration Tests - runs-on: ubuntu-latest - steps: - - name: Code checkout - uses: actions/checkout@v2 - - name: Install Rust toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: x86_64-unknown-linux-musl - - - name: Enable KVM group perms - run: | - echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules - sudo udevadm control --reload-rules - sudo udevadm trigger --name-match=kvm - sudo usermod -a -G kvm $USER - - - name: Install packages - run: sudo apt-get update && sudo apt-get install -y build-essential patchelf libclang-dev pkg-config net-tools libvirglrenderer-dev libepoxy-dev libdrm-dev libpipewire-0.3-dev - - - name: Install libkrunfw - run: curl -L -o /tmp/libkrunfw-4.9.0-x86_64.tgz https://github.com/containers/libkrunfw/releases/download/v4.9.0/libkrunfw-4.9.0-x86_64.tgz && mkdir tmp && tar xf /tmp/libkrunfw-4.9.0-x86_64.tgz -C tmp && sudo mv tmp/lib64/* /lib/x86_64-linux-gnu - - - name: Integration tests - run: RUST_LOG=trace KRUN_ENOMEM_WORKAROUND=1 KRUN_NO_UNSHARE=1 make test diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml new file mode 100644 index 000000000..da7673b59 --- /dev/null +++ b/.github/workflows/formatting.yml @@ -0,0 +1,24 @@ +name: Code Formatting +on: [pull_request] + +jobs: + formatting: + name: clang-format + cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: C code formatting + run: find init -iname '*.h' -o -iname '*.c' | xargs clang-format -n -Werror + + - name: Rust code formatting + run: cargo fmt -- --check + + - name: Rust code formatting (examples) + run: cd examples; cargo fmt -- --check + + - name: Rust code formatting (tests) + run: cd tests; cargo fmt -- --check diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml new file mode 100644 index 000000000..a7403a071 --- /dev/null +++ b/.github/workflows/integration_tests.yml @@ -0,0 +1,55 @@ +name: Integration tests +on: [pull_request] + +jobs: + # x86_64 only due to virtualization limitations of GitHub Actions + integration-tests: + name: Integration Tests (Linux x86_64) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: Add musl target + run: rustup target add x86_64-unknown-linux-musl + + - name: Build and install libkrun to test prefix + run: make test-prefix + + - name: Clippy (test_cases guest) + run: | + cd tests + cargo clippy --locked -p test_cases --features guest -- -D warnings + + - name: Clippy (test_cases host) + run: | + cd tests + PKG_CONFIG_PATH="$(realpath ../test-prefix/lib64/pkgconfig/)" LD_LIBRARY_PATH="$(realpath ../test-prefix/lib64/)" cargo clippy --locked -p test_cases --features host -- -D warnings + + - name: Clippy (runner) + run: | + cd tests + PKG_CONFIG_PATH="$(realpath ../test-prefix/lib64/pkgconfig/)" LD_LIBRARY_PATH="$(realpath ../test-prefix/lib64/)" cargo clippy --locked -p runner -- -D warnings + + - name: Clippy (guest-agent) + run: | + cd tests + cargo clippy --locked --target x86_64-unknown-linux-musl -p guest-agent -- -D warnings + + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + sudo usermod -a -G kvm $USER + + - name: Install additional packages + run: sudo apt-get install -y --no-install-recommends build-essential patchelf pkg-config net-tools + + - name: Install libkrunfw + run: curl -L -o /tmp/libkrunfw-4.9.0-x86_64.tgz https://github.com/containers/libkrunfw/releases/download/v4.9.0/libkrunfw-4.9.0-x86_64.tgz && mkdir tmp && tar xf /tmp/libkrunfw-4.9.0-x86_64.tgz -C tmp && sudo mv tmp/lib64/* /lib/x86_64-linux-gnu + + - name: Integration tests + run: RUST_LOG=trace KRUN_ENOMEM_WORKAROUND=1 KRUN_NO_UNSHARE=1 make test diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 000000000..59e304ea5 --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,26 @@ +name: Tests +on: [pull_request] + +jobs: + unit-tests: + name: Unit tests (${{ matrix.name }}) + runner: ubuntu-latest + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + + - name: Setup build environment + uses: ./.github/actions/setup-build-env + + - name: Create a fake init + run: touch init/init + + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + sudo usermod -a -G kvm $USER + + - name: Unit tests + run: cargo test \ No newline at end of file diff --git a/Makefile b/Makefile index 0e47e19b2..e1141625b 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ ifeq ($(PREFIX),) PREFIX := /usr/local endif -.PHONY: install clean test $(LIBRARY_RELEASE_$(OS)) $(LIBRARY_DEBUG_$(OS)) libkrun.pc +.PHONY: install clean test test-prefix $(LIBRARY_RELEASE_$(OS)) $(LIBRARY_DEBUG_$(OS)) libkrun.pc all: $(LIBRARY_RELEASE_$(OS)) libkrun.pc @@ -157,7 +157,11 @@ clean: rm -rf test-prefix cd tests; cargo clean -test: $(LIBRARY_RELEASE_$(OS)) +test-prefix/lib64/libkrun.pc: $(LIBRARY_RELEASE_$(OS)) mkdir -p test-prefix PREFIX="$$(realpath test-prefix)" make install + +test-prefix: test-prefix/lib64/libkrun.pc + +test: test-prefix cd tests; LD_LIBRARY_PATH="$$(realpath ../test-prefix/lib64/)" PKG_CONFIG_PATH="$$(realpath ../test-prefix/lib64/pkgconfig/)" ./run.sh diff --git a/tests/macros/src/lib.rs b/tests/macros/src/lib.rs index 67f1dabb7..563a990e3 100644 --- a/tests/macros/src/lib.rs +++ b/tests/macros/src/lib.rs @@ -13,7 +13,7 @@ pub fn guest(_args: TokenStream, input: TokenStream) -> TokenStream { .into(); prefix.extend(input); - prefix.into() + prefix } #[proc_macro_attribute] @@ -24,5 +24,5 @@ pub fn host(_args: TokenStream, input: TokenStream) -> TokenStream { .into(); prefix.extend(input); - prefix.into() + prefix } diff --git a/tests/test_cases/src/lib.rs b/tests/test_cases/src/lib.rs index a0be4d34a..68aa6433e 100644 --- a/tests/test_cases/src/lib.rs +++ b/tests/test_cases/src/lib.rs @@ -28,7 +28,10 @@ pub fn test_cases() -> Vec { }), ), TestCase::new("vsock-guest-connect", Box::new(TestVsockGuestConnect)), - TestCase::new("tsi-tcp-guest-connect", Box::new(TestTsiTcpGuestConnect::new())), + TestCase::new( + "tsi-tcp-guest-connect", + Box::new(TestTsiTcpGuestConnect::new()), + ), TestCase::new( "tsi-tcp-guest-listen", Box::new(TestTsiTcpGuestListen::new()), diff --git a/tests/test_cases/src/tcp_tester.rs b/tests/test_cases/src/tcp_tester.rs index 886c87bae..c90f12c3b 100644 --- a/tests/test_cases/src/tcp_tester.rs +++ b/tests/test_cases/src/tcp_tester.rs @@ -30,7 +30,7 @@ fn connect(port: u16) -> TcpStream { let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), port); let mut tries = 0; loop { - match TcpStream::connect(&addr) { + match TcpStream::connect(addr) { Ok(stream) => return stream, Err(err) => { if tries == 5 {