diff --git a/.github/actions/test/action.yml b/.github/actions/test/action.yml index ca4aa7d7f..019bee124 100644 --- a/.github/actions/test/action.yml +++ b/.github/actions/test/action.yml @@ -67,7 +67,7 @@ runs: run: | CMD="" [[ "${{ matrix.id }}" == "lint" ]] && CMD+="make check" - [[ "${{ matrix.id }}" == "compile" ]] && CMD+="make build FEATURES=all" + [[ "${{ matrix.id }}" == "compile" ]] && CMD+="make kernel FEATURES=all" [[ "${{ matrix.id }}" == "usermode_test" ]] && CMD+="make test" [[ "${{ matrix.id }}" == "ktest" ]] && CMD+="make ktest NETDEV=tap" [[ -n "${{ inputs.arch }}" ]] && CMD+=" OSDK_TARGET_ARCH=${{ inputs.arch }}" @@ -79,7 +79,7 @@ runs: if: ${{ !(inputs.auto_test == 'general' || inputs.auto_test == 'osdk') }} shell: bash run: | - CMD="make run AUTO_TEST=${{ inputs.auto_test }}" + CMD="make run_kernel AUTO_TEST=${{ inputs.auto_test }}" [[ "${{ inputs.intel_tdx }}" == "true" ]] && CMD+=" INTEL_TDX=1" [[ "${{ inputs.release }}" == "true" ]] && CMD+=" RELEASE=1" [[ "${{ inputs.enable_kvm }}" == "false" ]] && CMD+=" ENABLE_KVM=0" diff --git a/.github/workflows/test_asterinas_vsock.yml b/.github/workflows/test_asterinas_vsock.yml index 3a7e6fcee..3bc916ad4 100644 --- a/.github/workflows/test_asterinas_vsock.yml +++ b/.github/workflows/test_asterinas_vsock.yml @@ -24,7 +24,7 @@ jobs: docker run \ --privileged --network=host --device=/dev/kvm \ -v ./:/root/asterinas asterinas/asterinas:0.16.2-20251209 \ - make run AUTO_TEST=vsock ENABLE_KVM=0 SCHEME=microvm RELEASE_MODE=1 & + make run_kernel AUTO_TEST=vsock ENABLE_KVM=0 SCHEME=microvm RELEASE_MODE=1 & - name: Run Vsock Client on Host id: host_vsock_client run: | diff --git a/.github/workflows/test_iso_image.yml b/.github/workflows/test_iso_image.yml new file mode 100644 index 000000000..d74c1c6f6 --- /dev/null +++ b/.github/workflows/test_iso_image.yml @@ -0,0 +1,39 @@ +name: Test ISO image + +on: + workflow_dispatch: + pull_request: + paths: + - distro/** + - .github/workflows/test_iso_image.yml + - tools/nixos/** + push: + branches: + - main + paths: + - distro/** + - .github/workflows/test_iso_image.yml + - tools/nixos/** + +jobs: + iso-test: + runs-on: ubuntu-4-cores-150GB-ssd + container: + image: asterinas/asterinas:0.16.2-20251209 + options: -v /dev:/dev --privileged + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - name: Build Asterinas NixOS ISO installer image + run: | + make iso NIXOS_TEST_COMMAND='hello-asterinas' + - name: Run ISO image and install Asterinas NixOS + run: | + make run_iso || true + tail --lines 10 qemu.log | grep -q "^Installation finished" || (echo "Test ISO failed" && exit 1) + echo "Test ISO succeeds!" + - name : Run Asterinas NixOS + run: | + make run_nixos || true + tail --lines 10 qemu.log | grep -q "^Hello Asterinas!" || (echo "Test NixOS failed" && exit 1) + echo "Test NixOS succeeds!" diff --git a/.github/workflows/test_nixos_full.yml b/.github/workflows/test_nixos_full.yml index 0f7b0ac20..0494ee23d 100644 --- a/.github/workflows/test_nixos_full.yml +++ b/.github/workflows/test_nixos_full.yml @@ -33,12 +33,14 @@ jobs: - uses: actions/checkout@v4 - name: Use nix-env to install and run the hello package run: | - make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-env -iA nixos.hello && hello' || true + make nixos NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-env -iA nixos.hello && hello' || true + make run_nixos || true tail --lines 10 qemu.log | grep -q "^Hello, world!" || (echo "Test nix-env failed" && exit 1) echo "Test nix-env succeeds!" - name: Use nix-shell to install and run the hello package run: | - make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-shell -p hello --command hello' || true + make nixos NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='nix-shell -p hello --command hello' || true + make run_nixos || true tail --lines 10 qemu.log | grep -q "^Hello, world!" || (echo "Test nix-shell failed" && exit 1) echo "Test nix-shell succeeds!" @@ -56,6 +58,7 @@ jobs: distro/etc_nixos/configuration.nix - name: Run podman commands run: | - make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=8192 NIXOS_TEST_COMMAND='podman run docker.io/library/alpine:latest ls /etc' || true + make nixos NIXOS_DISK_SIZE_IN_MB=8192 NIXOS_TEST_COMMAND='podman run docker.io/library/alpine:latest ls /etc' || true + make run_nixos || true tail --lines 50 qemu.log | grep -q "alpine-release" || (echo "Test podman failed" && exit 1) echo "Test podman succeeds!" diff --git a/.github/workflows/test_nixos_minimal.yml b/.github/workflows/test_nixos_minimal.yml index 0dc8b594f..fc3223a07 100644 --- a/.github/workflows/test_nixos_minimal.yml +++ b/.github/workflows/test_nixos_minimal.yml @@ -37,7 +37,9 @@ jobs: with: image: asterinas/asterinas:0.16.2-20251209 options: --privileged -v /dev:/dev -v ${{ github.workspace }}:/root/asterinas - run: make run NIXOS=1 NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='hello-asterinas' || true + run: | + make nixos NIXOS_DISK_SIZE_IN_MB=6144 NIXOS_TEST_COMMAND='hello-asterinas' || true + make run_nixos || true - name: Check results run: | tail --lines 10 ${{ github.workspace }}/qemu.log | grep -q "^Hello Asterinas!" || (echo "Test NixOS failed" && exit 1) diff --git a/Makefile b/Makefile index 1174fc8ab..72f75cf7b 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,6 @@ DNS_SERVER ?= none # End of network settings # NixOS settings -NIXOS ?= 0 NIXOS_DISK_SIZE_IN_MB ?= 8192 NIXOS_DISABLE_SYSTEMD ?= false NIXOS_TEST_COMMAND ?= @@ -64,6 +63,10 @@ NIXOS_TEST_COMMAND ?= NIXOS_STAGE_2_INIT ?= /bin/sh -l # End of NixOS settings +# ISO installer settings +AUTO_INSTALL ?= true +# End of ISO installer settings + # ========================= End of Makefile options. ========================== SHELL := /bin/bash @@ -158,11 +161,6 @@ ifeq ($(NO_DEFAULT_FEATURES), 1) CARGO_OSDK_COMMON_ARGS += --no-default-features endif -ifeq ($(NIXOS), 1) -BOOT_PROTOCOL = linux-efi-handover64 -OVMF=off -endif - # To test the linux-efi-handover64 boot protocol, we need to use Debian's # GRUB release, which is installed in /usr/bin in our Docker image. ifeq ($(BOOT_PROTOCOL), linux-efi-handover64) @@ -248,7 +246,7 @@ OSDK_SRC_FILES := \ $(shell find osdk/Cargo.toml osdk/Cargo.lock osdk/src -type f) .PHONY: all -all: build +all: kernel # Install or update OSDK from source # To uninstall, do `cargo uninstall cargo-osdk` @@ -288,22 +286,15 @@ check_vdso: initramfs: check_vdso @$(MAKE) --no-print-directory -C test -.PHONY: build -build: initramfs $(CARGO_OSDK) +# Build the kernel with an initramfs +.PHONY: kernel +kernel: initramfs $(CARGO_OSDK) @cd kernel && cargo osdk build $(CARGO_OSDK_BUILD_ARGS) -ifeq ($(NIXOS),1) - @./tools/nixos/build_nixos.sh -endif -.PHONY: run -run: initramfs $(CARGO_OSDK) -ifeq ($(NIXOS),1) - @cd kernel && cargo osdk build $(CARGO_OSDK_BUILD_ARGS) - @./tools/nixos/build_nixos.sh - @./tools/nixos/run_nixos.sh target/nixos -else +# Build the kernel with an initramfs and then run it +.PHONY: run_kernel +run_kernel: initramfs $(CARGO_OSDK) @cd kernel && cargo osdk run $(CARGO_OSDK_BUILD_ARGS) -endif # Check the running status of auto tests from the QEMU log ifeq ($(AUTO_TEST), syscall) @tail --lines 100 qemu.log | grep -q "^All syscall tests passed." \ @@ -319,6 +310,29 @@ else ifeq ($(AUTO_TEST), vsock) || (echo "Vsock test failed" && exit 1) endif +# Build the Asterinas NixOS ISO installer image +iso: BOOT_PROTOCOL = linux-efi-handover64 +iso: + @make kernel + @./tools/nixos/build_iso.sh + +# Build the Asterinas NixOS ISO installer image and then do installation +run_iso: OVMF = off +run_iso: + @./tools/nixos/run_iso.sh + +# Create an Asterinas NixOS installation on host +nixos: BOOT_PROTOCOL = linux-efi-handover64 +nixos: + @make kernel + @./tools/nixos/build_nixos.sh + +# After creating a Asterinas NixOS installation (via either the `run_iso` or `nixos` target), +# run the NixOS +run_nixos: OVMF = off +run_nixos: + @./tools/nixos/run_nixos.sh target/nixos + .PHONY: gdb_server gdb_server: initramfs $(CARGO_OSDK) @cd kernel && cargo osdk run $(CARGO_OSDK_BUILD_ARGS) --gdb-server wait-client,vscode,addr=:$(GDB_TCP_PORT) diff --git a/README.md b/README.md index ec689ca0b..43d687a69 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,8 @@ docker run -it --privileged --network=host -v /dev:/dev -v $(pwd)/asterinas:/roo 3. Inside the container, go to the project folder to build and run Asterinas. ```bash -make build -make run +make kernel +make run_kernel ``` If everything goes well, Asterinas is now up and running inside a VM. diff --git a/README_CN.md b/README_CN.md index 60221c647..23c1b0774 100644 --- a/README_CN.md +++ b/README_CN.md @@ -62,8 +62,8 @@ docker run -it --privileged --network=host --device=/dev/kvm -v $(pwd)/asterinas 3. 在容器内,进入项目文件夹构建并运行星绽。 ```bash -make build -make run +make kernel +make run_kernel ``` 如果一切顺利,星绽现在应该在一个虚拟机内运行起来了。 diff --git a/README_JP.md b/README_JP.md index 834c450a4..64652d4ff 100644 --- a/README_JP.md +++ b/README_JP.md @@ -57,8 +57,8 @@ docker run -it --privileged --network=host --device=/dev/kvm -v $(pwd)/asterinas 3. コンテナ内でプロジェクトフォルダに移動し、Asterinasをビルドして実行します。 ```bash -make build -make run +make kernel +make run_kernel ``` すべてが順調に進めば、Asterinasは仮想マシン内で実行されます。 diff --git a/book/src/kernel/README.md b/book/src/kernel/README.md index ecbbe461c..315187684 100644 --- a/book/src/kernel/README.md +++ b/book/src/kernel/README.md @@ -54,8 +54,8 @@ docker run -it --privileged \ 3. Inside the container, go to the project folder to build and run Asterinas. ```bash -make build -make run +make kernel +make run_kernel ``` If everything goes well, Asterinas is now up and running inside a VM. diff --git a/book/src/kernel/advanced-instructions.md b/book/src/kernel/advanced-instructions.md index 5b7c9e31c..894457be6 100644 --- a/book/src/kernel/advanced-instructions.md +++ b/book/src/kernel/advanced-instructions.md @@ -37,7 +37,7 @@ cargo osdk test The following command builds and runs the test binaries in `test/src/apps` directory on Asterinas. ```bash -make run AUTO_TEST=test +make run_kernel AUTO_TEST=test ``` ### Syscall Test @@ -45,13 +45,13 @@ make run AUTO_TEST=test The following command builds and runs the syscall test binaries on Asterinas. ```bash -make run AUTO_TEST=syscall +make run_kernel AUTO_TEST=syscall ``` To run system call tests interactively, start an instance of Asterinas with the system call tests built and installed. ```bash -make run BUILD_SYSCALL_TEST=1 +make run_kernel BUILD_SYSCALL_TEST=1 ``` Then, in the interactive shell, run the following script to start the syscall tests. diff --git a/book/src/kernel/intel_tdx.md b/book/src/kernel/intel_tdx.md index cda2560c1..2c76c0d98 100644 --- a/book/src/kernel/intel_tdx.md +++ b/book/src/kernel/intel_tdx.md @@ -73,7 +73,7 @@ docker run -it --privileged --network=host --device=/dev/kvm -v $(pwd)/asterinas go to the project folder to build and run Asterinas. ```bash -make run INTEL_TDX=1 +make run_kernel INTEL_TDX=1 ``` If everything goes well, diff --git a/distro/aster_nixos_installer/default.nix b/distro/aster_nixos_installer/default.nix index a52fb9dfd..33e312d97 100644 --- a/distro/aster_nixos_installer/default.nix +++ b/distro/aster_nixos_installer/default.nix @@ -33,6 +33,7 @@ in pkgs.stdenv.mkDerivation { mkdir -p $out/{bin,etc_nixos} cp ${install_aster_nixos} $out/bin/install_aster_nixos.sh ln -s ${aster_configuration} $out/etc_nixos/aster_configuration.nix + ln -s ${etc-nixos}/configuration.nix $out/etc_nixos/configuration.nix ln -s ${etc-nixos}/modules $out/etc_nixos/modules ln -s ${etc-nixos}/overlays $out/etc_nixos/overlays ln -s ${aster-kernel} $out/kernel diff --git a/distro/aster_nixos_installer/templates/install_nixos.sh b/distro/aster_nixos_installer/templates/install_nixos.sh index e192300dc..16a88eef3 100644 --- a/distro/aster_nixos_installer/templates/install_nixos.sh +++ b/distro/aster_nixos_installer/templates/install_nixos.sh @@ -82,8 +82,13 @@ fi BUILD_DIR=$(mktemp -d -p /mnt) -BOOT_DEVICE=${DISK}p1 -ROOT_DEVICE=${DISK}p2 +if [ "${DISK#/dev/loop}" != "$DISK" ]; then + BOOT_DEVICE="${DISK}p1" + ROOT_DEVICE="${DISK}p2" +else + BOOT_DEVICE="${DISK}1" + ROOT_DEVICE="${DISK}2" +fi if [ ! -b "${BOOT_DEVICE}" ] && [ ! -b "${ROOT_DEVICE}" ]; then parted ${DISK} -- mklabel gpt parted ${DISK} -- mkpart ESP fat32 1MB 512MB diff --git a/distro/iso_image/default.nix b/distro/iso_image/default.nix new file mode 100644 index 000000000..84fe295ac --- /dev/null +++ b/distro/iso_image/default.nix @@ -0,0 +1,28 @@ +{ pkgs ? import { }, autoInstall ? false, test-command ? "", ... }: +let + installer = + pkgs.callPackage ../aster_nixos_installer { inherit test-command; }; + configuration = { + imports = [ + "${pkgs.path}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" + "${pkgs.path}/nixos/modules/installer/cd-dvd/channel.nix" + ]; + + services.getty.autologinUser = pkgs.lib.mkForce "root"; + environment.systemPackages = [ installer ]; + environment.loginShellInit = '' + if [ ! -e "$HOME/configuration.nix" ]; then + # Copy the default configuration.nix to user's home directory. + cp -L ${installer}/etc_nixos/configuration.nix $HOME + fi + + ${pkgs.lib.optionalString autoInstall '' + if [ "$(tty)" == "/dev/hvc0" ]; then + echo "The installer automatically runs on /dev/hvc0!" + install_aster_nixos.sh --config $HOME/configuration.nix --disk /dev/vda --force-format-disk || true + poweroff + fi + ''} + ''; + }; +in (pkgs.nixos configuration).config.system.build.isoImage diff --git a/test/README.md b/test/README.md index cddadd6ac..18017274b 100644 --- a/test/README.md +++ b/test/README.md @@ -38,9 +38,9 @@ While most tests rely on `Nix` for compilation, the `gvisor` syscall test suite The test suite supports building for multiple architectures, including `x86_64` and `riscv64`. You can specify the desired architecture by running: ```bash -make build OSDK_TARGET_ARCH=x86_64 +make kernel OSDK_TARGET_ARCH=x86_64 # or -make build OSDK_TARGET_ARCH=riscv64 +make kernel OSDK_TARGET_ARCH=riscv64 ``` The build artifacts (initramfs) can be found in the `test/build` directory after the compilation. diff --git a/test/src/benchmark/bench_linux_and_aster.sh b/test/src/benchmark/bench_linux_and_aster.sh index fd3a84e7d..9bb4f1bcd 100755 --- a/test/src/benchmark/bench_linux_and_aster.sh +++ b/test/src/benchmark/bench_linux_and_aster.sh @@ -118,7 +118,7 @@ run_benchmark() { done <<< "$runtime_configs_str" # Prepare commands for Asterinas and Linux using arrays - local asterinas_cmd_arr=(make run "BENCHMARK=${benchmark}") + local asterinas_cmd_arr=(make run_kernel "BENCHMARK=${benchmark}") # Add scheme part only if it's not empty and the platform is not TDX (OSDK doesn't support multiple SCHEME) [[ -n "$aster_scheme_cmd_part" && "$platform" != "tdx" ]] && asterinas_cmd_arr+=("$aster_scheme_cmd_part") asterinas_cmd_arr+=( diff --git a/tools/format_all.sh b/tools/format_all.sh index e117178c7..c32e42933 100755 --- a/tools/format_all.sh +++ b/tools/format_all.sh @@ -50,7 +50,7 @@ for CRATE in $EXCLUDED_CRATES; do continue ;; # `target/osdk/base` and `target/osdk/test-base` are generated by OSDK and does not need to be formatted. - # The directories do not exist before running `make build` or `make test`. + # The directories do not exist before running `make kernel` or `make test`. *target/osdk/base*) continue ;; diff --git a/tools/nixos/build_iso.sh b/tools/nixos/build_iso.sh new file mode 100755 index 000000000..0df72a8f1 --- /dev/null +++ b/tools/nixos/build_iso.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# SPDX-License-Identifier: MPL-2.0 + +set -e + +SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) +ASTERINAS_DIR=$(realpath ${SCRIPT_DIR}/../..) +DISTRO_DIR=$(realpath ${ASTERINAS_DIR}/distro) +TARGET_DIR=${ASTERINAS_DIR}/target/nixos + +mkdir -p ${TARGET_DIR} + +nix-build ${DISTRO_DIR}/iso_image \ + --arg autoInstall ${AUTO_INSTALL} \ + --argstr test-command "${NIXOS_TEST_COMMAND}" \ + --out-link ${TARGET_DIR}/iso_image diff --git a/tools/nixos/run_iso.sh b/tools/nixos/run_iso.sh new file mode 100755 index 000000000..ca0c47835 --- /dev/null +++ b/tools/nixos/run_iso.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# SPDX-License-Identifier: MPL-2.0 + +set -e + +SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) +ASTERINAS_DIR=$(realpath ${SCRIPT_DIR}/../..) +ASTER_IMAGE_PATH=${ASTERINAS_DIR}/target/nixos/asterinas.img +NIXOS_DISK_SIZE_IN_MB=${NIXOS_DISK_SIZE_IN_MB:-8192} +ISO_IMAGE_PATH=$(realpath ${ASTERINAS_DIR}/target/nixos/iso_image/iso/*.iso) + +if [ ! -f "$ISO_IMAGE_PATH" ]; then + echo "Error: ISO_IMAGE not found!" + exit 1 +fi + +rm -f ${ASTER_IMAGE_PATH} +echo "Creating image at ${ASTER_IMAGE_PATH} of size ${NIXOS_DISK_SIZE_IN_MB}MB......" +dd if=/dev/zero of=${ASTER_IMAGE_PATH} bs=1M count=${NIXOS_DISK_SIZE_IN_MB} +echo "Image created successfully!" + +QEMU_ARGS="qemu-system-x86_64 \ + -bios /root/ovmf/release/OVMF.fd \ + -cdrom ${ISO_IMAGE_PATH} -boot d \ + -drive if=none,format=raw,id=u0,file=${ASTER_IMAGE_PATH} \ + -device virtio-blk-pci,drive=u0,disable-legacy=on,disable-modern=off \ +" + +if [ "${ENABLE_KVM}" = "1" ]; then + QEMU_ARGS="${QEMU_ARGS} -accel kvm" +fi + +COMMON_QEMU_ARGS=$(${SCRIPT_DIR}/../qemu_args.sh common 2>/dev/null) +QEMU_ARGS=" + ${QEMU_ARGS} \ + ${COMMON_QEMU_ARGS} \ +" + +${QEMU_ARGS}